OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [lib/] [source/] [neorv32_cpu.c] - Diff between revs 2 and 9

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 2 Rev 9
Line 42... Line 42...
#include "neorv32.h"
#include "neorv32.h"
#include "neorv32_cpu.h"
#include "neorv32_cpu.h"
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * Put CPU into "sleep" mode.
 * Enable/disable CPU extension during runtime via the 'misa' CSR.
 *
 *
 * @note This function executes the WFI insstruction.
 * @warning This is still highly experimental! This function requires the Zicsr + Zifencei CPU extensions.
 * The WFI (wait for interrupt) instruction will make the CPU stall until
 *
 * an interupt request is detected. Interrupts have to be globally enabled
 * @param[in] sel Bit to be set in misa CSR / extension to be enabled. See #NEORV32_CPU_MISA_enum.
 * and at least one external source must be enabled (e.g., the CLIC or the machine
 * @param[in] state Set 1 to enable the selected extension, set 0 to disable it;
 * timer) to allow the CPU to wake up again. If 'Zicsr' CPU extension is disabled,
 * return 0 if success, 1 if error (invalid sel or extension cannot be enabled).
 * this will permanently stall the CPU.
 **************************************************************************/
 **************************************************************************/
int neorv32_cpu_switch_extension(int sel, int state) {
void neorv32_cpu_sleep(void) {
 
 
  // get current misa setting
 
  uint32_t misa_curr = neorv32_cpu_csr_read(CSR_MISA);
 
  uint32_t misa_prev = misa_curr;
 
 
  asm volatile ("wfi");
  // abort if misa.z is cleared
 
  if ((misa_curr & (1 << CPU_MISA_Z_EXT)) == 0) {
 
    return 1;
}
}
 
 
 
  // out of range?
/**********************************************************************//**
  if (sel > 25) {
 * Enable global CPU interrupts (via MIE flag in mstatus CSR).
    return 1;
 **************************************************************************/
 
void neorv32_cpu_eint(void) {
 
 
 
  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
 * Disable global CPU interrupts (via MIE flag in mstatus CSR).
  neorv32_cpu_csr_write(CSR_MISA, misa_curr);
 **************************************************************************/
  asm volatile("fence.i"); // required to flush prefetch buffers
void neorv32_cpu_dint(void) {
  asm volatile("nop");
 
 
  const int mask = 1 << CPU_MSTATUS_MIE;
  // dit it work?
  asm volatile ("csrrci zero, mstatus, %0" : : "i" (mask));
  if (neorv32_cpu_csr_read(CSR_MISA) == misa_prev) {
 
    return 1; // nope
 
  }
 
  else {
 
    return 0; // fine
 
  }
}
}
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * Enable specific CPU interrupt.
 * Enable specific CPU interrupt.
Line 116... Line 128...
  return 0;
  return 0;
}
}
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * 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.
 * Simple delay function (not very precise) using busy wait.
 *
 *
 * @param[in] time_ms Time in ms to wait.
 * @param[in] time_ms Time in ms to wait.
 **************************************************************************/
 **************************************************************************/
void neorv32_cpu_delay_ms(uint32_t time_ms) {
void neorv32_cpu_delay_ms(uint32_t time_ms) {

powered by: WebSVN 2.1.0

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