Initial commit.
This commit is contained in:
commit
edb5181e64
|
@ -0,0 +1,57 @@
|
|||
BUILD_DIR = build
|
||||
|
||||
C_SOURCES = \
|
||||
system_handlers.c \
|
||||
system_peripherals.c \
|
||||
system_init.c \
|
||||
syscalls.c \
|
||||
main.c
|
||||
|
||||
ASM_SOURCES = \
|
||||
startup.s
|
||||
|
||||
LDSCRIPT = linker.ld
|
||||
|
||||
TARGET = hello
|
||||
|
||||
CC = /home/imi415/Softwares/Arch/RISC-V/toolchains/rv32imc/bin/riscv32-unknown-elf-gcc
|
||||
AS = /home/imi415/Softwares/Arch/RISC-V/toolchains/rv32imc/bin/riscv32-unknown-elf-gcc
|
||||
CP = /home/imi415/Softwares/Arch/RISC-V/toolchains/rv32imc/bin/riscv32-unknown-elf-objcopy
|
||||
SZ = /home/imi415/Softwares/Arch/RISC-V/toolchains/rv32imc/bin/riscv32-unknown-elf-size
|
||||
|
||||
HEX = $(CP) -O ihex
|
||||
BIN = $(CP) -O binary
|
||||
|
||||
CFLAGS += -mabi=ilp32 -march=rv32imc -g
|
||||
ASFLAGS += -mabi=ilp32 -march=rv32imc -g
|
||||
LDFLAGS += -nostartfiles -specs=nano.specs -lc -lm -lnosys
|
||||
|
||||
|
||||
LDFLAGS += -T$(LDSCRIPT) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map -Wl,--print-memory-usage
|
||||
|
||||
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin
|
||||
|
||||
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
|
||||
vpath %.c $(sort $(dir $(C_SOURCES)))
|
||||
|
||||
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
|
||||
vpath %.s $(sort $(dir $(ASM_SOURCES)))
|
||||
|
||||
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
|
||||
$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
|
||||
|
||||
$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
|
||||
$(AS) -c $(CFLAGS) $< -o $@
|
||||
|
||||
$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
|
||||
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
|
||||
$(SZ) $@
|
||||
|
||||
$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
|
||||
$(HEX) $< $@
|
||||
|
||||
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
|
||||
$(BIN) $< $@
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir $@
|
|
@ -0,0 +1,87 @@
|
|||
_entry_point = _vectors_start + 0x80;
|
||||
|
||||
ENTRY(_entry_point)
|
||||
|
||||
_estack = 0x42040000;
|
||||
_minimum_stack_size = 0x2000;
|
||||
_minimum_heap_size = 0x2000;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
RO_CODE (rx) : ORIGIN = 0x42000000, LENGTH = 128K
|
||||
RW_DATA (xrw) : ORIGIN = 0x42020000, LENGTH = 128K
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.isr_vectors :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_vectors_start = .;
|
||||
KEEP(*(.isr_vectors))
|
||||
_vectors_end = .;
|
||||
. = ALIGN(4);
|
||||
} >RO_CODE
|
||||
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text)
|
||||
*(.text*)
|
||||
KEEP (*(.init))
|
||||
KEEP (*(.fini))
|
||||
. = ALIGN(4);
|
||||
} >RO_CODE
|
||||
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sdata = .;
|
||||
__global_pointer$ = . + 0x800;
|
||||
*(.data)
|
||||
*(.data*)
|
||||
*(.sdata)
|
||||
*(.sdata*)
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} >RW_DATA AT> RO_CODE
|
||||
|
||||
_sidata = LOADADDR(.data);
|
||||
|
||||
|
||||
.rodata :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rodata)
|
||||
*(.rodata*)
|
||||
. = ALIGN(4);
|
||||
} >RO_CODE
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sbss = .;
|
||||
_bss_start = _sbss;
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_ebss = .;
|
||||
_bss_end = _ebss;
|
||||
} >RW_DATA
|
||||
|
||||
._heap_stack_space :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
PROVIDE(end = .);
|
||||
PROVIDE(_end = .);
|
||||
. = . + _minimum_heap_size;
|
||||
. = . + _minimum_stack_size;
|
||||
. = ALIGN(8);
|
||||
} >RW_DATA
|
||||
|
||||
.riscv.attributes 0 :
|
||||
{
|
||||
*(.riscv.attributes)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xilinx_ip_defs.h"
|
||||
|
||||
#define DDR_BASE 0x1FC00000
|
||||
#define DDR_LENGTH 0x100
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
GPIO0->TRI = 0xFFFFFFFD;
|
||||
GPIO0->DATA = 0x00;
|
||||
printf("Dumping first 256 bytes of DDR memory...\r\n");
|
||||
for(uint32_t i = DDR_BASE; i < DDR_BASE + DDR_LENGTH; i++) {
|
||||
printf("%02x ", *(uint8_t *)i);
|
||||
if((i + 1) % 16 == 0) {
|
||||
printf("\r\n");
|
||||
}
|
||||
}
|
||||
printf("Dump done.\r\n");
|
||||
printf("== RISC-V: The Free and Open RISC Instruction Set Architecture ==\r\n");
|
||||
printf("Running on LowRISC Ibex\r\n");
|
||||
|
||||
printf("System core frequency: %ld\r\n", GetCoreClock());
|
||||
|
||||
volatile uint32_t reg_buf = 0;
|
||||
asm volatile("csrr %0, misa\n" : "=r"(reg_buf));
|
||||
printf("MISA: 0x%08x\r\n", reg_buf);
|
||||
|
||||
asm volatile("csrr %0, mhartid\n" : "=r"(reg_buf));
|
||||
printf("MHARTID: 0x%08x\r\n", reg_buf);
|
||||
|
||||
uint32_t previous_tick = GetTick();
|
||||
|
||||
while(1) {
|
||||
if(GetTick() - previous_tick >= 500) {
|
||||
previous_tick = SysTick;
|
||||
GPIO0->DATA ^= 0x02;
|
||||
printf("SysTick: %lu\r\n", GetTick());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
.section .text
|
||||
|
||||
.global Reset_Handler
|
||||
|
||||
Reset_Handler:
|
||||
mv x1, x0
|
||||
mv x2, x1
|
||||
mv x3, x1
|
||||
mv x4, x1
|
||||
mv x5, x1
|
||||
mv x6, x1
|
||||
mv x7, x1
|
||||
mv x8, x1
|
||||
mv x9, x1
|
||||
mv x10, x1
|
||||
mv x11, x1
|
||||
mv x12, x1
|
||||
mv x13, x1
|
||||
mv x14, x1
|
||||
mv x15, x1
|
||||
mv x16, x1
|
||||
mv x17, x1
|
||||
mv x18, x1
|
||||
mv x19, x1
|
||||
mv x20, x1
|
||||
mv x21, x1
|
||||
mv x22, x1
|
||||
mv x23, x1
|
||||
mv x24, x1
|
||||
mv x25, x1
|
||||
mv x26, x1
|
||||
mv x27, x1
|
||||
mv x28, x1
|
||||
mv x29, x1
|
||||
mv x30, x1
|
||||
mv x31, x1
|
||||
|
||||
.option push
|
||||
.option norelax
|
||||
la gp, __global_pointer$
|
||||
.option pop
|
||||
|
||||
la sp, _estack
|
||||
|
||||
la x25, _sidata
|
||||
la x26, _sdata
|
||||
la x27, _edata
|
||||
|
||||
bge x26, x27, copy_data_end
|
||||
|
||||
copy_data:
|
||||
lw x24, 0(x25)
|
||||
sw x24, 0(x26)
|
||||
addi x25, x25, 4
|
||||
addi x26, x26, 4
|
||||
|
||||
ble x26, x27, copy_data
|
||||
|
||||
copy_data_end:
|
||||
|
||||
/* Zero .bss section */
|
||||
la x26, _sbss
|
||||
la x27, _ebss
|
||||
|
||||
bge x26, x27, zero_bss_end
|
||||
|
||||
zero_bss:
|
||||
sw x0, 0(x26)
|
||||
addi x26, x26, 4
|
||||
ble x26, x27, zero_bss
|
||||
|
||||
zero_bss_end:
|
||||
jal x1, System_Init
|
||||
|
||||
addi x10, x0, 0
|
||||
addi x11, x0, 0
|
||||
jal x1, main
|
||||
|
||||
inf_loop:
|
||||
jal x0, inf_loop
|
||||
|
||||
Default_IRQHandler:
|
||||
jal x0, Generic_ExceptionCallback
|
||||
|
||||
Timer_IRQHandler:
|
||||
jal x0, Generic_TimerCallback
|
||||
|
||||
/* ISR vector table */
|
||||
.section .isr_vectors, "ax"
|
||||
.option norvc;
|
||||
|
||||
.org 0x00
|
||||
.rept 7
|
||||
jal x0, Default_IRQHandler
|
||||
.endr
|
||||
jal x0, Timer_IRQHandler
|
||||
.rept 23
|
||||
jal x0, Default_IRQHandler
|
||||
.endr
|
||||
|
||||
.org 0x80
|
||||
jal x0, Reset_Handler
|
|
@ -0,0 +1,20 @@
|
|||
#include <stdint.h>
|
||||
#include "xilinx_ip_defs.h"
|
||||
|
||||
|
||||
void _putchar(char ch)
|
||||
{
|
||||
while(((UART0->STAT & 0x04) == 0) || UART0->STAT & 0x08) {
|
||||
// Waits for TX FIFO empty.
|
||||
}
|
||||
UART0->TX_FIFO = ch;
|
||||
}
|
||||
|
||||
int _write(int handle, char *data, int size ) {
|
||||
int count;
|
||||
handle = handle;
|
||||
for( count = 0; count < size; count++) {
|
||||
_putchar(data[count]);
|
||||
}
|
||||
return count;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xilinx_ip_defs.h"
|
||||
|
||||
void Generic_ExceptionCallback(void) {
|
||||
for(;;) {
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void Generic_TimerCallback(void) {
|
||||
TIMER0->TCSR0 |= (1 << 0x08); // Clear interrupt;
|
||||
SysTick++;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#include "xilinx_ip_defs.h"
|
||||
|
||||
__IO uint32_t SysTick;
|
||||
|
||||
void System_Init(void) {
|
||||
// Clear UARTLite FIFOs
|
||||
UART0->CTRL = 0x03;
|
||||
|
||||
SysTick = 0;
|
||||
|
||||
// Enable interrupts
|
||||
asm volatile("csrs mie, %0\n" : : "r"(0x80)); // Enable timer interrupt
|
||||
asm volatile("csrs mstatus, %0\n" : : "r"(0x8)); // Enable global interrupt
|
||||
|
||||
// Setup systick timer
|
||||
TIMER0->TCSR0 = 0x12; // Generate mode, down count, auto-reload
|
||||
TIMER0->TCR0 = 0; // Clear counter
|
||||
TIMER0->TLR0 = SYS_CLK_FREQ / SYS_TICK_RATE; // Set reload value
|
||||
|
||||
TIMER0->TCSR0 |= (1 << 0x06U) | (1 << 0x07U); // Enable timer interrupt, enable counter.
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#include "xilinx_ip_defs.h"
|
||||
|
||||
__IO UartLite_TypeDef *UART0 = (UartLite_TypeDef *)UART0_BASE;
|
||||
__IO GPIO_TypeDef *GPIO0 = (GPIO_TypeDef *)GPIO0_BASE;
|
||||
__IO Timer_TypeDef *TIMER0 = (Timer_TypeDef *)TIMER0_BASE;
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef __XILINX_IP_DEFS_H
|
||||
#define __XILINX_IP_DEFS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define __IO volatile
|
||||
|
||||
typedef struct {
|
||||
__IO uint32_t RX_FIFO;
|
||||
__IO uint32_t TX_FIFO;
|
||||
__IO uint32_t STAT;
|
||||
__IO uint32_t CTRL;
|
||||
} UartLite_TypeDef;
|
||||
|
||||
typedef struct {
|
||||
__IO uint32_t DATA;
|
||||
__IO uint32_t TRI;
|
||||
__IO uint32_t DATA2;
|
||||
__IO uint32_t TRI2;
|
||||
} GPIO_TypeDef;
|
||||
|
||||
typedef struct {
|
||||
__IO uint32_t TCSR0;
|
||||
__IO uint32_t TLR0;
|
||||
__IO uint32_t TCR0;
|
||||
__IO uint32_t RSVD;
|
||||
__IO uint32_t TCSR1;
|
||||
__IO uint32_t TLR1;
|
||||
__IO uint32_t TCR1;
|
||||
} Timer_TypeDef;
|
||||
|
||||
#define UART0_BASE 0x40010000
|
||||
#define GPIO0_BASE 0x40000000
|
||||
#define TIMER0_BASE 0x40020000
|
||||
|
||||
#define SYS_CLK_FREQ 48000000
|
||||
#define SYS_TICK_RATE 1000
|
||||
|
||||
extern __IO UartLite_TypeDef *UART0;
|
||||
extern __IO GPIO_TypeDef *GPIO0;
|
||||
extern __IO Timer_TypeDef *TIMER0;
|
||||
|
||||
extern __IO uint32_t SysTick;
|
||||
|
||||
static inline uint32_t GetTick() {
|
||||
return SysTick;
|
||||
}
|
||||
|
||||
static inline uint32_t GetCoreClock() {
|
||||
return SYS_CLK_FREQ;
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue