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 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) | ||||
| { | ||||
|   volatile uint64_t magic_mem[8] __attribute__((aligned(64))); | ||||
| @ -76,7 +114,19 @@ void abort() | ||||
| 
 | ||||
| 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) | ||||
| @ -107,6 +157,7 @@ void _init(int cid, int nc) | ||||
| { | ||||
|   init_tls(); | ||||
|   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.
 | ||||
|   int ret = main(0, 0); | ||||
| @ -125,6 +176,11 @@ void _init(int cid, int nc) | ||||
| #undef putchar | ||||
| 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 int buflen = 0; | ||||
| 
 | ||||
| @ -134,7 +190,7 @@ int putchar(int ch) | ||||
|   { | ||||
|     syscall(SYS_write, 1, (uintptr_t)buf, buflen); | ||||
|     buflen = 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