diff --git a/hw/bsp/fomu/board.mk b/hw/bsp/fomu/board.mk new file mode 100644 index 00000000..86f8df23 --- /dev/null +++ b/hw/bsp/fomu/board.mk @@ -0,0 +1,29 @@ +CFLAGS += \ + -march=rv32i \ + -mabi=ilp32 \ + -nostdlib \ + -DCFG_TUSB_MCU=OPT_MCU_FOMU_EPTRI + +MCU_DIR = hw/mcu/fomu +BSP_DIR = hw/bsp/fomu + +# All source paths should be relative to the top level. +LD_FILE = hw/bsp/fomu/fomu.ld + +# TODO remove later +SRC_C += src/portable/$(VENDOR)/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c + +SRC_C += + +SRC_S += hw/bsp/fomu/crt0-vexriscv.S + +INC += \ + $(TOP)/$(BSP_DIR)/include + +# For TinyUSB port source +VENDOR = foosn +CHIP_FAMILY = fomu + +# flash using dfu-util +flash: $(BUILD)/$(BOARD)-firmware.dfu + dfu-util -D $^ diff --git a/hw/bsp/fomu/bsp.c b/hw/bsp/fomu/bsp.c new file mode 100644 index 00000000..861c223f --- /dev/null +++ b/hw/bsp/fomu/bsp.c @@ -0,0 +1,129 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include +#include +#include "common/tusb_common.h" +#include "csr.h" +#include "irq.h" + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void hal_dcd_isr(uint8_t rhport); + +void mputs(const char *str) { + (void)str; + while (*str) { + if (! (messible_status_read() & CSR_MESSIBLE_STATUS_FULL_OFFSET)) + messible_in_write(*str); + str++; + } +} + +void mputln(const char *str) { + mputs(str); + mputs("\n"); +} + +void fomu_error(uint32_t line) +{ + (void)line; + TU_BREAKPOINT(); + while (1) {} +} + +volatile uint32_t system_ticks = 0; +static void timer_init(void) +{ + int t; + + timer0_en_write(0); + t = CONFIG_CLOCK_FREQUENCY / 1000; // 1000 kHz tick + timer0_reload_write(t); + timer0_load_write(t); + timer0_en_write(1); + timer0_ev_enable_write(1); + timer0_ev_pending_write(1); + irq_setmask(irq_getmask() | (1 << TIMER0_INTERRUPT)); +} + +void isr(void) +{ + unsigned int irqs; + + irqs = irq_pending() & irq_getmask(); + + if (irqs & (1 << USB_INTERRUPT)) { + hal_dcd_isr(0); + } + if (irqs & (1 << TIMER0_INTERRUPT)) { + system_ticks++; + timer0_ev_pending_write(1); + } +} + +void board_init(void) +{ + mputln("Fomu Initializing"); + irq_setmask(0); + irq_setie(1); + timer_init(); + return; +} + +void board_led_write(bool state) +{ + rgb_ctrl_write(0xff); + rgb_raw_write(state); +} + +uint32_t board_button_read(void) +{ + return 0; +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ + (void) buf; + (void) len; + return 0; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif \ No newline at end of file diff --git a/hw/bsp/fomu/crt0-vexriscv.S b/hw/bsp/fomu/crt0-vexriscv.S new file mode 100644 index 00000000..931d50a0 --- /dev/null +++ b/hw/bsp/fomu/crt0-vexriscv.S @@ -0,0 +1,91 @@ +.global main +.global isr + +.section .text.start +.global _start + +_start: + j crt_init + nop + nop + nop + nop + nop + nop + nop + +.section .text +.global trap_entry +trap_entry: + sw x1, - 1*4(sp) + sw x5, - 2*4(sp) + sw x6, - 3*4(sp) + sw x7, - 4*4(sp) + sw x10, - 5*4(sp) + sw x11, - 6*4(sp) + sw x12, - 7*4(sp) + sw x13, - 8*4(sp) + sw x14, - 9*4(sp) + sw x15, -10*4(sp) + sw x16, -11*4(sp) + sw x17, -12*4(sp) + sw x28, -13*4(sp) + sw x29, -14*4(sp) + sw x30, -15*4(sp) + sw x31, -16*4(sp) + addi sp,sp,-16*4 + call isr + lw x1 , 15*4(sp) + lw x5, 14*4(sp) + lw x6, 13*4(sp) + lw x7, 12*4(sp) + lw x10, 11*4(sp) + lw x11, 10*4(sp) + lw x12, 9*4(sp) + lw x13, 8*4(sp) + lw x14, 7*4(sp) + lw x15, 6*4(sp) + lw x16, 5*4(sp) + lw x17, 4*4(sp) + lw x28, 3*4(sp) + lw x29, 2*4(sp) + lw x30, 1*4(sp) + lw x31, 0*4(sp) + addi sp,sp,16*4 + mret + .text + + +crt_init: + la sp, _fstack + 4 + la a0, trap_entry + csrw mtvec, a0 + +bss_init: + la a0, _fbss + la a1, _ebss +bss_loop: + beq a0,a1,bss_done + sw zero,0(a0) + add a0,a0,4 + j bss_loop +bss_done: + + /* Load DATA */ + la t0, _erodata + la t1, _fdata + la t2, _edata +3: + lw t3, 0(t0) + sw t3, 0(t1) + /* _edata is aligned to 16 bytes. Use word-xfers. */ + addi t0, t0, 4 + addi t1, t1, 4 + bltu t1, t2, 3b + + li a0, 0x880 //880 enable timer + external interrupt sources (until mstatus.MIE is set, they will never trigger an interrupt) + csrw mie,a0 + + call main +infinit_loop: + j infinit_loop diff --git a/hw/bsp/fomu/fomu.ld b/hw/bsp/fomu/fomu.ld new file mode 100644 index 00000000..f39d62f3 --- /dev/null +++ b/hw/bsp/fomu/fomu.ld @@ -0,0 +1,61 @@ +OUTPUT_FORMAT("elf32-littleriscv") +ENTRY(_start) + +__DYNAMIC = 0; + +MEMORY { + csr : ORIGIN = 0x60000000, LENGTH = 0x01000000 + vexriscv_debug : ORIGIN = 0xf00f0000, LENGTH = 0x00000100 + sram : ORIGIN = 0x10000000, LENGTH = 0x00020000 + rom : ORIGIN = 0x2001a000, LENGTH = 0x00200000 - 0x1a000 +} + +SECTIONS +{ + .text : + { + _ftext = .; + *(.text.start) + *(.text .stub .text.* .gnu.linkonce.t.*) + _etext = .; + } > rom + + .rodata : + { + . = ALIGN(4); + _frodata = .; + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + *(.srodata) + _erodata = .; + } > rom + + .data : AT (ADDR(.rodata) + SIZEOF (.rodata)) + { + . = ALIGN(4); + _fdata = .; + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + _gp = ALIGN(16); + *(.sdata .sdata.* .gnu.linkonce.s.* .sdata2 .sdata2.*) + _edata = ALIGN(16); /* Make sure _edata is >= _gp. */ + } > sram + + .bss : + { + . = ALIGN(4); + _fbss = .; + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = .; + _end = .; + PROVIDE(end = .); + } > sram +} + +PROVIDE(_fstack = ORIGIN(sram) + LENGTH(sram) - 4); diff --git a/hw/bsp/fomu/include/csr.h b/hw/bsp/fomu/include/csr.h new file mode 100644 index 00000000..b9bffada --- /dev/null +++ b/hw/bsp/fomu/include/csr.h @@ -0,0 +1,709 @@ +//-------------------------------------------------------------------------------- +// Auto-generated by Migen (f4fcd10) & LiteX (1425a68d) on 2019-10-11 22:01:17 +//-------------------------------------------------------------------------------- +#ifndef __GENERATED_CSR_H +#define __GENERATED_CSR_H +#include +#ifdef CSR_ACCESSORS_DEFINED +extern void csr_writeb(uint8_t value, unsigned long addr); +extern uint8_t csr_readb(unsigned long addr); +extern void csr_writew(uint16_t value, unsigned long addr); +extern uint16_t csr_readw(unsigned long addr); +extern void csr_writel(uint32_t value, unsigned long addr); +extern uint32_t csr_readl(unsigned long addr); +#else /* ! CSR_ACCESSORS_DEFINED */ +#include +#endif /* ! CSR_ACCESSORS_DEFINED */ + +/* ctrl */ +#define CSR_CTRL_BASE 0xe0000000L +#define CSR_CTRL_RESET_ADDR 0xe0000000L +#define CSR_CTRL_RESET_SIZE 1 +static inline unsigned char ctrl_reset_read(void) { + unsigned char r = csr_readl(0xe0000000L); + return r; +} +static inline void ctrl_reset_write(unsigned char value) { + csr_writel(value, 0xe0000000L); +} +#define CSR_CTRL_SCRATCH_ADDR 0xe0000004L +#define CSR_CTRL_SCRATCH_SIZE 4 +static inline unsigned int ctrl_scratch_read(void) { + unsigned int r = csr_readl(0xe0000004L); + r <<= 8; + r |= csr_readl(0xe0000008L); + r <<= 8; + r |= csr_readl(0xe000000cL); + r <<= 8; + r |= csr_readl(0xe0000010L); + return r; +} +static inline void ctrl_scratch_write(unsigned int value) { + csr_writel(value >> 24, 0xe0000004L); + csr_writel(value >> 16, 0xe0000008L); + csr_writel(value >> 8, 0xe000000cL); + csr_writel(value, 0xe0000010L); +} +#define CSR_CTRL_BUS_ERRORS_ADDR 0xe0000014L +#define CSR_CTRL_BUS_ERRORS_SIZE 4 +static inline unsigned int ctrl_bus_errors_read(void) { + unsigned int r = csr_readl(0xe0000014L); + r <<= 8; + r |= csr_readl(0xe0000018L); + r <<= 8; + r |= csr_readl(0xe000001cL); + r <<= 8; + r |= csr_readl(0xe0000020L); + return r; +} + +/* lxspi */ +#define CSR_LXSPI_BASE 0xe0007800L +#define CSR_LXSPI_BITBANG_ADDR 0xe0007800L +#define CSR_LXSPI_BITBANG_SIZE 1 +static inline unsigned char lxspi_bitbang_read(void) { + unsigned char r = csr_readl(0xe0007800L); + return r; +} +static inline void lxspi_bitbang_write(unsigned char value) { + csr_writel(value, 0xe0007800L); +} +#define CSR_LXSPI_BITBANG_MOSI_OFFSET 0 +#define CSR_LXSPI_BITBANG_MOSI_SIZE 1 +#define CSR_LXSPI_BITBANG_CLK_OFFSET 1 +#define CSR_LXSPI_BITBANG_CLK_SIZE 1 +#define CSR_LXSPI_BITBANG_CS_N_OFFSET 2 +#define CSR_LXSPI_BITBANG_CS_N_SIZE 1 +#define CSR_LXSPI_BITBANG_DIR_OFFSET 3 +#define CSR_LXSPI_BITBANG_DIR_SIZE 1 +#define CSR_LXSPI_MISO_ADDR 0xe0007804L +#define CSR_LXSPI_MISO_SIZE 1 +static inline unsigned char lxspi_miso_read(void) { + unsigned char r = csr_readl(0xe0007804L); + return r; +} +#define CSR_LXSPI_BITBANG_EN_ADDR 0xe0007808L +#define CSR_LXSPI_BITBANG_EN_SIZE 1 +static inline unsigned char lxspi_bitbang_en_read(void) { + unsigned char r = csr_readl(0xe0007808L); + return r; +} +static inline void lxspi_bitbang_en_write(unsigned char value) { + csr_writel(value, 0xe0007808L); +} + +/* messible */ +#define CSR_MESSIBLE_BASE 0xe0008000L +#define CSR_MESSIBLE_IN_ADDR 0xe0008000L +#define CSR_MESSIBLE_IN_SIZE 1 +static inline unsigned char messible_in_read(void) { + unsigned char r = csr_readl(0xe0008000L); + return r; +} +static inline void messible_in_write(unsigned char value) { + csr_writel(value, 0xe0008000L); +} +#define CSR_MESSIBLE_OUT_ADDR 0xe0008004L +#define CSR_MESSIBLE_OUT_SIZE 1 +static inline unsigned char messible_out_read(void) { + unsigned char r = csr_readl(0xe0008004L); + return r; +} +#define CSR_MESSIBLE_STATUS_ADDR 0xe0008008L +#define CSR_MESSIBLE_STATUS_SIZE 1 +static inline unsigned char messible_status_read(void) { + unsigned char r = csr_readl(0xe0008008L); + return r; +} +#define CSR_MESSIBLE_STATUS_FULL_OFFSET 0 +#define CSR_MESSIBLE_STATUS_FULL_SIZE 1 +#define CSR_MESSIBLE_STATUS_HAVE_OFFSET 1 +#define CSR_MESSIBLE_STATUS_HAVE_SIZE 1 + +/* reboot */ +#define CSR_REBOOT_BASE 0xe0006000L +#define CSR_REBOOT_CTRL_ADDR 0xe0006000L +#define CSR_REBOOT_CTRL_SIZE 1 +static inline unsigned char reboot_ctrl_read(void) { + unsigned char r = csr_readl(0xe0006000L); + return r; +} +static inline void reboot_ctrl_write(unsigned char value) { + csr_writel(value, 0xe0006000L); +} +#define CSR_REBOOT_CTRL_IMAGE_OFFSET 0 +#define CSR_REBOOT_CTRL_IMAGE_SIZE 2 +#define CSR_REBOOT_CTRL_KEY_OFFSET 2 +#define CSR_REBOOT_CTRL_KEY_SIZE 6 +#define CSR_REBOOT_ADDR_ADDR 0xe0006004L +#define CSR_REBOOT_ADDR_SIZE 4 +static inline unsigned int reboot_addr_read(void) { + unsigned int r = csr_readl(0xe0006004L); + r <<= 8; + r |= csr_readl(0xe0006008L); + r <<= 8; + r |= csr_readl(0xe000600cL); + r <<= 8; + r |= csr_readl(0xe0006010L); + return r; +} +static inline void reboot_addr_write(unsigned int value) { + csr_writel(value >> 24, 0xe0006004L); + csr_writel(value >> 16, 0xe0006008L); + csr_writel(value >> 8, 0xe000600cL); + csr_writel(value, 0xe0006010L); +} + +/* rgb */ +#define CSR_RGB_BASE 0xe0006800L +#define CSR_RGB_DAT_ADDR 0xe0006800L +#define CSR_RGB_DAT_SIZE 1 +static inline unsigned char rgb_dat_read(void) { + unsigned char r = csr_readl(0xe0006800L); + return r; +} +static inline void rgb_dat_write(unsigned char value) { + csr_writel(value, 0xe0006800L); +} +#define CSR_RGB_ADDR_ADDR 0xe0006804L +#define CSR_RGB_ADDR_SIZE 1 +static inline unsigned char rgb_addr_read(void) { + unsigned char r = csr_readl(0xe0006804L); + return r; +} +static inline void rgb_addr_write(unsigned char value) { + csr_writel(value, 0xe0006804L); +} +#define CSR_RGB_CTRL_ADDR 0xe0006808L +#define CSR_RGB_CTRL_SIZE 1 +static inline unsigned char rgb_ctrl_read(void) { + unsigned char r = csr_readl(0xe0006808L); + return r; +} +static inline void rgb_ctrl_write(unsigned char value) { + csr_writel(value, 0xe0006808L); +} +#define CSR_RGB_CTRL_EXE_OFFSET 0 +#define CSR_RGB_CTRL_EXE_SIZE 1 +#define CSR_RGB_CTRL_CURREN_OFFSET 1 +#define CSR_RGB_CTRL_CURREN_SIZE 1 +#define CSR_RGB_CTRL_RGBLEDEN_OFFSET 2 +#define CSR_RGB_CTRL_RGBLEDEN_SIZE 1 +#define CSR_RGB_CTRL_RRAW_OFFSET 3 +#define CSR_RGB_CTRL_RRAW_SIZE 1 +#define CSR_RGB_CTRL_GRAW_OFFSET 4 +#define CSR_RGB_CTRL_GRAW_SIZE 1 +#define CSR_RGB_CTRL_BRAW_OFFSET 5 +#define CSR_RGB_CTRL_BRAW_SIZE 1 +#define CSR_RGB_RAW_ADDR 0xe000680cL +#define CSR_RGB_RAW_SIZE 1 +static inline unsigned char rgb_raw_read(void) { + unsigned char r = csr_readl(0xe000680cL); + return r; +} +static inline void rgb_raw_write(unsigned char value) { + csr_writel(value, 0xe000680cL); +} +#define CSR_RGB_RAW_R_OFFSET 0 +#define CSR_RGB_RAW_R_SIZE 1 +#define CSR_RGB_RAW_G_OFFSET 1 +#define CSR_RGB_RAW_G_SIZE 1 +#define CSR_RGB_RAW_B_OFFSET 2 +#define CSR_RGB_RAW_B_SIZE 1 + +/* timer0 */ +#define CSR_TIMER0_BASE 0xe0002800L +#define CSR_TIMER0_LOAD_ADDR 0xe0002800L +#define CSR_TIMER0_LOAD_SIZE 4 +static inline unsigned int timer0_load_read(void) { + unsigned int r = csr_readl(0xe0002800L); + r <<= 8; + r |= csr_readl(0xe0002804L); + r <<= 8; + r |= csr_readl(0xe0002808L); + r <<= 8; + r |= csr_readl(0xe000280cL); + return r; +} +static inline void timer0_load_write(unsigned int value) { + csr_writel(value >> 24, 0xe0002800L); + csr_writel(value >> 16, 0xe0002804L); + csr_writel(value >> 8, 0xe0002808L); + csr_writel(value, 0xe000280cL); +} +#define CSR_TIMER0_RELOAD_ADDR 0xe0002810L +#define CSR_TIMER0_RELOAD_SIZE 4 +static inline unsigned int timer0_reload_read(void) { + unsigned int r = csr_readl(0xe0002810L); + r <<= 8; + r |= csr_readl(0xe0002814L); + r <<= 8; + r |= csr_readl(0xe0002818L); + r <<= 8; + r |= csr_readl(0xe000281cL); + return r; +} +static inline void timer0_reload_write(unsigned int value) { + csr_writel(value >> 24, 0xe0002810L); + csr_writel(value >> 16, 0xe0002814L); + csr_writel(value >> 8, 0xe0002818L); + csr_writel(value, 0xe000281cL); +} +#define CSR_TIMER0_EN_ADDR 0xe0002820L +#define CSR_TIMER0_EN_SIZE 1 +static inline unsigned char timer0_en_read(void) { + unsigned char r = csr_readl(0xe0002820L); + return r; +} +static inline void timer0_en_write(unsigned char value) { + csr_writel(value, 0xe0002820L); +} +#define CSR_TIMER0_UPDATE_VALUE_ADDR 0xe0002824L +#define CSR_TIMER0_UPDATE_VALUE_SIZE 1 +static inline unsigned char timer0_update_value_read(void) { + unsigned char r = csr_readl(0xe0002824L); + return r; +} +static inline void timer0_update_value_write(unsigned char value) { + csr_writel(value, 0xe0002824L); +} +#define CSR_TIMER0_VALUE_ADDR 0xe0002828L +#define CSR_TIMER0_VALUE_SIZE 4 +static inline unsigned int timer0_value_read(void) { + unsigned int r = csr_readl(0xe0002828L); + r <<= 8; + r |= csr_readl(0xe000282cL); + r <<= 8; + r |= csr_readl(0xe0002830L); + r <<= 8; + r |= csr_readl(0xe0002834L); + return r; +} +#define CSR_TIMER0_EV_STATUS_ADDR 0xe0002838L +#define CSR_TIMER0_EV_STATUS_SIZE 1 +static inline unsigned char timer0_ev_status_read(void) { + unsigned char r = csr_readl(0xe0002838L); + return r; +} +static inline void timer0_ev_status_write(unsigned char value) { + csr_writel(value, 0xe0002838L); +} +#define CSR_TIMER0_EV_PENDING_ADDR 0xe000283cL +#define CSR_TIMER0_EV_PENDING_SIZE 1 +static inline unsigned char timer0_ev_pending_read(void) { + unsigned char r = csr_readl(0xe000283cL); + return r; +} +static inline void timer0_ev_pending_write(unsigned char value) { + csr_writel(value, 0xe000283cL); +} +#define CSR_TIMER0_EV_ENABLE_ADDR 0xe0002840L +#define CSR_TIMER0_EV_ENABLE_SIZE 1 +static inline unsigned char timer0_ev_enable_read(void) { + unsigned char r = csr_readl(0xe0002840L); + return r; +} +static inline void timer0_ev_enable_write(unsigned char value) { + csr_writel(value, 0xe0002840L); +} + +/* touch */ +#define CSR_TOUCH_BASE 0xe0005800L +#define CSR_TOUCH_O_ADDR 0xe0005800L +#define CSR_TOUCH_O_SIZE 1 +static inline unsigned char touch_o_read(void) { + unsigned char r = csr_readl(0xe0005800L); + return r; +} +static inline void touch_o_write(unsigned char value) { + csr_writel(value, 0xe0005800L); +} +#define CSR_TOUCH_O_O_OFFSET 0 +#define CSR_TOUCH_O_O_SIZE 4 +#define CSR_TOUCH_OE_ADDR 0xe0005804L +#define CSR_TOUCH_OE_SIZE 1 +static inline unsigned char touch_oe_read(void) { + unsigned char r = csr_readl(0xe0005804L); + return r; +} +static inline void touch_oe_write(unsigned char value) { + csr_writel(value, 0xe0005804L); +} +#define CSR_TOUCH_OE_OE_OFFSET 0 +#define CSR_TOUCH_OE_OE_SIZE 4 +#define CSR_TOUCH_I_ADDR 0xe0005808L +#define CSR_TOUCH_I_SIZE 1 +static inline unsigned char touch_i_read(void) { + unsigned char r = csr_readl(0xe0005808L); + return r; +} +#define CSR_TOUCH_I_I_OFFSET 0 +#define CSR_TOUCH_I_I_SIZE 4 + +/* usb */ +#define CSR_USB_BASE 0xe0004800L +#define CSR_USB_PULLUP_OUT_ADDR 0xe0004800L +#define CSR_USB_PULLUP_OUT_SIZE 1 +static inline unsigned char usb_pullup_out_read(void) { + unsigned char r = csr_readl(0xe0004800L); + return r; +} +static inline void usb_pullup_out_write(unsigned char value) { + csr_writel(value, 0xe0004800L); +} +#define CSR_USB_SETUP_DATA_ADDR 0xe0004804L +#define CSR_USB_SETUP_DATA_SIZE 1 +static inline unsigned char usb_setup_data_read(void) { + unsigned char r = csr_readl(0xe0004804L); + return r; +} +#define CSR_USB_SETUP_DATA_DATA_OFFSET 0 +#define CSR_USB_SETUP_DATA_DATA_SIZE 8 +#define CSR_USB_SETUP_CTRL_ADDR 0xe0004808L +#define CSR_USB_SETUP_CTRL_SIZE 1 +static inline unsigned char usb_setup_ctrl_read(void) { + unsigned char r = csr_readl(0xe0004808L); + return r; +} +static inline void usb_setup_ctrl_write(unsigned char value) { + csr_writel(value, 0xe0004808L); +} +#define CSR_USB_SETUP_CTRL_HANDLED_OFFSET 1 +#define CSR_USB_SETUP_CTRL_HANDLED_SIZE 1 +#define CSR_USB_SETUP_CTRL_RESET_OFFSET 2 +#define CSR_USB_SETUP_CTRL_RESET_SIZE 1 +#define CSR_USB_SETUP_STATUS_ADDR 0xe000480cL +#define CSR_USB_SETUP_STATUS_SIZE 1 +static inline unsigned char usb_setup_status_read(void) { + unsigned char r = csr_readl(0xe000480cL); + return r; +} +#define CSR_USB_SETUP_STATUS_HAVE_OFFSET 0 +#define CSR_USB_SETUP_STATUS_HAVE_SIZE 1 +#define CSR_USB_SETUP_STATUS_IS_IN_OFFSET 1 +#define CSR_USB_SETUP_STATUS_IS_IN_SIZE 1 +#define CSR_USB_SETUP_STATUS_EPNO_OFFSET 2 +#define CSR_USB_SETUP_STATUS_EPNO_SIZE 4 +#define CSR_USB_SETUP_STATUS_PEND_OFFSET 6 +#define CSR_USB_SETUP_STATUS_PEND_SIZE 1 +#define CSR_USB_SETUP_STATUS_DATA_OFFSET 7 +#define CSR_USB_SETUP_STATUS_DATA_SIZE 1 +#define CSR_USB_SETUP_EV_STATUS_ADDR 0xe0004810L +#define CSR_USB_SETUP_EV_STATUS_SIZE 1 +static inline unsigned char usb_setup_ev_status_read(void) { + unsigned char r = csr_readl(0xe0004810L); + return r; +} +static inline void usb_setup_ev_status_write(unsigned char value) { + csr_writel(value, 0xe0004810L); +} +#define CSR_USB_SETUP_EV_PENDING_ADDR 0xe0004814L +#define CSR_USB_SETUP_EV_PENDING_SIZE 1 +static inline unsigned char usb_setup_ev_pending_read(void) { + unsigned char r = csr_readl(0xe0004814L); + return r; +} +static inline void usb_setup_ev_pending_write(unsigned char value) { + csr_writel(value, 0xe0004814L); +} +#define CSR_USB_SETUP_EV_ENABLE_ADDR 0xe0004818L +#define CSR_USB_SETUP_EV_ENABLE_SIZE 1 +static inline unsigned char usb_setup_ev_enable_read(void) { + unsigned char r = csr_readl(0xe0004818L); + return r; +} +static inline void usb_setup_ev_enable_write(unsigned char value) { + csr_writel(value, 0xe0004818L); +} +#define CSR_USB_IN_DATA_ADDR 0xe000481cL +#define CSR_USB_IN_DATA_SIZE 1 +static inline unsigned char usb_in_data_read(void) { + unsigned char r = csr_readl(0xe000481cL); + return r; +} +static inline void usb_in_data_write(unsigned char value) { + csr_writel(value, 0xe000481cL); +} +#define CSR_USB_IN_DATA_DATA_OFFSET 0 +#define CSR_USB_IN_DATA_DATA_SIZE 8 +#define CSR_USB_IN_STATUS_ADDR 0xe0004820L +#define CSR_USB_IN_STATUS_SIZE 1 +static inline unsigned char usb_in_status_read(void) { + unsigned char r = csr_readl(0xe0004820L); + return r; +} +#define CSR_USB_IN_STATUS_HAVE_OFFSET 0 +#define CSR_USB_IN_STATUS_HAVE_SIZE 1 +#define CSR_USB_IN_STATUS_IDLE_OFFSET 1 +#define CSR_USB_IN_STATUS_IDLE_SIZE 1 +#define CSR_USB_IN_STATUS_PEND_OFFSET 6 +#define CSR_USB_IN_STATUS_PEND_SIZE 1 +#define CSR_USB_IN_CTRL_ADDR 0xe0004824L +#define CSR_USB_IN_CTRL_SIZE 1 +static inline unsigned char usb_in_ctrl_read(void) { + unsigned char r = csr_readl(0xe0004824L); + return r; +} +static inline void usb_in_ctrl_write(unsigned char value) { + csr_writel(value, 0xe0004824L); +} +#define CSR_USB_IN_CTRL_EP_OFFSET 0 +#define CSR_USB_IN_CTRL_EP_SIZE 4 +#define CSR_USB_IN_CTRL_STALL_OFFSET 4 +#define CSR_USB_IN_CTRL_STALL_SIZE 1 +#define CSR_USB_IN_CTRL_RESET_OFFSET 5 +#define CSR_USB_IN_CTRL_RESET_SIZE 1 +#define CSR_USB_IN_EV_STATUS_ADDR 0xe0004828L +#define CSR_USB_IN_EV_STATUS_SIZE 1 +static inline unsigned char usb_in_ev_status_read(void) { + unsigned char r = csr_readl(0xe0004828L); + return r; +} +static inline void usb_in_ev_status_write(unsigned char value) { + csr_writel(value, 0xe0004828L); +} +#define CSR_USB_IN_EV_PENDING_ADDR 0xe000482cL +#define CSR_USB_IN_EV_PENDING_SIZE 1 +static inline unsigned char usb_in_ev_pending_read(void) { + unsigned char r = csr_readl(0xe000482cL); + return r; +} +static inline void usb_in_ev_pending_write(unsigned char value) { + csr_writel(value, 0xe000482cL); +} +#define CSR_USB_IN_EV_ENABLE_ADDR 0xe0004830L +#define CSR_USB_IN_EV_ENABLE_SIZE 1 +static inline unsigned char usb_in_ev_enable_read(void) { + unsigned char r = csr_readl(0xe0004830L); + return r; +} +static inline void usb_in_ev_enable_write(unsigned char value) { + csr_writel(value, 0xe0004830L); +} +#define CSR_USB_OUT_DATA_ADDR 0xe0004834L +#define CSR_USB_OUT_DATA_SIZE 1 +static inline unsigned char usb_out_data_read(void) { + unsigned char r = csr_readl(0xe0004834L); + return r; +} +#define CSR_USB_OUT_DATA_DATA_OFFSET 0 +#define CSR_USB_OUT_DATA_DATA_SIZE 8 +#define CSR_USB_OUT_STATUS_ADDR 0xe0004838L +#define CSR_USB_OUT_STATUS_SIZE 1 +static inline unsigned char usb_out_status_read(void) { + unsigned char r = csr_readl(0xe0004838L); + return r; +} +#define CSR_USB_OUT_STATUS_HAVE_OFFSET 0 +#define CSR_USB_OUT_STATUS_HAVE_SIZE 1 +#define CSR_USB_OUT_STATUS_IDLE_OFFSET 1 +#define CSR_USB_OUT_STATUS_IDLE_SIZE 1 +#define CSR_USB_OUT_STATUS_EPNO_OFFSET 2 +#define CSR_USB_OUT_STATUS_EPNO_SIZE 4 +#define CSR_USB_OUT_STATUS_PEND_OFFSET 6 +#define CSR_USB_OUT_STATUS_PEND_SIZE 1 +#define CSR_USB_OUT_CTRL_ADDR 0xe000483cL +#define CSR_USB_OUT_CTRL_SIZE 1 +static inline unsigned char usb_out_ctrl_read(void) { + unsigned char r = csr_readl(0xe000483cL); + return r; +} +static inline void usb_out_ctrl_write(unsigned char value) { + csr_writel(value, 0xe000483cL); +} +#define CSR_USB_OUT_CTRL_ENABLE_OFFSET 1 +#define CSR_USB_OUT_CTRL_ENABLE_SIZE 1 +#define CSR_USB_OUT_CTRL_RESET_OFFSET 2 +#define CSR_USB_OUT_CTRL_RESET_SIZE 1 +#define CSR_USB_OUT_STALL_ADDR 0xe0004840L +#define CSR_USB_OUT_STALL_SIZE 1 +static inline unsigned char usb_out_stall_read(void) { + unsigned char r = csr_readl(0xe0004840L); + return r; +} +static inline void usb_out_stall_write(unsigned char value) { + csr_writel(value, 0xe0004840L); +} +#define CSR_USB_OUT_STALL_EPNO_OFFSET 0 +#define CSR_USB_OUT_STALL_EPNO_SIZE 4 +#define CSR_USB_OUT_STALL_STALL_OFFSET 4 +#define CSR_USB_OUT_STALL_STALL_SIZE 1 +#define CSR_USB_OUT_EV_STATUS_ADDR 0xe0004844L +#define CSR_USB_OUT_EV_STATUS_SIZE 1 +static inline unsigned char usb_out_ev_status_read(void) { + unsigned char r = csr_readl(0xe0004844L); + return r; +} +static inline void usb_out_ev_status_write(unsigned char value) { + csr_writel(value, 0xe0004844L); +} +#define CSR_USB_OUT_EV_PENDING_ADDR 0xe0004848L +#define CSR_USB_OUT_EV_PENDING_SIZE 1 +static inline unsigned char usb_out_ev_pending_read(void) { + unsigned char r = csr_readl(0xe0004848L); + return r; +} +static inline void usb_out_ev_pending_write(unsigned char value) { + csr_writel(value, 0xe0004848L); +} +#define CSR_USB_OUT_EV_ENABLE_ADDR 0xe000484cL +#define CSR_USB_OUT_EV_ENABLE_SIZE 1 +static inline unsigned char usb_out_ev_enable_read(void) { + unsigned char r = csr_readl(0xe000484cL); + return r; +} +static inline void usb_out_ev_enable_write(unsigned char value) { + csr_writel(value, 0xe000484cL); +} +#define CSR_USB_ADDRESS_ADDR 0xe0004850L +#define CSR_USB_ADDRESS_SIZE 1 +static inline unsigned char usb_address_read(void) { + unsigned char r = csr_readl(0xe0004850L); + return r; +} +static inline void usb_address_write(unsigned char value) { + csr_writel(value, 0xe0004850L); +} +#define CSR_USB_ADDRESS_ADDR_OFFSET 0 +#define CSR_USB_ADDRESS_ADDR_SIZE 7 +#define CSR_USB_STAGE_NUM_ADDR 0xe0004854L +#define CSR_USB_STAGE_NUM_SIZE 1 +static inline unsigned char usb_stage_num_read(void) { + unsigned char r = csr_readl(0xe0004854L); + return r; +} +#define CSR_USB_LAST_STAGE_NUM_ADDR 0xe0004858L +#define CSR_USB_LAST_STAGE_NUM_SIZE 1 +static inline unsigned char usb_last_stage_num_read(void) { + unsigned char r = csr_readl(0xe0004858L); + return r; +} + +/* version */ +#define CSR_VERSION_BASE 0xe0007000L +#define CSR_VERSION_MAJOR_ADDR 0xe0007000L +#define CSR_VERSION_MAJOR_SIZE 1 +static inline unsigned char version_major_read(void) { + unsigned char r = csr_readl(0xe0007000L); + return r; +} +#define CSR_VERSION_MINOR_ADDR 0xe0007004L +#define CSR_VERSION_MINOR_SIZE 1 +static inline unsigned char version_minor_read(void) { + unsigned char r = csr_readl(0xe0007004L); + return r; +} +#define CSR_VERSION_REVISION_ADDR 0xe0007008L +#define CSR_VERSION_REVISION_SIZE 1 +static inline unsigned char version_revision_read(void) { + unsigned char r = csr_readl(0xe0007008L); + return r; +} +#define CSR_VERSION_GITREV_ADDR 0xe000700cL +#define CSR_VERSION_GITREV_SIZE 4 +static inline unsigned int version_gitrev_read(void) { + unsigned int r = csr_readl(0xe000700cL); + r <<= 8; + r |= csr_readl(0xe0007010L); + r <<= 8; + r |= csr_readl(0xe0007014L); + r <<= 8; + r |= csr_readl(0xe0007018L); + return r; +} +#define CSR_VERSION_GITEXTRA_ADDR 0xe000701cL +#define CSR_VERSION_GITEXTRA_SIZE 2 +static inline unsigned short int version_gitextra_read(void) { + unsigned short int r = csr_readl(0xe000701cL); + r <<= 8; + r |= csr_readl(0xe0007020L); + return r; +} +#define CSR_VERSION_DIRTY_ADDR 0xe0007024L +#define CSR_VERSION_DIRTY_SIZE 1 +static inline unsigned char version_dirty_read(void) { + unsigned char r = csr_readl(0xe0007024L); + return r; +} +#define CSR_VERSION_DIRTY_DIRTY_OFFSET 0 +#define CSR_VERSION_DIRTY_DIRTY_SIZE 1 +#define CSR_VERSION_MODEL_ADDR 0xe0007028L +#define CSR_VERSION_MODEL_SIZE 1 +static inline unsigned char version_model_read(void) { + unsigned char r = csr_readl(0xe0007028L); + return r; +} +#define CSR_VERSION_MODEL_MODEL_OFFSET 0 +#define CSR_VERSION_MODEL_MODEL_SIZE 8 +#define CSR_VERSION_SEED_ADDR 0xe000702cL +#define CSR_VERSION_SEED_SIZE 4 +static inline unsigned int version_seed_read(void) { + unsigned int r = csr_readl(0xe000702cL); + r <<= 8; + r |= csr_readl(0xe0007030L); + r <<= 8; + r |= csr_readl(0xe0007034L); + r <<= 8; + r |= csr_readl(0xe0007038L); + return r; +} + +/* constants */ +#define TIMER0_INTERRUPT 2 +static inline int timer0_interrupt_read(void) { + return 2; +} +#define USB_INTERRUPT 3 +static inline int usb_interrupt_read(void) { + return 3; +} +#define SPI_BOOT 1 +static inline int spi_boot_read(void) { + return 1; +} +#define SPI_ENTRYPOINT 536977408 +static inline int spi_entrypoint_read(void) { + return 536977408; +} +#define CONFIG_BITSTREAM_SYNC_HEADER1 2123999870 +static inline int config_bitstream_sync_header1_read(void) { + return 2123999870; +} +#define CONFIG_BITSTREAM_SYNC_HEADER2 2125109630 +static inline int config_bitstream_sync_header2_read(void) { + return 2125109630; +} +#define CONFIG_CLOCK_FREQUENCY 12000000 +static inline int config_clock_frequency_read(void) { + return 12000000; +} +#define CONFIG_CPU_RESET_ADDR 0 +static inline int config_cpu_reset_addr_read(void) { + return 0; +} +#define CONFIG_CPU_TYPE "VEXRISCV" +static inline const char * config_cpu_type_read(void) { + return "VEXRISCV"; +} +#define CONFIG_CPU_TYPE_VEXRISCV 1 +static inline int config_cpu_type_vexriscv_read(void) { + return 1; +} +#define CONFIG_CPU_VARIANT "MIN" +static inline const char * config_cpu_variant_read(void) { + return "MIN"; +} +#define CONFIG_CPU_VARIANT_MIN 1 +static inline int config_cpu_variant_min_read(void) { + return 1; +} +#define CONFIG_CSR_ALIGNMENT 32 +static inline int config_csr_alignment_read(void) { + return 32; +} +#define CONFIG_CSR_DATA_WIDTH 8 +static inline int config_csr_data_width_read(void) { + return 8; +} + +#endif diff --git a/hw/bsp/fomu/include/hw/common.h b/hw/bsp/fomu/include/hw/common.h new file mode 100644 index 00000000..6a97ca2e --- /dev/null +++ b/hw/bsp/fomu/include/hw/common.h @@ -0,0 +1,33 @@ +#ifndef _HW_COMMON_H_ +#define _HW_COMMON_H_ +#include +static inline void csr_writeb(uint8_t value, uint32_t addr) +{ + *((volatile uint8_t *)addr) = value; +} + +static inline uint8_t csr_readb(uint32_t addr) +{ + return *(volatile uint8_t *)addr; +} + +static inline void csr_writew(uint16_t value, uint32_t addr) +{ + *((volatile uint16_t *)addr) = value; +} + +static inline uint16_t csr_readw(uint32_t addr) +{ + return *(volatile uint16_t *)addr; +} + +static inline void csr_writel(uint32_t value, uint32_t addr) +{ + *((volatile uint32_t *)addr) = value; +} + +static inline uint32_t csr_readl(uint32_t addr) +{ + return *(volatile uint32_t *)addr; +} +#endif /* _HW_COMMON_H_ */ \ No newline at end of file diff --git a/hw/bsp/fomu/include/irq.h b/hw/bsp/fomu/include/irq.h new file mode 100644 index 00000000..a8221890 --- /dev/null +++ b/hw/bsp/fomu/include/irq.h @@ -0,0 +1,71 @@ +#ifndef __IRQ_H +#define __IRQ_H + +#ifdef __cplusplus +extern "C" { +#endif + + +#define CSR_MSTATUS_MIE 0x8 + +#define CSR_IRQ_MASK 0xBC0 +#define CSR_IRQ_PENDING 0xFC0 + +#define CSR_DCACHE_INFO 0xCC0 + +#define csrr(reg) ({ unsigned long __tmp; \ + asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ + __tmp; }) + +#define csrw(reg, val) ({ \ + if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ + asm volatile ("csrw " #reg ", %0" :: "i"(val)); \ + else \ + asm volatile ("csrw " #reg ", %0" :: "r"(val)); }) + +#define csrs(reg, bit) ({ \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile ("csrrs x0, " #reg ", %0" :: "i"(bit)); \ + else \ + asm volatile ("csrrs x0, " #reg ", %0" :: "r"(bit)); }) + +#define csrc(reg, bit) ({ \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile ("csrrc x0, " #reg ", %0" :: "i"(bit)); \ + else \ + asm volatile ("csrrc x0, " #reg ", %0" :: "r"(bit)); }) + +static inline unsigned int irq_getie(void) +{ + return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0; +} + +static inline void irq_setie(unsigned int ie) +{ + if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE); +} + +static inline unsigned int irq_getmask(void) +{ + unsigned int mask; + asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(CSR_IRQ_MASK)); + return mask; +} + +static inline void irq_setmask(unsigned int mask) +{ + asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask)); +} + +static inline unsigned int irq_pending(void) +{ + unsigned int pending; + asm volatile ("csrr %0, %1" : "=r"(pending) : "i"(CSR_IRQ_PENDING)); + return pending; +} + +#ifdef __cplusplus +} +#endif + +#endif /* __IRQ_H */ \ No newline at end of file diff --git a/hw/bsp/fomu/output_format.ld b/hw/bsp/fomu/output_format.ld new file mode 100644 index 00000000..5e76f5f4 --- /dev/null +++ b/hw/bsp/fomu/output_format.ld @@ -0,0 +1 @@ +OUTPUT_FORMAT("elf32-littleriscv") diff --git a/hw/bsp/fomu/regions.ld b/hw/bsp/fomu/regions.ld new file mode 100644 index 00000000..51811f66 --- /dev/null +++ b/hw/bsp/fomu/regions.ld @@ -0,0 +1,6 @@ +MEMORY { + csr : ORIGIN = 0x60000000, LENGTH = 0x01000000 + vexriscv_debug : ORIGIN = 0xf00f0000, LENGTH = 0x00000100 + sram : ORIGIN = 0x10000000, LENGTH = 0x00020000 + rom : ORIGIN = 0x00000000, LENGTH = 0x00002000 +}