Initial commit.

This commit is contained in:
imi415 2021-04-12 01:27:48 +08:00
commit 2fbd318615
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
22 changed files with 637 additions and 0 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "lib/printf"]
path = lib/printf
url = https://github.com/mpaland/printf.git

84
CMakeLists.txt Normal file
View File

@ -0,0 +1,84 @@
cmake_minimum_required(VERSION 3.10)
project(Flute_Hello)
enable_language(CXX)
enable_language(ASM)
# Device specific settings, goes to CFLAGS and LDFLAGS
set(CFLAGS_HARDWARE "-mabi=lp64 -march=rv64imac")
# Extra CFlags
set(CFLAGS_EXTRA "-Og")
set(LDFLAGS_EXTRA "-Wl,--print-memory-usage")
# Different linker scripts
set(LDSCRIPT_BRAM "${CMAKE_SOURCE_DIR}/startup/flute_bram.ld")
# Copy them from Makefile
set(C_SOURCES
"src/main.c"
"src/flute_system.c"
"src/flute_it.c"
"src/soc_peripherals.c"
"src/syscalls.c"
"src/system_init.c"
"src/drivers/xilinx_gpio.c"
"src/drivers/xilinx_timer.c"
"src/drivers/xilinx_uartlite.c"
"lib/printf/printf.c"
)
# Copy them from Makefile
set(ASM_SOURCES
"startup/startup.S"
)
# Copy them from Makefile
add_definitions(
)
# Copy them from Makefile
include_directories(
"include"
"lib/printf"
)
# Final compiler flags
set(CMAKE_C_FLAGS "${CFLAGS_HARDWARE} ${CFLAGS_EXTRA} -Wall -fdata-sections -ffunction-sections")
set(CMAKE_CXX_FLAGS "${CFLAGS_HARDWARE} ${CFLAGS_EXTRA} -Wall -fdata-sections -ffunction-sections")
set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp")
set(CMAKE_EXE_LINKER_FLAGS "${CFLAGS_HARDWARE} -Wl,--gc-sections -specs=nano.specs -nostartfiles -lc -lm -lnosys ${LDFLAGS_EXTRA}")
# Main targets are added here
# **** Internal BRAM ****
# Create ELF
add_executable("${CMAKE_PROJECT_NAME}_BRAM.elf" ${C_SOURCES} ${ASM_SOURCES})
target_link_options("${CMAKE_PROJECT_NAME}_BRAM.elf"
PRIVATE "-T${LDSCRIPT_BRAM}"
PRIVATE "-Wl,-Map=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}_BRAM.map,--cref"
)
target_compile_options("${CMAKE_PROJECT_NAME}_BRAM.elf"
PRIVATE "${FINAL_C_FLAGS}"
)
add_custom_command(OUTPUT "${CMAKE_PROJECT_NAME}_BRAM.hex"
COMMAND ${CMAKE_OBJCOPY} "-O" "ihex" "${CMAKE_PROJECT_NAME}_BRAM.elf" "${CMAKE_PROJECT_NAME}_BRAM.hex"
DEPENDS "${CMAKE_PROJECT_NAME}_BRAM.elf"
)
add_custom_target("${CMAKE_PROJECT_NAME}_BRAM_HEX"
DEPENDS "${CMAKE_PROJECT_NAME}_BRAM.hex"
)
add_custom_command(OUTPUT "${CMAKE_PROJECT_NAME}_BRAM.bin"
COMMAND ${CMAKE_OBJCOPY} "-O" "binary" "${CMAKE_PROJECT_NAME}_BRAM.elf" "${CMAKE_PROJECT_NAME}_BRAM.bin"
DEPENDS "${CMAKE_PROJECT_NAME}_BRAM.elf"
)
add_custom_target("${CMAKE_PROJECT_NAME}_BRAM_BIN"
DEPENDS "${CMAKE_PROJECT_NAME}_BRAM.bin"
)

13
include/flute_system.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef __IBEX_SYSTEM_H
#define __IBEX_SYSTEM_H
#include <stdint.h>
#define __csrr(csr, val) asm volatile("csrr %0, " csr "\n" : "=r"(val))
#define __csrw(csr, val) asm volatile("csrw " csr ", %0\n" : : "r"(val))
#define __csrs(csr, val) asm volatile("csrs " csr ", %0\n" : : "r"(val))
#define __csrc(csr, val) asm volatile("csrc " csr ", %0\n" : : "r"(val))
void System_Delay(uint64_t ticks);
#endif

