# Learnings — guomi-smart-card ## Architecture - C*Core C0 architecture (NOT ARM), little endian - Bare-metal while(1) super-loop, no RTOS - eFlash 512KB @ 0x00400000, RAM 64KB @ 0x00800000 - SPI FIFO only 8 bytes — MUST use DMA for any real data transfer ## Crypto API Conventions - Gen2 `_2` APIs (byte-buffer based) preferred over Gen1 struct-based - EDMAC clock discipline: ModuleClk_On before crypto, ModuleClk_Off after - TRNG must init first before any SM2 key generation - SM2/SM4/SHA share EDMAC channel — do not nest crypto operations ## SPI/DMA Critical Details (VERIFIED via .map file) - `dma_spitran()` binten hardcoded FALSE — interrupt branch is DEAD CODE - Must use `dma_spi_LLIReceive()` for continuous async receive - LLI `next_lli` points to itself for auto-loop - **`dmac_isr()` from `dmac_drv.c` is DISCARDED by linker — NOT in binary** - **Actual IRQ4 handler = `DMA_IRQHandler` from `libCUni360S_mcc.a(mcc_bsp.o)` at 0x0041b2ac** - **MUST modify `vector_table.h` ISR24** to repoint IRQ4 to our own DMA handler - **Vector table is `void *const` in flash** — `interrupt_setup()` only sets EIC priority, NOT the vector - SPI1+SPI2+PIT32 share IRQ3 (ISR23 = PIT32_SPI1_SPI2_ISR) - DMA completion interrupt goes through IRQ4 (ISR24) - DMAC_INT_NUM = 0x24 = VecTable[36] = ISR24 - SPI1 base = 0x70000000, SPIDR offset = 0x12 (verified in spi_reg.h and dmac_drv.c) - SPI instances spaced 0x10000 apart: SPI1=0x70000000, SPI2=0x70010000, SPI3=0x70020000 ## CRC Hardware (VERIFIED) - Hardware CRC engine does NOT support configurable polynomials - CRC_CR has NO polynomial field — only mode (CRC-8/16/32), source, endianness - **CRC16-CCITT (0x1021) MUST be implemented in SOFTWARE** - CRC0_BASE_ADDR = 0x78000000, CRC1_BASE_ADDR = 0x7c000000 ## RAM Budget (VERIFIED via .map file) - .data = 2,992 bytes (0xBB0) at 0x00800000-0x00800BB0 - .bss = 6,740 bytes (0x1A54) at 0x00800BB0-0x00802604 - Total used: 9,732 bytes (14.8%) - Free heap: 47,608 bytes (0xB9F8) from 0x00802604 to 0x0080DFFC - Stack: 8,192 bytes from 0x0080DFFC to 0x0080FFFC - _bss_end = 0x00802604, _end = 0x0080DFFC, STACK_LOCATION = 0x0080FFFC ## eFlash Budget (VERIFIED via .map file) - Firmware end: 0x0041C098 (.text_entry + .rodata + .text + .data LMA) - .bin size = 114,840 bytes = 0x1C098 (matches) - Key storage 0x00470000-0x00470800 = 100% free, page-aligned (pages 896-899) - EFLASH_END per alg_drv.h = 0x0047F000 (4KB reserved at top) - 343KB gap between firmware end and key storage region ## eFlash Key Storage - EFLASH_SetWritePermission() is GLOBAL — no per-page protection - Must verify address range BEFORE enabling write, clear IMMEDIATELY after - 512 bytes per page, log-structured wear leveling across 4 pages ## Git Strategy - Remote: http://gogs.weclouds.xyz:3000/kennyh/encryption_sm.git - Branch: main - Commit + push after each task completion