URL
https://opencores.org/ocsvn/neorv32/neorv32/trunk
Subversion Repositories neorv32
Compare Revisions
- This comparison shows the changes necessary to convert path
/neorv32/trunk/sw
- from Rev 11 to Rev 12
- ↔ Reverse comparison
Rev 11 → Rev 12
/bootloader/bootloader.c
149,7 → 149,6
uint32_t get_exe_word(int src, uint32_t addr); |
void system_error(uint8_t err_code); |
void print_hex_word(uint32_t num); |
void print_proc_version(void); |
|
// SPI flash access |
uint8_t spi_flash_read_byte(uint32_t addr); |
172,18 → 171,19
// ------------------------------------------------ |
|
// reset system time |
neorv32_mtime_set_time(0); |
MTIME_LO = 0; |
MTIME_HI = 0; |
|
// deactivate unused IO devices |
neorv32_wdt_disable(); |
neorv32_clic_disable(); |
neorv32_pwm_disable(); |
neorv32_spi_disable(); |
neorv32_trng_disable(); |
neorv32_twi_disable(); |
neorv32_wdt_disable(); |
|
// get clock speed (in Hz) |
uint32_t clock_speed = neorv32_cpu_csr_read(CSR_MCLOCK); |
uint32_t clock_speed = SYSINFO_CLK; |
|
// init SPI for 8-bit, clock-mode 0, MSB-first, no interrupt |
if (clock_speed < 40000000) { |
218,23 → 218,23
// ------------------------------------------------ |
neorv32_uart_print("\n\n\n\n<< NEORV32 Bootloader >>\n\n" |
"BLDV: "__DATE__"\nHWV: "); |
print_proc_version(); |
neorv32_rte_print_hw_version(); |
neorv32_uart_print("\nCLK: "); |
print_hex_word(neorv32_cpu_csr_read(CSR_MCLOCK)); |
neorv32_uart_print(" Hz\nMHID: "); |
print_hex_word(neorv32_cpu_csr_read(CSR_MHARTID)); |
print_hex_word(SYSINFO_CLK); |
neorv32_uart_print(" Hz\nUSER: "); |
print_hex_word(SYSINFO_USER_CODE); |
neorv32_uart_print("\nMISA: "); |
print_hex_word(neorv32_cpu_csr_read(CSR_MISA)); |
neorv32_uart_print("\nCONF: "); |
print_hex_word(neorv32_cpu_csr_read(CSR_MFEATURES)); |
print_hex_word(SYSINFO_FEATURES); |
neorv32_uart_print("\nIMEM: "); |
print_hex_word(neorv32_cpu_csr_read(CSR_MISPACESIZE)); |
print_hex_word(SYSINFO_ISPACE_SIZE); |
neorv32_uart_print(" bytes @ "); |
print_hex_word(neorv32_cpu_csr_read(CSR_MISPACEBASE)); |
print_hex_word(SYSINFO_ISPACE_BASE); |
neorv32_uart_print("\nDMEM: "); |
print_hex_word(neorv32_cpu_csr_read(CSR_MDSPACESIZE)); |
print_hex_word(SYSINFO_DSPACE_SIZE); |
neorv32_uart_print(" bytes @ "); |
print_hex_word(neorv32_cpu_csr_read(CSR_MDSPACEBASE)); |
print_hex_word(SYSINFO_DSPACE_BASE); |
|
|
// ------------------------------------------------ |
266,7 → 266,10
neorv32_uart_print("\n"); |
|
if (c == 'r') { // restart bootloader |
break; |
neorv32_cpu_dint(); // disable global interrupts |
// jump to beginning of boot ROM |
asm volatile ("li t0, %[input_i]; jr t0" : : [input_i] "i" (BOOTLOADER_BASE_ADDRESS)); |
while(1); // just for the compiler |
} |
else if (c == 'h') { // help menu |
print_help(); |
291,7 → 294,7
} |
} |
|
return 0; // bootloader will restart when returning |
return 0; // bootloader should never return |
} |
|
|
333,9 → 336,15
// wait for UART to finish transmitting |
while ((UART_CT & (1<<UART_CT_TX_BUSY)) != 0); |
|
// reset performance counters (to benchmark actual application) |
asm volatile ("csrrw zero, mcycle, zero"); // will also clear 'cycle' |
asm volatile ("csrrw zero, mcycleh, zero"); // will also clear 'cycleh' |
asm volatile ("csrrw zero, minstret, zero"); // will also clear 'instret' |
asm volatile ("csrrw zero, minstreth, zero"); // will also clear 'instreth' |
|
// start app at instruction space base address |
while (1) { |
register uint32_t app_base = neorv32_cpu_csr_read(CSR_MISPACEBASE); |
register uint32_t app_base = SYSINFO_ISPACE_BASE; |
asm volatile ("jalr zero, %0" : : "r" (app_base)); |
} |
} |
349,7 → 358,7
|
// make sure this was caused by MTIME IRQ |
uint32_t cause = neorv32_cpu_csr_read(CSR_MCAUSE); |
if (cause != 0x80000007) { // raw exception code for MTI |
if (cause != EXCCODE_MTI) { // raw exception code for MTI |
neorv32_uart_print("\n\nEXCEPTION: "); |
print_hex_word(cause); |
neorv32_uart_print(" @ 0x"); |
361,7 → 370,7
// toggle status LED |
neorv32_gpio_pin_toggle(STATUS_LED); |
// set time for next IRQ |
neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + (neorv32_cpu_csr_read(CSR_MCLOCK)/4)); |
neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + (SYSINFO_CLK/4)); |
} |
} |
|
374,7 → 383,7
void get_exe(int src) { |
|
// is instruction memory (actually, the IMEM) read-only? |
if (neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_MEM_INT_IMEM_ROM)) { |
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM)) { |
system_error(ERROR_ROM); |
} |
|
405,13 → 414,13
uint32_t check = get_exe_word(src, addr + EXE_OFFSET_CHECKSUM); // complement sum checksum |
|
// executable too large? |
uint32_t imem_size = neorv32_cpu_csr_read(CSR_MISPACESIZE); |
uint32_t imem_size = SYSINFO_ISPACE_SIZE; |
if (size > imem_size) { |
system_error(ERROR_SIZE); |
} |
|
// transfer program data |
uint32_t *pnt = (uint32_t*)neorv32_cpu_csr_read(CSR_MISPACEBASE); |
uint32_t *pnt = (uint32_t*)SYSINFO_ISPACE_BASE; |
uint32_t checksum = 0; |
uint32_t d = 0, i = 0; |
addr = addr + EXE_OFFSET_DATA; |
497,7 → 506,7
|
// store data from instruction memory and update checksum |
uint32_t checksum = 0; |
uint32_t *pnt = (uint32_t*)neorv32_cpu_csr_read(CSR_MISPACEBASE); |
uint32_t *pnt = (uint32_t*)SYSINFO_ISPACE_BASE; |
addr = addr + EXE_OFFSET_DATA; |
uint32_t i = 0; |
while (i < (size/4)) { // in words |
588,38 → 597,7
} |
|
|
/**********************************************************************//** |
* Print processor version. Deciaml format: "Dd.Dd.Dd.Dd". |
**************************************************************************/ |
void print_proc_version(void) { |
|
uint32_t i; |
char tmp, cnt; |
uint32_t version = neorv32_cpu_csr_read(CSR_MIMPID); |
|
for (i=0; i<4; i++) { |
|
tmp = (char)(version >> (24 - 8*i)); |
|
// serial division |
cnt = 0; |
while (tmp >= 10) { |
tmp = tmp - 10; |
cnt++; |
} |
|
if (cnt) { |
neorv32_uart_putc('0' + cnt); |
} |
neorv32_uart_putc('0' + tmp); |
if (i < 3) { |
neorv32_uart_putc('.'); |
} |
} |
} |
|
|
|
// ------------------------------------------------------------------------------------- |
// SPI flash functions |
// ------------------------------------------------------------------------------------- |
/common/bootloader_crt0.S
1,7 → 1,7
/* ################################################################################################# */ |
/* # << NEORV32 - bootloader_crt0.S - Bootloader Start-Up Code >> # */ |
/* # ********************************************************************************************* # */ |
/* # Minimal hardware setup (STACK + EXC handler). The rest is done by the bootloader itself. # */ |
/* # Minimal hardware setup (STACK + Trap handler). The rest is done by the bootloader itself. # */ |
/* # ********************************************************************************************* # */ |
/* # BSD 3-Clause License # */ |
/* # # */ |
40,9 → 40,9
.global _start |
|
|
// custom CSRs |
.set CSR_MDSPACEBASE, 0xfc5 // CUSTOM (r/-): Base address of data memory space (via MEM_DSPACE_BASE generic) */ |
.set CSR_MDSPACESIZE, 0xfc7 // CUSTOM (r/-): Total size of data memory space in byte (via MEM_DSPACE_SIZE generic) */ |
// SYSINFO |
.set SYSINFO_DSPACE_BASE, 0xFFFFFFF4 |
.set SYSINFO_DSPACE_SIZE, 0xFFFFFFFC |
|
|
_start: |
53,17 → 53,17
// Setup stack pointer |
// ********************************************************* |
__crt0_stack_pointer_init: |
csrrw x11, CSR_MDSPACEBASE, zero // data memory space base address |
csrrw x12, CSR_MDSPACESIZE, zero // data memory space size |
lw x11, SYSINFO_DSPACE_BASE(zero) // data memory space base address |
lw x12, SYSINFO_DSPACE_SIZE(zero) // data memory space size |
add sp, x11, x12 |
addi sp, sp, -4 // stack pointer = last entry |
addi sp, sp, -4 // stack pointer = last entry |
|
|
// ********************************************************* |
// Init exception vector base with dummy handler |
// ********************************************************* |
la x11, __crt0_dummy_exception_handler |
csrrw zero, mtvec, x11 |
la x13, __crt0_dummy_trap_handler |
csrw mtvec, x13 |
|
|
// ********************************************************* |
81,9 → 81,9
addi x8, zero, 0 |
addi x9, zero, 0 |
addi x10, zero, 0 |
addi x11, zero, 0 |
addi x12, zero, 0 |
addi x13, zero, 0 |
//addi x11, zero, 0 # allready initialized |
//addi x12, zero, 0 # allready initialized |
//addi x13, zero, 0 # allready initialized |
addi x14, zero, 0 |
addi x15, zero, 0 |
|
94,23 → 94,32
__crt0_main_entry: |
|
jal ra, main |
j _start # restart if main returns |
|
// if main returns: stall |
__crt0_the_end: |
j __crt0_the_end # restart if main returns |
|
|
// ********************************************************* |
// dummy exception handler (for exceptions only, no IRQs) |
// bootloader has to be compiled without any CPU extensions! |
// dummy trap handler (for exceptions & IRQs) |
// bootloader has to be compiled without any CPU extensions |
// - especially without C extension! |
// ********************************************************* |
__crt0_dummy_exception_handler: |
|
__crt0_dummy_trap_handler: |
|
addi sp, sp, -4 |
sw ra, 0(sp) |
sw x8, 0(sp) |
|
csrrw ra, mepc, zero |
addi ra, ra, +4 // just move on to next instruction |
csrrw zero, mepc, ra |
csrr x8, mcause |
blt x8, zero, __crt0_dummy_trap_handler_irq // skip mepc modification if interrupt |
|
lw ra, 0(sp) |
csrr x8, mepc |
addi x8, x8, +4 // move on to next instruction if exception |
csrw mepc, x8 |
|
__crt0_dummy_trap_handler_irq: |
|
lw x8, 0(sp) |
addi sp, sp, +4 |
|
mret |
/common/crt0.S
42,18 → 42,14
.global _start |
|
|
// custom CSRs |
.set CSR_MISPACEBASE, 0xfc4 // CUSTOM (r/-): Base address of instruction memory space (via MEM_ISPACE_BASE generic) */ |
.set CSR_MDSPACEBASE, 0xfc5 // CUSTOM (r/-): Base address of data memory space (via MEM_DSPACE_BASE generic) */ |
.set CSR_MISPACESIZE, 0xfc6 // CUSTOM (r/-): Total size of instruction memory space in byte (via MEM_ISPACE_SIZE generic) */ |
.set CSR_MDSPACESIZE, 0xfc7 // CUSTOM (r/-): Total size of data memory space in byte (via MEM_DSPACE_SIZE generic) */ |
|
// IO region |
.set IO_BEGIN, 0xFFFFFF80 // start of processor-internal IO region |
.set MTIMECMP_LO, 0xFFFFFF98 |
.set MTIMECMP_HI, 0xFFFFFF9C |
.set IO_BEGIN, 0xFFFFFF80 // start of processor-internal IO region |
|
// SYSINFO |
.set SYSINFO_DSPACE_BASE, 0xFFFFFFF4 |
.set SYSINFO_DSPACE_SIZE, 0xFFFFFFFC |
|
|
_start: |
.cfi_startproc |
.cfi_undefined ra |
114,8 → 110,8
// Setup stack pointer |
// ********************************************************* |
__crt0_stack_pointer_init: |
csrr x11, CSR_MDSPACEBASE // data memory space base address |
csrr x12, CSR_MDSPACESIZE // data memory space size |
lw x11, SYSINFO_DSPACE_BASE(zero) // data memory space base address |
lw x12, SYSINFO_DSPACE_SIZE(zero) // data memory space size |
add sp, x11, x12 |
addi sp, sp, -4 // stack pointer = last entry |
addi fp, sp, 0 // frame pointer = stack pointer |
138,7 → 134,7
la x11, __crt0_neorv32_rte |
csrw mtvec, x11 // set address of first-level exception handler |
|
csrr x11, CSR_MDSPACEBASE // data memory space base address |
lw x11, SYSINFO_DSPACE_BASE(zero) // data memory space base address |
la x12, __crt0_neorv32_rte_dummy_hanlder |
li x13, 2*16 // number of entries (16xEXC, 16xIRQ) |
|
162,12 → 158,7
addi x11, x11, 4 |
bne zero, x11, __crt0_reset_io_loop |
|
// set mtime_compare to MAX (to prevent an IRQ) |
li x11, -1 |
sw x11, MTIMECMP_LO(zero) |
sw x11, MTIMECMP_HI(zero) |
|
|
// ********************************************************* |
// Clear .bss section (byte-wise) |
// ********************************************************* |
227,6 → 218,7
// ********************************************************* |
// NEORV32 runtime environment: First-level exception/interrupt handler |
// ********************************************************* |
.align 4 |
__crt0_neorv32_rte: |
|
// -------------------------------------------- |
279,7 → 271,7
|
andi t1, t0, 0x0f // isolate cause ID |
slli t1, t1, 2 // make address offset |
csrr ra, CSR_MDSPACEBASE // data memory space base address |
lw ra, SYSINFO_DSPACE_BASE(zero) // data memory space base address |
add t1, t1, ra // get vetor table entry address (EXC vectors) |
|
csrr ra, mepc // get return address |
/example/coremark/core_portme.c
71,7 → 71,9
or zeroing some system parameters - e.g. setting the cpu clocks cycles to 0. |
*/ |
void start_time(void) { |
elapsed_cycles = neorv32_mtime_get_time(); |
elapsed_cycles = 0; // this is time zero |
neorv32_cpu_set_mcycle(0); |
neorv32_cpu_set_minstret(0); |
//GETMYTIME(&start_time_val ); |
} |
/* Function : stop_time |
93,7 → 95,7
and the resolution is controlled by <TIMER_RES_DIVIDER> |
*/ |
CORE_TICKS get_time(void) { |
CORE_TICKS elapsed = ((CORE_TICKS)neorv32_mtime_get_time()) - elapsed_cycles; |
CORE_TICKS elapsed = ((CORE_TICKS)neorv32_cpu_get_cycle()) - elapsed_cycles; |
elapsed_cycles = elapsed; |
//CORE_TICKS elapsed=(CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val)); |
return elapsed; |
106,7 → 108,7
*/ |
secs_ret time_in_secs(CORE_TICKS ticks) { |
//secs_ret retval=((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC; |
secs_ret retval=(secs_ret)(ticks / neorv32_cpu_csr_read(CSR_MCLOCK)); |
secs_ret retval=(secs_ret)(ticks / SYSINFO_CLK); |
return retval; |
} |
|
127,13 → 129,7
// setup neorv32 UART |
neorv32_uart_setup(BAUD_RATE, 0, 0); |
|
// check if MTIME unit was synthesized |
if (!neorv32_mtime_available()) { |
neorv32_uart_printf("NEORV32: Error! No MTIME unit synthesized!"); |
while(1); |
} |
|
neorv32_uart_printf("NEORV32: Processor running at %u Hz\n", (uint32_t)neorv32_cpu_csr_read(CSR_MCLOCK)); |
neorv32_uart_printf("NEORV32: Processor running at %u Hz\n", (uint32_t)SYSINFO_CLK); |
neorv32_uart_printf("NEORV32: Executing coremark (%u iterations). This may take some time...\n\n", (uint32_t)ITERATIONS); |
|
if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) { |
155,23 → 151,14
union { |
uint64_t uint64; |
uint32_t uint32[sizeof(uint64_t)/2]; |
} exe_cycles; |
|
union { |
uint64_t uint64; |
uint32_t uint32[sizeof(uint64_t)/2]; |
} exe_instructions, exe_time; |
|
exe_time.uint64 = (uint64_t)elapsed_cycles; |
exe_cycles.uint32[0] = neorv32_cpu_csr_read(CSR_TIME); |
exe_cycles.uint32[1] = neorv32_cpu_csr_read(CSR_TIMEH); |
exe_instructions.uint32[0] = neorv32_cpu_csr_read(CSR_INSTRET); |
exe_instructions.uint32[1] = neorv32_cpu_csr_read(CSR_INSTRETH); |
exe_instructions.uint64 = neorv32_cpu_get_instret(); |
|
neorv32_uart_printf("\nNEORV32: Executed instructions 0x%x_%x\n", (uint32_t)exe_instructions.uint32[1], (uint32_t)exe_instructions.uint32[0]); |
neorv32_uart_printf("NEORV32: Total required clock cycles 0x%x_%x\n", (uint32_t)exe_cycles.uint32[1], (uint32_t)exe_cycles.uint32[0]); |
neorv32_uart_printf("NEORV32: CoreMark core clock cycles 0x%x_%x\n", (uint32_t)exe_time.uint32[1], (uint32_t)exe_time.uint32[0]); |
neorv32_uart_printf("\nNEORV32: Executed instructions 0x%x_%x\n", (uint32_t)exe_instructions.uint32[1], (uint32_t)exe_instructions.uint32[0]); |
neorv32_uart_printf("NEORV32: CoreMark core clock cycles 0x%x_%x\n", (uint32_t)exe_time.uint32[1], (uint32_t)exe_time.uint32[0]); |
|
uint64_t average_cpi = exe_cycles.uint64 / exe_instructions.uint64; |
uint64_t average_cpi = exe_time.uint64 / exe_instructions.uint64; |
neorv32_uart_printf("NEORV32: Average CPI (integer part only): %u cycles/instruction\n", (uint32_t)average_cpi); |
} |
/example/cpu_test/main.c
36,7 → 36,7
/**********************************************************************//** |
* @file cpu_test/main.c |
* @author Stephan Nolting |
* @brief Simple CPU interrupts and exceptions test program. |
* @brief Simple CPU (interrupts and exceptions) test program. |
**************************************************************************/ |
|
#include <neorv32.h> |
50,6 → 50,8
#define BAUD_RATE 19200 |
//** Set 1 for detailed exception debug information */ |
#define DETAILED_EXCEPTION_DEBUG 0 |
//** Set 1 to run memory tests */ |
#define PROBING_MEM_TEST 0 |
//** Reachable unaligned address */ |
#define ADDR_UNALIGNED 0x00000002 |
//** Unreachable aligned address */ |
61,39 → 63,13
* @name Exception handler acknowledges |
**************************************************************************/ |
/**@{*/ |
/** Exception handler answers / identifiers */ |
enum EXC_HANDLER_ANSWERS { |
ANSWER_I_MISALIGN = 0x12345678, /**< Answer for misaligned instruction address excetion */ |
ANSWER_I_ACCESS = 0xAABB1133, /**< Answer for instruction access fault excetion */ |
ANSWER_I_ILLEGAL = 0x0199203B, /**< Answer for illegal instruction excetion */ |
ANSWER_BREAKPOINT = 0x12322330, /**< Answer for breakpoint excetion */ |
ANSWER_L_MISALIGN = 0xBABCCCCC, /**< Answer for misaligned load address excetion */ |
ANSWER_L_ACCESS = 0xDEF728AA, /**< Answer for load access fault excetion */ |
ANSWER_S_MISALIGN = 0xFF0927DD, /**< Answer for misaligned store address excetion */ |
ANSWER_S_ACCESS = 0x20091777, /**< Answer for store access fault excetion */ |
ANSWER_ENVCALL = 0x55662244, /**< Answer for environment call excetion */ |
ANSWER_MSI = 0xCDECDEA9, /**< Answer for machine software interrupt */ |
ANSWER_MTI = 0x0012FA53, /**< Answer for machine timer interrupt */ |
ANSWER_CLIC = 0xEEF33088 /**< Answer for machine external interrupt */ |
}; |
/** Gloabl volatile variable to store exception handler answer */ |
/** Global volatile variable to store exception handler answer */ |
volatile uint32_t exception_handler_answer; |
/**@}*/ |
|
|
// Prototypes |
void exc_handler_i_misalign(void); |
void exc_handler_i_access(void); |
void exc_handler_i_illegal(void); |
void exc_handler_breakpoint(void); |
void exc_handler_l_misalign(void); |
void exc_handler_l_access(void); |
void exc_handler_s_misalign(void); |
void exc_handler_s_access(void); |
void exc_handler_envcall(void); |
void exc_handler_msi(void); |
void exc_handler_mti(void); |
void irq_handler_clic_ch0(); |
void global_trap_handler(void); |
|
|
/**********************************************************************//** |
164,27 → 140,26
|
// install exception handler functions |
int install_err = 0; |
install_err += neorv32_rte_exception_install(EXCID_I_MISALIGNED, exc_handler_i_misalign); |
install_err += neorv32_rte_exception_install(EXCID_I_ACCESS, exc_handler_i_access); |
install_err += neorv32_rte_exception_install(EXCID_I_ILLEGAL, exc_handler_i_illegal); |
install_err += neorv32_rte_exception_install(EXCID_BREAKPOINT, exc_handler_breakpoint); |
install_err += neorv32_rte_exception_install(EXCID_L_MISALIGNED, exc_handler_l_misalign); |
install_err += neorv32_rte_exception_install(EXCID_L_ACCESS, exc_handler_l_access); |
install_err += neorv32_rte_exception_install(EXCID_S_MISALIGNED, exc_handler_s_misalign); |
install_err += neorv32_rte_exception_install(EXCID_S_ACCESS, exc_handler_s_access); |
install_err += neorv32_rte_exception_install(EXCID_MENV_CALL, exc_handler_envcall); |
install_err += neorv32_rte_exception_install(EXCID_MSI, exc_handler_msi); |
install_err += neorv32_rte_exception_install(EXCID_MTI, exc_handler_mti); |
install_err += neorv32_rte_exception_install(EXCID_I_MISALIGNED, global_trap_handler); |
install_err += neorv32_rte_exception_install(EXCID_I_ACCESS, global_trap_handler); |
install_err += neorv32_rte_exception_install(EXCID_I_ILLEGAL, global_trap_handler); |
install_err += neorv32_rte_exception_install(EXCID_BREAKPOINT, global_trap_handler); |
install_err += neorv32_rte_exception_install(EXCID_L_MISALIGNED, global_trap_handler); |
install_err += neorv32_rte_exception_install(EXCID_L_ACCESS, global_trap_handler); |
install_err += neorv32_rte_exception_install(EXCID_S_MISALIGNED, global_trap_handler); |
install_err += neorv32_rte_exception_install(EXCID_S_ACCESS, global_trap_handler); |
install_err += neorv32_rte_exception_install(EXCID_MENV_CALL, global_trap_handler); |
install_err += neorv32_rte_exception_install(EXCID_MTI, global_trap_handler); |
//install_err += neorv32_rte_exception_install(EXCID_MEI, -); done by neorv32_clic_handler_install |
|
if (install_err) { |
neorv32_uart_printf("install error!\n"); |
neorv32_uart_printf("RTE install error!\n"); |
return 0; |
} |
|
|
// install interrupt handler for clic WDT channel |
install_err += neorv32_clic_handler_install(CLIC_CH_WDT, irq_handler_clic_ch0); |
install_err += neorv32_clic_handler_install(CLIC_CH_WDT, global_trap_handler); |
|
if (install_err) { |
neorv32_uart_printf("CLIC install error!\n"); |
203,10 → 178,79
// enable global interrupts |
neorv32_cpu_eint(); |
|
exception_handler_answer = 0; |
exception_handler_answer = 0xFFFFFFFF; |
|
|
// ---------------------------------------------------------- |
// Instruction memory test |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("IMEM_TEST: "); |
#if (PROBING_MEM_TEST == 1) |
cnt_test++; |
|
register uint32_t dmem_probe_addr = neorv32_cpu_csr_read(CSR_MISPACEBASE); |
uint32_t dmem_probe_cnt = 0; |
|
while(1) { |
asm volatile ("lb zero, 0(%[input_j])" : : [input_j] "r" (dmem_probe_addr)); |
if (exception_handler_answer == EXCCODE_L_ACCESS) { |
break; |
} |
dmem_probe_addr++; |
dmem_probe_cnt++; |
} |
|
neorv32_uart_printf("%u bytes (should be %u bytes) ", dmem_probe_cnt, neorv32_cpu_csr_read(CSR_MISPACESIZE)); |
neorv32_uart_printf("@ 0x%x ", neorv32_cpu_csr_read(CSR_MISPACEBASE)); |
if (dmem_probe_cnt == neorv32_cpu_csr_read(CSR_MISPACESIZE)) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |
#else |
neorv32_uart_printf("skipped (disabled)\n"); |
#endif |
|
// ---------------------------------------------------------- |
// Data memory test |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("DMEM_TEST: "); |
#if (PROBING_MEM_TEST == 1) |
cnt_test++; |
|
register uint32_t imem_probe_addr = neorv32_cpu_csr_read(CSR_MDSPACEBASE); |
uint32_t imem_probe_cnt = 0; |
|
while(1) { |
asm volatile ("lb zero, 0(%[input_j])" : : [input_j] "r" (imem_probe_addr)); |
if (exception_handler_answer == EXCCODE_L_ACCESS) { |
break; |
} |
imem_probe_addr++; |
imem_probe_cnt++; |
} |
|
neorv32_uart_printf("%u bytes (should be %u bytes) ", imem_probe_cnt, neorv32_cpu_csr_read(CSR_MDSPACESIZE)); |
neorv32_uart_printf("@ 0x%x ", neorv32_cpu_csr_read(CSR_MDSPACEBASE)); |
if (imem_probe_cnt == neorv32_cpu_csr_read(CSR_MDSPACESIZE)) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |
#else |
neorv32_uart_printf("skipped (disabled)\n"); |
#endif |
|
|
// ---------------------------------------------------------- |
// Test counter CSR access for mcycle[h] |
// ---------------------------------------------------------- |
neorv32_uart_printf("MCYCLE[H]: "); |
213,10 → 257,10
cnt_test++; |
|
neorv32_cpu_csr_write(CSR_MCYCLE, 0x1BCD1234); |
neorv32_cpu_csr_write(CSR_MCYCLEH, 0x22334455); |
neorv32_cpu_csr_write(CSR_MCYCLEH, 0x00034455); |
|
if (((neorv32_cpu_csr_read(CSR_MCYCLE) & 0xffff0000L) == 0x1BCD0000) && |
(neorv32_cpu_csr_read(CSR_MCYCLEH) == 0x22334455)) { |
(neorv32_cpu_csr_read(CSR_MCYCLEH) == 0x00034455)) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
233,10 → 277,10
cnt_test++; |
|
neorv32_cpu_csr_write(CSR_MINSTRET, 0x11224499); |
neorv32_cpu_csr_write(CSR_MINSTRETH, 0x00110011); |
neorv32_cpu_csr_write(CSR_MINSTRETH, 0x00090011); |
|
if (((neorv32_cpu_csr_read(CSR_MINSTRET) & 0xffff0000L) == 0x11220000) && |
(neorv32_cpu_csr_read(CSR_MINSTRETH) == 0x00110011)) { |
(neorv32_cpu_csr_read(CSR_MINSTRETH) == 0x00090011)) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
272,13 → 316,13
// Test fence instructions - make sure CPU does not crash here and throws no exception |
// a more complex test is provided by the RISC-V compliance test |
// ---------------------------------------------------------- |
exception_handler_answer = 0; |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("FENCE(.I): "); |
cnt_test++; |
asm volatile ("fence"); |
asm volatile ("fence.i"); |
|
if (exception_handler_answer != 0) { |
if (exception_handler_answer != 0xFFFFFFFF) { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |
291,7 → 335,7
// ---------------------------------------------------------- |
// Unaligned instruction address |
// ---------------------------------------------------------- |
exception_handler_answer = 0; |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC I_ALIGN: "); |
|
// skip if C-mode is not implemented |
303,7 → 347,7
((void (*)(void))ADDR_UNALIGNED)(); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_I_MISALIGN) { |
if (exception_handler_answer == EXCCODE_I_MISALIGNED) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
321,7 → 365,7
// ---------------------------------------------------------- |
// Instruction access fault |
// ---------------------------------------------------------- |
exception_handler_answer = 0; |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC I_ACC: "); |
cnt_test++; |
|
329,7 → 373,7
((void (*)(void))ADDR_UNREACHABLE)(); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_I_ACCESS) { |
if (exception_handler_answer == EXCCODE_I_ACCESS) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
343,7 → 387,7
// ---------------------------------------------------------- |
// Illegal instruction |
// ---------------------------------------------------------- |
exception_handler_answer = 0; |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC I_ILLEG: "); |
cnt_test++; |
|
357,7 → 401,7
asm volatile ( "jalr ra, %0 " : "=r" (tmp_a) : "r" (tmp_a)); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_I_ILLEGAL) { |
if (exception_handler_answer == EXCCODE_I_ILLEGAL) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
371,7 → 415,7
// ---------------------------------------------------------- |
// Breakpoint instruction |
// ---------------------------------------------------------- |
exception_handler_answer = 0; |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC BREAK: "); |
cnt_test++; |
|
378,7 → 422,7
asm volatile("EBREAK"); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_BREAKPOINT) { |
if (exception_handler_answer == EXCCODE_BREAKPOINT) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
392,7 → 436,7
// ---------------------------------------------------------- |
// Unaligned load address |
// ---------------------------------------------------------- |
exception_handler_answer = 0; |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC L_ALIGN: "); |
cnt_test++; |
|
400,7 → 444,7
asm volatile ("lw zero, %[input_i](zero)" : : [input_i] "i" (ADDR_UNALIGNED)); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_L_MISALIGN) { |
if (exception_handler_answer == EXCCODE_L_MISALIGNED) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
414,7 → 458,7
// ---------------------------------------------------------- |
// Load access fault |
// ---------------------------------------------------------- |
exception_handler_answer = 0; |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC L_ACC: "); |
cnt_test++; |
|
422,7 → 466,7
dummy_dst = MMR_UNREACHABLE; |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_L_ACCESS) { |
if (exception_handler_answer == EXCCODE_L_ACCESS) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
436,7 → 480,7
// ---------------------------------------------------------- |
// Unaligned store address |
// ---------------------------------------------------------- |
exception_handler_answer = 0; |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC S_ALIGN: "); |
cnt_test++; |
|
444,7 → 488,7
asm volatile ("sw zero, %[input_i](zero)" : : [input_i] "i" (ADDR_UNALIGNED)); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_S_MISALIGN) { |
if (exception_handler_answer == EXCCODE_S_MISALIGNED) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
458,7 → 502,7
// ---------------------------------------------------------- |
// Store access fault |
// ---------------------------------------------------------- |
exception_handler_answer = 0; |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC S_ACC: "); |
cnt_test++; |
|
466,7 → 510,7
MMR_UNREACHABLE = 0; |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_S_ACCESS) { |
if (exception_handler_answer == EXCCODE_S_ACCESS) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
480,7 → 524,7
// ---------------------------------------------------------- |
// Environment call |
// ---------------------------------------------------------- |
exception_handler_answer = 0; |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC ENVCALL: "); |
cnt_test++; |
|
487,7 → 531,7
asm volatile("ECALL"); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_ENVCALL) { |
if (exception_handler_answer == EXCCODE_MENV_CALL) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
499,31 → 543,9
|
|
// ---------------------------------------------------------- |
// Machine software interrupt |
// ---------------------------------------------------------- |
exception_handler_answer = 0; |
neorv32_uart_printf("IRQ MSI: "); |
cnt_test++; |
|
// trigger machine software interrupt |
neorv32_cpu_sw_irq(); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_MSI) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |
#endif |
|
|
// ---------------------------------------------------------- |
// Machine timer interrupt (MTIME) |
// ---------------------------------------------------------- |
exception_handler_answer = 0; |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("IRQ MTI: "); |
cnt_test++; |
|
537,7 → 559,7
asm volatile("nop"); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_MTI) { |
if (exception_handler_answer == EXCCODE_MTI) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
554,7 → 576,7
// ---------------------------------------------------------- |
// Machine external interrupt (via CLIC) |
// ---------------------------------------------------------- |
exception_handler_answer = 0; |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("IRQ MEI: "); |
cnt_test++; |
|
568,7 → 590,7
asm volatile("nop"); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_CLIC) { |
if (exception_handler_answer == EXCCODE_MEI) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
582,7 → 604,7
// ---------------------------------------------------------- |
// Test WFI ("sleep") instructions |
// ---------------------------------------------------------- |
exception_handler_answer = 0; |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("WFI: "); |
cnt_test++; |
|
592,7 → 614,7
// put CPU into sleep mode |
asm volatile ("wfi"); |
|
if (exception_handler_answer != ANSWER_MTI) { |
if (exception_handler_answer != EXCCODE_MTI) { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |
603,9 → 625,6
|
|
|
|
|
|
// error report |
neorv32_uart_printf("\n\nTests: %i\nOK: %i\nFAIL: %i\n\n", cnt_test, cnt_ok, cnt_fail); |
|
622,88 → 641,8
|
|
/**********************************************************************//** |
* Misaligned instruction address exception handler. |
* Trap handler for ALL exceptions/interrupts. |
**************************************************************************/ |
void exc_handler_i_misalign(void) { |
exception_handler_answer = ANSWER_I_MISALIGN; |
void global_trap_handler(void) { |
exception_handler_answer = neorv32_cpu_csr_read(CSR_MCAUSE); |
} |
|
/**********************************************************************//** |
* Instruction access fault exception handler. |
**************************************************************************/ |
void exc_handler_i_access(void) { |
exception_handler_answer = ANSWER_I_ACCESS; |
} |
|
/**********************************************************************//** |
* Illegal instruction exception handler. |
**************************************************************************/ |
void exc_handler_i_illegal(void) { |
exception_handler_answer = ANSWER_I_ILLEGAL; |
} |
|
/**********************************************************************//** |
* Breakpoint exception handler. |
**************************************************************************/ |
void exc_handler_breakpoint(void) { |
exception_handler_answer = ANSWER_BREAKPOINT; |
} |
|
/**********************************************************************//** |
* Misaligned load address exception handler. |
**************************************************************************/ |
void exc_handler_l_misalign(void) { |
exception_handler_answer = ANSWER_L_MISALIGN; |
} |
|
/**********************************************************************//** |
* Load instruction access fault exception handler. |
**************************************************************************/ |
void exc_handler_l_access(void) { |
exception_handler_answer = ANSWER_L_ACCESS; |
} |
|
/**********************************************************************//** |
* Misaligned store address exception handler. |
**************************************************************************/ |
void exc_handler_s_misalign(void) { |
exception_handler_answer = ANSWER_S_MISALIGN; |
} |
|
/**********************************************************************//** |
* Store address access fault exception handler. |
**************************************************************************/ |
void exc_handler_s_access(void) { |
exception_handler_answer = ANSWER_S_ACCESS; |
} |
|
/**********************************************************************//** |
* Environment call exception handler. |
**************************************************************************/ |
void exc_handler_envcall(void) { |
exception_handler_answer = ANSWER_ENVCALL; |
} |
|
/**********************************************************************//** |
* Machine software interrupt exception handler. |
**************************************************************************/ |
void exc_handler_msi(void) { |
exception_handler_answer = ANSWER_MSI; |
} |
|
/**********************************************************************//** |
* Machine timer interrupt exception handler. |
**************************************************************************/ |
void exc_handler_mti(void) { |
exception_handler_answer = ANSWER_MTI; |
// set CMP of machine system timer MTIME to max to prevent an IRQ |
neorv32_mtime_set_timecmp(-1); |
} |
|
/**********************************************************************//** |
* CLIC interrupt handler for channel 0. |
**************************************************************************/ |
void irq_handler_clic_ch0(void) { |
exception_handler_answer = ANSWER_CLIC; |
} |
|
/example/demo_twi/main.c
185,7 → 185,7
} |
|
// print new clock frequency |
uint32_t clock = neorv32_cpu_csr_read(CSR_MCLOCK); |
uint32_t clock = SYSINFO_CLK; |
switch (prsc) { |
case 0: clock = clock / 2; break; |
case 1: clock = clock / 4; break; |
/lib/include/neorv32.h
61,38 → 61,33
**************************************************************************/ |
enum NEORV32_CPU_CSRS_enum { |
CSR_MSTATUS = 0x300, /**< 0x300 - mstatus (r/w): Machine status register */ |
CSR_MISA = 0x301, /**< 0x301 - misa (r/-): CPU ISA and extensions */ |
CSR_MISA = 0x301, /**< 0x301 - misa (r/-): CPU ISA and extensions (read-only in NEORV32) */ |
CSR_MIE = 0x304, /**< 0x304 - mie (r/w): Machine interrupt-enable register */ |
CSR_MTVEC = 0x305, /**< 0x305 - mtvec (r/w): Machine trap-handler base address (for ALL traps) */ |
|
CSR_MSCRATCH = 0x340, /**< 0x340 - mscratch (r/w): Machine scratch register */ |
CSR_MEPC = 0x341, /**< 0x341 - mepc (r/w): Machine exception program counter */ |
CSR_MCAUSE = 0x342, /**< 0x342 - mcause (r/-): Machine trap cause */ |
CSR_MTVAL = 0x343, /**< 0x343 - mtval (r/-): Machine bad address or instruction */ |
CSR_MCAUSE = 0x342, /**< 0x342 - mcause (r/w): Machine trap cause */ |
CSR_MTVAL = 0x343, /**< 0x343 - mtval (r/w): Machine bad address or instruction */ |
CSR_MIP = 0x344, /**< 0x344 - mip (r/w): Machine interrupt pending register */ |
|
CSR_MCYCLE = 0xb00, /**< 0xb00 - mcycle (r/w): Machine cycle counter low word */ |
CSR_MINSTRET = 0xb02, /**< 0xb02 - minstret (r/w): Machine instructions-retired counter low word */ |
CSR_MCYCLEH = 0xb80, /**< 0xb80 - mcycleh (r/w): Machine cycle counter high word */ |
CSR_MINSTRETH = 0xb82, /**< 0xb82 - minstreth (r/w): Machine instructions-retired counter high word */ |
CSR_MCYCLEH = 0xb80, /**< 0xb80 - mcycleh (r/w): Machine cycle counter high word - only 20-bit wide!*/ |
CSR_MINSTRETH = 0xb82, /**< 0xb82 - minstreth (r/w): Machine instructions-retired counter high word - only 20-bit wide! */ |
|
CSR_CYCLE = 0xc00, /**< 0xc00 - cycle (r/-): Cycle counter low word */ |
CSR_TIME = 0xc01, /**< 0xc01 - time (r/-): Timer low word (from MTIME.TIME) */ |
CSR_INSTRET = 0xc02, /**< 0xc02 - instret (r/-): Instructions-retired counter low word */ |
CSR_CYCLE = 0xc00, /**< 0xc00 - cycle (r/-): Cycle counter low word (from MCYCLE) */ |
CSR_TIME = 0xc01, /**< 0xc01 - time (r/-): Timer low word (from MTIME.TIME_LO) */ |
CSR_INSTRET = 0xc02, /**< 0xc02 - instret (r/-): Instructions-retired counter low word (from MINSTRET) */ |
|
CSR_CYCLEH = 0xc80, /**< 0xc80 - cycleh (r/-): Cycle counter high word */ |
CSR_TIMEH = 0xc81, /**< 0xc81 - timeh (r/-): Timer high word (from MTIME.TIME) */ |
CSR_INSTRETH = 0xc82, /**< 0xc82 - instreth (r/-): Instructions-retired counter high word */ |
CSR_CYCLEH = 0xc80, /**< 0xc80 - cycleh (r/-): Cycle counter high word (from MCYCLEH) - only 20-bit wide! */ |
CSR_TIMEH = 0xc81, /**< 0xc81 - timeh (r/-): Timer high word (from MTIME.TIME_HI) */ |
CSR_INSTRETH = 0xc82, /**< 0xc82 - instreth (r/-): Instructions-retired counter high word (from MINSTRETH) - only 20-bit wide! */ |
|
CSR_MIMPID = 0xf13, /**< 0xf13 - mimpid (r/-): Implementation ID/version */ |
CSR_MHARTID = 0xf14, /**< 0xf14 - mhartid (r/-): Hardware thread ID (via HART_ID generic) */ |
|
CSR_MFEATURES = 0xfc0, /**< 0xfc0 - CUSTOM (r/-): Implemented processor devices/features (via IO_x_USE generics) */ |
CSR_MCLOCK = 0xfc1, /**< 0xfc1 - CUSTOM (r/-): Processor primary clock spedd in Hz (via CLOCK_FREQUENCY generic)*/ |
CSR_MISPACEBASE = 0xfc4, /**< 0xfc4 - CUSTOM (r/-): Base address of instruction memory space (via MEM_ISPACE_BASE generic) */ |
CSR_MDSPACEBASE = 0xfc5, /**< 0xfc5 - CUSTOM (r/-): Base address of data memory space (via MEM_DSPACE_BASE generic) */ |
CSR_MISPACESIZE = 0xfc6, /**< 0xfc6 - CUSTOM (r/-): Total size of instruction memory space in byte (via MEM_ISPACE_SIZE generic) */ |
CSR_MDSPACESIZE = 0xfc7 /**< 0xfc7 - CUSTOM (r/-): Total size of data memory space in byte (via MEM_DSPACE_SIZE generic) */ |
CSR_MVENDORID = 0xf11, /**< 0xf11 - mvendorid (r/-): Vendor ID */ |
CSR_MARCHID = 0xf12, /**< 0xf12 - marchid (r/-): Architecture ID */ |
CSR_MIMPID = 0xf13, /**< 0xf13 - mimpid (r/-): Implementation ID/version */ |
CSR_MHARTID = 0xf14 /**< 0xf14 - mhartid (r/-): Hardware thread ID (always 0) */ |
}; |
|
|
109,7 → 104,7
* CPU <b>mie</b> CSR (r/w): Machine interrupt enable (RISC-V spec.) |
**************************************************************************/ |
enum NEORV32_CPU_MIE_enum { |
CPU_MIE_MSIE = 3, /**< CPU mie CSR (3): Machine software interrupt enable bit (r/w) */ |
CPU_MIE_MSIE = 3, /**< CPU mie CSR (3): Machine software interrupt enable (r/w) */ |
CPU_MIE_MTIE = 7, /**< CPU mie CSR (7): Machine timer interrupt (MTIME) enable bit (r/w) */ |
CPU_MIE_MEIE = 11 /**< CPU mie CSR (11): Machine external interrupt (via CLIC) enable bit (r/w) */ |
}; |
116,10 → 111,10
|
|
/**********************************************************************//** |
* CPU <b>mip</b> CSR (r/w): Machine interrupt pending (RISC-V spec.) |
* CPU <b>mip</b> CSR (r/-): Machine interrupt pending (RISC-V spec.) |
**************************************************************************/ |
enum NEORV32_CPU_MIP_enum { |
CPU_MIP_MSIP = 3, /**< CPU mip CSR (3): Machine software interrupt pending (r/w), can be triggered when set */ |
CPU_MIP_MSIP = 3, /**< CPU mip CSR (3): Machine software interrupt pending (r/-) */ |
CPU_MIP_MTIP = 7, /**< CPU mip CSR (7): Machine timer interrupt (MTIME) pending (r/-) */ |
CPU_MIP_MEIP = 11 /**< CPU mip CSR (11): Machine external interrupt (via CLIC) pending (r/-) */ |
}; |
141,30 → 136,6
|
|
/**********************************************************************//** |
* CPU <b>mfeatures</b> CSR (r/-): Implemented processor devices/features (CUSTOM) |
**************************************************************************/ |
enum NEORV32_CPU_MFEATURES_enum { |
CPU_MFEATURES_BOOTLOADER = 0, /**< CPU mfeatures CSR (0) (r/-): Bootloader implemented when 1 (via BOOTLOADER_USE generic) */ |
CPU_MFEATURES_MEM_EXT = 1, /**< CPU mfeatures CSR (1) (r/-): External bus interface implemented when 1 (via MEM_EXT_USE generic) */ |
CPU_MFEATURES_MEM_INT_IMEM = 2, /**< CPU mfeatures CSR (2) (r/-): Processor-internal instruction memory implemented when 1 (via MEM_INT_IMEM_USE generic) */ |
CPU_MFEATURES_MEM_INT_IMEM_ROM = 3, /**< CPU mfeatures CSR (3) (r/-): Processor-internal instruction memory implemented as ROM when 1 (via MEM_INT_IMEM_ROM generic) */ |
CPU_MFEATURES_MEM_INT_DMEM = 4, /**< CPU mfeatures CSR (4) (r/-): Processor-internal data memory implemented when 1 (via MEM_INT_DMEM_USE generic) */ |
CPU_MFEATURES_CSR_COUNTERS = 5, /**< CPU mfeatures CSR (5) (r/-): RISC-V performance counters implemented when 1 (via CSR_COUNTERS_USE generic) */ |
|
CPU_MFEATURES_IO_GPIO = 16, /**< CPU mfeatures CSR (16) (r/-): General purpose input/output port unit implemented when 1 (via IO_GPIO_USE generic) */ |
CPU_MFEATURES_IO_MTIME = 17, /**< CPU mfeatures CSR (17) (r/-): Machine system timer implemented when 1 (via IO_MTIME_USE generic) */ |
CPU_MFEATURES_IO_UART = 18, /**< CPU mfeatures CSR (18) (r/-): Universal asynchronous receiver/transmitter implemented when 1 (via IO_UART_USE generic) */ |
CPU_MFEATURES_IO_SPI = 19, /**< CPU mfeatures CSR (19) (r/-): Serial peripheral interface implemented when 1 (via IO_SPI_USE generic) */ |
CPU_MFEATURES_IO_TWI = 20, /**< CPU mfeatures CSR (20) (r/-): Two-wire interface implemented when 1 (via IO_TWI_USE generic) */ |
CPU_MFEATURES_IO_PWM = 21, /**< CPU mfeatures CSR (21) (r/-): Pulse-width modulation unit implemented when 1 (via IO_PWM_USE generic) */ |
CPU_MFEATURES_IO_WDT = 22, /**< CPU mfeatures CSR (22) (r/-): Watchdog timer implemented when 1 (via IO_WDT_USE generic) */ |
CPU_MFEATURES_IO_CLIC = 23, /**< CPU mfeatures CSR (23) (r/-): Core-local interrupt controller implemented when 1 (via IO_CLIC_USE generic) */ |
CPU_MFEATURES_IO_TRNG = 24, /**< CPU mfeatures CSR (24) (r/-): True random number generator implemented when 1 (via IO_TRNG_USE generic) */ |
CPU_MFEATURES_IO_DEVNULL = 25 /**< CPU mfeatures CSR (24) (r/-): Dummy device implemented when 1 (via IO_DEVNULL_USE generic) */ |
}; |
|
|
/**********************************************************************//** |
* Exception IDs. |
**************************************************************************/ |
enum NEORV32_EXCEPTION_IDS_enum { |
184,6 → 155,25
|
|
/**********************************************************************//** |
* Exception codes from mcause CSR. |
**************************************************************************/ |
enum NEORV32_EXCEPTION_CODES_enum { |
EXCCODE_I_MISALIGNED = 0x00000000, /**< 0: Instruction address misaligned */ |
EXCCODE_I_ACCESS = 0x00000001, /**< 1: Instruction (bus) access fault */ |
EXCCODE_I_ILLEGAL = 0x00000002, /**< 2: Illegal instruction */ |
EXCCODE_BREAKPOINT = 0x00000003, /**< 3: Breakpoint (EBREAK instruction) */ |
EXCCODE_L_MISALIGNED = 0x00000004, /**< 4: Load address misaligned */ |
EXCCODE_L_ACCESS = 0x00000005, /**< 5: Load (bus) access fault */ |
EXCCODE_S_MISALIGNED = 0x00000006, /**< 6: Store address misaligned */ |
EXCCODE_S_ACCESS = 0x00000007, /**< 7: Store (bus) access fault */ |
EXCCODE_MENV_CALL = 0x0000000b, /**< 11: Environment call from machine mode (ECALL instruction) */ |
EXCCODE_MSI = 0x80000003, /**< 16 + 3: Machine software interrupt */ |
EXCCODE_MTI = 0x80000007, /**< 16 + 7: Machine timer interrupt (via MTIME) */ |
EXCCODE_MEI = 0x8000000b /**< 16 + 11: Machine external interrupt (via CLIC) */ |
}; |
|
|
/**********************************************************************//** |
* Processor clock prescalers |
**************************************************************************/ |
enum NEORV32_CLOCK_PRSC_enum { |
512,10 → 502,56
**************************************************************************/ |
/**@{*/ |
/** DEVNULL data register (r/w) */ |
#define DEVNULL_DATA (*(IO_REG32 0xFFFFFFFCUL)) |
#define DEVNULL_DATA (*(IO_REG32 0xFFFFFFC8UL)) |
/**@}*/ |
|
|
/**********************************************************************//** |
* @name IO Device: System Configuration Info Memory (SYSINFO) |
**************************************************************************/ |
/**@{*/ |
/** SYSINFO(0): Clock speed */ |
#define SYSINFO_CLK (*(IO_ROM32 0xFFFFFFE0UL)) |
/** SYSINFO(1): Custom user code (via "USER_CODE" generic) */ |
#define SYSINFO_USER_CODE (*(IO_ROM32 0xFFFFFFE4UL)) |
/** SYSINFO(2): Clock speed */ |
#define SYSINFO_FEATURES (*(IO_ROM32 0xFFFFFFE8UL)) |
/** SYSINFO(3): reserved */ |
#define SYSINFO_reserved1 (*(IO_ROM32 0xFFFFFFECUL)) |
/** SYSINFO(4): Instruction memory address space base */ |
#define SYSINFO_ISPACE_BASE (*(IO_ROM32 0xFFFFFFF0UL)) |
/** SYSINFO(5): Data memory address space base */ |
#define SYSINFO_DSPACE_BASE (*(IO_ROM32 0xFFFFFFF4UL)) |
/** SYSINFO(6): Instruction memory address space size in bytes */ |
#define SYSINFO_ISPACE_SIZE (*(IO_ROM32 0xFFFFFFF8UL)) |
/** SYSINFO(7): Data memory address space size in bytes */ |
#define SYSINFO_DSPACE_SIZE (*(IO_ROM32 0xFFFFFFFCUL)) |
/**@}*/ |
|
|
/**********************************************************************//** |
* SYSINFO_FEATURES (r/-): Implemented processor devices/features |
**************************************************************************/ |
enum NEORV32_SYSINFO_FEATURES_enum { |
SYSINFO_FEATURES_BOOTLOADER = 0, /**< SYSINFO_FEATURES (0) (r/-): Bootloader implemented when 1 (via BOOTLOADER_USE generic) */ |
SYSINFO_FEATURES_MEM_EXT = 1, /**< SYSINFO_FEATURES (1) (r/-): External bus interface implemented when 1 (via MEM_EXT_USE generic) */ |
SYSINFO_FEATURES_MEM_INT_IMEM = 2, /**< SYSINFO_FEATURES (2) (r/-): Processor-internal instruction memory implemented when 1 (via MEM_INT_IMEM_USE generic) */ |
SYSINFO_FEATURES_MEM_INT_IMEM_ROM = 3, /**< SYSINFO_FEATURES (3) (r/-): Processor-internal instruction memory implemented as ROM when 1 (via MEM_INT_IMEM_ROM generic) */ |
SYSINFO_FEATURES_MEM_INT_DMEM = 4, /**< SYSINFO_FEATURES (4) (r/-): Processor-internal data memory implemented when 1 (via MEM_INT_DMEM_USE generic) */ |
|
SYSINFO_FEATURES_IO_GPIO = 16, /**< SYSINFO_FEATURES (16) (r/-): General purpose input/output port unit implemented when 1 (via IO_GPIO_USE generic) */ |
SYSINFO_FEATURES_IO_MTIME = 17, /**< SYSINFO_FEATURES (17) (r/-): Machine system timer implemented when 1 (via IO_MTIME_USE generic) */ |
SYSINFO_FEATURES_IO_UART = 18, /**< SYSINFO_FEATURES (18) (r/-): Universal asynchronous receiver/transmitter implemented when 1 (via IO_UART_USE generic) */ |
SYSINFO_FEATURES_IO_SPI = 19, /**< SYSINFO_FEATURES (19) (r/-): Serial peripheral interface implemented when 1 (via IO_SPI_USE generic) */ |
SYSINFO_FEATURES_IO_TWI = 20, /**< SYSINFO_FEATURES (20) (r/-): Two-wire interface implemented when 1 (via IO_TWI_USE generic) */ |
SYSINFO_FEATURES_IO_PWM = 21, /**< SYSINFO_FEATURES (21) (r/-): Pulse-width modulation unit implemented when 1 (via IO_PWM_USE generic) */ |
SYSINFO_FEATURES_IO_WDT = 22, /**< SYSINFO_FEATURES (22) (r/-): Watchdog timer implemented when 1 (via IO_WDT_USE generic) */ |
SYSINFO_FEATURES_IO_CLIC = 23, /**< SYSINFO_FEATURES (23) (r/-): Core-local interrupt controller implemented when 1 (via IO_CLIC_USE generic) */ |
SYSINFO_FEATURES_IO_TRNG = 24, /**< SYSINFO_FEATURES (24) (r/-): True random number generator implemented when 1 (via IO_TRNG_USE generic) */ |
SYSINFO_FEATURES_IO_DEVNULL = 25 /**< SYSINFO_FEATURES (24) (r/-): Dummy device implemented when 1 (via IO_DEVNULL_USE generic) */ |
}; |
|
|
// ---------------------------------------------------------------------------- |
// Include all IO driver headers |
// ---------------------------------------------------------------------------- |
/lib/include/neorv32_cpu.h
45,6 → 45,11
// prototypes |
int neorv32_cpu_irq_enable(uint8_t irq_sel); |
int neorv32_cpu_irq_disable(uint8_t irq_sel); |
uint64_t neorv32_cpu_get_cycle(void); |
void neorv32_cpu_set_mcycle(uint64_t value); |
uint64_t neorv32_cpu_get_instret(void); |
void neorv32_cpu_set_minstret(uint64_t value); |
uint64_t neorv32_cpu_get_systime(void); |
void neorv32_cpu_delay_ms(uint32_t time_ms); |
|
|
113,23 → 118,6
|
|
/**********************************************************************//** |
* Trigger machine software interrupt. |
* |
* @note The according IRQ has to be enabled via neorv32_cpu_irq_enable(uint8_t irq_sel) and |
* global interrupts must be enabled via neorv32_cpu_eint(void) to trigger an IRQ via software. |
* The MSI becomes active after 3 clock cycles. |
**************************************************************************/ |
inline void __attribute__ ((always_inline)) neorv32_cpu_sw_irq(void) { |
|
asm volatile ("csrrsi zero, mip, %0" : : "i" (1 << CPU_MIP_MSIP)); |
|
// the MSI becomes active 3 clock cycles afters issueing |
asm volatile ("nop"); // these nops are not required, they just make sure the MSI becomes active |
asm volatile ("nop"); // before the "real" next operation is executed |
} |
|
|
/**********************************************************************//** |
* Trigger breakpoint exception (via EBREAK instruction). |
**************************************************************************/ |
inline void __attribute__ ((always_inline)) neorv32_cpu_breakpoint(void) { |
/lib/include/neorv32_rte.h
48,6 → 48,7
int neorv32_rte_exception_uninstall(uint8_t exc_id); |
|
void neorv32_rte_print_hw_config(void); |
void neorv32_rte_print_hw_version(void); |
void neorv32_rte_print_credits(void); |
|
#endif // neorv32_rte_h |
/lib/source/neorv32_clic.c
61,7 → 61,7
**************************************************************************/ |
int neorv32_clic_available(void) { |
|
if (neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_IO_CLIC)) { |
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_CLIC)) { |
return 1; |
} |
else { |
/lib/source/neorv32_cpu.c
49,7 → 49,7
* @note Interrupts have to be globally enabled via neorv32_cpu_eint(void), too. |
* |
* @param[in] irq_sel CPU interrupt select. See #NEORV32_CPU_MIE_enum. |
* return 0 if success, 1 if error (invalid irq_sel). |
* @return 0 if success, 1 if error (invalid irq_sel). |
**************************************************************************/ |
int neorv32_cpu_irq_enable(uint8_t irq_sel) { |
|
67,7 → 67,7
* Disable specific CPU interrupt. |
* |
* @param[in] irq_sel CPU interrupt select. See #NEORV32_CPU_MIE_enum. |
* return 0 if success, 1 if error (invalid irq_sel). |
* @return 0 if success, 1 if error (invalid irq_sel). |
**************************************************************************/ |
int neorv32_cpu_irq_disable(uint8_t irq_sel) { |
|
82,6 → 82,139
|
|
/**********************************************************************//** |
* Get cycle count from cycle[h]. |
* |
* @note The cycle[h] CSR is shadowed copy of the mcycle[h] CSR. |
* |
* @return Current cycle counter (64 bit). |
**************************************************************************/ |
uint64_t neorv32_cpu_get_cycle(void) { |
|
union { |
uint64_t uint64; |
uint32_t uint32[sizeof(uint64_t)/2]; |
} cycles; |
|
uint32_t tmp1, tmp2, tmp3; |
while(1) { |
tmp1 = neorv32_cpu_csr_read(CSR_CYCLEH); |
tmp2 = neorv32_cpu_csr_read(CSR_CYCLE); |
tmp3 = neorv32_cpu_csr_read(CSR_CYCLEH); |
if (tmp1 == tmp3) { |
break; |
} |
} |
|
cycles.uint32[0] = tmp2; |
cycles.uint32[1] = tmp3; |
|
return cycles.uint64; |
} |
|
|
/**********************************************************************//** |
* Set mcycle[h] counter. |
* |
* @param[in] value New value for mcycle[h] CSR (64-bit). |
**************************************************************************/ |
void neorv32_cpu_set_mcycle(uint64_t value) { |
|
union { |
uint64_t uint64; |
uint32_t uint32[sizeof(uint64_t)/2]; |
} cycles; |
|
cycles.uint64 = value; |
|
neorv32_cpu_csr_write(CSR_MCYCLE, 0); |
neorv32_cpu_csr_write(CSR_MCYCLEH, cycles.uint32[1]); |
neorv32_cpu_csr_write(CSR_MCYCLE, cycles.uint32[0]); |
} |
|
|
/**********************************************************************//** |
* Get retired instructions counter from instret[h]. |
* |
* @note The instret[h] CSR is shadowed copy of the instret[h] CSR. |
* |
* @return Current instructions counter (64 bit). |
**************************************************************************/ |
uint64_t neorv32_cpu_get_instret(void) { |
|
union { |
uint64_t uint64; |
uint32_t uint32[sizeof(uint64_t)/2]; |
} cycles; |
|
uint32_t tmp1, tmp2, tmp3; |
while(1) { |
tmp1 = neorv32_cpu_csr_read(CSR_INSTRETH); |
tmp2 = neorv32_cpu_csr_read(CSR_INSTRET); |
tmp3 = neorv32_cpu_csr_read(CSR_INSTRETH); |
if (tmp1 == tmp3) { |
break; |
} |
} |
|
cycles.uint32[0] = tmp2; |
cycles.uint32[1] = tmp3; |
|
return cycles.uint64; |
} |
|
|
/**********************************************************************//** |
* Set retired instructions counter minstret[h]. |
* |
* @param[in] value New value for mcycle[h] CSR (64-bit). |
**************************************************************************/ |
void neorv32_cpu_set_minstret(uint64_t value) { |
|
union { |
uint64_t uint64; |
uint32_t uint32[sizeof(uint64_t)/2]; |
} cycles; |
|
cycles.uint64 = value; |
|
neorv32_cpu_csr_write(CSR_MINSTRET, 0); |
neorv32_cpu_csr_write(CSR_MINSTRETH, cycles.uint32[1]); |
neorv32_cpu_csr_write(CSR_MINSTRET, cycles.uint32[0]); |
} |
|
|
/**********************************************************************//** |
* Get current system time from time[h] CSR. |
* |
* @note This function requires the MTIME system timer to be implemented. |
* |
* @return Current system time (64 bit). |
**************************************************************************/ |
uint64_t neorv32_cpu_get_systime(void) { |
|
union { |
uint64_t uint64; |
uint32_t uint32[sizeof(uint64_t)/2]; |
} cycles; |
|
uint32_t tmp1, tmp2, tmp3; |
while(1) { |
tmp1 = neorv32_cpu_csr_read(CSR_TIMEH); |
tmp2 = neorv32_cpu_csr_read(CSR_TIME); |
tmp3 = neorv32_cpu_csr_read(CSR_TIMEH); |
if (tmp1 == tmp3) { |
break; |
} |
} |
|
cycles.uint32[0] = tmp2; |
cycles.uint32[1] = tmp3; |
|
return cycles.uint64; |
} |
|
|
/**********************************************************************//** |
* Simple delay function (not very precise) using busy wait. |
* |
* @param[in] time_ms Time in ms to wait. |
88,7 → 221,7
**************************************************************************/ |
void neorv32_cpu_delay_ms(uint32_t time_ms) { |
|
uint32_t clock_speed = neorv32_cpu_csr_read(CSR_MCLOCK) >> 10; // fake divide by 1000 |
uint32_t clock_speed = SYSINFO_CLK >> 10; // fake divide by 1000 |
clock_speed = clock_speed >> 5; // divide by loop execution time (~30 cycles) |
uint32_t cnt = clock_speed * time_ms; |
|
/lib/source/neorv32_gpio.c
52,7 → 52,7
**************************************************************************/ |
int neorv32_gpio_available(void) { |
|
if (neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_IO_GPIO)) { |
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_GPIO)) { |
return 1; |
} |
else { |
/lib/source/neorv32_mtime.c
52,7 → 52,7
**************************************************************************/ |
int neorv32_mtime_available(void) { |
|
if (neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_IO_MTIME)) { |
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_MTIME)) { |
return 1; |
} |
else { |
70,7 → 70,17
**************************************************************************/ |
void neorv32_mtime_set_time(uint64_t time) { |
|
MTIME = time; |
union { |
uint64_t uint64; |
uint32_t uint32[sizeof(uint64_t)/2]; |
} cycles; |
|
cycles.uint64 = time; |
|
MTIME_LO = 0; |
MTIME_HI = cycles.uint32[1]; |
MTIME_LO = cycles.uint32[0]; |
|
} |
|
|
83,7 → 93,25
**************************************************************************/ |
uint64_t neorv32_mtime_get_time(void) { |
|
return MTIME; |
union { |
uint64_t uint64; |
uint32_t uint32[sizeof(uint64_t)/2]; |
} cycles; |
|
uint32_t tmp1, tmp2, tmp3; |
while(1) { |
tmp1 = MTIME_HI; |
tmp2 = MTIME_LO; |
tmp3 = MTIME_HI; |
if (tmp1 == tmp3) { |
break; |
} |
} |
|
cycles.uint32[0] = tmp2; |
cycles.uint32[1] = tmp3; |
|
return cycles.uint64; |
} |
|
|
/lib/source/neorv32_pwm.c
52,7 → 52,7
**************************************************************************/ |
int neorv32_pwm_available(void) { |
|
if (neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_IO_PWM)) { |
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_PWM)) { |
return 1; |
} |
else { |
/lib/source/neorv32_rte.c
46,7 → 46,6
static void __neorv32_rte_dummy_exc_handler(void) __attribute__((unused)); |
static void __neorv32_rte_debug_exc_handler(void) __attribute__((unused)); |
static void __neorv32_rte_print_true_false(int state) __attribute__((unused)); |
static void __neorv32_rte_print_hw_version(void) __attribute__((unused)); |
|
|
/**********************************************************************//** |
94,7 → 93,7
if (exc_id == EXCID_MTI) { neorv32_cpu_irq_enable(CPU_MIE_MTIE); } // activate timer interrupt |
if (exc_id == EXCID_MEI) { neorv32_cpu_irq_enable(CPU_MIE_MEIE); } // activate external interrupt |
|
uint32_t vt_base = neorv32_cpu_csr_read(CSR_MDSPACEBASE); // base address of vector table |
uint32_t vt_base = SYSINFO_DSPACE_BASE; // base address of vector table |
vt_base = vt_base + (((uint32_t)exc_id) << 2); |
(*(IO_REG32 (vt_base))) = (uint32_t)handler; |
|
127,7 → 126,7
if (exc_id == EXCID_MTI) { neorv32_cpu_irq_disable(CPU_MIE_MTIE); } // deactivate timer interrupt |
if (exc_id == EXCID_MEI) { neorv32_cpu_irq_disable(CPU_MIE_MEIE); } // deactivate external interrupt |
|
uint32_t vt_base = neorv32_cpu_csr_read(CSR_MDSPACEBASE); // base address of vector table |
uint32_t vt_base = SYSINFO_DSPACE_BASE; // base address of vector table |
vt_base = vt_base + (((uint32_t)exc_id) << 2); |
(*(IO_REG32 (vt_base))) = (uint32_t)(&__neorv32_rte_dummy_exc_handler); // use dummy handler in case the exception is triggered |
|
161,9 → 160,9
register uint32_t trap_addr = neorv32_cpu_csr_read(CSR_MEPC); |
register uint32_t trap_inst; |
|
// get faulting instruction |
asm volatile ("lh %[result], 0(%[input_i])" : [result] "=r" (trap_inst) : [input_i] "r" (trap_addr)); |
|
|
if (trap_cause & 0x80000000) { |
neorv32_uart_printf("INTERRUPT"); |
} |
196,7 → 195,7
} |
|
// fault address |
neorv32_uart_printf("\nFaulting instruction: 0x%x\n", trap_inst); |
neorv32_uart_printf("\nFaulting instruction (low): 0x%x\n", trap_inst); |
neorv32_uart_printf("MTVAL: 0x%x\n", neorv32_cpu_csr_read(CSR_MTVAL)); |
|
if ((trap_inst & 3) != 3) { |
224,11 → 223,14
neorv32_uart_printf("\n-- Central Processing Unit --\n"); |
|
// Hart ID |
neorv32_uart_printf("Hart ID: 0x%x\n", neorv32_cpu_csr_read(CSR_MHARTID)); |
neorv32_uart_printf("Hart ID: %u\n", neorv32_cpu_csr_read(CSR_MHARTID)); |
|
// Custom user code |
neorv32_uart_printf("User code: 0x%x\n", SYSINFO_USER_CODE); |
|
// HW version |
neorv32_uart_printf("Hardware version: "); |
__neorv32_rte_print_hw_version(); |
neorv32_rte_print_hw_version(); |
neorv32_uart_printf(" (0x%x)\n", neorv32_cpu_csr_read(CSR_MIMPID)); |
|
// CPU architecture |
260,69 → 262,65
} |
neorv32_uart_printf("(0x%x)\n", tmp); |
|
// Performance counters |
neorv32_uart_printf("CNT & time CSRs: "); |
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_CSR_COUNTERS)); |
|
// Clock speed |
neorv32_uart_printf("Clock speed: %u Hz\n", neorv32_cpu_csr_read(CSR_MCLOCK)); |
neorv32_uart_printf("Clock speed: %u Hz\n", SYSINFO_CLK); |
|
// Memory configuration |
neorv32_uart_printf("\n-- Memory Configuration --\n"); |
|
uint32_t size = neorv32_cpu_csr_read(CSR_MISPACESIZE); |
uint32_t base = neorv32_cpu_csr_read(CSR_MISPACEBASE); |
uint32_t size = SYSINFO_ISPACE_SIZE; |
uint32_t base = SYSINFO_ISPACE_BASE; |
neorv32_uart_printf("Instruction memory: %u bytes @ 0x%x\n", size, base); |
neorv32_uart_printf("Internal IMEM: "); |
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_MEM_INT_IMEM)); |
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM)); |
neorv32_uart_printf("Internal IMEM as ROM: "); |
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_MEM_INT_IMEM_ROM)); |
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM)); |
|
size = neorv32_cpu_csr_read(CSR_MDSPACESIZE); |
base = neorv32_cpu_csr_read(CSR_MDSPACEBASE); |
size = SYSINFO_DSPACE_SIZE; |
base = SYSINFO_DSPACE_BASE; |
neorv32_uart_printf("Data memory: %u bytes @ 0x%x\n", size, base); |
neorv32_uart_printf("Internal DMEM: "); |
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_MEM_INT_DMEM)); |
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_DMEM)); |
|
neorv32_uart_printf("Bootloader: "); |
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_BOOTLOADER)); |
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_BOOTLOADER)); |
|
neorv32_uart_printf("External interface: "); |
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_MEM_EXT)); |
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT)); |
|
// peripherals |
neorv32_uart_printf("\n-- Peripherals --\n"); |
tmp = neorv32_cpu_csr_read(CSR_MFEATURES); |
tmp = SYSINFO_FEATURES; |
|
neorv32_uart_printf("GPIO: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_GPIO)); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_GPIO)); |
|
neorv32_uart_printf("MTIME: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_MTIME)); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_MTIME)); |
|
neorv32_uart_printf("UART: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_UART)); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_UART)); |
|
neorv32_uart_printf("SPI: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_SPI)); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_SPI)); |
|
neorv32_uart_printf("TWI: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_TWI)); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TWI)); |
|
neorv32_uart_printf("PWM: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_PWM)); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_PWM)); |
|
neorv32_uart_printf("WDT: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_WDT)); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_WDT)); |
|
neorv32_uart_printf("CLIC: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_CLIC)); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_CLIC)); |
|
neorv32_uart_printf("TRNG: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_TRNG)); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TRNG)); |
|
neorv32_uart_printf("DEVNULL: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_DEVNULL)); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_DEVNULL)); |
} |
|
|
344,10 → 342,9
|
|
/**********************************************************************//** |
* NEORV32 runtime environment: Private function to show the processor version in human-readable format. |
* @note This function is used by neorv32_rte_print_hw_config(void) only. |
* NEORV32 runtime environment: Function to show the processor version in human-readable format. |
**************************************************************************/ |
static void __neorv32_rte_print_hw_version(void) { |
void neorv32_rte_print_hw_version(void) { |
|
uint32_t i; |
char tmp, cnt; |
/lib/source/neorv32_spi.c
52,7 → 52,7
**************************************************************************/ |
int neorv32_spi_available(void) { |
|
if (neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_IO_SPI)) { |
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_SPI)) { |
return 1; |
} |
else { |
/lib/source/neorv32_trng.c
52,7 → 52,7
**************************************************************************/ |
int neorv32_trng_available(void) { |
|
if (neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_IO_TRNG)) { |
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_TRNG)) { |
return 1; |
} |
else { |
/lib/source/neorv32_twi.c
52,7 → 52,7
**************************************************************************/ |
int neorv32_twi_available(void) { |
|
if (neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_IO_TWI)) { |
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_TWI)) { |
return 1; |
} |
else { |
/lib/source/neorv32_uart.c
59,7 → 59,7
**************************************************************************/ |
int neorv32_uart_available(void) { |
|
if (neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_IO_UART)) { |
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_UART)) { |
return 1; |
} |
else { |
80,7 → 80,7
UART_CT = 0; // reset |
|
// raw baud rate prescaler |
uint32_t clock = neorv32_cpu_csr_read(CSR_MCLOCK); |
uint32_t clock = SYSINFO_CLK; |
uint16_t i = 0; // BAUD rate divisor |
uint8_t p = 0; // prsc = CLK/2 |
while (clock >= 2*baudrate) { |
/lib/source/neorv32_wdt.c
52,7 → 52,7
**************************************************************************/ |
int neorv32_wdt_available(void) { |
|
if (neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_IO_WDT)) { |
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_WDT)) { |
return 1; |
} |
else { |