From 0ba065db8a865ed6b67a604b1d9ba8db066f0c5e Mon Sep 17 00:00:00 2001 From: Ilia Sergachev Date: Sat, 15 Jan 2022 17:23:56 +0100 Subject: [PATCH] cores/cpu/eos_s3: enable software support --- litex/soc/cores/cpu/eos_s3/boot-helper.c | 5 +++ litex/soc/cores/cpu/eos_s3/core.py | 16 ++++--- litex/soc/cores/cpu/eos_s3/crt0.c | 35 +++++++++++++++ litex/soc/cores/cpu/eos_s3/irq.h | 37 ++++++++++++++++ litex/soc/cores/cpu/eos_s3/system.h | 56 ++++++++++++++++++++++++ litex/soc/integration/builder.py | 2 +- litex/soc/integration/soc.py | 2 +- 7 files changed, 146 insertions(+), 7 deletions(-) create mode 100644 litex/soc/cores/cpu/eos_s3/boot-helper.c create mode 100644 litex/soc/cores/cpu/eos_s3/crt0.c create mode 100644 litex/soc/cores/cpu/eos_s3/irq.h create mode 100644 litex/soc/cores/cpu/eos_s3/system.h diff --git a/litex/soc/cores/cpu/eos_s3/boot-helper.c b/litex/soc/cores/cpu/eos_s3/boot-helper.c new file mode 100644 index 000000000..9a2695e2f --- /dev/null +++ b/litex/soc/cores/cpu/eos_s3/boot-helper.c @@ -0,0 +1,5 @@ +void boot_helper(unsigned long r1, unsigned long r2, unsigned long r3, unsigned long addr); + +void boot_helper(unsigned long r1, unsigned long r2, unsigned long r3, unsigned long addr) { + goto *addr; +} \ No newline at end of file diff --git a/litex/soc/cores/cpu/eos_s3/core.py b/litex/soc/cores/cpu/eos_s3/core.py index 8552939d4..b78d9c8e1 100644 --- a/litex/soc/cores/cpu/eos_s3/core.py +++ b/litex/soc/cores/cpu/eos_s3/core.py @@ -24,18 +24,24 @@ class EOS_S3(CPU): human_name = "EOS S3" data_width = 32 endianness = "little" - reset_address = 0x00000000 - gcc_triple = "gcc-arm-none-eabi" + reset_address = 0x0000_0000 + gcc_triple = "arm-none-eabi" + gcc_flags = "-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16" linker_output_format = "elf32-littlearm" nop = "nop" - io_regions = {0x00000000: 0x100000000} # Origin, Length. + io_regions = {0x4000_0000: 0xc000_0000} # Origin, Length. # Memory Mapping. @property def mem_map(self): - return {"csr": 0x00000000} + return { + "rom": 0x0000_0000, + "sram": 0x2000_0000, + "csr": 0x4002_0000 + } - def __init__(self, platform, variant): + def __init__(self, platform, variant, *args, **kwargs): + super().__init__(*args, **kwargs) self.platform = platform self.reset = Signal() self.interrupt = Signal(4) diff --git a/litex/soc/cores/cpu/eos_s3/crt0.c b/litex/soc/cores/cpu/eos_s3/crt0.c new file mode 100644 index 000000000..44134ee07 --- /dev/null +++ b/litex/soc/cores/cpu/eos_s3/crt0.c @@ -0,0 +1,35 @@ +#include + +extern uint32_t _fdata_rom, _fdata, _edata, _fbss, _ebss; + +void SystemInit(void); +void Reset_Handler(void); +void _start(void); + +void _start(void) { + Reset_Handler(); +} + +void Reset_Handler(void) { + uint32_t *y = &_fdata_rom; + for (uint32_t *x = &_fdata; x < &_edata; x ++) + *x = *y ++; + + for (uint32_t *x = &_fbss; x < &_ebss; x ++) + *x = 0; + +#ifndef __NO_SYSTEM_INIT + SystemInit(); +#endif + + // just in case - for now EOS CPU support relies on QORC SDK + // and main() is launched inside SystemInit() as FreeRTOS task + // so this call is not reached + __asm__("bl main"); +} + +__attribute__((weak)) uint32_t __semihost_call(uint32_t r0, uint32_t r1); + +__attribute__((weak)) uint32_t __semihost_call(uint32_t r0, uint32_t r1) { + return 0; +} diff --git a/litex/soc/cores/cpu/eos_s3/irq.h b/litex/soc/cores/cpu/eos_s3/irq.h new file mode 100644 index 000000000..4c87950ef --- /dev/null +++ b/litex/soc/cores/cpu/eos_s3/irq.h @@ -0,0 +1,37 @@ +#ifndef __IRQ_H +#define __IRQ_H + +#ifdef __cplusplus +extern "C" { +#endif + +static inline unsigned int irq_getie(void) +{ + return 0; /* FIXME */ +} + +static inline void irq_setie(unsigned int ie) +{ + /* FIXME */ +} + +static inline unsigned int irq_getmask(void) +{ + return 0; /* FIXME */ +} + +static inline void irq_setmask(unsigned int mask) +{ + /* FIXME */ +} + +static inline unsigned int irq_pending(void) +{ + return 0; /* FIXME */ +} + +#ifdef __cplusplus +} +#endif + +#endif /* __IRQ_H */ diff --git a/litex/soc/cores/cpu/eos_s3/system.h b/litex/soc/cores/cpu/eos_s3/system.h new file mode 100644 index 000000000..a0d777a85 --- /dev/null +++ b/litex/soc/cores/cpu/eos_s3/system.h @@ -0,0 +1,56 @@ +#ifndef __SYSTEM_H +#define __SYSTEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +__attribute__((unused)) static void flush_cpu_icache(void){}; +__attribute__((unused)) static void flush_cpu_dcache(void){}; +void flush_l2_cache(void); + +void busy_wait(unsigned int ms); +void busy_wait_us(unsigned int us); + +#define CSR_UART_BASE +#define UART_POLLING +#define UART_ID_HW 1 // hard UART on the S3 +#define UART_ID UART_ID_HW + +void uart_tx(int uartid, int c); +int uart_rx(int uartid); +int uart_rx_available(int uartid); +int uart_tx_is_fifo_full(int uart_id); + +static inline void uart_rxtx_write(char c) { + uart_tx(UART_ID, c); +} + +static inline uint8_t uart_rxtx_read(void) { + return uart_rx(UART_ID); +} + +static inline uint8_t uart_txfull_read(void) { + return uart_tx_is_fifo_full(UART_ID); +} + +static inline uint8_t uart_rxempty_read(void) { + return uart_rx_available(UART_ID); +} + +static inline void uart_ev_pending_write(uint8_t x) {} + +static inline uint8_t uart_ev_pending_read(void) { + return 0; +} + +static inline void uart_ev_enable_write(uint8_t x) {} + + +#ifdef __cplusplus +} +#endif + +#endif /* __SYSTEM_H */ diff --git a/litex/soc/integration/builder.py b/litex/soc/integration/builder.py index 653f85f0a..50e08dbed 100644 --- a/litex/soc/integration/builder.py +++ b/litex/soc/integration/builder.py @@ -281,7 +281,7 @@ class Builder: self.soc.platform.output_dir = self.output_dir # Check if BIOS is used and add software package if so. - with_bios = self.soc.cpu_type not in [None, "eos-s3", 'gowin_emcu'] + with_bios = self.soc.cpu_type not in [None, 'gowin_emcu'] if with_bios: self.add_software_package("bios") diff --git a/litex/soc/integration/soc.py b/litex/soc/integration/soc.py index f5f2540a5..72630b284 100644 --- a/litex/soc/integration/soc.py +++ b/litex/soc/integration/soc.py @@ -1094,7 +1094,7 @@ class SoC(Module): self.add_constant(name + "_" + constant.name, constant.value.value) # SoC CPU Check ---------------------------------------------------------------------------- - if not isinstance(self.cpu, (cpu.CPUNone, cpu.EOS_S3)): + if not isinstance(self.cpu, cpu.CPUNone): cpu_reset_address_valid = False for name, container in self.bus.regions.items(): if self.bus.check_region_is_in(