adds ehrenberg platform

This commit is contained in:
2024-01-13 23:06:01 +01:00
parent 1d55083a55
commit 13cd5cc76d
17 changed files with 829 additions and 71 deletions

22
env/common-gcc.mk vendored
View File

@ -1,8 +1,10 @@
ifndef _MK_COMMON
_MK_COMMON := # defined
.PHONY: all
all: $(TARGET)
TL_TARGET?=all
.PHONY: $(TL_TARGET)
$(TL_TARGET): $(TARGET)
include $(BSP_BASE)/libwrap/libwrap.mk
@ -14,17 +16,17 @@ ASM_SRCS += $(ENV_DIR)/start.S
ASM_SRCS += $(ENV_DIR)/entry.S
C_SRCS += $(PLATFORM_DIR)/init.c
LINKER_SCRIPT := $(PLATFORM_DIR)/$(LINK_TARGET).lds
LINKER_SCRIPT ?= $(PLATFORM_DIR)/$(LINK_TARGET).lds
INCLUDES += -I$(BSP_BASE)/include
INCLUDES += -I$(BSP_BASE)/drivers/
INCLUDES += -I$(ENV_DIR)
INCLUDES += -I$(PLATFORM_DIR)
TOOL_DIR ?= $(BSP_BASE)/../toolchain/bin/
LDFLAGS += -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI)
ifndef NO_DEFAULT_LINK
LDFLAGS += -T $(LINKER_SCRIPT) -Wl,--no-warn-rwx-segments -Wl,-Map=$(TARGET).map -nostartfiles
endif
LDFLAGS += -L$(ENV_DIR)
# --specs=nano.specs
@ -53,12 +55,14 @@ CC=$(TOOL_DIR)$(TRIPLET)-gcc
LD=$(TOOL_DIR)$(TRIPLET)-gcc
AR=$(TOOL_DIR)$(TRIPLET)-ar
OBJDUMP := $(TOOL_DIR)$(TRIPLET)-objdump
OBJCOPY := $(TOOL_DIR)$(TRIPLET)-objcopy
$(TARGET): $(LINK_OBJS) $(LINK_DEPS)
ifndef NO_DEFAULT_LINK
$(TARGET).elf: $(LINK_OBJS) $(LINK_DEPS)
$(LD) $(LINK_OBJS) $(LDFLAGS) $(LIBWRAP) -o $@
$(OBJDUMP) -d -S $(TARGET) > $(TARGET).dis
$(OBJDUMP) -d -S $@ > $(TARGET).dis
endif
$(ASM_OBJS): %.o: %.S $(HEADERS)
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<