10
include/main.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef __MAIN_H
#define __MAIN_H
#include "flute_system.h"
#include "soc_peripherals.h"
extern xilinx_uartlite_handle_t soc_uart;
extern xilinx_gpio_handle_t soc_gpio;
#endif

39
include/soc_peripherals.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef __SOC_PERIPHERALS_H
#define __SOC_PERIPHERALS_H
#include "xilinx_uartlite.h"
#include "xilinx_gpio.h"
#include "xilinx_timer.h"
#include "flute_system.h"
// Peripheral defines
#define UART0_BASE 0x40000000
#define GPIO0_BASE 0x40010000
#define TIMER0_BASE 0x40020000
#define CLINT_BASE 0x02000000
// SoC config
#define SYS_CLK_FREQ 32000000
#define SYS_TICK_RATE 1000
#define SYS_TICK_STEP (SYS_CLK_FREQ / SYS_TICK_RATE)
// Peripherals
extern __IO xilinx_uartlite_t *UART0;
extern __IO xilinx_gpio_t *GPIO0;
extern __IO xilinx_timer_t *TIMER0;
// SysTick
extern volatile uint64_t SysTick;
static inline uint32_t GetTick() {
return SysTick;
}
static inline uint32_t GetCoreClock() {
return SYS_CLK_FREQ;
}
#endif

13
include/system_defs.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef __XILINX_IP_DEFS_H
#define __XILINX_IP_DEFS_H
#include <stdint.h>
#define __IO volatile
#define RET_OK 0
#define RET_ERR 1
typedef int sys_ret_t;
#endif

23
include/xilinx_gpio.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef __XILINX_GPIO_H
#define __XILINX_GPIO_H
#include "system_defs.h"
typedef struct {
__IO uint32_t DATA;
__IO uint32_t TRI;
__IO uint32_t DATA2;
__IO uint32_t TRI2;
} xilinx_gpio_t;
typedef struct {
__IO xilinx_gpio_t *instance;
} xilinx_gpio_handle_t;
sys_ret_t xilinx_gpio_init(xilinx_gpio_handle_t *handle);
sys_ret_t xilinx_gpio_pinmode(xilinx_gpio_handle_t *handle, uint32_t pin, uint8_t output);
sys_ret_t xilinx_gpio_write(xilinx_gpio_handle_t *handle, uint32_t pin, uint8_t value);
uint8_t xilinx_gpio_read(xilinx_gpio_handle_t *handle, uint32_t pin);
sys_ret_t xilinx_gpio_toggle(xilinx_gpio_handle_t *handle, uint32_t pin);
#endif

16
include/xilinx_timer.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef __XILINX_TIMER_H
#define __XILINX_TIMER_H
#include "system_defs.h"
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;
} xilinx_timer_t;
#endif

21
include/xilinx_uartlite.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef __XILINX_UARTLITE_H
#define __XILINX_UARTLITE_H
#include "system_defs.h"
typedef struct {
__IO uint32_t RX_FIFO;
__IO uint32_t TX_FIFO;
__IO uint32_t STAT;
__IO uint32_t CTRL;
} xilinx_uartlite_t;
typedef struct {
__IO xilinx_uartlite_t *instance;
} xilinx_uartlite_handle_t;
sys_ret_t xilinx_uartlite_init(xilinx_uartlite_handle_t *handle);
sys_ret_t xilinx_uartlite_send(xilinx_uartlite_handle_t *handle, uint8_t *data, uint32_t len);
sys_ret_t xilinx_uartlite_receive(xilinx_uartlite_handle_t *handle, uint8_t *data, uint32_t len);
#endif

1
lib/printf Submodule

@ -0,0 +1 @@
Subproject commit d3b984684bb8a8bdc48cc7a1abecb93ce59bbe3e

View File

@ -0,0 +1,5 @@
set(CMAKE_C_COMPILER $ENV{TOOLCHAIN_PATH}/riscv64-unknown-elf-gcc)
set(CMAKE_CXX_COMPILER $ENV{TOOLCHAIN_PATH}/riscv64-unknown-elf-gcc)
# Make CMake happy about those compilers
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")

35
src/drivers/xilinx_gpio.c Normal file
View File

