Merge pull request #1178 from sergachev/gowin_emcu

Enable LiteX BIOS on Gowin EMCU ARM core
This commit is contained in:
enjoy-digital 2022-01-23 21:01:06 +01:00 committed by GitHub
commit 8d3f12ebbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 167 additions and 8 deletions

View File

@ -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;
}

View File

@ -61,7 +61,7 @@ class GowinEMCU(CPU):
io_regions = {
# Origin, Length.
0x4000_0000: 0x2000_0000,
0xa000_0000: 0x6000_0000
0xA000_0000: 0x6000_0000
}
@property
@ -69,6 +69,7 @@ class GowinEMCU(CPU):
return {
"rom": 0x0000_0000,
"sram": 0x2000_0000,
"peripherals": 0x4000_0000,
"csr": 0xA000_0000,
}
@ -168,9 +169,6 @@ class GowinEMCU(CPU):
self.periph_buses = [self.pbus]
ahb_targexp0 = ahb.Interface()
for s, _ in ahb_targexp0.master_signals:
# TODO: due to unexpected writes by the CPU bus is currently forced read-only
if s == "write":
continue
self.cpu_params[f"o_TARGEXP0H{s.upper()}"] = getattr(ahb_targexp0, s)
for s, _ in ahb_targexp0.slave_signals:
self.cpu_params[f"i_TARGEXP0H{s.upper()}"] = getattr(ahb_targexp0, s)

View File

@ -0,0 +1,47 @@
#include <stdint.h>
#include "system.h"
#include "generated/soc.h"
extern uint32_t _fdata_rom, _fdata, _edata, _fbss, _ebss, _fstack;
void _start(void);
void default_handler(void);
void _start(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;
UART0->ctrl = 0b11; // set rx and tx enable bits
UART0->baud_div = CONFIG_CLOCK_FREQUENCY / 115200; // FIXME
__asm__("bl main");
while(1);
}
void default_handler(void) {
while(1);
}
const void* isr_vector[] __attribute__((__used__)) __attribute__((section(".isr_vector"))) = {
&_fstack,
_start,
default_handler,
default_handler,
default_handler,
default_handler,
default_handler,
0,
0,
0,
0,
default_handler,
default_handler,
0,
default_handler,
default_handler
};

View File

@ -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 */

View File

@ -0,0 +1,72 @@
#ifndef __SYSTEM_H
#define __SYSTEM_H
#ifdef __cplusplus
extern "C" {
#endif
__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);
#include <stdint.h>
// FIXME
#define CSR_UART_BASE
#define UART_POLLING
struct EMCU_UART
{
volatile uint32_t data;
volatile uint32_t state;
volatile uint32_t ctrl;
volatile uint32_t int_ctrl;
volatile uint32_t baud_div;
};
#define PERIPHERALS_BASE 0x40000000
#define UART0 ((struct EMCU_UART *) (PERIPHERALS_BASE + 0x4000))
static inline char uart_txfull_read(void);
static inline char uart_rxempty_read(void);
static inline void uart_ev_enable_write(char c);
static inline void uart_rxtx_write(char c);
static inline char uart_rxtx_read(void);
static inline void uart_ev_pending_write(char);
static inline char uart_ev_pending_read(void);
static inline char uart_txfull_read(void) {
return UART0->state & 0b01;
}
static inline char uart_rxempty_read(void) {
return !(UART0->state & 0b10);
}
static inline void uart_ev_enable_write(char c) {
// FIXME
}
static inline void uart_rxtx_write(char c) {
UART0->data = (uint32_t) c;
}
static inline char uart_rxtx_read(void)
{
return (char)(UART0->data);
}
static inline void uart_ev_pending_write(char x) {}
static inline char uart_ev_pending_read(void) {
return 0;
}
#ifdef __cplusplus
}
#endif
#endif /* __SYSTEM_H */

View File

@ -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, 'gowin_emcu']
with_bios = self.soc.cpu_type is not None
if with_bios:
self.add_software_package("bios")

View File

@ -8,8 +8,8 @@ SECTIONS
.text :
{
_ftext = .;
/* Quicklogic EOS-S3 interrupt vector table uses section name "isr_vector" */
/* ARM table has to be placed at start */
/* ARM (Quicklogic EOS-S3, Gowin EMCU) interrupt vector tables use section name "isr_vector" */
/* - such a table has to be placed at start */
KEEP(*(.isr_vector))
/* Make sure crt0 files come first, and they, and the isr */
/* don't get disposed of by greedy optimisation */

View File

@ -74,7 +74,7 @@ static void boot_sequence(void)
printf("No boot medium found\n");
}
int main(int i, char **c)
__attribute__((__used__)) int main(int i, char **c)
{
char buffer[CMD_LINE_BUFFER_SIZE];
char *params[MAX_PARAM];