# ============================================
# SRAM PUF Demo — CMake Build
# Supports: Cortex-M0 (mps2-an386) + RISC-V (virt)
#
# Usage:
#   cmake -B build_m0  -G Ninja -DCMAKE_TOOLCHAIN_FILE=cmake/arm-none-eabi-toolchain.cmake
#   cmake -B build_riscv -G Ninja -DCMAKE_TOOLCHAIN_FILE=cmake/riscv-toolchain.cmake
#   ninja -C build_m0
#   ninja -C build_riscv
# ============================================

cmake_minimum_required(VERSION 3.15)
project(sram_puf_demo C ASM)

set(CMAKE_EXECUTABLE_SUFFIX ".elf")

# ── Random seed ──────────────────────────────────
# Generate a random 64-bit hex seed at configure time.
# Override by: cmake -DSRAM_PUF_RANDOM_SEED_HEX=abcd1234...
if(NOT SRAM_PUF_RANDOM_SEED_HEX)
    string(RANDOM LENGTH 16 ALPHABET 0123456789abcdef SRAM_PUF_RANDOM_SEED_HEX)
endif()
message(STATUS "SRAM PUF random seed: 0x${SRAM_PUF_RANDOM_SEED_HEX}")
add_compile_definitions(SRAM_PUF_RANDOM_SEED=0x${SRAM_PUF_RANDOM_SEED_HEX}ULL)

# ── Test trials ──────────────────────────────────
# Override by: cmake -DTEST_TRIALS=100
if(TEST_TRIALS)
    add_compile_definitions(TEST_TRIALS=${TEST_TRIALS})
    message(STATUS "TEST_TRIALS: ${TEST_TRIALS}")
endif()

# ── Include paths ────────────────────────────────
include_directories(
    ${CMAKE_SOURCE_DIR}/components/sram_puf_demo/include
    ${CMAKE_SOURCE_DIR}/components/sram_puf_demo/src
    ${CMAKE_SOURCE_DIR}/components/sram_puf_demo/src/sram_puf_para
)

# ── Common sources (shared by both architectures) ─
set(COMMON_SOURCES
    main.c
    components/sram_puf_demo/src/sram_puf_demo.c
    components/sram_puf_demo/src/sha256.c
    components/sram_puf_demo/src/sram_puf_bin_comm.c
)

# ═══════════════════════════════════════════════════
# Cortex-M0 target
# ═══════════════════════════════════════════════════
if(CPU_ARCH STREQUAL "arm-m0")
    set(TARGET_NAME firmware_m0)

    set(ARCH_SOURCES
        startup_m0.c
        components/sram_puf_demo/src/sram_puf_code_bin_enroll_recon_m0.c
    )

    add_executable(${TARGET_NAME}
        ${COMMON_SOURCES}
        ${ARCH_SOURCES}
    )

    target_compile_options(${TARGET_NAME} PRIVATE
        -mcpu=cortex-m0 -mthumb
        -nostdlib -nostartfiles -ffreestanding
        -O2 -Wall -Werror
        -DTARGET_MPS2
    )

    target_link_options(${TARGET_NAME} PRIVATE
        -mcpu=cortex-m0 -mthumb
        -nostdlib -nostartfiles -ffreestanding
        -T ${CMAKE_SOURCE_DIR}/mps2-an386.ld
    )

    target_link_libraries(${TARGET_NAME} PRIVATE gcc)

    set(TARGET_ELF ${TARGET_NAME}.elf)

    # POST_BUILD: generate .bin and .dis
    add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
        COMMAND ${CMAKE_OBJCOPY} -O binary ${TARGET_ELF} ${TARGET_NAME}.bin
        COMMAND ${CMAKE_OBJDUMP} -d ${TARGET_ELF} > ${TARGET_NAME}.dis
        COMMENT "Generating ${TARGET_NAME}.bin and ${TARGET_NAME}.dis"
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    )

    # QEMU run target (manual: ninja -C build_m0 qemu_run)
    add_custom_target(qemu_run
        COMMAND qemu-system-arm
            -machine mps2-an386 -nographic -semihosting
            -kernel ${TARGET_ELF}
        DEPENDS ${TARGET_NAME}
        COMMENT "Running ${TARGET_NAME} in QEMU (Cortex-M0)"
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    )

# ═══════════════════════════════════════════════════
# RISC-V target
# ═══════════════════════════════════════════════════
elseif(CPU_ARCH STREQUAL "riscv")
    set(TARGET_NAME firmware_riscv)

    set(ARCH_SOURCES
        start_riscv.S
        components/sram_puf_demo/src/sram_puf_code_bin_enroll_recon_riscv.c
    )

    add_executable(${TARGET_NAME}
        ${COMMON_SOURCES}
        ${ARCH_SOURCES}
    )

    target_compile_options(${TARGET_NAME} PRIVATE
        -march=rv32imc -mabi=ilp32
        -nostdlib -nostartfiles -ffreestanding
        -O2 -Wall -Werror
    )

    target_link_options(${TARGET_NAME} PRIVATE
        -march=rv32imc -mabi=ilp32
        -nostdlib -nostartfiles -ffreestanding
        -T ${CMAKE_SOURCE_DIR}/link_riscv.ld
    )

    target_link_libraries(${TARGET_NAME} PRIVATE gcc)

    set(TARGET_ELF ${TARGET_NAME}.elf)

    add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
        COMMAND ${CMAKE_OBJCOPY} -O binary ${TARGET_ELF} ${TARGET_NAME}.bin
        COMMAND ${CMAKE_OBJDUMP} -d ${TARGET_ELF} > ${TARGET_NAME}.dis
        COMMENT "Generating ${TARGET_NAME}.bin and ${TARGET_NAME}.dis"
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    )

    # QEMU run target (manual: ninja -C build_riscv qemu_run)
    add_custom_target(qemu_run
        COMMAND qemu-system-riscv32
            -machine virt -m 128M -nographic -bios none
            -kernel ${TARGET_ELF}
        DEPENDS ${TARGET_NAME}
        COMMENT "Running ${TARGET_NAME} in QEMU (RISC-V)"
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    )

else()
    message(FATAL_ERROR "Unknown CPU_ARCH: ${CPU_ARCH}. "
        "Use cmake/arm-none-eabi-toolchain.cmake or cmake/riscv-toolchain.cmake")
endif()

# ── Display info ─────────────────────────────────
message(STATUS "Target      : ${TARGET_NAME}")
message(STATUS "CC          : ${CMAKE_C_COMPILER}")
message(STATUS "Binary dir  : ${CMAKE_BINARY_DIR}")