@ -0,0 +1,35 @@
#include "xilinx_gpio.h"
sys_ret_t xilinx_gpio_init(xilinx_gpio_handle_t *handle) {
handle->instance->TRI = 0xFFFFFFFF;
return RET_OK;
}
sys_ret_t xilinx_gpio_pinmode(xilinx_gpio_handle_t *handle, uint32_t pin, uint8_t output) {
if(output) {
handle->instance->TRI &= ~(1U << pin);
}
else {
handle->instance->TRI |= (1U << pin);
}
return RET_OK;
}
sys_ret_t xilinx_gpio_write(xilinx_gpio_handle_t *handle, uint32_t pin, uint8_t value) {
if(value) {
handle->instance->DATA |= (1U << pin);
}
else {
handle->instance->DATA &= ~(1U << pin);
}
return RET_OK;
}
uint8_t xilinx_gpio_read(xilinx_gpio_handle_t *handle, uint32_t pin) {
return (handle->instance->DATA & (1U << pin)) ? 1 : 0;
}
sys_ret_t xilinx_gpio_toggle(xilinx_gpio_handle_t *handle, uint32_t pin) {
handle->instance->DATA ^= (1U << pin);
return RET_OK;
}

View File

@ -0,0 +1,2 @@
#include "xilinx_timer.h"

View File

@ -0,0 +1,27 @@
#include "xilinx_uartlite.h"
sys_ret_t xilinx_uartlite_init(xilinx_uartlite_handle_t *handle) {
handle->instance->CTRL |= 0x03; // Reset FIFO
return RET_OK;
}
sys_ret_t xilinx_uartlite_send(xilinx_uartlite_handle_t *handle, uint8_t *data, uint32_t len) {
for(uint32_t i = 0; i < len; i++) {
while(handle->instance->STAT & (1U << 0x03) || !(handle->instance->STAT & (1U << 0x02))) { // Check if TX FIFO is full
// TODO: Unless we figure out where systick should be.
}
handle->instance->TX_FIFO = data[i];
}
return RET_OK;
}
sys_ret_t xilinx_uartlite_receive(xilinx_uartlite_handle_t *handle, uint8_t *data, uint32_t len) {
for(uint32_t i = 0; i < len; i++) {
while((handle->instance->STAT & 0x01U) == 0) { // Check if RX FIFO is empty
// TODO: Unless we figure out where our systick should be.
}
data[i] = handle->instance->RX_FIFO & 0xFF;
}
return RET_OK;
}

22
src/flute_it.c Normal file
View File

@ -0,0 +1,22 @@
#include "flute_system.h"
#include "soc_peripherals.h"
void Timer_IRQHandler(void) {
SysTick++;
*(uint64_t *)(CLINT_BASE + 0x4000) = SYS_TICK_STEP;
*(uint64_t *)(CLINT_BASE + 0xBFF8) = 0ULL;
}
__attribute__((interrupt)) void Exception_Handler(void) {
uint64_t mcause = 0;
__csrr("mcause", mcause);
switch(mcause) {
case 0x8000000000000007: // MTIME
Timer_IRQHandler();
break;
default:
for(;;) {}
}
}

23
src/flute_system.c Normal file
View File

@ -0,0 +1,23 @@
#include "soc_peripherals.h"
void __enable_irqs(void){
//
}
void __enable_mcount(void) {
//
}
void __read_mcycle(void) {
//
}
void __enable_irqn(int IRQn) {
//
}
void System_Delay(uint64_t ticks) {
uint64_t tick_start = SysTick;
while(SysTick < tick_start + ticks) {
//
}
}

52
src/main.c Normal file
View File

@ -0,0 +1,52 @@
#include <stdint.h>
#include "printf.h"
#include "main.h"
xilinx_uartlite_handle_t soc_uart;
xilinx_gpio_handle_t soc_gpio;
void _print_arch_string(uint64_t misa);
int main(int argc, char *argv[]) {
printf("Running on a Bluespec flute core.\r\n");
uint64_t csr = 0;
__csrr("misa", csr);
printf("MISA: 0x%016llx, this is a ", csr);
_print_arch_string(csr);
printf(" processor.\r\n");
printf("System clock frequency: %luHz\r\n", SYS_CLK_FREQ);
for(;;) {
System_Delay(10000);
__csrr("mcycle", csr);
printf("mcycle: 0x%016llx\r\n", csr);
}
return 0;
}
void _print_arch_string(uint64_t misa) {
switch(misa >> 62) {
case 1:
printf("RV32");
break;
case 2:
printf("RV64");
break;
case 3:
printf("RV128");
break;
}
for(uint8_t i = 0; i < 26; i++) {
if(misa >> i & 0x01ULL) {
printf("%c", 'A' + i);
}
}
}

5
src/soc_peripherals.c Normal file
View File

