diff --git a/c_project/Makefile b/c_project/Makefile new file mode 100644 index 0000000..2ca229c --- /dev/null +++ b/c_project/Makefile @@ -0,0 +1,140 @@ +# Color definitions ------------------------------- + +NO_COLOR="\033[0m" +RED="\033[38;5;009m" +GREEN="\033[38;5;010m" +YELLOW="\033[38;5;011m" +ORANGE="\033[38;5;214m" +LIGHTPURPLE="\033[38;5;177m" +PURPLE="\033[38;5;135m" +CYAN="\033[38;5;014m" +LIGHTBLUE="\033[38;5;39m" +BLUE="\033[38;5;75m" +DARKBLUE="\033[38;5;33m" +LIGHTGRAY="\033[38;5;252m" +DARKGRAY="\033[38;5;242m" +BRIGHTRED="\033[91m" +BOLD="\033[1m" + +# PATHS (adapt to your system)---------------------- + +PATH_RISCV=/opt/riscv/ +PATH_RISC_BIN=$(PATH_RISCV)bin/ +PATH_VERILATOR_BIN?=/usr/local/bin/verilator +PREFIX?=$(PATH_RISC_BIN)riscv64-unknown-elf + +# TOOLS -------------------------------------------- + +AR?=$(PREFIX)-ar +GCC?=$(PREFIX)-gcc +CLANG=clang +GDB?=$(PREFIX)-gdb +OBJDUMP?=$(PREFIX)-objdump +OBJCOPY?=$(PREFIX)-objcopy +RISCVPATH=$(PATH_RISCV)riscv64-unknown-elf +OPENOCD?=$(PATH_RISC_BIN)openocd +ECHO?=echo + +# GCC FLAGS --------------------------------------- + +CC=$(GCC) + +GCC_CFLAGS_COMMON := -g \ + -O3 \ + -fno-builtin-printf \ + -Wno-unused-parameter \ + -Wall -Wextra -Wredundant-decls \ + -Wshadow -Wno-unused-function \ + -fno-common \ + -I$(RISCVPATH)/include + +GCC_CFLAGS_MURAX=-fstrict-volatile-bitfields --specs=nosys.specs + +RISCV_ARCH?=rv32im +RISCV_ABI?=ilp32 +RISCV_CMODEL?=medany +RISCV_ARCHFLAGS +=-march=$(RISCV_ARCH) +RISCV_ARCHFLAGS +=-mabi=$(RISCV_ABI) +RISCV_ARCHFLAGS +=-mcmodel=$(RISCV_CMODEL) +GCC_RISCV_ARCHFLAGS=$(RISCV_ARCHFLAGS) + +CFLAGS += $(GCC_CFLAGS_COMMON) \ + $(GCC_CFLAGS_MURAX) \ + $(GCC_RISCV_ARCHFLAGS) + +# Linker flags -------------------------------------- + +PLATFORM ?= pqvexriscvsim + +LDSCRIPT = $(PLATFORM).ld +LDFLAGS = -L$(RISCVPATH)/lib/rv32imac/ilp32 +LDFLAGS += $(GCC_RISCV_ARCHFLAGS) +LDFLAGS += --specs=nosys.specs +LDFLAGS += -Wl,-T$(LDSCRIPT) +LDFLAGS += -nostartfiles -ffreestanding -Wl,--gc-sections +LDFLAGS += -L. +LDFLAGS += -Wl,--start-group -l$(PLATFORM)bsp -lc -Wl,--end-group + +# Object files -------------------------------------- + +SDK_ASM_SRCS := $(wildcard *.S) +SDK_C_SRCS := $(wildcard *.c) +SDK_C_OBJS := $(SDK_C_SRCS:.c=.o) +SDK_ASM_OBJS := $(SDK_ASM_SRCS:.S=.o) +SDK_OBJS := $(SDK_C_OBJS) $(SDK_ASM_OBJS) + +# Target all ---------------------------------------- + +.PHONY: all +all: main.hex main.bin + +# LIBWRAP + +include vexriscv/vexriscv.mk + +# Targets -------------------------------------------- + +main.bin: main + @$(ECHO) $(PURPLE)"obj "$@""$(LIGHTGRAY) + $(OBJCOPY) -O binary $< $@ + +main.hex: main + @$(ECHO) $(PURPLE)"obj "$@""$(LIGHTGRAY) + $(OBJCOPY) -O ihex $< $@ + +main: $(LIBWRAP) $(SDK_OBJS) $(LDSCRIPT) + @$(ECHO) $(LIGHTPURPLE)"building "$@""$(LIGHTGRAY) + $(GCC) $(GCC_RISCV_ARCHFLAGS) $(GCC_CFLAGS_COMMON) $(SDK_OBJS) -o $@ $(LDFLAGS) + +%.o: %.S + @$(ECHO) $(ORANGE)"building "$@" (.S)"$(LIGHTGRAY) + $(CC) $(CFLAGS) -c -o $@ $^ + +%.o: %.c + @$(ECHO) $(ORANGE)"building "$@" (.c)"$(LIGHTGRAY) + $(CC) $(CFLAGS) -c -o $@ $^ + +.PHONY: clean +clean: + @$(ECHO) $(RED)"cleaning..."$(LIGHTGRAY) + rm -f main main.bin main.hex $(SDK_OBJS) $(LIBWRAP_OBJS) $(LIBWRAP) + +help: + @$(ECHO) $(RED)"Compile & Simulate"$(LIGHTGRAY) + @$(ECHO) $(LIGHTGRAY)"1. "$(CYAN)"make"$(LIGHTGRAY) + @$(ECHO) $(LIGHTGRAY)"2. open 3 terminals"$(LIGHTGRAY) + @$(ECHO) $(LIGHTGRAY)"3. Terminal 2: "$(CYAN)"make startsim"$(LIGHTGRAY) + @$(ECHO) $(LIGHTGRAY)"4. Terminal 3: "$(CYAN)"make openocd"$(LIGHTGRAY) + @$(ECHO) $(LIGHTGRAY)"5. Terminal 1: "$(CYAN)"make flash"$(LIGHTGRAY) + +# Targets for starting simulation, openocd and gdb ---------------------------- + +# startsim: +# cd ../Building_Tools/pqriscv-vexriscv/ ; sbt "runMain mupq.PQVexRiscvSim --ram 256,128" + +# openocd: +# cd ../Building_Tools/pqriscv-vexriscv/ ; /opt/verilator/bin/openocd --file pqvexriscvsim.cfg + +#flash: +# /opt/riscv/bin/riscv64-unknown-elf-gdb -ex 'set remotetimeout 15' -ex 'target remote :3333' -ex 'load' -ex 'break main' -ex 'continue' main + diff --git a/c_project/crt.S b/c_project/crt.S new file mode 100644 index 0000000..adfc5ab --- /dev/null +++ b/c_project/crt.S @@ -0,0 +1,97 @@ +# .global crtStart +# .global main +# .global irqCallback + +# crtStart: +# j crtInit +# nop +# nop +# nop +# nop +# nop +# nop +# nop + +# .global trap_entry +# trap_entry: +# sw x1, - 1*4(sp) +# sw x5, - 2*4(sp) +# sw x6, - 3*4(sp) +# sw x7, - 4*4(sp) +# sw x10, - 5*4(sp) +# sw x11, - 6*4(sp) +# sw x12, - 7*4(sp) +# sw x13, - 8*4(sp) +# sw x14, - 9*4(sp) +# sw x15, -10*4(sp) +# sw x16, -11*4(sp) +# sw x17, -12*4(sp) +# sw x28, -13*4(sp) +# sw x29, -14*4(sp) +# sw x30, -15*4(sp) +# sw x31, -16*4(sp) +# addi sp,sp,-16*4 +# call irqCallback +# lw x1 , 15*4(sp) +# lw x5, 14*4(sp) +# lw x6, 13*4(sp) +# lw x7, 12*4(sp) +# lw x10, 11*4(sp) +# lw x11, 10*4(sp) +# lw x12, 9*4(sp) +# lw x13, 8*4(sp) +# lw x14, 7*4(sp) +# lw x15, 6*4(sp) +# lw x16, 5*4(sp) +# lw x17, 4*4(sp) +# lw x28, 3*4(sp) +# lw x29, 2*4(sp) +# lw x30, 1*4(sp) +# lw x31, 0*4(sp) +# addi sp,sp,16*4 +# mret +# .text + + +# crtInit: +# .option push +# .option norelax +# la gp, __global_pointer$ +# .option pop +# la sp, _stack_start + +# bss_init: +# la a0, _bss_start +# la a1, _bss_end +# bss_loop: +# beq a0,a1,bss_done +# sw zero,0(a0) +# add a0,a0,4 +# j bss_loop +# bss_done: + +# ctors_init: +# la a0, _ctors_start +# addi sp,sp,-4 +# ctors_loop: +# la a1, _ctors_end +# beq a0,a1,ctors_done +# lw a3,0(a0) +# add a0,a0,4 +# sw a0,0(sp) +# jalr a3 +# lw a0,0(sp) +# j ctors_loop +# ctors_done: +# addi sp,sp,4 + + +# li a0, 0x880 //880 enable timer + external interrupts +# csrw mie,a0 +# li a0, 0x1808 //1808 enable interrupts +# csrw mstatus,a0 + +# call main +# infinitLoop: +# j infinitLoop + diff --git a/c_project/crt.o b/c_project/crt.o new file mode 100644 index 0000000..7838fdd Binary files /dev/null and b/c_project/crt.o differ diff --git a/c_project/hal-vexriscv.c b/c_project/hal-vexriscv.c new file mode 100644 index 0000000..29fa8e5 --- /dev/null +++ b/c_project/hal-vexriscv.c @@ -0,0 +1,60 @@ +#include "hal.h" +#include + +/* Murax UART */ + +typedef struct { + volatile uint32_t DATA; + volatile uint32_t STATUS; + volatile uint32_t CLOCK_DIVIDER; + volatile uint32_t FRAME_CONFIG; +} Uart_Reg; + +enum UartParity { NONE = 0, EVEN = 1, ODD = 2 }; +enum UartStop { ONE = 0, TWO = 1 }; + +typedef struct { + uint32_t dataLength; + enum UartParity parity; + enum UartStop stop; + uint32_t clockDivider; +} Uart_Config; + +static uint32_t uart_writeAvailability(Uart_Reg* reg) +{ + return (reg->STATUS >> 16) & 0xFF; +} + +static void uart_write(Uart_Reg* reg, uint32_t data) +{ + while (uart_writeAvailability(reg) == 0) + ; + reg->DATA = data; +} + +#define UART ((Uart_Reg*)(0xF0010000)) + +void hal_send(const uint8_t* in, const size_t len) { + for (size_t i = 0; i < len; i++) { + uart_write(UART, in[i]); + } +} + +void hal_send_str(const char* in) +{ + const char* cur = in; + while(*cur) { + uart_write(UART, *cur); + cur += 1; + } +} + +__attribute__((naked)) uint64_t hal_get_time(void) +{ +#define LE "\n\t" + asm volatile (LE"csrr a1, mcycleh" + LE"csrr a0, mcycle" + LE"csrr a2, mcycleh" + LE"bne a1, a2, hal_get_time" + LE"ret"); +} diff --git a/c_project/hal-vexriscv.o b/c_project/hal-vexriscv.o new file mode 100644 index 0000000..9ecd279 Binary files /dev/null and b/c_project/hal-vexriscv.o differ diff --git a/c_project/hal.c b/c_project/hal.c new file mode 100644 index 0000000..2c43d0e --- /dev/null +++ b/c_project/hal.c @@ -0,0 +1,21 @@ +#include + +#include +#include + +#include +#undef errno +extern int errno; + +#include "hal.h" + +void _putchar(char c) { + hal_send((uint8_t*)&c, 1); +} + +void _write(int fd, const void* ptr, size_t len) { + // Don't care about the fd. Just put everything on the UART console. + (void)fd; + hal_send(ptr, len); +} + diff --git a/c_project/hal.h b/c_project/hal.h new file mode 100644 index 0000000..217bb5b --- /dev/null +++ b/c_project/hal.h @@ -0,0 +1,18 @@ +#ifndef VECRISCV_HAL_H_ +#define VECRISCV_HAL_H_ + +#include +#include +#include + +#define printf printf_ + +void hal_send(const uint8_t* in, const size_t len); +void hal_send_str(const char* in); + +int printf_(const char* format, ...); + +void _putchar(char c); +void _write(int fd, const void* ptr, size_t len); + +#endif /* VECRISCV_HAL_H_ */ diff --git a/c_project/hal.o b/c_project/hal.o new file mode 100644 index 0000000..a9f3a9e Binary files /dev/null and b/c_project/hal.o differ diff --git a/c_project/libpqvexriscvsimbsp.a b/c_project/libpqvexriscvsimbsp.a new file mode 100644 index 0000000..478caae Binary files /dev/null and b/c_project/libpqvexriscvsimbsp.a differ diff --git a/c_project/main b/c_project/main new file mode 100755 index 0000000..486cffd Binary files /dev/null and b/c_project/main differ diff --git a/c_project/main.bin b/c_project/main.bin new file mode 100755 index 0000000..701d736 Binary files /dev/null and b/c_project/main.bin differ diff --git a/c_project/main.c b/c_project/main.c new file mode 100644 index 0000000..cb0c90c --- /dev/null +++ b/c_project/main.c @@ -0,0 +1,29 @@ +#include +#include "hal.h" + +typedef struct { + volatile uint32_t state; +} My_Mem; + +#define MY_MEM ((My_Mem*)(0xF0030000)) + +int main(void) +{ + printf("HELLO WORLD\n"); + + uint32_t state = 10000; + uint32_t state_return; + + while (1) + { + printf("State in : %i\n", state); + + MY_MEM->state = state; + state_return = MY_MEM->state; + + state = state + 1; + + printf("State out: %i\n", state_return); + } + return 0; +} diff --git a/c_project/main.hex b/c_project/main.hex new file mode 100644 index 0000000..fcb07ac --- /dev/null +++ b/c_project/main.hex @@ -0,0 +1,446 @@ +:0200000480007A +:10000000130000001300000013000000971104000B +:100010009381C1C1170106001301C1FE171500002D +:1000200013054574970504009385C5FD1706040064 +:100030001306C63F63FCC5008322050023A05500BC +:100040001305450093854500E3E8C5FE1705040048 +:100050001305C53D970504009385453D6378B500BC +:100060002320050013054500E36CB5FE9700000052 +:10007000130101FF23241100371500001305058823 +:100080007310453037250000130585807310053047 +:100090001305000093050000EF00C0126F104035FB +:1000A0006F000000130000001300000013000000A8 +:1000B000130101F8232211002324210023263100FB +:1000C00023284100232A5100232C6100232E710094 +:1000D00023208102232291022324A1022326B1029C +:1000E0002328C102232AD102232CE102232EF1026C +:1000F0002320010523221105232421052326310570 +:1001000023284105232A5105232C6105232E71053F +:1001100023208107232291072324A1072326B10747 +:100120002328C107232AD107232CE107232EF10717 +:10013000EF00800883204100032181008321C1005A +:100140000322010183224101032381018323C10191 +:100150000324010283244102032581028325C10275 +:100160000326010383264103032781038327C10359 +:100170000328010483284104032981048329C1043D +:10018000032A0105832A4105032B8105832BC10521 +:10019000032C0106832C4106032D8106832DC10605 +:1001A000032E0107832E4107032F8107832FC107E9 +:1001B00013010108730020306F00000000000000F0 +:0401C000000000003B +:1001C400130101FE232C8100171500001305C555EA +:1001D40037240000232A91002328210123263101FA +:1001E400232E110013040471EF00107D97190000F1 +:1001F40093898954B70403F0171900001309C954EB +:100204009305040013850900EF00107B23A08400EC +:1002140083A504001305090013041400EF00D0792A +:100224006FF01FFE97070080938787DD99C7171526 +:1002340000001305052A6F10202D82806376D600F6 +:10024400B385C5002380A500678000006780000097 +:10025400130101FD0323810323202103232E3101F4 +:10026400232C4101232A51012328610123267101F2 +:1002740023248101232611022324810223229102B3 +:10028400232291012320A101137C2300138B060058 +:10029400130A0500938A0500930906001309070051 +:1002A40083260103832B410363140C061375130087 +:1002B400639A0B1C63F6D7021307F0016364F732E9 +:1002C40013060003930500026F008000638AB700E1 +:1002D400938717003307F900A30FC7FEE3E8D7FE9F +:1002E4006308050263F6770313070002638EE71AB7 +:1002F40013060003930500026F0080006386B71A9B +:10030400938717003307F900A30FC7FEE39877FF1D +:100314001377030163020708137703406314071A72 +:10032400639E0718130700016382E82A93072000DD +:10033400638EF826930700032300F9009307100047 +:100344006304081A3307F900138417009307D002D3 +:100354002300F7001373330063140300636A740FFC +:10036400938C09006F00C00413070002638AE7023C +:10037400B306F90093871700130780072380E6006C +:1003840013070002638EE7003307F90093060003A6 +:100394002300D7009387170013070002E392E7FABC +:1003A400137333006302030A938C090013040002DD +:1003B400B38C8C00330D9901330489000345F4FF99 +:1003C40033068D4093060B001304F4FF93850A0053 +:1003D40093840C00E7000A00E31289FE63080C0210 +:1003E400B389344163F479031386040093060B0044 +:1003F40093850A001305000293841400E7000A00A1 +:100404009389190013860400E3E279FF8320C10273 +:100414000324810213850400032901028324410279 +:100424008329C101032A8101832A4101032B01018C +:10043400832BC100032C8100832C4100032D010078 +:10044400130101036780000013040002637C740B32 +:10045400B38C7901B38C8C401386090093060B008E +:1004640093850A001305000293041600E7000A00AE +:1004740013860400E39494FF93840C00E31A04F2BB +:100484006FF0DFF5630E05086316080A1377C300DF +:100494006312070AE3F8D7E41307F001E372F7E203 +:1004A40093070002E3F677E793770301E38A07EE05 +:1004B400937703406390070E930700026380F60866 +:1004C400638E770713070001638AE8081307200087 +:1004D400E398E8EA13070002E384E7EC3307F90042 +:1004E400938717006F00C00D137743006310070252 +:1004F400137783006316070813733300138407000C +:10050400E30603F4938C09006FF01FF73307F90037 +:10051400138417009307B0022300F7006FF09FE3E2 +:10052400E3F8D7DE1307F001E37CF7D89307000262 +:100534006FF01FDE938BFBFF6FF0DFF51387F7FF80 +:10054400630E0704930600016380D80C9306200011 +:100554006386D806930707006FF01FE3137703023F +:10056400E30407E013070002E38CE7E23307F90032 +:10057400930680052300D700938717006FF05FE090 +:100584003307F90013841700930700022300F700D0 +:100594006FF05FDC930700026FF0DFF29307000156 +:1005A4006388F80493072000E396F8FA930720067B +:1005B4002300F900930710006FF01FDD3307E900F3 +:1005C400930620062300D7006FF09FDB1377030206 +:1005D400E31E07F8930780072300F9009307100030 +:1005E4006FF09FDA93070002E31E05CE6FF05FD22F +:1005F40093770302E38007FE930780052300F90045 +:10060400930710006FF05FD8937603029387E7FF98 +:10061400E39E06F4B306F900930707006FF0DFD5F5 +:10062400130101FB232E3103232611042324810407 +:10063400232291042320210583294105631A0704F9 +:1006440013F309409300010193F9F9FE63020304D3 +:1006540003230105232431012320110123226100F6 +:100664009308080013880700930707001387000006 +:10067400EFF01FBE8320C1040324810483244104BA +:10068400032901048329C1031301010567800000C4 +:1006940013FE090213031006631C0E081379F30FEB +:1006A400930F07001353F701930001011307000090 +:1006B400930310009302F0FF13049000130969FFE1 +:1006C40093040002130F0000130EE001B3DECF41C8 +:1006D40093FE1E001313130033E36E00B39EC30195 +:1006E400130EFEFF6346030133030341336FDF013F +:1006F400E31E5EFC1373F30F6366640213030303C8 +:100704001373F30F13071700338EE000A30F6EFE6D +:10071400E3000FF4E30E97F213030000930F0F00AE +:100724006FF05FFA330323011373F30F6FF09FFD30 +:10073400130310046FF09FF6130101F7232C8106B5 +:1007440023206107232E71052328A1052326B10543 +:10075400232E1106232A9106232821072326310755 +:100764002324410723225107232C8105232A9105A1 +:10077400232611093363F700232CA100232EB10093 +:10078400130B0600938B0600130D08001384080056 +:10079400832E0109832DC1096316030893F60D40C6 +:1007A40093FDFDFE6380060893090000130A01020D +:1007B400832781098325C101032581012322F100B7 +:1007C400832741092324B101930804002320F10065 +:1007D40013080D009387090013070A0093860B0082 +:1007E40013060B00EFF0DFA68320C1070324810763 +:1007F40083244107032901078329C106032A8106AB +:10080400832A4106032B0106832BC105032C810592 +:10081400832C4105032D0105832DC1041301010916 +:100824006780000013F60D0293061006631E060E81 +:100834009384070093D5F40193070700130E000077 +:1008440093090000130A01029300F0011309100038 +:100854009308F0FF930A9000938C66FF130C000238 +:100864001307E003130F000013030000939F140009 +:100874003386E04093D2F50193161E0033D5E7008A +:100884003396CF00130807FEB3E6D2009395150004 +:100894003365A6006344080033D50441137515007D +:1008A400B365B500138E060063C8D6033316E9009A +:1008B40033858540B3B2A500B383D6411358F641BE +:1008C4006394DE0063EA850093050500338E53408C +:1008D400336FCF00336303011307F7FFE31A17F9EC +:1008E40093F5F50F63ECBA029385050393F7F50FBF +:1008F4009389190033073A01A30FF7FEB3676F001A +:10090400E38807EAE38689EB9355F301130E0000AD +:1009140093070F00930403006FF09FF4B3859501D0 +:1009240093F7F50F6FF0DFFC930610046FF05FF0A0 +:10093400130101FA23282105232631052324410527 +:10094400232C81032326B103232E1104232C810499 +:10095400232A91042322510523206105232E7103A8 +:10096400232A91032328A103938905001309060070 +:10097400138C0600930D0700170A0000130A4A8D12 +:1009840063840500130A050003450C00130D0000E1 +:1009940063040516B70701009387F7FF930400016A +:1009A400971C0000938C0CBF130B9000232AF100BA +:1009B4006F00000213060D009306090093850900D9 +:1009C400130D1D00E7000A0003450C006306051221 +:1009D40093075002130C1C00E31EF5FC03450C00A6 +:1009E40013071C0093060000930705FE93F7F70F07 +:1009F4001306070063ECF40293972700B38797016B +:100A040083A70700B38797016780070093E6160062 +:100A1400130C070003450C0013071C001306070002 +:100A2400930705FE93F7F70FE3F8F4FC930705FD2E +:100A340093F7F70F6370FB129307A0026308F51C8A +:100A44009307E00213060C00930B0000130C07003D +:100A5400930F00006304F5149307A0066306F516CC +:100A640063FEA7069307C006630AF53C9307A00735 +:100A74006318F5000345160093E60610130C1C00DA +:100A84009307B5FD93F7F70F13073005E364F7F207 +:100A940017170000130747B493972700B387E7009D +:100AA40083A70700B387E7006780070093E6260063 +:100AB400130C07006FF01FF693E64600130C0700B3 +:100AC4006FF05FF593E60601130C07006FF09FF4D7 +:100AD40093E68600130C07006FF0DFF3930780069C +:100AE400E310F5FA03451600630EF53893E606089D +:100AF400130C1C006FF0DFF813060D0063642D0166 +:100B04001306F9FF930609009385090013050000F5 +:100B1400E7000A008320C1050324810513050D00A5 +:100B240083244105032901058329C104032A81047F +:100B3400832A4104032B0104832BC103032C810367 +:100B4400832C4103032D0103832DC10213010106EC +:100B540067800000930B00006F00C000130C0700B7 +:100B64001307170013942B00330474011314140097 +:100B74003304A4000345070013060700930B04FD88 +:100B8400930705FD93F7F70FE37AFBFC130C2C0096 +:100B94009307E002930F0000E310F5EC0345160001 +:100BA40093E60640930705FD93F7F70F6378FB027E +:100BB4009307A0026300F52A9307A00613060C000E +:100BC400130C1C00E31EF5E893E60620034516000B +:100BD400130C1C006FF0DFEA130C0600939A2F002D +:100BE400B38AFA01939A1A00B38AAA0003451C0037 +:100BF40013061C00938F0AFD930705FD93F7F70F67 +:100C0400E37CFBFC130C2C006FF01FE583AB0D00A1 +:100C1400938D4D0063CC0B2003451C00130C2C005A +:100C24006FF01FF703A40D0093874D00232CF100F0 +:100C34000345040063920F24930DE0FF630A0552F9 +:100C440093871D002328F1003306F4009307040062 +:100C54006F008000638CC7009387170003C70700E9 +:100C6400E31A07FEB38787402328F10093FA06406E +:100C740063880A008327010163F4FF002328F1013C +:100C840093F72600232EF100638407366308052CAE +:100C9400638C0A28B38AAF0113060D006386CA0267 +:100CA4009306090093850900930D1600E7000A00D6 +:100CB400B387AD41B307F40003C50700630C052CEB +:100CC40013860D00E39ECAFC8327C101138D0A001D +:100CD40063960728832D81016FF01FCF03A70D00B2 +:100CE40013E41602930780002320F10013060D007D +:100CF4002322810093880F0013080001930700004A +:100D0400930609009385090013050A00EFF05F912B +:100D1400938D4D00130D05006FF01FCB93874D008D +:100D2400930A1D0093F626002328F10013840A0079 +:100D34006386062603C50D0013060D0093060900FD +:100D440093850900E7000A0013071000338DAB01F7 +:100D54006378773B93071400130604009306090095 +:100D6400138407009385090013050002E7000A00B5 +:100D7400E3128DFE832D01016FF01FC593078007D9 +:100D84006304F53C930780056306F5109307F006AA +:100D94006302F53293072006630AF51013079006E1 +:100DA40013F6F6FE93F706401308A0006314E5104B +:100DB40013F40620638A07101376E6FF9307900660 +:100DC400137406206302F51093074006630EF50EB4 +:100DD4006318042E9377061013844D00639A073426 +:100DE40093770604639A07309377060803A70D00E8 +:100DF40063860700832741013377F7002322C1006C +:100E04002320710193880F00930700006F00C00F27 +:100E140013060D009306090093850900130550027B +:100E2400130D1D00E7000A006FF01FBA93E62600B9 +:100E3400B30B704103451C006FF05FDE03451600E1 +:100E4400E31CF5C293E6063003452600130C360076 +:100E54006FF01FC383AF0D0003452600130C36004B +:100E640093C7FFFF93D7F741B3FFFF00938D4D0066 +:100E7400130626006FF05FBE630C052E938DFFFFF3 +:100E84006FF01FDC93E6060C03452600130C3600B6 +:100E94006FF01FBF13F636FF93F706401366060282 +:100EA40063840720130800016FF01FF1130820006A +:100EB400138606001307400693770640631AE52C51 +:100EC40013740620E39A07EE631E04169377061044 +:100ED40013844D00639C07229377060463980720CC +:100EE40093770608638C072683970D0093D6F74102 +:100EF40033C7F6003307D7402322C10023207101F2 +:100F040093880F0093D7F70113060D009306090089 +:100F14009385090013050A00EFF08FF0130D050007 +:100F2400930D04006FF05FAA13060D0093060900E9 +:100F340093850900930A1600E7000A00B387AA41C3 +:100F4400B307F40003C5070013860A00E31005FE87 +:100F5400138D0A008327C101E38E07D6832701017D +:100F640013060D00E3F877D73384AB01330DF44057 +:100F74009306090093850900130500021304160063 +:100F8400E7000A0013060400E314A4FF832D810183 +:100F94006FF09FA3138D0D006FF0DFFB130710009C +:100FA4006372771F1304FDFF330474016F00800024 +:100FB400938A1A0013060D0093060900938509000D +:100FC40013050002138D0A00E7000A00E3928AFE6B +:100FD400138D1A0003C50D009306090013060400BF +:100FE40093850900E7000A00832D01016FF0DF9D5E +:100FF400032701019307170063707719B387AB01C7 +:10100400B38DE7402328F10193071D0013060D005B +:10101400930609009385090013050002138D070048 +:10102400E7000A00832F0101E31EBDFD0345040010 +:1010340093871B002328F100E31C05C4832D810141 +:101044006FF09F98938D7D0093FD8DFF03A54D0058 +:1010540083A70D00930808009356F541B3C7F60023 +:101064003387D740B3C5A600B3B7E700B386D540EE +:101074002326C100232471012322F101232001002E +:101084001358F501B387F64013060D0093060900C3 +:101094009385090013050A00EFF00FEA938D8D0084 +:1010A400130D05006FF05F9213F40620130800017E +:1010B4006FF01FD213088000138606006FF09FDFC5 +:1010C400938D7D0093FD8DFF03A70D0083A74D0035 +:1010D400930808002326C100232471012322F1016F +:1010E40023200100130800006FF01FFA83C70D00CE +:1010F400138707006FF05FE003C70D006FF01FD088 +:10110400138D0A00832D01016FF01F8C83A70D003E +:1011140093880F002322C10013D7F741B346F70089 +:101124002320710193D7F7013387E6406FF0DFDDA9 +:1011340003A70D0093880F002322C100232071010F +:10114400930700006FF05FDC93F70640130800017B +:1011540013F636FFE38407C66FF01FC683A70D009E +:1011640093D6F74133C7F6003307D7406FF0DFD883 +:10117400232801006FF09FAF2328F100E31A05B084 +:101184006FF0DFEB13040D00138D0A006FF09FE482 +:10119400930606006FF0DFFB631405006780000010 +:1011A4006F00801A6308050003A3050083A54500AA +:1011B4006700030067800000130101FC1303410270 +:1011C4002322B1022324C1022326D1022328E102CF +:1011D4009306050093058100130703001306F0FF2F +:1011E40017050000130585FB232E1100232AF102A5 +:1011F400232C0103232E110323266100EFF04FF368 +:101204008320C1011301010467800000130101FC64 +:10121400130381022324C1022326D1022328E102DD +:101224009386050013070300930505001306F0FFDA +:1012340017F5FFFF1305C500232E1100232AF10221 +:10124400232C0103232E110323266100EFF04FEE1C +:101254008320C1011301010467800000130101FC14 +:101264001303C1022326D1022328E10293060600B8 +:1012740013070300138605009305050017F5FFFF08 +:10128400130505FC232E1100232AF102232C01034C +:10129400232E110323266100EFF08FE98320C1017F +:1012A4001301010467800000130101FE1387050088 +:1012B400930605009305C1001306F0FF170500000F +:1012C4001305C5ED232E1100EFF08FE68320C10135 +:1012D40013010102678000001387060093060600CD +:1012E400138605009305050017F5FFFF130545F563 +:1012F4006FF00FE4130101FC1303C1022326D10292 +:101304002328E1022324A1002326B100930606002A +:1013140093058100130703001306F0FF170500006F +:10132400130585E8232E1100232AF102232C01033F +:10133400232E110323226100EFF08FDF8320C101EC +:101344001301010467800000130101FEA307A1003B +:10135400930510001305F100232E1100EF00C001C6 +:101364008320C10113010102678000001385050079 +:10137400930506006F004000638605023306B5003E +:10138400370701F0834605008327470093D70701F9 +:1013940093F7F70FE38A07FE2320D7001305150000 +:1013A400E312A6FE678000008346050063840602FC +:1013B400370701F08327470093D7070193F7F70F07 +:1013C400E38A07FE2320D700130515008346050092 +:1013D400E39206FE67800000F32500B8732500B091 +:1013E400732600B8E39AC5FE678000004111814569 +:1013F40022C406C62A841928970700009387C73594 +:1014040088435C5D91C3829722854922797197074D +:1014140000009387673462C403AC07004ECE52CCFD +:1014240056CA5AC806D622D426D24AD05EC6AA8A3A +:101434002E8B054AFD5903298C1463040902832465 +:1014440049001384F4FF634E04008A04CA946306BB +:101454000B0283A74410638267037D14F114E3181D +:1014640034FFB250225492540259F249624AD24A89 +:10147400424BB24B224C4561828083274900D440C1 +:10148400FD176380870423A20400E1DA8327891807 +:1014940033178A00832B4900F98F99EB82968327AF +:1014A4004900E39A77F983278C14E38827FB61B713 +:1014B4008327C91883A544087D8F19E7568582962A +:1014C400F9BF23228900D1B72E858296C9BF411165 +:1014D40022C4970700009387A72817040000130469 +:1014E40024281D8C06C626C2098411C8931424001E +:1014F400F114BE949C407D14F114829765FCB240B3 +:101504002244924441018280AA85814601460145D4 +:1015140009A09707000093872724984383278714FB +:10152400A1C3D8437D48634DE804131827001DC1A7 +:10153400338307012324C30883A887180546331679 +:10154400E600B3E8C80023A417192324D31089465E +:10155400630DD5000507D8C3C2978CC701458280A7 +:101564009307C7142324F7146DBF83A6C718050770 +:10157400D8C3558E23A6C718C2978CC7014582804D +:101584007D55828067800000678000006F00000046 +:1015940040F5FFFF9CF4FFFF9CF4FFFF34F5FFFFD1 +:1015A4009CF4FFFF9CF4FFFF9CF4FFFF9CF4FFFFFF +:1015B4009CF4FFFF9CF4FFFF9CF4FFFF28F5FFFF62 +:1015C4009CF4FFFF1CF5FFFF9CF4FFFF9CF4FFFF5E +:1015D4007CF4FFFF3CF8FFFFE0F3FFFFE0F3FFFFC5 +:1015E400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFFB3 +:1015F400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFFA3 +:10160400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF92 +:10161400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF82 +:10162400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF72 +:10163400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF62 +:10164400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF52 +:10165400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF42 +:10166400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF32 +:10167400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF22 +:10168400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF12 +:10169400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF02 +:1016A400A8F7FFFFE0F3FFFFE0F3FFFFE0F3FFFF26 +:1016B400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFFE2 +:1016C400E0F3FFFFE0F3FFFFA8F7FFFF48F7FFFF9A +:1016D400A8F7FFFFE0F3FFFFE0F3FFFFE0F3FFFFF6 +:1016E400E0F3FFFFA8F7FFFFE0F3FFFFE0F3FFFFE6 +:1016F400E0F3FFFFE0F3FFFFE0F3FFFFA8F7FFFFD6 +:1017040008F7FFFFE0F3FFFFE0F3FFFF50F6FFFFF2 +:10171400E0F3FFFFA8F7FFFFE0F3FFFFE0F3FFFFB5 +:10172400A8F7FFFF48454C4C4F20574F524C440AF2 +:1017340000000000537461746520696E203A20250E +:10174400690A00005374617465206F75743A20252A +:08175400690A00000000048096 +:04175C0028020080DF +:1017600000000000EC02048054030480BC030480E9 +:101770000000000000000000000000000000000069 +:101780000000000000000000000000000000000059 +:101790000000000000000000000000000000000049 +:1017A0000000000000000000000000000000000039 +:1017B0000000000000000000000000000000000029 +:1017C0000000000000000000000000000000000019 +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000000000000000000F9 +:1017F00000000000000000000000000000000000E9 +:1018000000000000000000000100000000000000D7 +:101810000E33CDAB34126DE6ECDE05000B0000009C +:1018200000000000000000000000000000000000B8 +:1018300000000000000000000000000000000000A8 +:101840000000000000000000000000000000000098 +:101850000000000000000000000000000000000088 +:101860000000000000000000000000000000000078 +:101870000000000000000000000000000000000068 +:101880000000000000000000000000000000000058 +:101890000000000000000000000000000000000048 +:1018A0000000000000000000000000000000000038 +:1018B0000000000000000000000000000000000028 +:1018C0000000000000000000000000000000000018 +:1018D0000000000000000000000000000000000008 +:1018E00000000000000000000000000000000000F8 +:1018F00000000000000000000000000000000000E8 +:1019000000000000000000000000000000000000D7 +:1019100000000000000000000000000000000000C7 +:1019200000000000000000000000000000000000B7 +:1019300000000000000000000000000000000000A7 +:101940000000000000000000000000000000000097 +:101950000000000000000000000000000000000087 +:101960000000000000000000000000000000000077 +:101970000000000000000000000000000000000067 +:101980000000000000000000000000000000000057 +:101990000000000000000000000000000000000047 +:1019A0000000000000000000000000000000000037 +:1019B0000000000000000000000000000000000027 +:1019C0000000000000000000000000000000000017 +:1019D0000000000000000000000000000000000007 +:1019E00000000000000000000000000000000000F7 +:1019F00000000000000000000000000000000000E7 +:101A000000000000000000000000000000000000D6 +:101A100000000000000000000000000000000000C6 +:101A200000000000000000000000000000000000B6 +:101A300000000000000000000000000000000000A6 +:101A40000000000000000000000000000000000096 +:101A50000000000000000000000000000000000086 +:101A60000000000000000000000000000000000076 +:101A70000000000000000000000000000000000066 +:101A80000000000000000000000000000000000056 +:101A90000000000000000000000000000000000046 +:101AA0000000000000000000000000000000000036 +:101AB0000000000000000000000000000000000026 +:101AC0000000000000000000000000000000000016 +:101AD0000000000000000000000000000000000006 +:101AE00000000000000000000000000000000000F6 +:101AF00000000000000000000000000000000000E6 +:101B000000000000000000000000000000000000D5 +:101B100000000000000000000000000000000000C5 +:101B200000000000000000000000000000000000B5 +:101B300000000000000000000000000000000000A5 +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:081B800000000000000000005D +:040000058000000077 +:00000001FF diff --git a/c_project/main.o b/c_project/main.o new file mode 100644 index 0000000..5ba535e Binary files /dev/null and b/c_project/main.o differ diff --git a/c_project/memcmp.c b/c_project/memcmp.c new file mode 100644 index 0000000..2348afe --- /dev/null +++ b/c_project/memcmp.c @@ -0,0 +1,16 @@ +/* Public domain. */ +#include + +int +memcmp (const void *str1, const void *str2, size_t count) +{ + const unsigned char *s1 = str1; + const unsigned char *s2 = str2; + + while (count-- > 0) + { + if (*s1++ != *s2++) + return s1[-1] < s2[-1] ? -1 : 1; + } + return 0; +} diff --git a/c_project/memcmp.o b/c_project/memcmp.o new file mode 100644 index 0000000..666c6aa Binary files /dev/null and b/c_project/memcmp.o differ diff --git a/c_project/memcpy.c b/c_project/memcpy.c new file mode 100644 index 0000000..39786ba --- /dev/null +++ b/c_project/memcpy.c @@ -0,0 +1,61 @@ +/* Public domain. */ +#include + +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include +#include + +typedef long word; +#define lsize sizeof(word) +#define lmask (lsize - 1) +void *memcpy(void *dest, const void *src, size_t count) +{ + char *d = (char *)dest; + const char *s = (const char *)src; + int len; + if(count == 0 || dest == src) + return dest; + if(((long)d | (long)s) & lmask) { + // src and/or dest do not align on word boundary + if((((long)d ^ (long)s) & lmask) || (count < lsize)) + len = count; // copy the rest of the buffer with the byte mover + else + len = lsize - ((long)d & lmask); // move the ptrs up to a word boundary + count -= len; + for(; len > 0; len--) + *d++ = *s++; + } + for(len = count / lsize; len > 0; len--) { + *(word *)d = *(word *)s; + d += lsize; + s += lsize; + } + for(len = count & lmask; len > 0; len--) + *d++ = *s++; + return dest; +} diff --git a/c_project/memcpy.o b/c_project/memcpy.o new file mode 100644 index 0000000..1611f63 Binary files /dev/null and b/c_project/memcpy.o differ diff --git a/c_project/memset.c b/c_project/memset.c new file mode 100644 index 0000000..86efb6d --- /dev/null +++ b/c_project/memset.c @@ -0,0 +1,64 @@ +/* +** Copyright 2005, Michael Noisternig. All rights reserved. +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ +/* + * Copyright (c) 2008 Travis Geiselbrecht + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include +#include + +// void * +// memset(void *s, int c, size_t count) +// { +// char *xs = (char *) s; +// // size_t len = (-(size_t)s) & (sizeof(size_t)-1); +// // int cc = c & 0xff; +// // if ( count > len ) { +// // count -= len; +// // cc |= cc << 8; +// // cc |= cc << 16; +// // // write to non-aligned memory byte-wise +// // for ( ; len > 0; len-- ) +// // *xs++ = c; +// // // write to aligned memory dword-wise +// // for ( len = count/sizeof(size_t); len > 0; len-- ) { +// // *((size_t *)xs) = cc; +// // xs += sizeof(size_t); +// // } +// // count &= sizeof(size_t)-1; +// // } +// // write remaining bytes +// for ( ; count > 0; count-- ) +// *xs++ = (char) c; +// return s; +// } + +void * +memset (void *dest, int val, size_t len) +{ + unsigned char *ptr = dest; + while (len-- > 0) + *ptr++ = (unsigned char) val; + return dest; +} \ No newline at end of file diff --git a/c_project/memset.o b/c_project/memset.o new file mode 100644 index 0000000..3ec3a82 Binary files /dev/null and b/c_project/memset.o differ diff --git a/c_project/nonvolatile.ld b/c_project/nonvolatile.ld new file mode 100644 index 0000000..0809fad --- /dev/null +++ b/c_project/nonvolatile.ld @@ -0,0 +1,141 @@ +/* SECTIONS for non-volatile chip configuration, i.e. chips with flash */ + +SECTIONS +{ + .init : + { + KEEP (*(SORT_NONE(.init))) + } >rom + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >rom + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >rom + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + .rodata : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >rom + + . = ALIGN(4); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >rom + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >rom + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >rom + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >rom + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >rom + + .lalign : + { + . = ALIGN(4); + } >rom + + .dalign : + { + . = ALIGN(4); + } >ram AT>rom + + .data : + { + PROVIDE( _data = . ); + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + } >ram AT>rom + + PROVIDE( _data_lma = LOADADDR(.data) ); + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram + + . = ALIGN(8); + PROVIDE( _end = . ); + PROVIDE( end = . ); +} + +PROVIDE(_sp = ORIGIN(ram) + LENGTH(ram)); +PROVIDE(_heap_end = ORIGIN(ram) + LENGTH(ram)); diff --git a/c_project/pqvexriscvsim.ld b/c_project/pqvexriscvsim.ld new file mode 100644 index 0000000..1d34047 --- /dev/null +++ b/c_project/pqvexriscvsim.ld @@ -0,0 +1,14 @@ +OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") +OUTPUT_ARCH(riscv) + +ENTRY( _start ) + +__ram_size = 384K; + +MEMORY +{ + rom (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 256K + ram (wxa!ri) : ORIGIN = 0x80040000, LENGTH = 128K +} + +INCLUDE nonvolatile.ld diff --git a/c_project/printf.c b/c_project/printf.c new file mode 100644 index 0000000..7bf7d74 --- /dev/null +++ b/c_project/printf.c @@ -0,0 +1,987 @@ +/////////////////////////////////////////////////////////////////////////////// +// \author (c) Marco Paland (info@paland.com) +// 2014-2019, PALANDesign Hannover, Germany +// +// \license The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on +// embedded systems with a very limited resources. These routines are thread +// safe and reentrant! +// Use this instead of the bloated standard/newlib printf cause these use +// malloc for printf (and may not be thread safe). +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include + +#include "printf.h" + + +// define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H ...) to include the +// printf_config.h header file +// default: undefined +#ifdef PRINTF_INCLUDE_CONFIG_H +#include "printf_config.h" +#endif + + +// 'ntoa' conversion buffer size, this must be big enough to hold one converted +// numeric number including padded zeros (dynamically created on stack) +// default: 32 byte +#ifndef PRINTF_NTOA_BUFFER_SIZE +#define PRINTF_NTOA_BUFFER_SIZE 32U +#endif + +// 'ftoa' conversion buffer size, this must be big enough to hold one converted +// float number including padded zeros (dynamically created on stack) +// default: 32 byte +#ifndef PRINTF_FTOA_BUFFER_SIZE +#define PRINTF_FTOA_BUFFER_SIZE 32U +#endif + +// support for the floating point type (%f) +// default: activated +// #ifndef PRINTF_DISABLE_SUPPORT_FLOAT +// #define PRINTF_SUPPORT_FLOAT +// #endif + +// support for exponential floating point notation (%e/%g) +// default: activated +// #ifndef PRINTF_DISABLE_SUPPORT_EXPONENTIAL +// #define PRINTF_SUPPORT_EXPONENTIAL +// #endif + +// define the default floating point precision +// default: 6 digits +// #ifndef PRINTF_DEFAULT_FLOAT_PRECISION +// #define PRINTF_DEFAULT_FLOAT_PRECISION 6U +// #endif + +// define the largest float suitable to print with %f +// default: 1e9 +// #ifndef PRINTF_MAX_FLOAT +// #define PRINTF_MAX_FLOAT 1e9 +// #endif + +// support for the long long types (%llu or %p) +// default: activated +#ifndef PRINTF_DISABLE_SUPPORT_LONG_LONG +#define PRINTF_SUPPORT_LONG_LONG +#endif + +// support for the ptrdiff_t type (%t) +// ptrdiff_t is normally defined in as long or long long type +// default: activated +// #ifndef PRINTF_DISABLE_SUPPORT_PTRDIFF_T +// #define PRINTF_SUPPORT_PTRDIFF_T +// #endif + +/////////////////////////////////////////////////////////////////////////////// + +// internal flag definitions +#define FLAGS_ZEROPAD (1U << 0U) +#define FLAGS_LEFT (1U << 1U) +#define FLAGS_PLUS (1U << 2U) +#define FLAGS_SPACE (1U << 3U) +#define FLAGS_HASH (1U << 4U) +#define FLAGS_UPPERCASE (1U << 5U) +#define FLAGS_CHAR (1U << 6U) +#define FLAGS_SHORT (1U << 7U) +#define FLAGS_LONG (1U << 8U) +#define FLAGS_LONG_LONG (1U << 9U) +#define FLAGS_PRECISION (1U << 10U) +#define FLAGS_ADAPT_EXP (1U << 11U) + + +// import float.h for DBL_MAX +// #if defined(PRINTF_SUPPORT_FLOAT) +// #include +// #endif + + +// output function type +typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen); + + +// wrapper (used as buffer) for output function type +typedef struct { + void (*fct)(char character, void* arg); + void* arg; +} out_fct_wrap_type; + + +// Sometimes div modulo is not available, we implement one with shift/and/or +static int divmod(int* Qptr, int* Rptr, const int N, const int D) { + if (D == 0) { + return -1; + } + + int Q = 0; + int R = 0; + for (int i = 8*sizeof(int) - 1; i >= 0; i--) { + R <<= 1; + R |= (N >> i) & 0x1; + if (R >= D) { + R -= D; + Q |= 1 << i; + } + } + *Qptr = Q; + *Rptr = R; + return 0; +} + +// Sometimes div modulo is not available, we implement one with shift/and/or +static int divmod_long_long(long long* Qptr, long long* Rptr, const long long N, const int D) { + if (D == 0) { + return -1; + } + + long long Q = 0; + long long R = 0; + for (long long i = 8*sizeof(long long) - 1; i >= 0; i--) { + R <<= 1; + R |= (N >> i) & 0x1; + if (R >= D) { + R -= D; + Q |= 1 << i; + } + } + *Qptr = Q; + *Rptr = R; + return 0; +} + + +// internal buffer output +static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen) +{ + if (idx < maxlen) { + ((char*)buffer)[idx] = character; + } +} + + +// internal null output +static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen) +{ + (void)character; (void)buffer; (void)idx; (void)maxlen; +} + + +// internal _putchar wrapper +static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen) +{ + (void)buffer; (void)idx; (void)maxlen; + if (character) { + _putchar(character); + } +} + + +// internal output function wrapper +static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen) +{ + (void)idx; (void)maxlen; + if (character) { + // buffer is the output fct pointer + ((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg); + } +} + + +// internal secure strlen +// \return The length of the string (excluding the terminating 0) limited by 'maxsize' +static inline unsigned int _strnlen_s(const char* str, size_t maxsize) +{ + const char* s; + for (s = str; *s && maxsize--; ++s); + return (unsigned int)(s - str); +} + + +// internal test if char is a digit (0-9) +// \return true if char is a digit +static inline bool _is_digit(char ch) +{ + return (ch >= '0') && (ch <= '9'); +} + + +// internal ASCII string to unsigned int conversion +static unsigned int _atoi(const char** str) +{ + unsigned int i = 0U; + while (_is_digit(**str)) { + i = i * 10U + (unsigned int)(*((*str)++) - '0'); + } + return i; +} + + +// output the specified string in reverse, taking care of any zero-padding +static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags) +{ + const size_t start_idx = idx; + + // pad spaces up to given width + if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { + for (size_t i = len; i < width; i++) { + out(' ', buffer, idx++, maxlen); + } + } + + // reverse string + while (len) { + out(buf[--len], buffer, idx++, maxlen); + } + + // append pad spaces up to given width + if (flags & FLAGS_LEFT) { + while (idx - start_idx < width) { + out(' ', buffer, idx++, maxlen); + } + } + + return idx; +} + + +// internal itoa format +static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) +{ + // pad leading zeros + if (!(flags & FLAGS_LEFT)) { + if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { + width--; + } + while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } + while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } + } + + // handle hash + if (flags & FLAGS_HASH) { + if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) { + len--; + if (len && (base == 16U)) { + len--; + } + } + if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'x'; + } + else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'X'; + } + else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'b'; + } + if (len < PRINTF_NTOA_BUFFER_SIZE) { + buf[len++] = '0'; + } + } + + if (len < PRINTF_NTOA_BUFFER_SIZE) { + if (negative) { + buf[len++] = '-'; + } + else if (flags & FLAGS_PLUS) { + buf[len++] = '+'; // ignore the space if the '+' exists + } + else if (flags & FLAGS_SPACE) { + buf[len++] = ' '; + } + } + + return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); +} + + +// internal itoa for 'long' type +static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[PRINTF_NTOA_BUFFER_SIZE]; + size_t len = 0U; + int q, r; + + // no hash for 0 values + if (!value) { + flags &= ~FLAGS_HASH; + } + + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) { + q = 0, r = 0; + len = 0; + do { + divmod(&q, &r, value, base); + const char digit = (char)(r); + // buf[idx2++] = '0' + digit; + buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value = q; + } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + // while (idx2 > 0) { + // _putchar(buf[--idx2]); + // written++; + // } + // idx++; + + + + // do { + // const char digit = (char)(value % base); + // buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + // value /= base; + // } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } + + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); +} + + +// // internal itoa for 'long long' type +#if defined(PRINTF_SUPPORT_LONG_LONG) +static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[PRINTF_NTOA_BUFFER_SIZE]; + size_t len = 0U; + long long q, r; + + // no hash for 0 values + if (!value) { + flags &= ~FLAGS_HASH; + } + + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) { + q = 0, r = 0; + len = 0; + do { + divmod_long_long(&q, &r, value, base); + const char digit = (char)(r); + // buf[idx2++] = '0' + digit; + buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value = q; + } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + + + // do { + // const char digit = (char)(value % base); + // buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + // value /= base; + // } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } + + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); +} +#endif // PRINTF_SUPPORT_LONG_LONG + + +// #if defined(PRINTF_SUPPORT_FLOAT) +// +// #if defined(PRINTF_SUPPORT_EXPONENTIAL) +// // forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT +// static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags); +// #endif +// +// +// // internal ftoa for fixed decimal floating point +// static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) +// { +// char buf[PRINTF_FTOA_BUFFER_SIZE]; +// size_t len = 0U; +// double diff = 0.0; +// +// // powers of 10 +// static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; +// +// // test for special values +// if (value != value) +// return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags); +// if (value < -DBL_MAX) +// return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags); +// if (value > DBL_MAX) +// return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); +// +// // test for very large values +// // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad +// if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) { +// #if defined(PRINTF_SUPPORT_EXPONENTIAL) +// return _etoa(out, buffer, idx, maxlen, value, prec, width, flags); +// #else +// return 0U; +// #endif +// } +// +// // test for negative +// bool negative = false; +// if (value < 0) { +// negative = true; +// value = 0 - value; +// } +// +// // set default precision, if not set explicitly +// if (!(flags & FLAGS_PRECISION)) { +// prec = PRINTF_DEFAULT_FLOAT_PRECISION; +// } +// // limit precision to 9, cause a prec >= 10 can lead to overflow errors +// while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) { +// buf[len++] = '0'; +// prec--; +// } +// +// int whole = (int)value; +// double tmp = (value - whole) * pow10[prec]; +// unsigned long frac = (unsigned long)tmp; +// diff = tmp - frac; +// +// if (diff > 0.5) { +// ++frac; +// // handle rollover, e.g. case 0.99 with prec 1 is 1.0 +// if (frac >= pow10[prec]) { +// frac = 0; +// ++whole; +// } +// } +// else if (diff < 0.5) { +// } +// else if ((frac == 0U) || (frac & 1U)) { +// // if halfway, round up if odd OR if last digit is 0 +// ++frac; +// } +// +// if (prec == 0U) { +// diff = value - (double)whole; +// if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) { +// // exactly 0.5 and ODD, then round up +// // 1.5 -> 2, but 2.5 -> 2 +// ++whole; +// } +// } +// else { +// unsigned int count = prec; +// // now do fractional part, as an unsigned number +// while (len < PRINTF_FTOA_BUFFER_SIZE) { +// --count; +// buf[len++] = (char)(48U + (frac % 10U)); +// if (!(frac /= 10U)) { +// break; +// } +// } +// // add extra 0s +// while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) { +// buf[len++] = '0'; +// } +// if (len < PRINTF_FTOA_BUFFER_SIZE) { +// // add decimal +// buf[len++] = '.'; +// } +// } +// +// // do whole part, number is reversed +// while (len < PRINTF_FTOA_BUFFER_SIZE) { +// buf[len++] = (char)(48 + (whole % 10)); +// if (!(whole /= 10)) { +// break; +// } +// } +// +// // pad leading zeros +// if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) { +// if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { +// width--; +// } +// while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) { +// buf[len++] = '0'; +// } +// } +// +// if (len < PRINTF_FTOA_BUFFER_SIZE) { +// if (negative) { +// buf[len++] = '-'; +// } +// else if (flags & FLAGS_PLUS) { +// buf[len++] = '+'; // ignore the space if the '+' exists +// } +// else if (flags & FLAGS_SPACE) { +// buf[len++] = ' '; +// } +// } +// +// return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); +// } +// +// +// #if defined(PRINTF_SUPPORT_EXPONENTIAL) +// // internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse +// static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) +// { +// // check for NaN and special values +// if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) { +// return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags); +// } +// +// // determine the sign +// const bool negative = value < 0; +// if (negative) { +// value = -value; +// } +// +// // default precision +// if (!(flags & FLAGS_PRECISION)) { +// prec = PRINTF_DEFAULT_FLOAT_PRECISION; +// } +// +// // determine the decimal exponent +// // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c) +// union { +// uint64_t U; +// double F; +// } conv; +// +// conv.F = value; +// int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2 +// conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2) +// // now approximate log10 from the log2 integer part and an expansion of ln around 1.5 +// int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168); +// // now we want to compute 10^expval but we want to be sure it won't overflow +// exp2 = (int)(expval * 3.321928094887362 + 0.5); +// const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453; +// const double z2 = z * z; +// conv.U = (uint64_t)(exp2 + 1023) << 52U; +// // compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex +// conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); +// // correct for rounding errors +// if (value < conv.F) { +// expval--; +// conv.F /= 10; +// } +// +// // the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters +// unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U; +// +// // in "%g" mode, "prec" is the number of *significant figures* not decimals +// if (flags & FLAGS_ADAPT_EXP) { +// // do we want to fall-back to "%f" mode? +// if ((value >= 1e-4) && (value < 1e6)) { +// if ((int)prec > expval) { +// prec = (unsigned)((int)prec - expval - 1); +// } +// else { +// prec = 0; +// } +// flags |= FLAGS_PRECISION; // make sure _ftoa respects precision +// // no characters in exponent +// minwidth = 0U; +// expval = 0; +// } +// else { +// // we use one sigfig for the whole part +// if ((prec > 0) && (flags & FLAGS_PRECISION)) { +// --prec; +// } +// } +// } +// +// // will everything fit? +// unsigned int fwidth = width; +// if (width > minwidth) { +// // we didn't fall-back so subtract the characters required for the exponent +// fwidth -= minwidth; +// } else { +// // not enough characters, so go back to default sizing +// fwidth = 0U; +// } +// if ((flags & FLAGS_LEFT) && minwidth) { +// // if we're padding on the right, DON'T pad the floating part +// fwidth = 0U; +// } +// +// // rescale the float value +// if (expval) { +// value /= conv.F; +// } +// +// // output the floating part +// const size_t start_idx = idx; +// idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP); +// +// // output the exponent part +// if (minwidth) { +// // output the exponential symbol +// out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); +// // output the exponent value +// idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth-1, FLAGS_ZEROPAD | FLAGS_PLUS); +// // might need to right-pad spaces +// if (flags & FLAGS_LEFT) { +// while (idx - start_idx < width) out(' ', buffer, idx++, maxlen); +// } +// } +// return idx; +// } +// #endif // PRINTF_SUPPORT_EXPONENTIAL +// #endif // PRINTF_SUPPORT_FLOAT + + +// internal vsnprintf +static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va) +{ + unsigned int flags, width, precision, n; + size_t idx = 0U; + + if (!buffer) { + // use null output function + out = _out_null; + } + + while (*format) + { + // format specifier? %[flags][width][.precision][length] + if (*format != '%') { + // no + out(*format, buffer, idx++, maxlen); + format++; + continue; + } + else { + // yes, evaluate it + format++; + } + + // evaluate flags + flags = 0U; + do { + switch (*format) { + case '0': flags |= FLAGS_ZEROPAD; format++; n = 1U; break; + case '-': flags |= FLAGS_LEFT; format++; n = 1U; break; + case '+': flags |= FLAGS_PLUS; format++; n = 1U; break; + case ' ': flags |= FLAGS_SPACE; format++; n = 1U; break; + case '#': flags |= FLAGS_HASH; format++; n = 1U; break; + default : n = 0U; break; + } + } while (n); + + // evaluate width field + width = 0U; + if (_is_digit(*format)) { + width = _atoi(&format); + } + else if (*format == '*') { + const int w = va_arg(va, int); + if (w < 0) { + flags |= FLAGS_LEFT; // reverse padding + width = (unsigned int)-w; + } + else { + width = (unsigned int)w; + } + format++; + } + + // evaluate precision field + precision = 0U; + if (*format == '.') { + flags |= FLAGS_PRECISION; + format++; + if (_is_digit(*format)) { + precision = _atoi(&format); + } + else if (*format == '*') { + const int prec = (int)va_arg(va, int); + precision = prec > 0 ? (unsigned int)prec : 0U; + format++; + } + } + + // evaluate length field + switch (*format) { + case 'l' : + flags |= FLAGS_LONG; + format++; + if (*format == 'l') { + flags |= FLAGS_LONG_LONG; + format++; + } + break; + case 'h' : + flags |= FLAGS_SHORT; + format++; + if (*format == 'h') { + flags |= FLAGS_CHAR; + format++; + } + break; +// #if defined(PRINTF_SUPPORT_PTRDIFF_T) +// case 't' : +// flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); +// format++; +// break; +// #endif + case 'j' : + flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; + case 'z' : + flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; + default : + break; + } + + // evaluate specifier + switch (*format) { + case 'd' : + case 'i' : + case 'u' : + case 'x' : + case 'X' : + case 'o' : + case 'b' : { + // set the base + unsigned int base; + if (*format == 'x' || *format == 'X') { + base = 16U; + } + else if (*format == 'o') { + base = 8U; + } + else if (*format == 'b') { + base = 2U; + } + else { + base = 10U; + flags &= ~FLAGS_HASH; // no hash for dec format + } + // uppercase + if (*format == 'X') { + flags |= FLAGS_UPPERCASE; + } + + // no plus or space flag for u, x, X, o, b + if ((*format != 'i') && (*format != 'd')) { + flags &= ~(FLAGS_PLUS | FLAGS_SPACE); + } + + // ignore '0' flag when precision is given + if (flags & FLAGS_PRECISION) { + flags &= ~FLAGS_ZEROPAD; + } + + // convert the integer + if ((*format == 'i') || (*format == 'd')) { + // signed + if (flags & FLAGS_LONG_LONG) { +#if defined(PRINTF_SUPPORT_LONG_LONG) + const long long value = va_arg(va, long long); + idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); +#endif + } + else if (flags & FLAGS_LONG) { + const long value = va_arg(va, long); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + else { + const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + } + else { + // unsigned + if (flags & FLAGS_LONG_LONG) { +#if defined(PRINTF_SUPPORT_LONG_LONG) + idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); +#endif + } + else if (flags & FLAGS_LONG) { + idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); + } + else { + const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int); + idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); + } + } + format++; + break; + } +// #if defined(PRINTF_SUPPORT_FLOAT) +// case 'f' : +// case 'F' : +// if (*format == 'F') flags |= FLAGS_UPPERCASE; +// idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); +// format++; +// break; +// #if defined(PRINTF_SUPPORT_EXPONENTIAL) +// case 'e': +// case 'E': +// case 'g': +// case 'G': +// if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP; +// if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE; +// idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); +// format++; +// break; +// #endif // PRINTF_SUPPORT_EXPONENTIAL +// #endif // PRINTF_SUPPORT_FLOAT + case 'c' : { + unsigned int l = 1U; + // pre padding + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // char output + out((char)va_arg(va, int), buffer, idx++, maxlen); + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 's' : { + const char* p = va_arg(va, char*); + unsigned int l = _strnlen_s(p, precision ? precision : (size_t)-1); + // pre padding + if (flags & FLAGS_PRECISION) { + l = (l < precision ? l : precision); + } + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // string output + while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) { + out(*(p++), buffer, idx++, maxlen); + } + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 'p' : { + width = sizeof(void*) * 2U; + flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; +#if defined(PRINTF_SUPPORT_LONG_LONG) + const bool is_ll = sizeof(uintptr_t) == sizeof(long long); + if (is_ll) { + idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags); + } + else { +#endif + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags); +#if defined(PRINTF_SUPPORT_LONG_LONG) + } +#endif + format++; + break; + } + + case '%' : + out('%', buffer, idx++, maxlen); + format++; + break; + + default : + out(*format, buffer, idx++, maxlen); + format++; + break; + } + } + + // termination + out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); + + // return written chars without terminating \0 + return (int)idx; +} + + +/////////////////////////////////////////////////////////////////////////////// + +int printf_(const char* format, ...) +{ + va_list va; + va_start(va, format); + char buffer[1]; + const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va); + va_end(va); + return ret; +} + + +int sprintf_(char* buffer, const char* format, ...) +{ + va_list va; + va_start(va, format); + const int ret = _vsnprintf(_out_buffer, buffer, (size_t)-1, format, va); + va_end(va); + return ret; +} + + +int snprintf_(char* buffer, size_t count, const char* format, ...) +{ + va_list va; + va_start(va, format); + const int ret = _vsnprintf(_out_buffer, buffer, count, format, va); + va_end(va); + return ret; +} + + +int vprintf_(const char* format, va_list va) +{ + char buffer[1]; + return _vsnprintf(_out_char, buffer, (size_t)-1, format, va); +} + + +int vsnprintf_(char* buffer, size_t count, const char* format, va_list va) +{ + return _vsnprintf(_out_buffer, buffer, count, format, va); +} + + +int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) +{ + va_list va; + va_start(va, format); + const out_fct_wrap_type out_fct_wrap = { out, arg }; + const int ret = _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va); + va_end(va); + return ret; +} diff --git a/c_project/printf.h b/c_project/printf.h new file mode 100644 index 0000000..165f348 --- /dev/null +++ b/c_project/printf.h @@ -0,0 +1,121 @@ +/////////////////////////////////////////////////////////////////////////////// +// \author (c) Marco Paland (info@paland.com) +// 2014-2019, PALANDesign Hannover, Germany +// +// \license The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on +// embedded systems with a very limited resources. +// Use this instead of bloated standard/newlib printf. +// These routines are thread safe and reentrant. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _PRINTF_H_ +#define _PRINTF_H_ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#define PRINTF_DISABLE_SUPPORT_FLOAT +#define PRINTF_DISABLE_SUPPORT_EXPONENTIAL +// #define PRINTF_DISABLE_SUPPORT_LONG_LONG +#define PRINTF_DISABLE_SUPPORT_PTRDIFF_T + +/** + * Output a character to a custom device like UART, used by the printf() function + * This function is declared here only. You have to write your custom implementation somewhere + * \param character Character to output + */ +void _putchar(char character); + + +/** + * Tiny printf implementation + * You have to implement _putchar if you use printf() + * To avoid conflicts with the regular printf() API it is overridden by macro defines + * and internal underscore-appended functions like printf_() are used + * \param format A string that specifies the format of the output + * \return The number of characters that are written into the array, not counting the terminating null character + */ +#define printf printf_ +int printf_(const char* format, ...); + + +/** + * Tiny sprintf implementation + * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD! + * \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output! + * \param format A string that specifies the format of the output + * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + */ +#define sprintf sprintf_ +int sprintf_(char* buffer, const char* format, ...); + + +/** + * Tiny snprintf/vsnprintf implementation + * \param buffer A pointer to the buffer where to store the formatted string + * \param count The maximum number of characters to store in the buffer, including a terminating null character + * \param format A string that specifies the format of the output + * \param va A value identifying a variable arguments list + * \return The number of characters that COULD have been written into the buffer, not counting the terminating + * null character. A value equal or larger than count indicates truncation. Only when the returned value + * is non-negative and less than count, the string has been completely written. + */ +#define snprintf snprintf_ +#define vsnprintf vsnprintf_ +int snprintf_(char* buffer, size_t count, const char* format, ...); +int vsnprintf_(char* buffer, size_t count, const char* format, va_list va); + + +/** + * Tiny vprintf implementation + * \param format A string that specifies the format of the output + * \param va A value identifying a variable arguments list + * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + */ +#define vprintf vprintf_ +int vprintf_(const char* format, va_list va); + + +/** + * printf with output function + * You may use this as dynamic alternative to printf() with its fixed _putchar() output + * \param out An output function which takes one character and an argument pointer + * \param arg An argument pointer for user data passed to output function + * \param format A string that specifies the format of the output + * \return The number of characters that are sent to the output function, not counting the terminating null character + */ +int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...); + + +#ifdef __cplusplus +} +#endif + + +#endif // _PRINTF_H_ diff --git a/c_project/printf.o b/c_project/printf.o new file mode 100644 index 0000000..89e63bb Binary files /dev/null and b/c_project/printf.o differ diff --git a/c_project/vexriscv/init.c b/c_project/vexriscv/init.c new file mode 100644 index 0000000..35df643 --- /dev/null +++ b/c_project/vexriscv/init.c @@ -0,0 +1,13 @@ +#include "weak_under_alias.h" + +void __weak__init() {} + +void __weak__fini() {} + +weak_under_alias(_init); +weak_under_alias(_fini); + +void _exit(int code) { + (void)code; + while (1) {} +} \ No newline at end of file diff --git a/c_project/vexriscv/nonvolatile.ld b/c_project/vexriscv/nonvolatile.ld new file mode 100644 index 0000000..0809fad --- /dev/null +++ b/c_project/vexriscv/nonvolatile.ld @@ -0,0 +1,141 @@ +/* SECTIONS for non-volatile chip configuration, i.e. chips with flash */ + +SECTIONS +{ + .init : + { + KEEP (*(SORT_NONE(.init))) + } >rom + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >rom + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >rom + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + .rodata : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >rom + + . = ALIGN(4); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >rom + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >rom + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >rom + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >rom + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >rom + + .lalign : + { + . = ALIGN(4); + } >rom + + .dalign : + { + . = ALIGN(4); + } >ram AT>rom + + .data : + { + PROVIDE( _data = . ); + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + } >ram AT>rom + + PROVIDE( _data_lma = LOADADDR(.data) ); + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram + + . = ALIGN(8); + PROVIDE( _end = . ); + PROVIDE( end = . ); +} + +PROVIDE(_sp = ORIGIN(ram) + LENGTH(ram)); +PROVIDE(_heap_end = ORIGIN(ram) + LENGTH(ram)); diff --git a/c_project/vexriscv/pqvexriscvsim.ld b/c_project/vexriscv/pqvexriscvsim.ld new file mode 100644 index 0000000..f3e1ee6 --- /dev/null +++ b/c_project/vexriscv/pqvexriscvsim.ld @@ -0,0 +1,14 @@ +OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") +OUTPUT_ARCH(riscv) + +ENTRY( _start ) + +__ram_size = 128K; + +MEMORY +{ + rom (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 64K + ram (wxa!ri) : ORIGIN = 0x80010000, LENGTH = 64K +} + +INCLUDE nonvolatile.ld diff --git a/c_project/vexriscv/pqvexriscvsim_init.o b/c_project/vexriscv/pqvexriscvsim_init.o new file mode 100644 index 0000000..da5c041 Binary files /dev/null and b/c_project/vexriscv/pqvexriscvsim_init.o differ diff --git a/c_project/vexriscv/pqvexriscvsim_start.o b/c_project/vexriscv/pqvexriscvsim_start.o new file mode 100644 index 0000000..ffda862 Binary files /dev/null and b/c_project/vexriscv/pqvexriscvsim_start.o differ diff --git a/c_project/vexriscv/start.S b/c_project/vexriscv/start.S new file mode 100644 index 0000000..f9c0ddc --- /dev/null +++ b/c_project/vexriscv/start.S @@ -0,0 +1,164 @@ + .section .init + .global _start + .type _start,@function +_start: + nop + nop + nop +#ifndef VEXRISCV_RWMTVEC + j + nop + nop + nop + nop + nop + nop + nop + j trap_entry +_crtInit: +#endif + .cfi_startproc + .cfi_undefined ra +.option push +.option norelax + la gp, __global_pointer$ +.option pop + la sp, _sp + +#ifndef VEXRISCV_VOLATILE + /* Load data section */ + la a0, _data_lma + la a1, _data + la a2, _edata + bgeu a1, a2, 2f +1: + lw t0, (a0) + sw t0, (a1) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a1, a2, 1b +2: +#endif + + /* Clear bss section */ + la a0, __bss_start + la a1, _end + bgeu a0, a1, 2f +1: + sw zero, (a0) + addi a0, a0, 4 + bltu a0, a1, 1b +2: + + /* Call global constructors */ +#if 0 + /* [2019-12-12 Daan] Ha, ha! Nope! The stack machine seems to get + * corrupted in one of these calls. Afaik we don't need any of these + * constructors. Just skip it, and get on with calling main. */ + la a0, __libc_fini_array + call atexit + call __libc_init_array +#endif + + auipc ra, 0 + addi sp, sp, -16 + sw ra, 8(sp) + + /* Enable Interrupts and set trap vector */ +#ifndef VEXRISCV_RWMTVEC + la a0, trap_entry + csrw mtvec, a0 +#endif + li a0, 0x880 //880 enable timer + external interrupts + csrw mie, a0 + li a0, 0x1808 //1808 enable interrupts + csrw mstatus, a0 + + /* argc = argv = 0 */ + li a0, 0 + li a1, 0 + call main + tail exit +1: + j 1b + .cfi_endproc + + .align 4 + .weak trap_entry + .global trap_entry +trap_entry: + addi sp, sp, -32*4 + + sw x1, 1*4(sp) + sw x2, 2*4(sp) + sw x3, 3*4(sp) + sw x4, 4*4(sp) + sw x5, 5*4(sp) + sw x6, 6*4(sp) + sw x7, 7*4(sp) + sw x8, 8*4(sp) + sw x9, 9*4(sp) + sw x10, 10*4(sp) + sw x11, 11*4(sp) + sw x12, 12*4(sp) + sw x13, 13*4(sp) + sw x14, 14*4(sp) + sw x15, 15*4(sp) + sw x16, 16*4(sp) + sw x17, 17*4(sp) + sw x18, 18*4(sp) + sw x19, 19*4(sp) + sw x20, 20*4(sp) + sw x21, 21*4(sp) + sw x22, 22*4(sp) + sw x23, 23*4(sp) + sw x24, 24*4(sp) + sw x25, 25*4(sp) + sw x26, 26*4(sp) + sw x27, 27*4(sp) + sw x28, 28*4(sp) + sw x29, 29*4(sp) + sw x30, 30*4(sp) + sw x31, 31*4(sp) + + call irqCallback + + lw x1, 1*4(sp) + lw x2, 2*4(sp) + lw x3, 3*4(sp) + lw x4, 4*4(sp) + lw x5, 5*4(sp) + lw x6, 6*4(sp) + lw x7, 7*4(sp) + lw x8, 8*4(sp) + lw x9, 9*4(sp) + lw x10, 10*4(sp) + lw x11, 11*4(sp) + lw x12, 12*4(sp) + lw x13, 13*4(sp) + lw x14, 14*4(sp) + lw x15, 15*4(sp) + lw x16, 16*4(sp) + lw x17, 17*4(sp) + lw x18, 18*4(sp) + lw x19, 19*4(sp) + lw x20, 20*4(sp) + lw x21, 21*4(sp) + lw x22, 22*4(sp) + lw x23, 23*4(sp) + lw x24, 24*4(sp) + lw x25, 25*4(sp) + lw x26, 26*4(sp) + lw x27, 27*4(sp) + lw x28, 28*4(sp) + lw x29, 29*4(sp) + lw x30, 30*4(sp) + lw x31, 31*4(sp) + + addi sp, sp, 32*4 + mret + + .weak irqCallback +irqCallback: +1: + j 1b diff --git a/c_project/vexriscv/vexriscv.mk b/c_project/vexriscv/vexriscv.mk new file mode 100644 index 0000000..6c238df --- /dev/null +++ b/c_project/vexriscv/vexriscv.mk @@ -0,0 +1,45 @@ +PLATFORM ?= murax + +LIBWRAP_CFLAGS += -Os -Wall -Wextra +LIBWRAP_CFLAGS += $(GCC_RISCV_ARCHFLAGS) -fstrict-volatile-bitfields --specs=nosys.specs + +ifeq ($(PLATFORM),murax) +LIBWRAP_CFLAGS += -DVEXRISCV_VOLATILE +endif + +ifeq ($(PLATFORM),pqvexriscvup5k) +LIBWRAP_CFLAGS += -DVEXRISCV_VOLATILE -DVEXRISCV_RWMTVEC +endif + +ifeq ($(PLATFORM),pqvexriscvicoboard) +LIBWRAP_CFLAGS += -DVEXRISCV_VOLATILE -DVEXRISCV_RWMTVEC +endif + +ifeq ($(PLATFORM),pqvexriscvsim) +LIBWRAP_CFLAGS += -DVEXRISCV_RWMTVEC +endif + +LIBWRAP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) + +LIBWRAP_SRCS_C = init.c +LIBWRAP_SRCS_ASM = start.s + +LIBWRAP_OBJS_ = $(LIBWRAP_SRCS_C:.c=.o) $(LIBWRAP_SRCS_ASM:.s=.o) +LIBWRAP_OBJS = $(addprefix $(LIBWRAP_DIR)$(PLATFORM)_,$(LIBWRAP_OBJS_)) + +LIBWRAP = lib$(PLATFORM)bsp.a + +$(LIBWRAP): $(LIBWRAP_OBJS) + @$(ECHO) $(LIGHTBLUE)"building "$@""$(LIGHTGRAY) + $(AR) rcs $@ $^ + +$(LIBWRAP_DIR)$(PLATFORM)_%.o: $(LIBWRAP_DIR)%.c + @$(ECHO) $(DARKBLUE)" "$(LIBWRAP_DIR)" "$(LIGHTGRAY) + @$(ECHO) $(DARKBLUE)"building "$@" (.c)"$(LIGHTGRAY) + $(GCC) $(LIBWRAP_CFLAGS) -c -o $@ $< + +$(LIBWRAP_DIR)$(PLATFORM)_%.o: $(LIBWRAP_DIR)%.S + @$(ECHO) $(DARKBLUE)"building "$@" (.S)"$(LIGHTGRAY) + $(GCC) $(LIBWRAP_CFLAGS) -c -o $@ $< + + diff --git a/c_project/vexriscv/weak_under_alias.h b/c_project/vexriscv/weak_under_alias.h new file mode 100644 index 0000000..4de2501 --- /dev/null +++ b/c_project/vexriscv/weak_under_alias.h @@ -0,0 +1,7 @@ +#ifndef WEAK_UNDER_ALIAS_H +#define WEAK_UNDER_ALIAS_H + +#define weak_under_alias(name) \ + extern __typeof (__weak_##name) name __attribute__ ((weak, alias ("__weak_"#name))) + +#endif /* WEAK_UNDER_ALIAS_H */ diff --git a/vexriscv/src/main/scala/mupq/MyMem.scala b/vexriscv/src/main/scala/mupq/MyMem.scala index 3ad7208..275e6df 100644 --- a/vexriscv/src/main/scala/mupq/MyMem.scala +++ b/vexriscv/src/main/scala/mupq/MyMem.scala @@ -4,22 +4,31 @@ import spinal.core._ import spinal.lib._ import spinal.lib.bus.amba3.apb._ +object MyMem{ + def getApb3Config = Apb3Config( + addressWidth = 20, + dataWidth = 32 + ) +} + class MyMem() extends Component { val io = new Bundle { - val bus = slave(Apb3(Apb3Config(addressWidth = 20, dataWidth = 32))) - val interrupt = out Bool + val bus = slave(Apb3(MyMem.getApb3Config)) } + val myReg = Reg(Bits(32 bit)) + val busCtrl = Apb3SlaveFactory(io.bus) + + busCtrl.readAndWrite(myReg,address = 0x30000,bitOffset = 0) + /** - val coproc = new KeccakCoproMultimemWrapper(dataWidth, keccakN) - **/ val busReady = Reg(Bool) init(false) val busAccess = io.bus.PENABLE && io.bus.PSEL(0) io.bus.PRDATA := 0 busReady := busAccess && !busReady io.bus.PREADY := busReady - io.interrupt := False - /** + + when(busReady) { when(io.bus.PWRITE) { start := io.bus.PWDATA(0) // Set flags on write, will trigger the coprocessor diff --git a/vexriscv/src/main/scala/mupq/PQVexRiscv.scala b/vexriscv/src/main/scala/mupq/PQVexRiscv.scala index ba04488..98c326c 100644 --- a/vexriscv/src/main/scala/mupq/PQVexRiscv.scala +++ b/vexriscv/src/main/scala/mupq/PQVexRiscv.scala @@ -168,7 +168,7 @@ abstract class PQVexRiscv( } val myMem = new MyMem() - core.timerInterrupt setWhen(myMem.io.interrupt) + // core.timerInterrupt setWhen(myMem.io.interrupt) apbMapping += myMem.io.bus -> (0x30000, 4 KiB) val apbDecoder = Apb3Decoder(