From c37286cf019b60d071c8031ad0f6c196fd7074dc Mon Sep 17 00:00:00 2001 From: Toby Jaffey Date: Mon, 8 Dec 2025 23:54:14 +0000 Subject: [PATCH] Add "self", example of building uvm32 to run inside uvm32 mandelbrot app is embedded in host-mini, which is then compiled to a .bin --- README.md | 1 + apps/Makefile | 2 ++ apps/self/Makefile | 27 +++++++++++++++ apps/self/self.c | 80 +++++++++++++++++++++++++++++++++++++++++++ precompiled/self.bin | Bin 0 -> 4980 bytes 5 files changed, 110 insertions(+) create mode 100644 apps/self/Makefile create mode 100644 apps/self/self.c create mode 100755 precompiled/self.bin diff --git a/README.md b/README.md index a5fa6ea..c888ad1 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ Although based on a fully fledged CPU emulator, uvm32 is intended for executing * [apps/lissajous](apps/lissajous) C console lissajous curve (showing softfp, floating point) * [apps/hello-asm](apps/hello-asm) Minimal hello world assembly * [apps/fib](apps/fib) C fibonacci series program (iterative and recursive) + * [apps/self](apps/self) host-mini with embedded mandelbrot generation program, compiled as an app (inception!) * [apps/sketch](apps/sketch) C Arduino/Wiring/Processing type program in `setup()` and `loop()` style * [apps/rust-hello](apps/rust-hello) Rust hello world program (note, the version of rust installed by brew on mac has issues, use the official rust installer from https://rust-lang.org/learn/get-started/) * [apps/zig-mandel](apps/zig-mandel) Zig ASCII mandelbrot generator program diff --git a/apps/Makefile b/apps/Makefile index abe6621..69c99b7 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -6,6 +6,7 @@ all: (cd helloworld && make) (cd lissajous && make) (cd conio && make) + (cd self && make) (cd zig-mandel && make) (cd zigtris && make) (cd rust-hello && make) @@ -16,6 +17,7 @@ clean: (cd helloworld && make clean) (cd lissajous && make clean) (cd conio && make clean) + (cd self && make clean) (cd zig-mandel && make clean) (cd zigtris && make clean) (cd rust-hello && make clean) diff --git a/apps/self/Makefile b/apps/self/Makefile new file mode 100644 index 0000000..1494480 --- /dev/null +++ b/apps/self/Makefile @@ -0,0 +1,27 @@ +PROJECT:=self + +DOCKER_IMAGE=riscv-dev +DOCKER_CMD:=docker run --rm -v ${PWD}../../../:/data -w /data/apps/${PROJECT} ${DOCKER_IMAGE} +PREFIX:=${DOCKER_CMD} riscv64-unknown-elf- +CFLAGS+=-I../../common -I../../uvm32 -DUVM32_MEMORY_SIZE=8192 +CFLAGS+=-fno-stack-protector +CFLAGS+=-static-libgcc -fdata-sections -ffunction-sections +CFLAGS+=-g -Os -march=rv32ima_zicsr -mabi=ilp32 -static +LDFLAGS:= -T ../linker.ld -nostdlib -Wl,--gc-sections +LIBS:= #-lgcc # needed for softfp + +SRCS=${PROJECT}.c ../../uvm32/uvm32.c ../crt0.S + +all: + ${PREFIX}gcc -o ${PROJECT}.elf ${CFLAGS} ${LDFLAGS} ${SRCS} ${LIBS} + $(PREFIX)objcopy ${PROJECT}.elf -O binary ${PROJECT}.bin + +disasm: all + $(PREFIX)objdump -S -d -f ${PROJECT}.elf + +test: all + ../../host/host ${PWD}/${PROJECT}.bin + +clean: + rm -f ${PROJECT}.o ${PROJECT}.elf ${PROJECT}.bin + diff --git a/apps/self/self.c b/apps/self/self.c new file mode 100644 index 0000000..72b36fa --- /dev/null +++ b/apps/self/self.c @@ -0,0 +1,80 @@ +#define USE_MAIN +#include "uvm32_target.h" + +#include "uvm32.h" +#include "../common/uvm32_common_custom.h" + +// Precompiled binary program to print integers +// This code expects to print via syscall 0x13C (UVM32_SYSCALL_PRINTD in common/uvm32_common_custom.h) +uint8_t rom[] = { + 0x23, 0x26, 0x11, 0x00, 0xef, 0x00, 0xc0, 0x00, 0xb7, 0x08, 0x00, 0x01, + 0x73, 0x00, 0x00, 0x00, 0x37, 0xf5, 0xff, 0xff, 0xb7, 0x15, 0x00, 0x00, + 0x37, 0xe6, 0xff, 0xff, 0x13, 0x07, 0xf0, 0x01, 0xb7, 0x47, 0x00, 0x00, + 0xb7, 0x06, 0x00, 0x01, 0x13, 0x08, 0xd5, 0xcc, 0x93, 0x82, 0x35, 0x33, + 0x13, 0x03, 0x76, 0xe6, 0x93, 0x83, 0x35, 0xb3, 0x13, 0x86, 0x16, 0x00, + 0x63, 0xc8, 0x02, 0x09, 0x13, 0x0e, 0x03, 0x00, 0x63, 0xca, 0x63, 0x06, + 0x93, 0x0e, 0x00, 0x00, 0x93, 0x05, 0x00, 0x00, 0x13, 0x0f, 0x00, 0x00, + 0x93, 0x0f, 0x00, 0x00, 0x93, 0x06, 0x00, 0x02, 0x13, 0x85, 0x06, 0xfe, + 0x63, 0x62, 0xa7, 0x04, 0x33, 0x85, 0xd5, 0x01, 0x63, 0xee, 0xa7, 0x02, + 0x13, 0x05, 0x00, 0x00, 0x93, 0x08, 0x06, 0x00, 0x33, 0x8f, 0xef, 0x03, + 0xb3, 0x8f, 0xd5, 0x41, 0x73, 0x00, 0x00, 0x00, 0x13, 0x5f, 0xbf, 0x40, + 0xb3, 0x8f, 0xcf, 0x01, 0x33, 0x0f, 0x0f, 0x01, 0xb3, 0x85, 0xff, 0x03, + 0x93, 0xd5, 0xc5, 0x00, 0x33, 0x05, 0xef, 0x03, 0x93, 0x5e, 0xc5, 0x00, + 0x93, 0x86, 0x16, 0x00, 0x6f, 0xf0, 0xdf, 0xfb, 0x13, 0x85, 0x06, 0x00, + 0x93, 0x08, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x13, 0x0e, 0x1e, 0x09, + 0xe3, 0xda, 0xc3, 0xf9, 0x13, 0x05, 0xa0, 0x00, 0x93, 0x08, 0x00, 0x00, + 0x73, 0x00, 0x00, 0x00, 0x13, 0x08, 0x98, 0x19, 0xe3, 0xdc, 0x02, 0xf7, + 0x37, 0x05, 0x00, 0x80, 0x13, 0x05, 0x05, 0x0e, 0x93, 0x08, 0x30, 0x00, + 0x73, 0x00, 0x00, 0x00, 0x67, 0x80, 0x00, 0x00, 0x48, 0x65, 0x6c, 0x6c, + 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x00 +}; + +// Create an identifier for our host handler +// syscalls exposed to vm environement +typedef enum { + F_PUTC, + F_PRINTLN, +} f_code_t; + +// Map exposed syscalls to syscalls +const uvm32_mapping_t env[] = { + { .syscall = UVM32_SYSCALL_PRINTLN, .typ = UVM32_SYSCALL_TYP_BUF_TERMINATED_WR, .code = F_PRINTLN }, + { .syscall = UVM32_SYSCALL_PUTC, .typ = UVM32_SYSCALL_TYP_U32_WR, .code = F_PUTC }, +}; + +void main(void) { + uvm32_state_t vmst; + uvm32_evt_t evt; + bool isrunning = true; + + uvm32_init(&vmst, env, sizeof(env) / sizeof(env[0])); + uvm32_load(&vmst, rom, sizeof(rom)); + + while(isrunning) { + uvm32_run(&vmst, &evt, 100); // num instructions before vm considered hung + + switch(evt.typ) { + case UVM32_EVT_END: + isrunning = false; + break; + case UVM32_EVT_SYSCALL: // vm has paused to handle UVM32_SYSCALL + switch((f_code_t)evt.data.syscall.code) { + case F_PUTC: + putc(evt.data.syscall.val.u32); + break; + case F_PRINTLN: + for (int i=0;iYpl})o1J%v(SRa5uUv43=f)Y_s4IF9SMmQ$=#+MAk2 z=hfaim_pGXbZAjppe4?3>I6epsrg|CLt1QjXc-JcE7!Ipq^|A4h-DP+9QZku(>ab( zN+ctT;=cPR)r!{;IC$sWdwA|S=brnW`<@m17`;cNOkFS)IWJH{4{sT1b(_isdq)DWFJ}|rSb|%I=*~u13KVx{~a%eqeVu^}-ZF-3Z#*|(q z*FvQH&orM5=&gqX8N{PMpan7yob>CP4*LKi;_5!H^dW$VZB%;YwQMDFV0hLy^3q-w)OHn#*`kZ*!+mij~M)j!H>Psu{U~V zQ;)8HT+=fjKk3su4*N14JwE*tnlJN-lNujn%FlrE+Zrpc#G97EDDwHf%A=Nh0D0Iz zd+@PLb46zy8N4UWZy<)1}L&!s*-^^2HZW|FQSUdHT~D4;?i0ADSdWU(zJ& zB6n@&(^m5<;Qgu&=Jn&llxZ{SIBG)-l)(4ad3Ca>XzJ~~b(yw_I;%ZzW?~aTaf4~% zkIG@aJzFOZ-3W_g4Eo^HEDXIhGH;l&l*8F829<2ZE(LihLGC&hUvI}J0_k~Kxx zB-jY@0n-$w;(JX#FbqAj$!49Jd}1xR-;A&4195U2%?5kuZPMEq$-hn!|3-=N>Y^r0 zkq}@1+mJL4Y9e%TgSfWWkZhKOuh5A&F<;oM;uYaSXC~I`=i%+BwTU{FORVj4j}#j+ zZ70di78~@J9`>odbB`q(B=%hGfn?p-+yfgAu;(a+y){krYs|IQ_MDF!>i@86+ z-mPyV`Oo!+&2pNGGf9jDW$qPw_nVR()P+%qA{N7KD*R6NC18_%M=svfoSRojHYCU? zUefrUlIG;E5O16!CvRxNFe!ecT2;I(l{EQW8#xU4@)GjM&Q;0n|nVi4eCNpcSs}J<@zr+ zN@E9!-xj~9d{REcr-<@1a{_ruGja|kG(K!#U+7UgmCzhxQd77kcjqW>MoHzzDXN%f zzU$lrzWchW=D%+?LLDKCDgevMfrDlPMF?# ziWN<(b+>6X=S{s0J%z0!(Rlqk9!8<&fG-}daJB<=2YhLHo8rJ1&Js%sbFJ35)p`9d zckR9f$->~Te&BA~SH@V?-J_mYm)yradC5KK$rTBoWoeSBy^y;Ts5|7Zbm{josr)!u zLyNa7T#0GioT`d%0e=|Hs$S&I9r`8q2WxG7hxbh){uE-~LGF$G8(z(*y3I~RS87Jp zt)u!)mMQ<<_V{Cp-&o_1E584_H$I{GQP<-ydHUB@`>T8fzIuM6cPu$2_&PJA*@bCM z_;v6J%{I#vx8OT#*SLPFD!y5$`OeDZ-b%d-`{OvfnmiW6{!fxRrz(cbaRYeRrwK~= z+_mhd$_Fd0`r_zsJ^rZTufF5)V~XGSPOYx6_7R-(BF@zea=U!~`JQFl0|US(=2P~$ zS+2s*;Oeu-dD5$6u}3$>Ex)$BziWA8JK5$9)K%@QA@@G4|10O1diMXyIqu09oS%5| z1(9W6iKDlQV|nzb*{VA{bIzGibED_PFni3o>EMxc)8(@{o#98+ppG_?Y6aj(U8%r(fe+@+S1Z?~QkO`v2zfn>_s& z#0#M%o+?B{L&~qW^_mJh`13i1F{(E!tgNE`(>xU?uO}3eo(`o*Ak_duOlV*|kV=L!E`^l-i9 zd%*U2RsY|Yr4(^)1KX0M{sa5Z$muw6tI+NI`32mM3P-K6km`3wZS%4^J5_tDdR|?! z2RwPn-si~`IRuRR;$`fqiC#I5^$c>~Fsgjm!`j>KqH){nqj>*t4_#hRws<}6yY-bS zM}M)9GZl;8j(hsC9P#ytDaB0HTh%^#cXt(A$MH4L3tH{C@6~)h8m|YI)PGy~bz9xR z)O`y4QS113!NVW;&)GQMO=f)hk0L&s-6Fjccb=yI3F+1l&NupD=pyc9z=BXAD1y3A zZ%cUhVrNM8-6&bdr^)*F8M0nYBF1Lqrh*topR`_6wbx&Xhbe7`r!@7hqWYzH?3~{k zyNuj}UW<_RqX=SchA*QFsy~aPlRmZXijG>xdW}KP>r)jcTc*s!1iAleEanX0MRo%F za+&Nb?pxW*=zEhrR>vi^Z?M@v&y5M6_1bx5e@@vyF#GVYIqnj8PKpinl)E2(4W3c& zlbSR5I^Jc@zkFc!{Dg`{G*o>0iLEQ|7cq4gPM|Sn>+M>*_w!0l8cjSk*Jk-B) z^M`fRSl`YMkA1dhbN?fcKJvMqZQC%h7^3tX=mO|E$d9^i_urv)cgdl<?{48o~4z#iku2g9g6a_VcwyvS{%b*cZN2Erl!9R<+F%U}D`|s;`o(8>TQu+pH z7E}hU!@FWL=rf=rpb^lspcgM~u&X#5f`Mf5=YgBgPv)V!ZXPaX;iHP&=rMwZ8>gi6;&Ib&!fD z8U>GBH{Kw`>Q$HO{_H-sU>z=QyLQUp&$2Ko4)u_V57!fy}0sfk-Bd>r%AG{}DX zJ>7Zw%^vj)iTD4k+j;uDW=A5xlBzD>JcI8q@9FYy@Qns*C>(|z{IB-SiHA4TxxYU3 sf%>lW`!VzRd)+I(Qak|c4g|vL8i+!)no|e