@ -0,0 +1,5 @@
#include "soc_peripherals.h"
__IO xilinx_uartlite_t *UART0 = (xilinx_uartlite_t *) UART0_BASE;
__IO xilinx_gpio_t *GPIO0 = (xilinx_gpio_t *) GPIO0_BASE;
__IO xilinx_timer_t *TIMER0 = (xilinx_timer_t *) TIMER0_BASE;

34
src/syscalls.c Normal file
View File

@ -0,0 +1,34 @@
#include <stdint.h>
#include <errno.h>
#include "main.h"
extern int _heap_start;
extern int _heap_end;
static void *_old_heap = &_heap_start;
int _write(int handle, char *data, int size) {
handle = handle;
xilinx_uartlite_send(&soc_uart, (uint8_t *)data, size);
return size;
}
void *_sbrk(int nbytes) {
char *_old = _old_heap;
if(&_heap_start == &_heap_end) {
errno = -ENOMEM;
return (void *)-1;
}
if((_old + nbytes) < (char *)&_heap_end) {
_old += nbytes;
} else {
errno = -ENOMEM;
return (void *)-1;
}
return _old_heap;
}
void _putchar(char character) {
xilinx_uartlite_send(&soc_uart, (uint8_t *)&character, 0x01);
}

28
src/system_init.c Normal file
View File

@ -0,0 +1,28 @@
#include "main.h"
__IO uint64_t SysTick;
void System_Init(void) {
soc_uart.instance = UART0;
xilinx_uartlite_init(&soc_uart);
soc_gpio.instance = GPIO0;
xilinx_gpio_init(&soc_gpio);
xilinx_gpio_pinmode(&soc_gpio, 0, 1);
// Setup interrupt system
uint64_t csr = 0ULL;
__csrw("mtvec", csr);
SysTick = 0ULL;
*(uint64_t *)(CLINT_BASE + 0x4000) = SYS_TICK_STEP;
*(uint64_t *)(CLINT_BASE + 0xBFF8) = 0ULL;
csr = 1U << 7; // MTIE
__csrw("mie", csr); // Enable timer interrupt
csr = 1U << 3; // MIE
__csrw("mstatus", csr);
}

91
startup/flute_bram.ld Normal file
View File

@ -0,0 +1,91 @@
_entry_point = 0x1000;
ENTRY(_entry_point)
_estack = 0x00020000;
_minimum_stack_size = 0x1000;
_minimum_heap_size = 0x1000;
MEMORY
{
RO_CODE (rx) : ORIGIN = 0x00000000, LENGTH = 64K
RW_DATA (xrw) : ORIGIN = 0x00010000, LENGTH = 64K
}
SECTIONS
{
.isr_vectors :
{
. = ALIGN(8);
_vectors_start = .;
KEEP(*(.isr_vectors))
_vectors_end = .;
. = ALIGN(8);
} >RO_CODE
.text :
{
. = ALIGN(8);
*(.text)
*(.text*)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(8);
} >RO_CODE
.data :
{
. = ALIGN(8);
_sdata = .;
__global_pointer$ = . + 0x800;
*(.data)
*(.data*)
*(.sdata)
*(.sdata*)
. = ALIGN(8);
_edata = .;
} >RW_DATA AT> RO_CODE
_sidata = LOADADDR(.data);
.rodata :
{
. = ALIGN(8);
*(.rodata)
*(.rodata*)
. = ALIGN(8);
} >RO_CODE
.bss :
{
. = ALIGN(8);
_sbss = .;
_bss_start = _sbss;
*(.bss)
*(.bss*)
*(.sbss)
*(.sbss*)
*(COMMON)
. = ALIGN(8);
_ebss = .;
_bss_end = _ebss;
} >RW_DATA
._heap_stack_space :
{
. = ALIGN(8);
_heap_start = .;
. = . + _minimum_heap_size;
_heap_end = .;
_end = .;
. = ALIGN(8);
. = . + _minimum_stack_size;
. = ALIGN(8);
} >RW_DATA
.riscv.attributes 0 :
{
*(.riscv.attributes)
}
}

90
startup/startup.S Normal file
View File

@ -0,0 +1,90 @@
.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:
ld x24, 0(x25)
sd x24, 0(x26)
addi x25, x25, 8
addi x26, x26, 8
blt x26, x27, copy_data
copy_data_end:
/* Zero .bss section */
la x26, _sbss
la x27, _ebss
bge x26, x27, zero_bss_end
zero_bss:
sd x0, 0(x26)
addi x26, x26, 8
blt 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
/* ISR vector table */
.section .isr_vectors, "ax"
.option norvc;
.org 0x00
jal x0, Exception_Handler
.org 0x1000
jal x0, Reset_Handler