OpenCores
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 8 to Rev 9
    Reverse comparison

Rev 8 → Rev 9

/bootloader/bootloader.c
63,7 → 63,7
/** UART BAUD rate */
#define BAUD_RATE (19200)
/** Time until the auto-boot sequence starts (in seconds) */
#define AUTOBOOT_TIMEOUT (8)
#define AUTOBOOT_TIMEOUT 8
/** Bootloader status LED at GPIO output port (0..15) */
#define STATUS_LED (0)
/** SPI flash boot image base address */
/lib/include/neorv32_cpu.h
43,14 → 43,9
#define neorv32_cpu_h
 
// prototypes
void neorv32_cpu_sleep(void);
void neorv32_cpu_eint(void);
void neorv32_cpu_dint(void);
int neorv32_cpu_switch_extension(int sel, int state);
int neorv32_cpu_irq_enable(uint8_t irq_sel);
int neorv32_cpu_irq_disable(uint8_t irq_sel);
void neorv32_cpu_sw_irq(void);
void neorv32_cpu_breakpoint(void);
void neorv32_cpu_env_call(void);
void neorv32_cpu_delay_ms(uint32_t time_ms);
 
 
83,4 → 78,74
asm volatile ("csrw %[input_i], %[input_j]" : : [input_i] "i" (csr_id), [input_j] "r" (csr_data));
}
 
 
/**********************************************************************//**
* Put CPU into "sleep" mode.
*
* @note This function executes the WFI insstruction.
* The WFI (wait for interrupt) instruction will make the CPU stall until
* an interupt request is detected. Interrupts have to be globally enabled
* and at least one external source must be enabled (e.g., the CLIC or the machine
* timer) to allow the CPU to wake up again. If 'Zicsr' CPU extension is disabled,
* this will permanently stall the CPU.
**************************************************************************/
inline void __attribute__ ((always_inline)) neorv32_cpu_sleep(void) {
 
asm volatile ("wfi");
}
 
 
/**********************************************************************//**
* Enable global CPU interrupts (via MIE flag in mstatus CSR).
**************************************************************************/
inline void __attribute__ ((always_inline)) neorv32_cpu_eint(void) {
 
asm volatile ("csrrsi zero, mstatus, %0" : : "i" (1 << CPU_MSTATUS_MIE));
}
 
 
/**********************************************************************//**
* Disable global CPU interrupts (via MIE flag in mstatus CSR).
**************************************************************************/
inline void __attribute__ ((always_inline)) neorv32_cpu_dint(void) {
 
asm volatile ("csrrci zero, mstatus, %0" : : "i" (1 << CPU_MSTATUS_MIE));
}
 
 
/**********************************************************************//**
* 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) {
 
asm volatile ("ebreak");
}
 
 
/**********************************************************************//**
* Trigger "environment call" exception (via ECALL instruction).
**************************************************************************/
inline void __attribute__ ((always_inline)) neorv32_cpu_env_call(void) {
 
asm volatile ("ecall");
}
 
 
#endif // neorv32_cpu_h
/lib/source/neorv32_cpu.c
44,38 → 44,50
 
 
/**********************************************************************//**
* Put CPU into "sleep" mode.
* Enable/disable CPU extension during runtime via the 'misa' CSR.
*
* @note This function executes the WFI insstruction.
* The WFI (wait for interrupt) instruction will make the CPU stall until
* an interupt request is detected. Interrupts have to be globally enabled
* and at least one external source must be enabled (e.g., the CLIC or the machine
* timer) to allow the CPU to wake up again. If 'Zicsr' CPU extension is disabled,
* this will permanently stall the CPU.
* @warning This is still highly experimental! This function requires the Zicsr + Zifencei CPU extensions.
*
* @param[in] sel Bit to be set in misa CSR / extension to be enabled. See #NEORV32_CPU_MISA_enum.
* @param[in] state Set 1 to enable the selected extension, set 0 to disable it;
* return 0 if success, 1 if error (invalid sel or extension cannot be enabled).
**************************************************************************/
void neorv32_cpu_sleep(void) {
int neorv32_cpu_switch_extension(int sel, int state) {
 
asm volatile ("wfi");
}
// get current misa setting
uint32_t misa_curr = neorv32_cpu_csr_read(CSR_MISA);
uint32_t misa_prev = misa_curr;
 
// abort if misa.z is cleared
if ((misa_curr & (1 << CPU_MISA_Z_EXT)) == 0) {
return 1;
}
 
/**********************************************************************//**
* Enable global CPU interrupts (via MIE flag in mstatus CSR).
**************************************************************************/
void neorv32_cpu_eint(void) {
// out of range?
if (sel > 25) {
return 1;
}
 
const int mask = 1 << CPU_MSTATUS_MIE;
asm volatile ("csrrsi zero, mstatus, %0" : : "i" (mask));
}
// enable/disable selected extension
if (state & 1) {
misa_curr |= (1 << sel);
}
else {
misa_curr &= ~(1 << sel);
}
 
// try updating misa
neorv32_cpu_csr_write(CSR_MISA, misa_curr);
asm volatile("fence.i"); // required to flush prefetch buffers
asm volatile("nop");
 
/**********************************************************************//**
* Disable global CPU interrupts (via MIE flag in mstatus CSR).
**************************************************************************/
void neorv32_cpu_dint(void) {
 
const int mask = 1 << CPU_MSTATUS_MIE;
asm volatile ("csrrci zero, mstatus, %0" : : "i" (mask));
// dit it work?
if (neorv32_cpu_csr_read(CSR_MISA) == misa_prev) {
return 1; // nope
}
else {
return 0; // fine
}
}
 
 
118,37 → 130,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.
**************************************************************************/
void neorv32_cpu_sw_irq(void) {
 
register uint32_t mask = (uint32_t)(1 << CPU_MIP_MSIP);
asm volatile ("csrrs zero, mip, %0" : : "r" (mask));
}
 
 
/**********************************************************************//**
* Trigger breakpoint exception (via EBREAK instruction).
**************************************************************************/
void neorv32_cpu_breakpoint(void) {
 
asm volatile ("ebreak");
}
 
 
/**********************************************************************//**
* Trigger "environment call" exception (via ECALL instruction).
**************************************************************************/
void neorv32_cpu_env_call(void) {
 
asm volatile ("ecall");
}
 
 
/**********************************************************************//**
* Simple delay function (not very precise) using busy wait.
*
* @param[in] time_ms Time in ms to wait.

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.