Initial commit.

This commit is contained in:
imi415 2020-05-30 22:42:07 +08:00
commit edb5181e64
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
9 changed files with 401 additions and 0 deletions

57
Makefile Normal file
View File

@ -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 $@

87
linker.ld Normal file
View File

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

42
main.c Normal file
View File

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

102
startup.s Normal file
View File

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

20
syscalls.c Normal file
View File

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

14
system_handlers.c Normal file
View File

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

21
system_init.c Normal file
View File

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

5
system_peripherals.c Normal file
View File

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

53
xilinx_ip_defs.h Normal file
View File

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