summaryrefslogtreecommitdiff
path: root/bsp/env/freedom-e300-hifive1/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsp/env/freedom-e300-hifive1/init.c')
-rw-r--r--bsp/env/freedom-e300-hifive1/init.c238
1 files changed, 0 insertions, 238 deletions
diff --git a/bsp/env/freedom-e300-hifive1/init.c b/bsp/env/freedom-e300-hifive1/init.c
deleted file mode 100644
index 621a6e2..0000000
--- a/bsp/env/freedom-e300-hifive1/init.c
+++ /dev/null
@@ -1,238 +0,0 @@
-#include <stdint.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include "platform.h"
-#include "encoding.h"
-
-extern int main(int argc, char** argv);
-extern void trap_entry();
-
-static unsigned long mtime_lo(void)
-{
- return *(volatile unsigned long *)(CLINT_CTRL_ADDR + CLINT_MTIME);
-}
-
-#ifdef __riscv32
-
-static uint32_t mtime_hi(void)
-{
- return *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIME + 4);
-}
-
-uint64_t get_timer_value()
-{
- while (1) {
- uint32_t hi = mtime_hi();
- uint32_t lo = mtime_lo();
- if (hi == mtime_hi())
- return ((uint64_t)hi << 32) | lo;
- }
-}
-
-#else /* __riscv32 */
-
-uint64_t get_timer_value()
-{
- return mtime_lo();
-}
-
-#endif
-
-unsigned long get_timer_freq()
-{
- return 32768;
-}
-
-static void use_hfrosc(int div, int trim)
-{
- // Make sure the HFROSC is running at its default setting
- PRCI_REG(PRCI_HFROSCCFG) = (ROSC_DIV(div) | ROSC_TRIM(trim) | ROSC_EN(1));
- while ((PRCI_REG(PRCI_HFROSCCFG) & ROSC_RDY(1)) == 0) ;
- PRCI_REG(PRCI_PLLCFG) &= ~PLL_SEL(1);
-}
-
-static void use_pll(int refsel, int bypass, int r, int f, int q)
-{
- // Ensure that we aren't running off the PLL before we mess with it.
- if (PRCI_REG(PRCI_PLLCFG) & PLL_SEL(1)) {
- // Make sure the HFROSC is running at its default setting
- use_hfrosc(4, 16);
- }
-
- // Set PLL Source to be HFXOSC if available.
- uint32_t config_value = 0;
-
- config_value |= PLL_REFSEL(refsel);
-
- if (bypass) {
- // Bypass
- config_value |= PLL_BYPASS(1);
-
- PRCI_REG(PRCI_PLLCFG) = config_value;
-
- // If we don't have an HFXTAL, this doesn't really matter.
- // Set our Final output divide to divide-by-1:
- PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0));
- } else {
- // In case we are executing from QSPI,
- // (which is quite likely) we need to
- // set the QSPI clock divider appropriately
- // before boosting the clock frequency.
-
- // Div = f_sck/2
- SPI0_REG(SPI_REG_SCKDIV) = 8;
-
- // Set DIV Settings for PLL
- // Both HFROSC and HFXOSC are modeled as ideal
- // 16MHz sources (assuming dividers are set properly for
- // HFROSC).
- // (Legal values of f_REF are 6-48MHz)
-
- // Set DIVR to divide-by-2 to get 8MHz frequency
- // (legal values of f_R are 6-12 MHz)
-
- config_value |= PLL_BYPASS(1);
- config_value |= PLL_R(r);
-
- // Set DIVF to get 512Mhz frequncy
- // There is an implied multiply-by-2, 16Mhz.
- // So need to write 32-1
- // (legal values of f_F are 384-768 MHz)
- config_value |= PLL_F(f);
-
- // Set DIVQ to divide-by-2 to get 256 MHz frequency
- // (legal values of f_Q are 50-400Mhz)
- config_value |= PLL_Q(q);
-
- // Set our Final output divide to divide-by-1:
- PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0));
-
- PRCI_REG(PRCI_PLLCFG) = config_value;
-
- // Un-Bypass the PLL.
- PRCI_REG(PRCI_PLLCFG) &= ~PLL_BYPASS(1);
-
- // Wait for PLL Lock
- // Note that the Lock signal can be glitchy.
- // Need to wait 100 us
- // RTC is running at 32kHz.
- // So wait 4 ticks of RTC.
- uint32_t now = mtime_lo();
- while (mtime_lo() - now < 4) ;
-
- // Now it is safe to check for PLL Lock
- while ((PRCI_REG(PRCI_PLLCFG) & PLL_LOCK(1)) == 0) ;
- }
-
- // Switch over to PLL Clock source
- PRCI_REG(PRCI_PLLCFG) |= PLL_SEL(1);
-}
-
-static void use_default_clocks()
-{
- // Turn off the LFROSC
- AON_REG(AON_LFROSC) &= ~ROSC_EN(1);
-
- // Use HFROSC
- use_hfrosc(4, 16);
-}
-
-static unsigned long __attribute__((noinline)) measure_cpu_freq(size_t n)
-{
- unsigned long start_mtime, delta_mtime;
- unsigned long mtime_freq = get_timer_freq();
-
- // Don't start measuruing until we see an mtime tick
- unsigned long tmp = mtime_lo();
- do {
- start_mtime = mtime_lo();
- } while (start_mtime == tmp);
-
- unsigned long start_mcycle = read_csr(mcycle);
-
- do {
- delta_mtime = mtime_lo() - start_mtime;
- } while (delta_mtime < n);
-
- unsigned long delta_mcycle = read_csr(mcycle) - start_mcycle;
-
- return (delta_mcycle / delta_mtime) * mtime_freq
- + ((delta_mcycle % delta_mtime) * mtime_freq) / delta_mtime;
-}
-
-unsigned long get_cpu_freq()
-{
- static uint32_t cpu_freq;
-
- if (!cpu_freq) {
- // warm up I$
- measure_cpu_freq(1);
- // measure for real
- cpu_freq = measure_cpu_freq(10);
- }
-
- return cpu_freq;
-}
-
-static void uart_init(size_t baud_rate)
-{
- GPIO_REG(GPIO_IOF_SEL) &= ~IOF0_UART0_MASK;
- GPIO_REG(GPIO_IOF_EN) |= IOF0_UART0_MASK;
- UART0_REG(UART_REG_DIV) = get_cpu_freq() / baud_rate - 1;
- UART0_REG(UART_REG_TXCTRL) |= UART_TXEN;
-}
-
-
-
-#ifdef USE_PLIC
-extern void handle_m_ext_interrupt();
-#endif
-
-#ifdef USE_M_TIME
-extern void handle_m_time_interrupt();
-#endif
-
-uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc)
-{
- if (0){
-#ifdef USE_PLIC
- // External Machine-Level interrupt from PLIC
- } else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT)) {
- handle_m_ext_interrupt();
-#endif
-#ifdef USE_M_TIME
- // External Machine-Level interrupt from PLIC
- } else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER)){
- handle_m_time_interrupt();
-#endif
- }
- else {
- write(1, "trap\n", 5);
- _exit(1 + mcause);
- }
- return epc;
-}
-
-void _init()
-{
-
- #ifndef NO_INIT
- use_default_clocks();
- use_pll(0, 0, 1, 31, 1);
- uart_init(115200);
-
- printf("core freq at %d Hz\n", get_cpu_freq());
-
- write_csr(mtvec, &trap_entry);
- if (read_csr(misa) & (1 << ('F' - 'A'))) { // if F extension is present
- write_csr(mstatus, MSTATUS_FS); // allow FPU instructions without trapping
- write_csr(fcsr, 0); // initialize rounding mode, undefined at reset
- }
- #endif
-
-}
-
-void _fini()
-{
-}