Initial import of basic non-Linux firmware example

Cloned from litex-hub/fpga_101/lab004/firmware, and all
demo-specific display / LED test functionality removed.

Per the author, _florent_, on Freenode IRC 06/14/2020,
this basic code is provided without any copyright restrictions.
parents
BUILD_DIR=../build/versa_ecp5
include $(BUILD_DIR)/software/include/generated/variables.mak
include $(SOC_DIRECTORY)/software/common.mak
OBJECTS=isr.o main.o
all: firmware.bin
# pull in dependency info for *existing* .o files
-include $(OBJECTS:.o=.d)
%.bin: %.elf
$(OBJCOPY) -O binary $< $@
chmod -x $@
firmware.elf: $(OBJECTS)
$(LD) $(LDFLAGS) \
-T linker.ld \
-N -o $@ \
$(BUILD_DIR)/software/libbase/crt0-ctr.o \
$(OBJECTS) \
-L$(BUILD_DIR)/software/libbase \
-L$(BUILD_DIR)/software/libcompiler_rt \
-lbase-nofloat -lcompiler_rt
chmod -x $@
main.o: main.c
$(compile)
%.o: %.c
$(compile)
%.o: %.S
$(assemble)
clean:
$(RM) $(OBJECTS) $(OBJECTS:.o=.d) firmware.elf firmware.bin .*~ *~
.PHONY: all main.o clean load
#include <generated/csr.h>
#include <generated/soc.h>
#include <irq.h>
#include <uart.h>
void isr(void);
#ifdef CONFIG_CPU_HAS_INTERRUPT
void isr(void)
{
__attribute__((unused)) unsigned int irqs;
irqs = irq_pending() & irq_getmask();
#ifndef UART_POLLING
if(irqs & (1 << UART_INTERRUPT))
uart_isr();
#endif
}
#else
void isr(void){};
#endif
INCLUDE generated/output_format.ld
ENTRY(_start)
__DYNAMIC = 0;
INCLUDE generated/regions.ld
SECTIONS
{
.text :
{
_ftext = .;
*(.text .stub .text.* .gnu.linkonce.t.*)
_etext = .;
} > main_ram
.rodata :
{
. = ALIGN(4);
_frodata = .;
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
_erodata = .;
} > main_ram
.data :
{
. = ALIGN(4);
_fdata = .;
*(.data .data.* .gnu.linkonce.d.*)
*(.data1)
_gp = ALIGN(16);
*(.sdata .sdata.* .gnu.linkonce.s.*)
_edata = .;
} > main_ram
.bss :
{
. = ALIGN(4);
_fbss = .;
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
_end = .;
} > sram
}
PROVIDE(_fstack = ORIGIN(sram) + LENGTH(sram) - 4);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <irq.h>
#include <uart.h>
#include <console.h>
#include <generated/csr.h>
static char *readstr(void)
{
char c[2];
static char s[64];
static int ptr = 0;
if(readchar_nonblock()) {
c[0] = readchar();
c[1] = 0;
switch(c[0]) {
case 0x7f:
case 0x08:
if(ptr > 0) {
ptr--;
putsnonl("\x08 \x08");
}
break;
case 0x07:
break;
case '\r':
case '\n':
s[ptr] = 0x00;
putsnonl("\n");
ptr = 0;
return s;
default:
if(ptr >= (sizeof(s) - 1))
break;
putsnonl(c);
s[ptr] = c[0];
ptr++;
break;
}
}
return NULL;
}
static char *get_token(char **str)
{
char *c, *d;
c = (char *)strchr(*str, ' ');
if(c == NULL) {
d = *str;
*str = *str+strlen(*str);
return d;
}
*c = 0;
d = *str;
*str = c+1;
return d;
}
static void prompt(void)
{
printf("RUNTIME>");
}
static void help(void)
{
puts("Available commands:");
puts("help - this command");
puts("reboot - reboot CPU");
}
static void reboot(void)
{
ctrl_reset_write(1);
}
static void console_service(void)
{
char *str;
char *token;
str = readstr();
if(str == NULL) return;
token = get_token(&str);
if(strcmp(token, "help") == 0)
help();
else if(strcmp(token, "reboot") == 0)
reboot();
prompt();
}
int main(void)
{
#ifdef CONFIG_CPU_HAS_INTERRUPT
irq_setmask(0);
irq_setie(1);
#endif
uart_init();
puts("\nLab004 - CPU testing software built "__DATE__" "__TIME__"\n");
help();
prompt();
while(1) {
console_service();
}
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment