Merge pull request #1178 from sergachev/gowin_emcu
Enable LiteX BIOS on Gowin EMCU ARM core
This commit is contained in:
commit
8d3f12ebbd
|
@ -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;
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
};
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue