mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Hello Wally application now running, can print in spike and wsim via UART. Verilator simulation is broken
This commit is contained in:
parent
43e267799d
commit
b7467156c5
@ -15,6 +15,44 @@
|
|||||||
extern volatile uint64_t tohost;
|
extern volatile uint64_t tohost;
|
||||||
extern volatile uint64_t fromhost;
|
extern volatile uint64_t fromhost;
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// Start of code added for Wally
|
||||||
|
// Use UART rather than syscall host interface for printing
|
||||||
|
//////////////////////////////
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void uartInit(void) {
|
||||||
|
volatile uint8_t *UART_LCR = (uint8_t*)0x10000003;
|
||||||
|
*UART_LCR = 0b0000011; // 8-bit characters, 1 stop bit, no parity
|
||||||
|
}
|
||||||
|
|
||||||
|
void uartSend(char c) {
|
||||||
|
volatile uint8_t *UART_THR = (uint8_t*)0x10000000;
|
||||||
|
volatile uint8_t *UART_LSR = (uint8_t*)0x10000005;
|
||||||
|
|
||||||
|
while (!(*UART_LSR & (1<<5))); // wait for THRE (trans hold reg empty)
|
||||||
|
*UART_THR = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
char uartReceive(void) {
|
||||||
|
volatile uint8_t *UART_RBR = (uint8_t*)0x10000000;
|
||||||
|
volatile uint8_t *UART_LSR = (uint8_t*)0x10000005;
|
||||||
|
|
||||||
|
while (!(*UART_LSR & (1<<0))); // wait for DR (Data Ready)
|
||||||
|
return *UART_RBR;
|
||||||
|
}
|
||||||
|
|
||||||
|
char uartPutStr(const char *str) {
|
||||||
|
while (*str) {
|
||||||
|
uartSend(*str++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// End of code added for Wally
|
||||||
|
//////////////////////////////
|
||||||
|
|
||||||
static uintptr_t syscall(uintptr_t which, uint64_t arg0, uint64_t arg1, uint64_t arg2)
|
static uintptr_t syscall(uintptr_t which, uint64_t arg0, uint64_t arg1, uint64_t arg2)
|
||||||
{
|
{
|
||||||
volatile uint64_t magic_mem[8] __attribute__((aligned(64)));
|
volatile uint64_t magic_mem[8] __attribute__((aligned(64)));
|
||||||
@ -76,7 +114,19 @@ void abort()
|
|||||||
|
|
||||||
void printstr(const char* s)
|
void printstr(const char* s)
|
||||||
{
|
{
|
||||||
syscall(SYS_write, 1, (uintptr_t)s, strlen(s));
|
// david_harris@hmc.edu 11/30/24 switch to printing via UART rather than syscall
|
||||||
|
// This works on both Spike and Wally simulations
|
||||||
|
//syscall(SYS_write, 1, (uintptr_t)s, strlen(s));
|
||||||
|
uartPutStr(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Added 30 November 2024 David_Harris@hmc.edu
|
||||||
|
// The compiler encountering printf with a pure string argument tries to invoke puts
|
||||||
|
// rather than the usual printf, so puts must be defined.
|
||||||
|
int puts(const char* s)
|
||||||
|
{
|
||||||
|
printstr(s);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __attribute__((weak)) thread_entry(int cid, int nc)
|
void __attribute__((weak)) thread_entry(int cid, int nc)
|
||||||
@ -107,6 +157,7 @@ void _init(int cid, int nc)
|
|||||||
{
|
{
|
||||||
init_tls();
|
init_tls();
|
||||||
thread_entry(cid, nc);
|
thread_entry(cid, nc);
|
||||||
|
uartInit(); // added 11/30/2024 David_Harris@hmc.edu for printing via UART
|
||||||
|
|
||||||
// only single-threaded programs should ever get here.
|
// only single-threaded programs should ever get here.
|
||||||
int ret = main(0, 0);
|
int ret = main(0, 0);
|
||||||
@ -125,6 +176,11 @@ void _init(int cid, int nc)
|
|||||||
#undef putchar
|
#undef putchar
|
||||||
int putchar(int ch)
|
int putchar(int ch)
|
||||||
{
|
{
|
||||||
|
// David_Harris@hmc.edu 11/30/2024
|
||||||
|
// Replaced syscall with uartSend
|
||||||
|
uartSend(ch);
|
||||||
|
|
||||||
|
/*
|
||||||
static __thread char buf[64] __attribute__((aligned(64)));
|
static __thread char buf[64] __attribute__((aligned(64)));
|
||||||
static __thread int buflen = 0;
|
static __thread int buflen = 0;
|
||||||
|
|
||||||
@ -134,7 +190,7 @@ int putchar(int ch)
|
|||||||
{
|
{
|
||||||
syscall(SYS_write, 1, (uintptr_t)buf, buflen);
|
syscall(SYS_write, 1, (uintptr_t)buf, buflen);
|
||||||
buflen = 0;
|
buflen = 0;
|
||||||
}
|
} */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
33
examples/C/hello/Makefile
Normal file
33
examples/C/hello/Makefile
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
TARGET = hello
|
||||||
|
|
||||||
|
$(TARGET).objdump: $(TARGET)
|
||||||
|
riscv64-unknown-elf-objdump -S -D $(TARGET) > $(TARGET).objdump
|
||||||
|
cp $(TARGET) $(TARGET).elf
|
||||||
|
|
||||||
|
$(TARGET): $(TARGET).c Makefile
|
||||||
|
riscv64-unknown-elf-gcc -o $(TARGET) -gdwarf-2 -O\
|
||||||
|
-march=rv64gc -mabi=lp64d -mcmodel=medany \
|
||||||
|
-nostdlib -static -lm -fno-tree-loop-distribute-patterns \
|
||||||
|
-T../common/test.ld -I../common \
|
||||||
|
$(TARGET).c ../common/crt.S ../common/syscalls.c
|
||||||
|
# Compiler flags:
|
||||||
|
# -o $(TARGET) defines the name of the output file
|
||||||
|
# -g generates debugging symbols for gdb
|
||||||
|
# -O turns on basic optimization; -O3 turns on heavy optimization; omit for no optimization
|
||||||
|
# -march=rv64gc -mabi=lp64d =mcmodel=medany generates code for RV64GC with doubles and long/ptrs = 64 bits
|
||||||
|
# -static forces static linking (no dynamic shared libraries on bare metal)
|
||||||
|
# -lm links the math library if necessary (when #include math.h)
|
||||||
|
# -nostdlib avoids inserting standard startup files and default libraries
|
||||||
|
# because we are using crt.s on bare metal
|
||||||
|
# -fno-tree-loop-distribute-patterns turns replacing loops with memcpy/memset in the std library
|
||||||
|
# -T specifies the linker file
|
||||||
|
# -I specifies the include path (e.g. for util.h)
|
||||||
|
# The last line defines the C files to compile.
|
||||||
|
# crt.S is needed as our startup file to initialize the processor
|
||||||
|
# syscalls.c implements printf through the HTIF for Spike
|
||||||
|
# other flags from riscv-tests makefiles that don't seem to be important
|
||||||
|
# -ffast-math -DPREALLOCATE=1 -std=gnu99 \
|
||||||
|
# -fno-common -fno-builtin-printf -nostartfiles -lgcc \
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(TARGET) $(TARGET).objdump
|
23
examples/C/hello/hello.c
Normal file
23
examples/C/hello/hello.c
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// hello.c
|
||||||
|
// David_Harris@hmc.edu 30 November 2024
|
||||||
|
|
||||||
|
// Hello World program illustrating compiled C code printing via the UART
|
||||||
|
// The Wally team has modified the Berkeley syscalls.c (in examples/C/common)
|
||||||
|
// to print via UART rather than the syscall interface. This is supported
|
||||||
|
// on both Spike and Wally. It assumes the PC16550-compatible UART is at
|
||||||
|
// the default SiFive address of 0x10000000.
|
||||||
|
// Note that there seem to be some discrepancies between the UART and Spike
|
||||||
|
// such that using \n\r for new lines works best.
|
||||||
|
|
||||||
|
// compile with make
|
||||||
|
// simulate with: wsim rv64gc hello.elf --sim verilator
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
printf("Hello Wally!\n\r");
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
printf("%d ", i);
|
||||||
|
}
|
||||||
|
printf("\n\r");
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user