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/lib
- from Rev 37 to Rev 39
- ↔ Reverse comparison
Rev 37 → Rev 39
/include/neorv32.h
143,8 → 143,11
* CPU <b>misa</b> CSR (r/-): Machine instruction set extensions (RISC-V spec.) |
**************************************************************************/ |
enum NEORV32_CPU_MISA_enum { |
CPU_MISA_A_EXT = 0, /**< CPU misa CSR (0): A: Atomic instructions CPU extension available (r/-)*/ |
CPU_MISA_B_EXT = 1, /**< CPU misa CSR (1): B: Bit manipulation CPU extension available (r/-)*/ |
CPU_MISA_C_EXT = 2, /**< CPU misa CSR (2): C: Compressed instructions CPU extension available (r/-)*/ |
CPU_MISA_E_EXT = 4, /**< CPU misa CSR (3): E: Embedded CPU extension available (r/-) */ |
CPU_MISA_E_EXT = 4, /**< CPU misa CSR (4): E: Embedded CPU extension available (r/-) */ |
CPU_MISA_F_EXT = 4, /**< CPU misa CSR (5): F: Floating point (single-precision) extension available (r/-) */ |
CPU_MISA_I_EXT = 8, /**< CPU misa CSR (8): I: Base integer ISA CPU extension available (r/-) */ |
CPU_MISA_M_EXT = 12, /**< CPU misa CSR (12): M: Multiplier/divider CPU extension available (r/-)*/ |
CPU_MISA_U_EXT = 20, /**< CPU misa CSR (20): U: User mode CPU extension available (r/-)*/ |
/include/neorv32_cpu.h
52,6 → 52,7
uint64_t neorv32_cpu_get_systime(void); |
void neorv32_cpu_delay_ms(uint32_t time_ms); |
void __attribute__((naked)) neorv32_cpu_goto_user_mode(void); |
int neorv32_cpu_atomic_cas(uint32_t addr, uint32_t expected, uint32_t desired); |
|
|
/**********************************************************************//** |
/source/neorv32_cpu.c
217,23 → 217,26
|
|
/**********************************************************************//** |
* Simple delay function (not very precise) using busy wait. |
* Simple delay function using busy wait. |
* |
* @warning This function requires the cycle CSR(s). Hence, the Zicsr extension is mandatory. |
* |
* @param[in] time_ms Time in ms to wait. |
**************************************************************************/ |
void neorv32_cpu_delay_ms(uint32_t time_ms) { |
|
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; |
uint64_t time_resume = neorv32_cpu_get_cycle(); |
|
// one iteration = ~30 cycles |
while (cnt) { |
asm volatile("nop"); |
asm volatile("nop"); |
asm volatile("nop"); |
asm volatile("nop"); |
cnt--; |
uint32_t clock = SYSINFO_CLK; // clock ticks per second |
clock = clock / 1000; // clock ticks per ms |
|
uint64_t wait_cycles = ((uint64_t)clock) * ((uint64_t)time_ms); |
time_resume += wait_cycles; |
|
while(1) { |
if (neorv32_cpu_get_cycle() >= time_resume) { |
break; |
} |
} |
} |
|
241,16 → 244,54
/**********************************************************************//** |
* Switch from privilege mode MACHINE to privilege mode USER. |
* |
* @note This function requires the U extension to be implemented. |
* @note Maybe you should do a fence.i after this. |
* @warning This function requires the U extension to be implemented. |
**************************************************************************/ |
void __attribute__((naked)) neorv32_cpu_goto_user_mode(void) { |
|
// make sure to use NO registers in here! -> naked |
|
asm volatile ("csrw mepc, ra \n\t" // move return address to mepc so we can return using "mret". also, we can use ra as general purpose register in here |
asm volatile ("csrw mepc, ra \n\t" // move return address to mepc so we can return using "mret". also, we can now use ra as general purpose register in here |
"li ra, %[input_imm] \n\t" // bit mask to clear the two MPP bits |
"csrrc zero, mstatus, ra \n\t" // clear MPP bits -> MPP=u-mode |
"mret \n\t" // return and switch to user mode |
: : [input_imm] "i" ((1<<CPU_MSTATUS_MPP_H) | (1<<CPU_MSTATUS_MPP_L))); |
} |
|
|
/**********************************************************************//** |
* Atomic compare-and-swap operation (for implemeneting semaphores and mutexes). |
* |
* @warning This function requires the A (atomic) CPU extension. |
* |
* @param[in] addr Address of memory location. |
* @param[in] expected Expected value (for comparison). |
* @param[in] desired Desired value (new value). |
* @return Returns 0 on success, 1 on failure. |
**************************************************************************/ |
int __attribute__ ((noinline)) neorv32_cpu_atomic_cas(uint32_t addr, uint32_t expected, uint32_t desired) { |
#ifdef __riscv_atomic |
|
register uint32_t addr_reg = addr; |
register uint32_t des_reg = desired; |
register uint32_t tmp_reg; |
|
// load original value + reservation (lock) |
asm volatile ("lr.w %[result], (%[input])" : [result] "=r" (tmp_reg) : [input] "r" (addr_reg)); |
|
if (tmp_reg != expected) { |
asm volatile ("lw x0, 0(%[input])" : : [input] "r" (addr_reg)); // clear reservation lock |
return 1; |
} |
|
// store-conditional |
asm volatile ("sc.w %[result], %[input_i], (%[input_j])" : [result] "=r" (tmp_reg) : [input_i] "r" (des_reg), [input_j] "r" (addr_reg)); |
|
if (tmp_reg) { |
return 1; |
} |
|
return 0; |
#else |
return 1; // A extension not implemented -Y always fail |
#endif |
} |
/source/neorv32_rte.c
397,38 → 397,38
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT)); |
|
// peripherals |
neorv32_uart_printf("\n-- Processor Peripherals --\n"); |
neorv32_uart_printf("\n-- Available Processor Peripherals --\n"); |
|
tmp = SYSINFO_FEATURES; |
|
neorv32_uart_printf("GPIO: "); |
neorv32_uart_printf("GPIO - "); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_GPIO)); |
|
neorv32_uart_printf("MTIME: "); |
neorv32_uart_printf("MTIME - "); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_MTIME)); |
|
neorv32_uart_printf("UART: "); |
neorv32_uart_printf("UART - "); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_UART)); |
|
neorv32_uart_printf("SPI: "); |
neorv32_uart_printf("SPI - "); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_SPI)); |
|
neorv32_uart_printf("TWI: "); |
neorv32_uart_printf("TWI - "); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TWI)); |
|
neorv32_uart_printf("PWM: "); |
neorv32_uart_printf("PWM - "); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_PWM)); |
|
neorv32_uart_printf("WDT: "); |
neorv32_uart_printf("WDT - "); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_WDT)); |
|
neorv32_uart_printf("TRNG: "); |
neorv32_uart_printf("TRNG - "); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TRNG)); |
|
neorv32_uart_printf("CFU0: "); |
neorv32_uart_printf("CFU0 - "); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_CFU0)); |
|
neorv32_uart_printf("CFU1: "); |
neorv32_uart_printf("CFU1 - "); |
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_CFU1)); |
} |
|
506,9 → 506,8
**************************************************************************/ |
void neorv32_rte_print_credits(void) { |
|
neorv32_uart_print("\nThe NEORV32 Processor Project, by Stephan Nolting\n" |
"https://github.com/stnolting/neorv32\n" |
"made in Hannover, Germany EU\n\n"); |
neorv32_uart_print("The NEORV32 Processor Project by Stephan Nolting\n" |
"https://github.com/stnolting/neorv32\n\n"); |
} |
|
|