copy
This commit is contained in:
39
firmware/Makefile
Normal file
39
firmware/Makefile
Normal file
@@ -0,0 +1,39 @@
|
||||
TARGET = firmware
|
||||
BAUDRATE = 115200
|
||||
SERIALPORT ?= /dev/ttyACM0
|
||||
|
||||
CROSS ?= riscv64-unknown-elf-
|
||||
|
||||
CC = $(CROSS)gcc
|
||||
OBJCOPY = $(CROSS)objcopy
|
||||
|
||||
CFLAGS = -march=rv32i -mabi=ilp32 -g -Os -Wall -Werror
|
||||
LDFLAGS = -Tsoc.ld -Triscv_standalone.ld -nostdlib
|
||||
|
||||
SOURCES = \
|
||||
start.S \
|
||||
$(TARGET).c
|
||||
|
||||
|
||||
# By default, build our binary.
|
||||
all: $(TARGET).bin
|
||||
|
||||
#
|
||||
# Firmware binary.
|
||||
#
|
||||
|
||||
$(TARGET).elf: $(SOURCES) soc.ld resources.h
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $(SOURCES) -o $@
|
||||
|
||||
$(TARGET).bin: $(TARGET).elf
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
|
||||
|
||||
#
|
||||
# Virtual/command targets.
|
||||
#
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET).elf $(TARGET).bin
|
||||
71
firmware/firmware.c
Normal file
71
firmware/firmware.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Great Scott Gadgets <info@greatscottgadgets.com>
|
||||
* Copyright (c) 2022 Hans Baier <hansfbaier@gmail.com>
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "resources.h"
|
||||
|
||||
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(*array))
|
||||
|
||||
//
|
||||
// Support functions.
|
||||
//
|
||||
|
||||
/**
|
||||
* Transmits a single charater over our example UART.
|
||||
*/
|
||||
void print_char(char c)
|
||||
{
|
||||
while(!uart_tx_rdy_read());
|
||||
uart_tx_data_write(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transmits a string over our UART.
|
||||
*/
|
||||
void uart_puts(char *str)
|
||||
{
|
||||
for (char *c = str; *c; ++c) {
|
||||
if (*c == '\n') {
|
||||
print_char('\r');
|
||||
}
|
||||
|
||||
print_char(*c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a hex character over our UART.
|
||||
*/
|
||||
void print_nibble(uint8_t nibble)
|
||||
{
|
||||
static const char hexits[] = "0123456789abcdef";
|
||||
print_char(hexits[nibble & 0xf]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a single byte, in hex, over our UART.
|
||||
*/
|
||||
void print_byte(uint8_t byte)
|
||||
{
|
||||
print_nibble(byte >> 4);
|
||||
print_nibble(byte & 0xf);
|
||||
}
|
||||
|
||||
//
|
||||
// Core application.
|
||||
//
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uart_puts("SoC started! (built: " __TIME__ ")\n");
|
||||
|
||||
while (1) {
|
||||
for(int i=0; i<(1<<23); i++) ;
|
||||
uart_puts("Ping...\r\n");
|
||||
}
|
||||
}
|
||||
44
firmware/riscv_standalone.ld
Normal file
44
firmware/riscv_standalone.ld
Normal file
@@ -0,0 +1,44 @@
|
||||
OUTPUT_FORMAT("elf32-littleriscv")
|
||||
OUTPUT_ARCH("riscv")
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
|
||||
/* Start of day code. */
|
||||
.init :
|
||||
{
|
||||
*(.init) *(.init.*)
|
||||
} > rom
|
||||
.text :
|
||||
{
|
||||
*(.text) *(.text.*)
|
||||
} > rom
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata) *(.rodata.*)
|
||||
} > rom
|
||||
.sdata :
|
||||
{
|
||||
PROVIDE(__global_pointer$ = .);
|
||||
*(.sdata) *(.sdata.*)
|
||||
}
|
||||
.data :
|
||||
{
|
||||
*(.data) *(.data.*)
|
||||
} > ram
|
||||
.bss :
|
||||
{
|
||||
*(.bss) *(.bss.*)
|
||||
} > ram
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.eh_frame) *(.eh_frame.*)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PROVIDE(__stack_top = ORIGIN(ram) + LENGTH(ram));
|
||||
35
firmware/start.S
Normal file
35
firmware/start.S
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Great Scott Gadgets <info@greatscottgadgets.com>
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
.section .init, "ax"
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
.cfi_startproc
|
||||
.cfi_undefined ra
|
||||
|
||||
/* Set up our global pointer. */
|
||||
.option push
|
||||
.option norelax
|
||||
la gp, __global_pointer$
|
||||
.option pop
|
||||
|
||||
/* Set up our stack. */
|
||||
la sp, __stack_top
|
||||
add s0, sp, zero
|
||||
|
||||
/*
|
||||
* NOTE: In most cases, we'd clear the BSS, here.
|
||||
*
|
||||
* In our case, our FPGA automaticaly starts with all of our RAM
|
||||
* initialized to zero; so our BSS comes pre-cleared. We'll skip the
|
||||
* formality of re-clearing it.
|
||||
*/
|
||||
|
||||
/* Finally, start our main routine. */
|
||||
jal zero, main
|
||||
|
||||
.cfi_endproc
|
||||
.end
|
||||
Reference in New Issue
Block a user