1/* Copied from https://wiki.osdev.org/HiFive-1_Bare_Bones#The_kernel_source_code */2/* Should eventually be rewritten in Zig with proper abstraction for the PRCI. */34#include <stdint.h>56#define PRCI_CTRL_ADDR 0x10008000UL7#define PRCI_HFROSCCFG (0x0000)8#define PRCI_PLLCFG (0x0008)9#define ROSC_EN(x) (((x) & 0x1) << 30)10#define PLL_REFSEL(x) (((x) & 0x1) << 17)11#define PLL_BYPASS(x) (((x) & 0x1) << 18)12#define PLL_SEL(x) (((x) & 0x1) << 16)1314static inline uint32_t15mmio_read_u32(unsigned long reg, unsigned int offset)16{17 return (*(volatile uint32_t *) ((reg) + (offset)));18}1920static inline void21mmio_write_u32(unsigned long reg, unsigned int offset, uint32_t val)22{23 (*(volatile uint32_t *) ((reg) + (offset))) = val;24}2526void27clock_init(void)28{29 /* Make sure the HFROSC is on */30 mmio_write_u32(PRCI_CTRL_ADDR, PRCI_HFROSCCFG,31 mmio_read_u32(PRCI_CTRL_ADDR, PRCI_HFROSCCFG)32 | ROSC_EN(1));3334 /* Run off 16 MHz Crystal for accuracy */35 mmio_write_u32(PRCI_CTRL_ADDR, PRCI_PLLCFG,36 mmio_read_u32(PRCI_CTRL_ADDR, PRCI_PLLCFG)37 | (PLL_REFSEL(1) | PLL_BYPASS(1)));38 mmio_write_u32(PRCI_CTRL_ADDR, PRCI_PLLCFG,39 mmio_read_u32(PRCI_CTRL_ADDR, PRCI_PLLCFG)40 | (PLL_SEL(1)));4142 /* Turn off HFROSC to save power */43 mmio_write_u32(PRCI_CTRL_ADDR, PRCI_HFROSCCFG,44 mmio_read_u32(PRCI_CTRL_ADDR, PRCI_HFROSCCFG)45 & ~(ROSC_EN(1)));46}