feat: optimize startup and linking
This commit is contained in:
@@ -19,27 +19,34 @@ CFLAGS += -nostartfiles -nostdlib -nostdinc -static -fno-builtin
|
|||||||
CFLAGS += -DCLOCKS_PER_SEC=CORE_CLOCKS_PER_SEC -D_CLOCKS_PER_SEC_=CORE_CLOCKS_PER_SEC
|
CFLAGS += -DCLOCKS_PER_SEC=CORE_CLOCKS_PER_SEC -D_CLOCKS_PER_SEC_=CORE_CLOCKS_PER_SEC
|
||||||
CFLAGS += -DUSE_CPU_CLOCK_COUNT
|
CFLAGS += -DUSE_CPU_CLOCK_COUNT
|
||||||
|
|
||||||
|
LINKER_SCRIPT ?= $(COMMON_DIR)/env/script.lds
|
||||||
|
BSP_STARTUP ?= $(COMMON_DIR)/env/start.S
|
||||||
|
BSP_USE_TRAP ?= 1
|
||||||
|
BSP_USE_DRIVERS ?= 1
|
||||||
|
|
||||||
#若使用 newlib , 将下面的 -lsemihost 替换为 -lgloss
|
#若使用 newlib , 将下面的 -lsemihost 替换为 -lgloss
|
||||||
LDFLAGS += -T $(LINKER_SCRIPT) \
|
LDFLAGS += -T $(LINKER_SCRIPT) \
|
||||||
-Wl,--gc-sections -Wl,--check-sections \
|
-Wl,--gc-sections -Wl,--check-sections \
|
||||||
-lc -lm -lg -lsemihost -lgcc -L$(PICOLIBC_DIR)/lib
|
-lc -lm -lg -lsemihost -lgcc -L$(PICOLIBC_DIR)/lib
|
||||||
|
|
||||||
LINKER_SCRIPT := $(COMMON_DIR)/env/script.lds
|
ASM_SRCS += $(BSP_STARTUP)
|
||||||
|
|
||||||
ASM_SRCS += $(COMMON_DIR)/env/start.S
|
|
||||||
|
|
||||||
|
ifeq ($(BSP_USE_TRAP),1)
|
||||||
ifeq ($(TARGET), RTThread_Nano)
|
ifeq ($(TARGET), RTThread_Nano)
|
||||||
|
|
||||||
else
|
else
|
||||||
ASM_SRCS += $(COMMON_DIR)/env/trap_handler.S
|
ASM_SRCS += $(COMMON_DIR)/env/trap_handler.S
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(BSP_USE_DRIVERS),1)
|
||||||
C_SRCS += $(COMMON_DIR)/drivers/confreg_time.c
|
C_SRCS += $(COMMON_DIR)/drivers/confreg_time.c
|
||||||
C_SRCS += $(COMMON_DIR)/drivers/core_time.c
|
C_SRCS += $(COMMON_DIR)/drivers/core_time.c
|
||||||
C_SRCS += $(COMMON_DIR)/drivers/common_func.c
|
C_SRCS += $(COMMON_DIR)/drivers/common_func.c
|
||||||
C_SRCS += $(COMMON_DIR)/drivers/dvi.c \
|
C_SRCS += $(COMMON_DIR)/drivers/dvi.c \
|
||||||
$(COMMON_DIR)/drivers/led.c \
|
$(COMMON_DIR)/drivers/led.c \
|
||||||
$(COMMON_DIR)/drivers/seg7.c
|
$(COMMON_DIR)/drivers/seg7.c
|
||||||
|
endif
|
||||||
|
|
||||||
INCLUDES += -I./ \
|
INCLUDES += -I./ \
|
||||||
-I$(COMMON_DIR)/include \
|
-I$(COMMON_DIR)/include \
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
#include "fft.h"
|
|
||||||
#include "common_func.h"
|
|
||||||
|
|
||||||
void fft_start() {
|
|
||||||
RegWrite(FFT_CSR_REG, FFT_CTRL_START);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fft_wait() {
|
|
||||||
while ((RegRead(FFT_CSR_REG) & FFT_STAT_DONE) == 0) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int fft_get_csr() {
|
|
||||||
return RegRead(FFT_CSR_REG);
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
volatile uint32_t SRC_ADDR; // 0x00: 源地址
|
|
||||||
volatile uint32_t DST_ADDR; // 0x04: 目的地址
|
|
||||||
volatile uint32_t LENGTH; // 0x08: 传输总字节数
|
|
||||||
volatile uint32_t TAG; // 0x0C: 软件 Tag (硬件不处理,留给软件标记任务用)
|
|
||||||
volatile uint32_t CTRL; // 0x10: 控制寄存器 (配置 Burst 属性 + 启动)
|
|
||||||
volatile uint32_t STATUS; // 0x14: 状态寄存器 (Busy, Done)
|
|
||||||
volatile uint32_t MODE; // 0x18: 0=mem2mem, 1=mem2ep, 2=ep2mem
|
|
||||||
volatile uint32_t EP_CFG; // 0x1C: [3:0]=bank, [15:8]=word offset, [19:16]=endpoint id
|
|
||||||
volatile uint32_t RESV[8]; // 0x20 ~ 0x3C: 保留空间,凑齐 0x40 字节
|
|
||||||
} dma_ch_regs_t;
|
|
||||||
|
|
||||||
// DMA 控制器基地址
|
|
||||||
#define CDMA_MUX_BASE 0xbf300000
|
|
||||||
#define DMA_CH(i) ((volatile dma_ch_regs_t*)(CDMA_MUX_BASE + (i) * 0x40))
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
volatile uint32_t CTRL; // 0x200: bit0 start
|
|
||||||
volatile uint32_t STATUS; // 0x204: bit0 busy, bit1 done (W1C)
|
|
||||||
volatile uint32_t SRC_BASE; // 0x208
|
|
||||||
volatile uint32_t DST_BASE; // 0x20C
|
|
||||||
volatile uint32_t GROUPS; // 0x210
|
|
||||||
volatile uint32_t MAT_BASE; // 0x214: 保留,兼容旧软件
|
|
||||||
volatile uint32_t SRC_STRIDE; // 0x218
|
|
||||||
volatile uint32_t DST_STRIDE; // 0x21C
|
|
||||||
} dma_seq_regs_t;
|
|
||||||
|
|
||||||
#define DMA_SEQ ((volatile dma_seq_regs_t*)(CDMA_MUX_BASE + 0x200))
|
|
||||||
|
|
||||||
// CTRL 寄存器位定义
|
|
||||||
#define CTRL_START_BIT (1 << 0)
|
|
||||||
#define CTRL_BURST_SIZE(x) (((x) & 0x7) << 3) // Bits [5:3]: AXI AxSIZE (0=1B, 1=2B, 2=4B, 3=8B)
|
|
||||||
#define CTRL_BURST_LEN(x) (((x) & 0xFF) << 6) // Bits [13:6]: AXI AxLEN (0=1 beat, 15=16 beats)
|
|
||||||
|
|
||||||
#define DMA_MODE_MEM2MEM 0
|
|
||||||
#define DMA_MODE_MEM2EP 1
|
|
||||||
#define DMA_MODE_EP2MEM 2
|
|
||||||
#define DMA_EP_CFG(id, bank, word_off) \
|
|
||||||
((((id) & 0xF) << 16) | (((word_off) & 0xFF) << 8) | ((bank) & 0xF))
|
|
||||||
|
|
||||||
// STATUS 寄存器位定义
|
|
||||||
#define STATUS_BUSY_BIT (1 << 0)
|
|
||||||
#define STATUS_DONE_BIT (1 << 1)
|
|
||||||
|
|
||||||
#define SEQ_START_BIT (1 << 0)
|
|
||||||
#define SEQ_SKIP_STORE_BIT (1 << 1)
|
|
||||||
#define SEQ_BUSY_BIT (1 << 0)
|
|
||||||
#define SEQ_DONE_BIT (1 << 1)
|
|
||||||
|
|
||||||
void dma_start_transfer(int ch_id, uint32_t src, uint32_t dst, uint32_t bytes, uint32_t tag);
|
|
||||||
void dma_wait_polling(int ch_id);
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#define FFT_BASE 0xbf400000
|
|
||||||
#define FFT_IN_RE_BASE (FFT_BASE + 0x1000)
|
|
||||||
#define FFT_IN_IM_BASE (FFT_BASE + 0x2000)
|
|
||||||
#define FFT_OUT_RE_BASE (FFT_BASE + 0x3000)
|
|
||||||
#define FFT_OUT_IM_BASE (FFT_BASE + 0x4000)
|
|
||||||
#define FFT_CSR_REG (FFT_BASE + 0xF000)
|
|
||||||
#define FFT_CTRL_START (1 << 4)
|
|
||||||
#define FFT_STAT_DONE (1 << 1)
|
|
||||||
#define FFT_STAT_BUSY (1 << 0)
|
|
||||||
#define FFT_POINT_NUM 1024
|
|
||||||
|
|
||||||
void fft_start();
|
|
||||||
void fft_wait();
|
|
||||||
unsigned int fft_get_csr();
|
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
TARGET = user-sample
|
TARGET = user-sample
|
||||||
|
|
||||||
MATMUL_GROUP_NUM ?= 5000
|
MATMUL_GROUP_NUM ?= 5000
|
||||||
CFLAGS += -O3 -g -DMATMUL_GROUP_NUM=$(MATMUL_GROUP_NUM)
|
MATMUL_WRITEBACK_RESULTS ?= 0
|
||||||
|
MATMUL_FAST_START ?= 1
|
||||||
|
CFLAGS += -O3 -g -DMATMUL_GROUP_NUM=$(MATMUL_GROUP_NUM) -DMATMUL_WRITEBACK_RESULTS=$(MATMUL_WRITEBACK_RESULTS) -DMATMUL_FAST_START=$(MATMUL_FAST_START)
|
||||||
|
|
||||||
C_SRCS := $(wildcard ./*.c )
|
C_SRCS := $(wildcard ./*.c )
|
||||||
|
|
||||||
@@ -9,6 +11,14 @@ OBJDIR = obj
|
|||||||
COMMON_DIR = ../../bsp
|
COMMON_DIR = ../../bsp
|
||||||
GCC_DIR=../../../toolchains/loongson-gnu-toolchain-8.3-x86_64-loongarch32r-linux-gnusf-v2.0
|
GCC_DIR=../../../toolchains/loongson-gnu-toolchain-8.3-x86_64-loongarch32r-linux-gnusf-v2.0
|
||||||
PICOLIBC_DIR=../../../toolchains/picolibc
|
PICOLIBC_DIR=../../../toolchains/picolibc
|
||||||
|
|
||||||
|
ifeq ($(MATMUL_FAST_START),1)
|
||||||
|
LINKER_SCRIPT := script_matmul_fast.lds
|
||||||
|
BSP_STARTUP := start_matmul_fast.S
|
||||||
|
BSP_USE_TRAP := 0
|
||||||
|
BSP_USE_DRIVERS := 0
|
||||||
|
endif
|
||||||
|
|
||||||
include ../../bsp/common.mk
|
include ../../bsp/common.mk
|
||||||
|
|
||||||
# Strip picolibc: no -lc -lm -lg -lsemihost, keep -lgcc only
|
# Strip picolibc: no -lc -lm -lg -lsemihost, keep -lgcc only
|
||||||
|
|||||||
90
sdk/software/examples/asm/script_matmul_fast.lds
Normal file
90
sdk/software/examples/asm/script_matmul_fast.lds
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
OUTPUT_ARCH(loongarch)
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
isram (rwxai) : ORIGIN = 0x1c000000, LENGTH = 512K
|
||||||
|
dsram (rwxai) : ORIGIN = 0x1c080000, LENGTH = 512K
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
__stack_size = DEFINED(__stack_size) ? __stack_size : 4K;
|
||||||
|
|
||||||
|
.init :
|
||||||
|
{
|
||||||
|
KEEP(*(SORT_NONE(.init)))
|
||||||
|
} >isram AT>isram
|
||||||
|
|
||||||
|
. = ALIGN(16);
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
_ftext = .;
|
||||||
|
*(.text.unlikely .text.unlikely.*)
|
||||||
|
*(.text.startup .text.startup.*)
|
||||||
|
*(.text .text.*)
|
||||||
|
*(.gnu.linkonce.t.*)
|
||||||
|
} >isram AT>isram
|
||||||
|
|
||||||
|
. = ALIGN(16);
|
||||||
|
.rodata :
|
||||||
|
{
|
||||||
|
*(.rdata)
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
*(.srodata.cst16)
|
||||||
|
*(.srodata.cst8)
|
||||||
|
*(.srodata.cst4)
|
||||||
|
*(.srodata.cst2)
|
||||||
|
*(.srodata .srodata.*)
|
||||||
|
} >isram AT>isram
|
||||||
|
|
||||||
|
. = ALIGN(16);
|
||||||
|
PROVIDE(__etext = .);
|
||||||
|
PROVIDE(_etext = .);
|
||||||
|
PROVIDE(etext = .);
|
||||||
|
PROVIDE(_data_lma = .);
|
||||||
|
|
||||||
|
.data ORIGIN(dsram) :
|
||||||
|
{
|
||||||
|
PROVIDE(_data = .);
|
||||||
|
*(.data .data.*)
|
||||||
|
*(.gnu.linkonce.d.*)
|
||||||
|
. = ALIGN(16);
|
||||||
|
PROVIDE(__global_pointer$ = . + 0x800);
|
||||||
|
*(.sdata .sdata.*)
|
||||||
|
*(.gnu.linkonce.s.*)
|
||||||
|
. = ALIGN(16);
|
||||||
|
PROVIDE(_edata = .);
|
||||||
|
PROVIDE(edata = .);
|
||||||
|
} >dsram AT>isram
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
PROVIDE(__bss_start = .);
|
||||||
|
*(.sbss*)
|
||||||
|
*(.sbss.*)
|
||||||
|
*(.dynsbss)
|
||||||
|
*(.scommon)
|
||||||
|
*(.bss)
|
||||||
|
*(.bss.*)
|
||||||
|
*(.dynbss)
|
||||||
|
*(.gnu.linkonce.sb.*)
|
||||||
|
*(.gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(16);
|
||||||
|
PROVIDE(_end = .);
|
||||||
|
PROVIDE(end = .);
|
||||||
|
} >dsram AT>dsram
|
||||||
|
|
||||||
|
PROVIDE(__heap_start = _end);
|
||||||
|
|
||||||
|
.stack ORIGIN(dsram) + LENGTH(dsram) - __stack_size :
|
||||||
|
{
|
||||||
|
PROVIDE(_heap_end = .);
|
||||||
|
PROVIDE(__heap_end = _heap_end);
|
||||||
|
PROVIDE(__heap_size = __heap_end - __heap_start);
|
||||||
|
. = __stack_size;
|
||||||
|
PROVIDE(_stack = .);
|
||||||
|
} >dsram AT>dsram
|
||||||
|
}
|
||||||
54
sdk/software/examples/asm/start_matmul_fast.S
Normal file
54
sdk/software/examples/asm/start_matmul_fast.S
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#include "regdef.h"
|
||||||
|
|
||||||
|
.section .init
|
||||||
|
.globl _start
|
||||||
|
.type _start, @function
|
||||||
|
|
||||||
|
_start:
|
||||||
|
/* Enable direct mapped windows used by SRAM and uncached peripherals. */
|
||||||
|
li.w t0, 0x8
|
||||||
|
li.w t1, 0x18
|
||||||
|
csrxchg t0, t1, csr_crmd
|
||||||
|
|
||||||
|
csrwr zero, csr_dmw0
|
||||||
|
csrwr zero, csr_dmw1
|
||||||
|
li.w t0, 0x19
|
||||||
|
csrwr t0, csr_dmw0
|
||||||
|
li.w t0, 0xa0000009
|
||||||
|
csrwr t0, csr_dmw1
|
||||||
|
|
||||||
|
li.w t0, 0x10
|
||||||
|
li.w t1, 0x18
|
||||||
|
csrxchg t0, t1, csr_crmd
|
||||||
|
|
||||||
|
/* Polling-only benchmark: keep interrupts disabled. */
|
||||||
|
li.w t0, 0x4
|
||||||
|
csrxchg zero, t0, csr_crmd
|
||||||
|
csrwr zero, csr_prmd
|
||||||
|
csrwr zero, csr_ecfg
|
||||||
|
|
||||||
|
/* UART0 init, 115200 baud with the same divisor selection as BSP start.S. */
|
||||||
|
li.w t0, 0xbf000000
|
||||||
|
li.w t1, 0x07
|
||||||
|
st.b t1, t0, 2
|
||||||
|
li.w t1, 0x80
|
||||||
|
st.b t1, t0, 3
|
||||||
|
st.b zero, t0, 1
|
||||||
|
li.w t2, 0xbf20f500
|
||||||
|
ld.w t2, t2, 0
|
||||||
|
li.w t1, 0x1b
|
||||||
|
beq zero, t2, 1f
|
||||||
|
li.w t1, 0x1
|
||||||
|
1:
|
||||||
|
st.b t1, t0, 0
|
||||||
|
li.w t1, 0x03
|
||||||
|
st.b t1, t0, 3
|
||||||
|
st.b zero, t0, 4
|
||||||
|
|
||||||
|
la.local sp, _stack
|
||||||
|
li.w a0, 0
|
||||||
|
li.w a1, 0
|
||||||
|
bl main
|
||||||
|
|
||||||
|
1:
|
||||||
|
b 1b
|
||||||
@@ -26,6 +26,23 @@ static void uart_puts(const char *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void uart_put_matmul_start_fifo(void)
|
||||||
|
{
|
||||||
|
UART_THR = 'M';
|
||||||
|
UART_THR = 'A';
|
||||||
|
UART_THR = 'T';
|
||||||
|
UART_THR = 'M';
|
||||||
|
UART_THR = 'U';
|
||||||
|
UART_THR = 'L';
|
||||||
|
UART_THR = '_';
|
||||||
|
UART_THR = 'S';
|
||||||
|
UART_THR = 'T';
|
||||||
|
UART_THR = 'A';
|
||||||
|
UART_THR = 'R';
|
||||||
|
UART_THR = 'T';
|
||||||
|
UART_THR = '\n';
|
||||||
|
}
|
||||||
|
|
||||||
static void uart_puthex(unsigned int val)
|
static void uart_puthex(unsigned int val)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -44,7 +61,9 @@ static void uart_puthex(unsigned int val)
|
|||||||
#define MATMUL_WRITEBACK_RESULTS 1
|
#define MATMUL_WRITEBACK_RESULTS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MATMUL_FAST_START == 0
|
||||||
unsigned long UART_BASE = 0xbf000000;
|
unsigned long UART_BASE = 0xbf000000;
|
||||||
|
#endif
|
||||||
|
|
||||||
#define EXTRAM_BASE_PHYS 0x1c400000u
|
#define EXTRAM_BASE_PHYS 0x1c400000u
|
||||||
#define SRC_BASE_WORDS 0u
|
#define SRC_BASE_WORDS 0u
|
||||||
@@ -65,8 +84,6 @@ int main(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uart_puts("MATMUL_START\n");
|
|
||||||
|
|
||||||
DMA_SEQ->STATUS = SEQ_DONE_BIT;
|
DMA_SEQ->STATUS = SEQ_DONE_BIT;
|
||||||
DMA_SEQ->SRC_BASE = EXTRAM_PHYS_AB(0);
|
DMA_SEQ->SRC_BASE = EXTRAM_PHYS_AB(0);
|
||||||
DMA_SEQ->DST_BASE = EXTRAM_PHYS_C(0);
|
DMA_SEQ->DST_BASE = EXTRAM_PHYS_C(0);
|
||||||
@@ -78,6 +95,8 @@ int main(void)
|
|||||||
#if MATMUL_WRITEBACK_RESULTS == 0
|
#if MATMUL_WRITEBACK_RESULTS == 0
|
||||||
seq_ctrl |= SEQ_SKIP_STORE_BIT;
|
seq_ctrl |= SEQ_SKIP_STORE_BIT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
uart_put_matmul_start_fifo();
|
||||||
DMA_SEQ->CTRL = seq_ctrl;
|
DMA_SEQ->CTRL = seq_ctrl;
|
||||||
|
|
||||||
while ((DMA_SEQ->STATUS & SEQ_DONE_BIT) == 0u) {
|
while ((DMA_SEQ->STATUS & SEQ_DONE_BIT) == 0u) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "dma.h"
|
#include "dma.h"
|
||||||
|
|
||||||
void dma_start_transfer(int ch_id, uint32_t src, uint32_t dst, uint32_t bytes, uint32_t tag) {
|
void dma_start_transfer(int ch_id, u32 src, u32 dst, u32 bytes, u32 tag) {
|
||||||
volatile dma_ch_regs_t* ch = DMA_CH(ch_id);
|
volatile dma_ch_regs_t* ch = DMA_CH(ch_id);
|
||||||
|
|
||||||
// 检查通道是否空闲 防止覆盖正在运行的任务
|
// 检查通道是否空闲 防止覆盖正在运行的任务
|
||||||
@@ -18,7 +18,7 @@ void dma_start_transfer(int ch_id, uint32_t src, uint32_t dst, uint32_t bytes, u
|
|||||||
// 置 Burst 属性并触发传输
|
// 置 Burst 属性并触发传输
|
||||||
// AXI SIZE: 2 (代表 2^2 = 4 Bytes,与 32-bit 数据线匹配)
|
// AXI SIZE: 2 (代表 2^2 = 4 Bytes,与 32-bit 数据线匹配)
|
||||||
// AXI LEN: 15 (代表 16 beats 突发传输,最高效)
|
// AXI LEN: 15 (代表 16 beats 突发传输,最高效)
|
||||||
uint32_t ctrl_val = CTRL_BURST_SIZE(2) | CTRL_BURST_LEN(15);
|
u32 ctrl_val = CTRL_BURST_SIZE(2) | CTRL_BURST_LEN(63);
|
||||||
|
|
||||||
// 写入 CTRL 并拉高 Bit 0 (Start)
|
// 写入 CTRL 并拉高 Bit 0 (Start)
|
||||||
ch->CTRL = ctrl_val | CTRL_START_BIT;
|
ch->CTRL = ctrl_val | CTRL_START_BIT;
|
||||||
55
sdk/software/examples/mlkem_test/dma.h
Normal file
55
sdk/software/examples/mlkem_test/dma.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef unsigned int u32;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
volatile u32 SRC_ADDR; // 0x00: source address
|
||||||
|
volatile u32 DST_ADDR; // 0x04: destination address
|
||||||
|
volatile u32 LENGTH; // 0x08: transfer byte count
|
||||||
|
volatile u32 TAG; // 0x0C: software tag (ignored by HW)
|
||||||
|
volatile u32 CTRL; // 0x10: control (burst config + start)
|
||||||
|
volatile u32 STATUS; // 0x14: status (busy, done)
|
||||||
|
volatile u32 MODE; // 0x18: 0=mem2mem, 1=mem2ep, 2=ep2mem
|
||||||
|
volatile u32 EP_CFG; // 0x1C: [3:0]=bank, [15:8]=word offset, [19:16]=endpoint id
|
||||||
|
volatile u32 RESV[8]; // 0x20 ~ 0x3C: padding to 0x40 bytes
|
||||||
|
} dma_ch_regs_t;
|
||||||
|
|
||||||
|
// DMA 控制器基地址
|
||||||
|
#define CDMA_MUX_BASE 0xbf300000
|
||||||
|
#define DMA_CH(i) ((volatile dma_ch_regs_t*)(CDMA_MUX_BASE + (i) * 0x40))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
volatile u32 CTRL; // 0x200: bit0 start
|
||||||
|
volatile u32 STATUS; // 0x204: bit0 busy, bit1 done (W1C)
|
||||||
|
volatile u32 SRC_BASE; // 0x208
|
||||||
|
volatile u32 DST_BASE; // 0x20C
|
||||||
|
volatile u32 GROUPS; // 0x210
|
||||||
|
volatile u32 MAT_BASE; // 0x214: reserved for compatibility
|
||||||
|
volatile u32 SRC_STRIDE; // 0x218
|
||||||
|
volatile u32 DST_STRIDE; // 0x21C
|
||||||
|
} dma_seq_regs_t;
|
||||||
|
|
||||||
|
#define DMA_SEQ ((volatile dma_seq_regs_t*)(CDMA_MUX_BASE + 0x200))
|
||||||
|
|
||||||
|
// CTRL 寄存器位定义
|
||||||
|
#define CTRL_START_BIT (1 << 0)
|
||||||
|
#define CTRL_BURST_SIZE(x) (((x) & 0x7) << 3) // Bits [5:3]: AXI AxSIZE (0=1B, 1=2B, 2=4B, 3=8B)
|
||||||
|
#define CTRL_BURST_LEN(x) (((x) & 0xFF) << 6) // Bits [13:6]: AXI AxLEN (0=1 beat, 15=16 beats)
|
||||||
|
|
||||||
|
#define DMA_MODE_MEM2MEM 0
|
||||||
|
#define DMA_MODE_MEM2EP 1
|
||||||
|
#define DMA_MODE_EP2MEM 2
|
||||||
|
#define DMA_EP_CFG(id, bank, word_off) \
|
||||||
|
((((id) & 0xF) << 16) | (((word_off) & 0xFF) << 8) | ((bank) & 0xF))
|
||||||
|
|
||||||
|
// STATUS 寄存器位定义
|
||||||
|
#define STATUS_BUSY_BIT (1 << 0)
|
||||||
|
#define STATUS_DONE_BIT (1 << 1)
|
||||||
|
|
||||||
|
#define SEQ_START_BIT (1 << 0)
|
||||||
|
#define SEQ_SKIP_STORE_BIT (1 << 1)
|
||||||
|
#define SEQ_BUSY_BIT (1 << 0)
|
||||||
|
#define SEQ_DONE_BIT (1 << 1)
|
||||||
|
|
||||||
|
void dma_start_transfer(int ch_id, u32 src, u32 dst, u32 bytes, u32 tag);
|
||||||
|
void dma_wait_polling(int ch_id);
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
* automatically wait-stated on the bus).
|
* automatically wait-stated on the bus).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
@@ -149,15 +150,15 @@ static void readback(uint32_t sel, uint8_t *buf, int n)
|
|||||||
/* PLACEHOLDER2 */
|
/* PLACEHOLDER2 */
|
||||||
|
|
||||||
/* Arbitrary but fixed test seeds / message (32 bytes each). */
|
/* Arbitrary but fixed test seeds / message (32 bytes each). */
|
||||||
static const uint8_t SEED_D[32] = {
|
static uint8_t SEED_D[32] = {
|
||||||
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
|
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
|
||||||
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F
|
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F
|
||||||
};
|
};
|
||||||
static const uint8_t SEED_Z[32] = {
|
static uint8_t SEED_Z[32] = {
|
||||||
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
|
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
|
||||||
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F
|
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F
|
||||||
};
|
};
|
||||||
static const uint8_t MSG_M[32] = {
|
static uint8_t MSG_M[32] = {
|
||||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
|
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
|
||||||
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF
|
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF
|
||||||
};
|
};
|
||||||
@@ -206,6 +207,51 @@ int main(void)
|
|||||||
read_block32(MLKEM_SS, ss_dec);
|
read_block32(MLKEM_SS, ss_dec);
|
||||||
print_hex("SS_DEC=", ss_dec, 32);
|
print_hex("SS_DEC=", ss_dec, 32);
|
||||||
|
|
||||||
|
/* ── 4. Verify shared secrets match ───────────────────────────── */
|
||||||
|
mismatch = 0;
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
if (ss_enc[i] != ss_dec[i]) mismatch++;
|
||||||
|
|
||||||
|
if (mismatch == 0)
|
||||||
|
printf("MLKEM_RESULT=PASS\n");
|
||||||
|
else
|
||||||
|
printf("MLKEM_RESULT=FAIL (%d byte mismatch)\n", mismatch);
|
||||||
|
|
||||||
|
printf("MLKEM_DONE\n");
|
||||||
|
|
||||||
|
|
||||||
|
SEED_D[2] = 0;
|
||||||
|
SEED_Z[2] = 0;
|
||||||
|
MSG_M[2] = 0;
|
||||||
|
memset(ek, 0, sizeof(ek));
|
||||||
|
memset(dk, 0, sizeof(dk));
|
||||||
|
memset(ct, 0, sizeof(ct));
|
||||||
|
memset(ss_enc, 0, sizeof(ss_enc));
|
||||||
|
memset(ss_dec, 0, sizeof(ss_dec));
|
||||||
|
|
||||||
|
/* ── 1. KeyGen: d,z -> ek, dk ─────────────────────────────────── */
|
||||||
|
write_block32(MLKEM_D, SEED_D);
|
||||||
|
write_block32(MLKEM_Z, SEED_Z);
|
||||||
|
run_op(OP_KEYGEN);
|
||||||
|
readback(RDB_EK, ek, EK_BYTES);
|
||||||
|
readback(RDB_DK, dk, DK_BYTES);
|
||||||
|
print_hex("EK32=", ek, 32); /* first 32 bytes as a fingerprint */
|
||||||
|
|
||||||
|
/* ── 2. Encaps: ek + msg -> ss, ct ────────────────────────────── */
|
||||||
|
preload(PRE_EK, ek, EK_BYTES);
|
||||||
|
write_block32(MLKEM_MSG, MSG_M);
|
||||||
|
run_op(OP_ENCAPS);
|
||||||
|
read_block32(MLKEM_SS, ss_enc);
|
||||||
|
readback(RDB_CT, ct, CT_BYTES);
|
||||||
|
print_hex("SS_ENC=", ss_enc, 32);
|
||||||
|
|
||||||
|
/* ── 3. Decaps: dk + ct -> ss' ────────────────────────────────── */
|
||||||
|
preload(PRE_DK, dk, DK_BYTES);
|
||||||
|
preload(PRE_C, ct, CT_BYTES);
|
||||||
|
run_op(OP_DECAPS);
|
||||||
|
read_block32(MLKEM_SS, ss_dec);
|
||||||
|
print_hex("SS_DEC=", ss_dec, 32);
|
||||||
|
|
||||||
/* ── 4. Verify shared secrets match ───────────────────────────── */
|
/* ── 4. Verify shared secrets match ───────────────────────────── */
|
||||||
mismatch = 0;
|
mismatch = 0;
|
||||||
for (i = 0; i < 32; i++)
|
for (i = 0; i < 32; i++)
|
||||||
|
|||||||
Reference in New Issue
Block a user