1
env/ehrenberg/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/*.o

140
env/ehrenberg/init.c vendored Normal file
View File

@ -0,0 +1,140 @@
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include "platform.h"
#include "encoding.h"
#include <ehrenberg/devices.h>
#if __riscv_xlen == 32
#define MCAUSE_INT 0x80000000UL
#define MCAUSE_CAUSE 0x000003FFUL
#else
#define MCAUSE_INT 0x8000000000000000UL
#define MCAUSE_CAUSE 0x00000000000003FFUL
#endif
extern int main(int argc, char** argv);
extern void trap_entry();
#define IRQ_M_SOFT 3
#define IRQ_M_TIMER 7
#define IRQ_M_EXT 11
#define NUM_INTERRUPTS 16
#define MTIMER_NEXT_TICK_INC 1000
void handle_m_ext_interrupt(void);
void handle_m_time_interrupt(void);
uint32_t handle_trap(uint32_t mcause, uint32_t mepc, uint32_t sp);
void default_handler(void);
void _init(void);
typedef void (*my_interrupt_function_ptr_t) (void);
my_interrupt_function_ptr_t localISR[NUM_INTERRUPTS] __attribute__((aligned(64)));
static unsigned long mtime_lo(void)
{
unsigned long ret;
__asm volatile("rdtime %0":"=r"(ret));
return ret;
}
#if __riscv_xlen==32
static uint32_t mtime_hi(void)
{
unsigned long ret;
__asm volatile("rdtimeh %0":"=r"(ret));
return ret;
}
uint64_t get_timer_value()
{
while (1) {
uint32_t hi = mtime_hi();
uint32_t lo = mtime_lo();
if (hi == mtime_hi())
return ((uint64_t)hi << 32) | lo;
}
}
#elif __riscv_xlen==64
uint64_t get_timer_value()
{
return mtime_lo();
}
#endif
unsigned long get_timer_freq()
{
return 32768;
}
unsigned long get_cpu_freq()
{
return 100000000;
}
void init_pll(void){
//TODO: implement initialization
}
static void uart_init(size_t baud_rate)
{
//TODO: implement initialization
}
void __attribute__((weak)) handle_m_ext_interrupt(){
}
void __attribute__((weak)) handle_m_time_interrupt(){
uint64_t time = ((uint64_t)mtimer->mtimeh)<<32 || mtimer->mtime;
time+=MTIMER_NEXT_TICK_INC;
mtimer->mtimecmph = time>>32;
mtimer->mtimecmp = time;
}
void __attribute__((weak)) default_handler(void) {
puts("default handler\n");
}
uint32_t handle_trap(uint32_t mcause, uint32_t mepc, uint32_t sp){
if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT)) {
handle_m_ext_interrupt();
// External Machine-Level interrupt from PLIC
} else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER)){
handle_m_time_interrupt();
} else {
write(1, "trap\n", 5);
_exit(1 + mcause);
}
return mepc;
}
void _init()
{
#ifndef NO_INIT
init_pll();
uart_init(115200);
printf("core freq at %d Hz\n", get_cpu_freq());
write_csr(mtvec, &trap_entry);
if (read_csr(misa) & (1 << ('F' - 'A'))) { // if F extension is present
write_csr(mstatus, MSTATUS_FS); // allow FPU instructions without trapping
write_csr(fcsr, 0); // initialize rounding mode, undefined at reset
}
int i=0;
while(i<NUM_INTERRUPTS) {
localISR[i++] = default_handler;
}
#endif
}
void _fini()
{
}

173
env/ehrenberg/link.lds vendored Normal file
View File

@ -0,0 +1,173 @@
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
MEMORY
{
flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 512M
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 128K
}
PHDRS
{
flash PT_LOAD;
ram_init PT_LOAD;
ram PT_NULL;
}
SECTIONS
{
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
.init ORIGIN(flash) :
{
KEEP (*(SORT_NONE(.init)))
} >flash AT>flash :flash
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >flash AT>flash :flash
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >flash AT>flash :flash
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata :
{
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
} >flash AT>flash :flash
. = ALIGN(4);
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >flash AT>flash :flash
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >flash AT>flash :flash
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >flash AT>flash :flash
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >flash AT>flash :flash
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >flash AT>flash :flash
.lalign :
{
. = ALIGN(4);
PROVIDE( _data_lma = . );
} >flash AT>flash :flash
.dalign :
{
. = ALIGN(4);
PROVIDE( _data = . );
} >ram AT>flash :ram_init
.data :
{
__DATA_BEGIN__ = .;
*(.data .data.*)
*(.gnu.linkonce.d.*)
} >ram AT>flash :ram_init
.srodata :
{
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
} >ram AT>flash :ram_init
.sdata :
{
__SDATA_BEGIN__ = .;
*(.sdata .sdata.*)
*(.gnu.linkonce.s.*)
} >ram AT>flash :ram_init
. = ALIGN(4);
PROVIDE( _edata = . );
PROVIDE( edata = . );
PROVIDE( _fbss = . );
PROVIDE( __bss_start = . );
.bss :
{
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
} >ram AT>ram :ram
. = ALIGN(8);
__BSS_END__ = .;
__global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800, MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));
PROVIDE( _end = . );
PROVIDE( end = . );
.stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
{
PROVIDE( _heap_end = . );
. = __stack_size;
PROVIDE( _sp = . );
} >ram AT>ram :ram
PROVIDE( tohost = 0xfffffff0 );
PROVIDE( fromhost = 0xfffffff8 );
}

119
env/ehrenberg/platform.h vendored Normal file
View File

@ -0,0 +1,119 @@
// See LICENSE for license details.
#ifndef _ISS_PLATFORM_H
#define _ISS_PLATFORM_H
// Some things missing from the official encoding.h
#define MCAUSE_INT 0x80000000
#define MCAUSE_CAUSE 0x7FFFFFFF
#include "ehrenberg/const.h"
#include "ehrenberg/devices.h"
/****************************************************************************
* Platform definitions
*****************************************************************************/
// Memory map
#define MASKROM_BASE_ADDR _AC(0x00001000,UL)
#define TRAPVEC_TABLE_BASE_ADDR _AC(0x00001010,UL)
#define OTP_MMAP_ADDR _AC(0x00020000,UL)
#define CLINT_BASE_ADDR _AC(0x02000000,UL)
#define PLIC_BASE_ADDR _AC(0x0C000000,UL)
#define AON_BASE_ADDR _AC(0x10000000,UL)
#define PRCI_BASE_ADDR _AC(0x10008000,UL)
#define OTP_BASE_ADDR _AC(0x10010000,UL)
#define GPIO_BASE_ADDR _AC(0x10012000,UL)
#define UART0_BASE_ADDR _AC(0x10013000,UL)
#define SPI0_BASE_ADDR _AC(0x10014000,UL)
#define PWM0_BASE_ADDR _AC(0x10015000,UL)
#define UART1_BASE_ADDR _AC(0x10023000,UL)
#define SPI1_BASE_ADDR _AC(0x10024000,UL)
#define PWM1_BASE_ADDR _AC(0x10025000,UL)
#define SPI2_BASE_ADDR _AC(0x10034000,UL)
#define PWM2_BASE_ADDR _AC(0x10035000,UL)
#define SPI0_MMAP_ADDR _AC(0x20000000,UL)
#define MEM_BASE_ADDR _AC(0x80000000,UL)
// IOF masks
#define IOF0_SPI1_MASK _AC(0x000007FC,UL)
#define SPI11_NUM_SS (4)
#define IOF_SPI1_SS0 (2u)
#define IOF_SPI1_SS1 (8u)
#define IOF_SPI1_SS2 (9u)
#define IOF_SPI1_SS3 (10u)
#define IOF_SPI1_MOSI (3u)
#define IOF_SPI1_MISO (4u)
#define IOF_SPI1_SCK (5u)
#define IOF_SPI1_DQ0 (3u)
#define IOF_SPI1_DQ1 (4u)
#define IOF_SPI1_DQ2 (6u)
#define IOF_SPI1_DQ3 (7u)
#define IOF0_SPI2_MASK _AC(0xFC000000,UL)
#define SPI2_NUM_SS (1)
#define IOF_SPI2_SS0 (26u)
#define IOF_SPI2_MOSI (27u)
#define IOF_SPI2_MISO (28u)
#define IOF_SPI2_SCK (29u)
#define IOF_SPI2_DQ0 (27u)
#define IOF_SPI2_DQ1 (28u)
#define IOF_SPI2_DQ2 (30u)
#define IOF_SPI2_DQ3 (31u)
//#define IOF0_I2C_MASK _AC(0x00003000,UL)
#define IOF0_UART0_MASK _AC(0x00030000, UL)
#define IOF_UART0_RX (16u)
#define IOF_UART0_TX (17u)
#define IOF0_UART1_MASK _AC(0x03000000, UL)
#define IOF_UART1_RX (24u)
#define IOF_UART1_TX (25u)
#define IOF1_PWM0_MASK _AC(0x0000000F, UL)
#define IOF1_PWM1_MASK _AC(0x00780000, UL)
#define IOF1_PWM2_MASK _AC(0x00003C00, UL)
// Interrupt numbers
#define INT_RESERVED 0
#define INT_WDOGCMP 1
#define INT_RTCCMP 2
#define INT_UART0_BASE 3
#define INT_UART1_BASE 4
#define INT_SPI0_BASE 5
#define INT_SPI1_BASE 6
#define INT_SPI2_BASE 7
#define INT_GPIO_BASE 8
#define INT_PWM0_BASE 40
#define INT_PWM1_BASE 44
#define INT_PWM2_BASE 48
// Helper functions
#define _REG32(p, i) (*(volatile uint32_t *) ((p) + (i)))
#define _REG32P(p, i) ((volatile uint32_t *) ((p) + (i)))
#define AON_REG(offset) _REG32(AON_BASE_ADDR, offset)
#define CLINT_REG(offset) _REG32(CLINT_BASE_ADDR, offset)
#define GPIO_REG(offset) _REG32(GPIO_BASE_ADDR, offset)
#define OTP_REG(offset) _REG32(OTP_BASE_ADDR, offset)
#define PLIC_REG(offset) _REG32(PLIC_BASE_ADDR, offset)
#define PRCI_REG(offset) _REG32(PRCI_BASE_ADDR, offset)
#define PWM0_REG(offset) _REG32(PWM0_BASE_ADDR, offset)
#define PWM1_REG(offset) _REG32(PWM1_BASE_ADDR, offset)
#define PWM2_REG(offset) _REG32(PWM2_BASE_ADDR, offset)
#define SPI0_REG(offset) _REG32(SPI0_BASE_ADDR, offset)
#define SPI1_REG(offset) _REG32(SPI1_BASE_ADDR, offset)
#define SPI2_REG(offset) _REG32(SPI2_BASE_ADDR, offset)
#define UART0_REG(offset) _REG32(UART0_BASE_ADDR, offset)
#define UART1_REG(offset) _REG32(UART1_BASE_ADDR, offset)
// Misc
#include <stdint.h>
void init_pll(void);
unsigned long get_cpu_freq(void);
unsigned long get_timer_freq(void);
uint64_t get_timer_value(void);
#endif /* _ISS_PLATFORM_H */