From 90d88f65b6023483c43e79b76fdba56423c11905 Mon Sep 17 00:00:00 2001 From: Andre Richter Date: Mon, 31 Dec 2018 00:50:28 +0100 Subject: [PATCH] Streamlining, cleanup, and minor fixes. --- 01_bareminimum/Makefile | 22 +++----- 02_multicore_rust/Makefile | 22 +++----- 02_multicore_rust/src/main.rs | 4 +- 03_uart1/Makefile | 22 +++----- 03_uart1/README.md | 4 +- 03_uart1/kernel8 | Bin 67944 -> 68104 bytes 03_uart1/kernel8.img | Bin 849 -> 958 bytes 03_uart1/src/main.rs | 10 ++-- 04_mailboxes/Makefile | 24 ++++----- 04_mailboxes/kernel8 | Bin 69120 -> 69304 bytes 04_mailboxes/kernel8.img | Bin 1795 -> 1914 bytes 04_mailboxes/src/main.rs | 16 +++--- 05_uart0/Makefile | 22 +++----- 05_uart0/kernel8 | Bin 69440 -> 69616 bytes 05_uart0/kernel8.img | Bin 2027 -> 2150 bytes 05_uart0/src/main.rs | 22 ++++---- 06_raspbootin64/Makefile | 22 +++----- 06_raspbootin64/src/main.rs | 4 +- 07_abstraction/Makefile | 24 ++++----- 07_abstraction/README.md | 24 ++++----- 07_abstraction/kernel8 | Bin 69448 -> 69624 bytes 07_abstraction/kernel8.img | Bin 2023 -> 2142 bytes 07_abstraction/raspi3_boot/src/lib.rs | 16 +++--- 07_abstraction/src/main.rs | 24 +++++---- 08_random/Makefile | 24 ++++----- 08_random/kernel8 | Bin 70208 -> 70448 bytes 08_random/kernel8.img | Bin 1874 -> 2029 bytes 08_random/raspi3_boot/src/lib.rs | 16 +++--- 08_random/src/main.rs | 20 ++++--- 09_delays/Makefile | 24 ++++----- 09_delays/kernel8 | Bin 69056 -> 69296 bytes 09_delays/kernel8.img | Bin 1595 -> 1771 bytes 09_delays/raspi3_boot/src/lib.rs | 16 +++--- 09_delays/src/main.rs | 26 ++++----- 0A_power/Makefile | 24 ++++----- 0A_power/kernel8 | Bin 69264 -> 69440 bytes 0A_power/kernel8.img | Bin 1734 -> 1842 bytes 0A_power/raspi3_boot/src/lib.rs | 16 +++--- 0A_power/src/main.rs | 18 ++++--- 0B_exception_levels/Makefile | 20 +++---- 0B_exception_levels/README.md | 32 +++++------ 0B_exception_levels/kernel8 | Bin 70512 -> 70672 bytes 0B_exception_levels/kernel8.img | Bin 2631 -> 2591 bytes 0B_exception_levels/raspi3_boot/src/lib.rs | 10 ++-- 0B_exception_levels/src/delays.rs | 13 +++++ 0B_exception_levels/src/gpio.rs | 56 ++++++++++++++++++-- 0B_exception_levels/src/main.rs | 45 ++++++++-------- 0B_exception_levels/src/uart.rs | 52 +++++++++--------- 0C_virtual_memory/Makefile | 20 +++---- 0C_virtual_memory/kernel8 | Bin 71568 -> 71232 bytes 0C_virtual_memory/kernel8.img | Bin 2576 -> 2184 bytes 0C_virtual_memory/raspi3_boot/src/lib.rs | 10 ++-- 0C_virtual_memory/src/delays.rs | 37 +++++++++++++ 0C_virtual_memory/src/gpio.rs | 56 ++++++++++++++++++-- 0C_virtual_memory/src/main.rs | 22 ++++---- 0C_virtual_memory/src/mmu.rs | 4 +- 0C_virtual_memory/src/uart.rs | 32 +++++------ 0D_cache_performance/Makefile | 20 +++---- 0D_cache_performance/README.md | 6 +-- 0D_cache_performance/kernel8 | Bin 72016 -> 71992 bytes 0D_cache_performance/kernel8.img | Bin 3504 -> 3428 bytes 0D_cache_performance/raspi3_boot/src/lib.rs | 10 ++-- 0D_cache_performance/src/benchmark.rs | 8 +-- 0D_cache_performance/src/delays.rs | 37 +++++++++++++ 0D_cache_performance/src/gpio.rs | 56 ++++++++++++++++++-- 0D_cache_performance/src/main.rs | 20 ++++--- 0D_cache_performance/src/uart.rs | 32 +++++------ 67 files changed, 614 insertions(+), 450 deletions(-) create mode 100644 0C_virtual_memory/src/delays.rs create mode 100644 0D_cache_performance/src/delays.rs diff --git a/01_bareminimum/Makefile b/01_bareminimum/Makefile index 9283b7c3..dbf18840 100644 --- a/01_bareminimum/Makefile +++ b/01_bareminimum/Makefile @@ -24,6 +24,8 @@ TARGET = aarch64-unknown-none +SOURCES = $(wildcard **/*.rs) $(wildcard **/*.S) link.ld + OBJCOPY = cargo objcopy -- OBJCOPY_PARAMS = --strip-all -O binary @@ -31,26 +33,18 @@ UTILS_CONTAINER = andrerichter/raspi3-utils DOCKER_CMD = docker run -it --rm -v $(shell pwd):/work -w /work QEMU_CMD = qemu-system-aarch64 -M raspi3 -kernel kernel8.img -all: clean kernel8.img +.PHONY: all qemu clippy clean objdump nm -target/$(TARGET)/debug/kernel8: src/main.rs - cargo xbuild --target=$(TARGET) - cp $@ . +all: clean kernel8.img -target/$(TARGET)/release/kernel8: src/main.rs +target/$(TARGET)/release/kernel8: $(SOURCES) cargo xbuild --target=$(TARGET) --release - cp $@ . - -ifeq ($(DEBUG),1) -kernel8: target/$(TARGET)/debug/kernel8 -else -kernel8: target/$(TARGET)/release/kernel8 -endif -kernel8.img: kernel8 +kernel8.img: target/$(TARGET)/release/kernel8 + cp $< . $(OBJCOPY) $(OBJCOPY_PARAMS) $< kernel8.img -qemu: +qemu: all $(DOCKER_CMD) $(UTILS_CONTAINER) $(QEMU_CMD) -d in_asm clean: diff --git a/02_multicore_rust/Makefile b/02_multicore_rust/Makefile index 3552607b..6cfaf5cb 100644 --- a/02_multicore_rust/Makefile +++ b/02_multicore_rust/Makefile @@ -24,6 +24,8 @@ TARGET = aarch64-unknown-none +SOURCES = $(wildcard **/*.rs) $(wildcard **/*.S) link.ld + OBJCOPY = cargo objcopy -- OBJCOPY_PARAMS = --strip-all -O binary @@ -31,26 +33,18 @@ UTILS_CONTAINER = andrerichter/raspi3-utils DOCKER_CMD = docker run -it --rm -v $(shell pwd):/work -w /work QEMU_CMD = qemu-system-aarch64 -M raspi3 -kernel kernel8.img -all: clean kernel8.img +.PHONY: all qemu clippy clean objdump nm -target/$(TARGET)/debug/kernel8: src/main.rs - cargo xbuild --target=$(TARGET) - cp $@ . +all: clean kernel8.img -target/$(TARGET)/release/kernel8: src/main.rs +target/$(TARGET)/release/kernel8: $(SOURCES) cargo xbuild --target=$(TARGET) --release - cp $@ . - -ifeq ($(DEBUG),1) -kernel8: target/$(TARGET)/debug/kernel8 -else -kernel8: target/$(TARGET)/release/kernel8 -endif -kernel8.img: kernel8 +kernel8.img: target/$(TARGET)/release/kernel8 + cp $< . $(OBJCOPY) $(OBJCOPY_PARAMS) $< kernel8.img -qemu: +qemu: all $(DOCKER_CMD) $(UTILS_CONTAINER) $(QEMU_CMD) -d in_asm clippy: diff --git a/02_multicore_rust/src/main.rs b/02_multicore_rust/src/main.rs index a35bd169..08a6b7e4 100644 --- a/02_multicore_rust/src/main.rs +++ b/02_multicore_rust/src/main.rs @@ -25,8 +25,8 @@ #![no_std] #![no_main] -raspi3_boot::entry!(kernel_entry); - fn kernel_entry() -> ! { loop {} } + +raspi3_boot::entry!(kernel_entry); diff --git a/03_uart1/Makefile b/03_uart1/Makefile index d957691c..cfe6c745 100644 --- a/03_uart1/Makefile +++ b/03_uart1/Makefile @@ -24,6 +24,8 @@ TARGET = aarch64-unknown-none +SOURCES = $(wildcard **/*.rs) $(wildcard **/*.S) link.ld + OBJCOPY = cargo objcopy -- OBJCOPY_PARAMS = --strip-all -O binary @@ -31,26 +33,18 @@ UTILS_CONTAINER = andrerichter/raspi3-utils DOCKER_CMD = docker run -it --rm -v $(shell pwd):/work -w /work QEMU_CMD = qemu-system-aarch64 -M raspi3 -kernel kernel8.img -all: clean kernel8.img +.PHONY: all qemu clippy clean objdump nm -target/$(TARGET)/debug/kernel8: src/main.rs - cargo xbuild --target=$(TARGET) - cp $@ . +all: clean kernel8.img -target/$(TARGET)/release/kernel8: src/main.rs +target/$(TARGET)/release/kernel8: $(SOURCES) cargo xbuild --target=$(TARGET) --release - cp $@ . - -ifeq ($(DEBUG),1) -kernel8: target/$(TARGET)/debug/kernel8 -else -kernel8: target/$(TARGET)/release/kernel8 -endif -kernel8.img: kernel8 +kernel8.img: target/$(TARGET)/release/kernel8 + cp $< . $(OBJCOPY) $(OBJCOPY_PARAMS) $< kernel8.img -qemu: +qemu: all $(DOCKER_CMD) $(UTILS_CONTAINER) $(QEMU_CMD) -serial null -serial stdio clippy: diff --git a/03_uart1/README.md b/03_uart1/README.md index 5978705c..979892cc 100644 --- a/03_uart1/README.md +++ b/03_uart1/README.md @@ -43,8 +43,8 @@ the host PC. ```console ferris@box:~$ make qemu - -Hello Rustacean! +[0] UART is live! +[1] Press a key to continue booting... Greetings fellow Rustacean! ``` However, let it be said that it is more thrilling to see your first output from diff --git a/03_uart1/kernel8 b/03_uart1/kernel8 index 92f12ee2324d80c0a3900a00bd7d3ca66ccce88f..8b7e9a3ca08d1a84eec3459e5f922a13897fb9fa 100755 GIT binary patch delta 801 zcmZ9IO=uHQ5XWcsZPMLn>lY!!#^ePfXq9cPLGV-s!Rkq46rqMTZPp|vWKB1XNDrEW zkYiUG-bpY8KW{2%gAif_PvS}Kwe+OeOAms0iElT%e(YT4z2D4#=Ffb+C)St6rGvtx zWQ-h_+XSp=KhMAH;rqru)bVk{z_nl*U^zmdFw^TLUvm)MLA=6(Zu9a|yA@h8Q=LwX)cL9=r{&(T0$=-2?Tej9WHI|~6 zP9>5wuhU|_sz!ZNM^p6tysGOoO$+KRTG8m7R;uJn3o4z}H2%mcibBr}&#S8W(djj{ zSk!LP#DZQ)&#CEB)MwQ8vKs`)u*8~#Tg?$}?w`n7ZvhrvylC?k7w5<2f$#zUpHsDY z%+{maUDY)2-u1Q-6E;eWgp`jA`v)T+T4i0&e z@GT9BAjCx!B_^~5iH^ESb&`y!U37COyxzW-Cr$8M&b{aR&N<(`kL&8-sam@xS{@@Y zr)LzhD)YAV&cuErj5RbH2EK=iMD>V5E6b+2*zQerS|Z&I1zihyt^!wZmz%(z@5n=` zNQ1hi3)JN&0#|)BX~e}=wm(fqkq-olOYcpSqZIwtS0agz%DqF4sHWv74PD}l#Cd4P zJ)*^b_ig%n#(k2>e}>vSg>v~}G`q33p1)tnug1JaHNrm>B=LZC6-A`Eq9Vv`6@eRN z>q(#!A*0S!MV_u$#{~rs6W%Hhi@pbZqrNsxoTwn=>lHyy-&Vk^CcBXD*{N z&H}zM?Svc+$a%-pQSp#>7Iyeu$zS}Bf6JavkrQy!T7>AeB~U0g7Tj@ozU9Wt4+A%z zgLgE<<-fhsFzZhb1!+Z2%JTD(q;*eNN>8k{}3kx`m4 zW%69c-6o6-3=`z1GVFZG&S0dtfOldNQ$x@LWrm5Fd<;AD|Noy3l2?4gJMj?sJ9~6c`k)JYbgBI=~!%jRUBYgOPtCCy>?z()NrT zuMaUWguwZ&3_n0(hk>s92-V9KZ4j#v>KGKFkXfvdlUbIk$Q5lEs}N9>T3oDFFuBOBbc4f;hzrX{k9m`Q-{hrNt$Q$*GBXid+DB CpJb!} delta 172 zcmdnTevxg04C9`Ovc-&ZCr-RBna;p4MV^@*eNN>8k{(}kx`m4 zYVush-8?VZ8I0toGVILcW7s*lhe?%(fp?-3Q$x@LWrm6AllL;Ehi>`*f4TyL!j%Wi z@>&O& ! { let uart = uart::MiniUart::new(); // set up serial console uart.init(); + uart.puts("\n[0] UART is live!\n"); - uart.getc(); // Press a key first before being greeted - uart.puts("Hello Rustacean!\n"); + uart.puts("[1] Press a key to continue booting... "); + uart.getc(); + uart.puts("Greetings fellow Rustacean!\n"); // echo everything back loop { uart.send(uart.getc()); } } + +raspi3_boot::entry!(kernel_entry); diff --git a/04_mailboxes/Makefile b/04_mailboxes/Makefile index d957691c..4797e77b 100644 --- a/04_mailboxes/Makefile +++ b/04_mailboxes/Makefile @@ -24,6 +24,8 @@ TARGET = aarch64-unknown-none +SOURCES = $(wildcard **/*.rs) $(wildcard **/*.S) link.ld + OBJCOPY = cargo objcopy -- OBJCOPY_PARAMS = --strip-all -O binary @@ -31,27 +33,19 @@ UTILS_CONTAINER = andrerichter/raspi3-utils DOCKER_CMD = docker run -it --rm -v $(shell pwd):/work -w /work QEMU_CMD = qemu-system-aarch64 -M raspi3 -kernel kernel8.img -all: clean kernel8.img +.PHONY: all qemu clippy clean objdump nm -target/$(TARGET)/debug/kernel8: src/main.rs - cargo xbuild --target=$(TARGET) - cp $@ . +all: clean kernel8.img -target/$(TARGET)/release/kernel8: src/main.rs +target/$(TARGET)/release/kernel8: $(SOURCES) cargo xbuild --target=$(TARGET) --release - cp $@ . - -ifeq ($(DEBUG),1) -kernel8: target/$(TARGET)/debug/kernel8 -else -kernel8: target/$(TARGET)/release/kernel8 -endif -kernel8.img: kernel8 +kernel8.img: target/$(TARGET)/release/kernel8 + cp $< . $(OBJCOPY) $(OBJCOPY_PARAMS) $< kernel8.img -qemu: - $(DOCKER_CMD) $(UTILS_CONTAINER) $(QEMU_CMD) -serial null -serial stdio +qemu: all + $(DOCKER_CMD) $(UTILS_CONTAINER) $(QEMU_CMD) -serial stdio clippy: cargo xclippy --target=$(TARGET) diff --git a/04_mailboxes/kernel8 b/04_mailboxes/kernel8 index 822794ab9fed42fe03cc8315e7b47911bb937851..32219e4edd398b0a795dd1e903b052fa9e744a79 100755 GIT binary patch delta 1185 zcmZ8fOK1~O6uoyQ$t2PEsfjhlHZS-sm005!7g`0;g@VSqDiM=*)XcAxJ?Nx~V^0xG}D(RuOTbAjbPF|6=q1PC z68vGbtnu_~V6Of<>AO|DKGcK-JTYY8n_wK_Tv&ykz13>R{juiJ8%ldQ7;x^|Mgxc; z+)S4cbJ#*Y1sicbEmW`-=g>~MYoN4(E6{0iRk|m+?^Kc87y8MZQURK#;B0(Ln^h*q zE%GUyRGEBelMm>%BySNqxbqqX9r&_{0E6KnD1Xo(7P%cVQc5ZQu1hh})1dtHcam7cFq*+k_g5dGJxgw~uO5Y+^Co{8+@BLoB$RB2JuzTWOUO7vp+La7a#Q?d1+Y(~;#(0NF7epp~SdVx+mnX!Iyk01X zr0CI)iQb&(%4K`g**;yQayd@+N25`(C9mr;FNl45CX+iN;(dkQWS5@IvP3!|wjUD( zJ)cfyM7Hl>O3(9vb)xO4$?eW2QyHC=>AMS;Qdq+zUZ4Su-|`t<(AfSYp&J{ERhQfP z3+?X-Gb*r1`yW4TjaR1m@^jTDZqymN#<&818{iQC zP;$MZh&;_FD=35>Yzzv1E8ybWbs`HTy$pwGIad{Hqeknh+PS;opYGZX{I>C$wHmIn zl^I+QP($Q&fa#1&otpki3xQr1dbJBJ_>5`KH&QOKnDK*W04UK^SwfS&KprlzPb5zTLi$jPG`mj|w@1=`A PT<>|}wMts4;=}MC4POP^ delta 1072 zcmZ9LO-K}B7{{OIo!y<;m0i^QVA*tMi%9bzZBbH@TM!u0p-m5UC_h+iaa(CugCJTX z3Oz)QWKV@wcuAoSB9(i}OgcnRR_0ZsgRPemBP(coW@jd9-^=s9|KIcRpLb>^hiyGW zw*D#%Y1KQOk_@>ejYlW4I6PQ^NxU$q;k>s2;ksXfj^=E(@$q!!R^h1a9CY+@M62lh; zoT5I7;e-hv(wq)Q2yI+BL|z-dJLn&TbT9P0t%7?iCF>~sS%zRn@&y%~T3MDVf>95o zOBU`YG8AJ4;Iv2JZ@`BOstr&j~d8v=NivV7}-JrS;sO z`o7%Qf9HKJchslp?4tx_K|2r6i4ROst_WVCeGY6-#j{ybL4Cg<`L|3-CqF1WM+vOg zoE)n;)}yjK%}@6Cd>Phs?K!`?uV!sSBo^yb!`;cQmbOSsJm5NfPEAG<(UzDR?>^lc zNvP4}F4ff(Z)uH1)UHnTOm`$ z1#cNU22SqHYvQ9ZC)TD0%ozaxJGW-{=auc?cE$g+v#M52-STSbKUgp1{QUlQ_RM{P zU=7%wGXhY+pb#WbWUGY%N-drGT=?cmTLHdCs&k`?Gjz<2wMEw5&p7mH0QGc>WvA6g nqFFcAmnyPBm&`kJa3=q}9;^{xoD}xpURR~dNC^nK?Z(PKXG`p8 diff --git a/04_mailboxes/kernel8.img b/04_mailboxes/kernel8.img index 9a7cef7a568243a39356c6f901be62d26c3ae8e3..3ce695a4119d9e9763ab91fddadbd6ef2fa29d00 100755 GIT binary patch delta 596 zcmXw!L1+^}6o%)`X458OgfunAG|4O?ArwO0;KhT+L(zi;jp?aGx`|_560^9QXbVDG zyjbwi<+ap{=*e0T^kQuef)u>;Bueq%rRgcHC{nyAVw~Nrr}^jm-~8{N`=Q^Vg&|n6 z6BazM?a#3Skj0cls*}B5acv{H{+#C9u|fIjC7gpejN)T3AcKc#6i(ntIt<6~iqK)y zX%1wU_wcpgKd~eDclJ;{}2*3ePa+`_uwL z7E(*3z1v4rixu-Z*5##R~`-7PR`Duq#7AmE=0Ch%r)_Lp3HvCkf-}yDXs?KU3h;_N~qm5S>0>F z>XHZ?Lq#5di+Ea2!&xlJX|3CrZ|_Q=rXWyNC@H#?`V)3p@+v(Pv7LCn?X3IZ=%}Z^ z3GL1{5?&RFsIsW;vgrdR>fOVbe+sVSoIi3Ll6FA+AS2Fm(EoLVkmA7|U-}1I!HJO) z8$VwtGTmY|{SH@x6Q@e-vdJxrX{^d;Si@iyqu$W#P0q@OA;eTRn`IYF&K+&B8@yIC z?y^GDYG@U%)kTC}Vq-JR;-;?ESiO0x%uTW23>%qtz45wMu5pokgxzj(^Z%q0{0D~6 B$zlKi delta 523 zcmeyx*UUFThH>sh*kx^HlUaWEeE^qN`LD3gz2r^tilMX!_@R=%!hTsal!%qRw+(`!Pr4=^x< z$SW{k1&M`Dp2(`s=skHSt9tzxc88rz3=AS5xeTD3C?kWA4N%X1CWv<#85kziABx+d zC?GviiK!vzK{C_CdH?=Tf5FUXG@pqhTak$&1f)hWM0(;PsQfgb{6lGnoglTpKx}ac z`#X>gR=YxaB1rBLGlQ5BE6{SV;2NkPyR1>$WJk92`n>=DrzD%fy=a( diff --git a/04_mailboxes/src/main.rs b/04_mailboxes/src/main.rs index f3bfe851..1f8d42d0 100644 --- a/04_mailboxes/src/main.rs +++ b/04_mailboxes/src/main.rs @@ -34,14 +34,17 @@ mod uart; use core::sync::atomic::{compiler_fence, Ordering}; -raspi3_boot::entry!(kernel_entry); - fn kernel_entry() -> ! { let mut mbox = mbox::Mbox::new(); let uart = uart::MiniUart::new(); // set up serial console uart.init(); + uart.puts("\n[0] UART is live!\n"); + + uart.puts("[1] Press a key to continue booting... "); + uart.getc(); + uart.puts("Greetings fellow Rustacean!\n"); // get the board's unique serial number with a mailbox call mbox.buffer[0] = 8 * 4; // length of the message @@ -64,16 +67,13 @@ fn kernel_entry() -> ! { Ok(()) => true, }; - uart.getc(); // Press a key first before being greeted - uart.puts("Hello Rustacean!\n"); - if serial_avail { - uart.puts("My serial number is: "); + uart.puts("[i] My serial number is: 0x"); uart.hex(mbox.buffer[6]); uart.hex(mbox.buffer[5]); uart.puts("\n"); } else { - uart.puts("Unable to query serial!\n"); + uart.puts("[i] Unable to query serial!\n"); } // echo everything back @@ -81,3 +81,5 @@ fn kernel_entry() -> ! { uart.send(uart.getc()); } } + +raspi3_boot::entry!(kernel_entry); diff --git a/05_uart0/Makefile b/05_uart0/Makefile index ee81d528..4797e77b 100644 --- a/05_uart0/Makefile +++ b/05_uart0/Makefile @@ -24,6 +24,8 @@ TARGET = aarch64-unknown-none +SOURCES = $(wildcard **/*.rs) $(wildcard **/*.S) link.ld + OBJCOPY = cargo objcopy -- OBJCOPY_PARAMS = --strip-all -O binary @@ -31,26 +33,18 @@ UTILS_CONTAINER = andrerichter/raspi3-utils DOCKER_CMD = docker run -it --rm -v $(shell pwd):/work -w /work QEMU_CMD = qemu-system-aarch64 -M raspi3 -kernel kernel8.img -all: clean kernel8.img +.PHONY: all qemu clippy clean objdump nm -target/$(TARGET)/debug/kernel8: src/main.rs - cargo xbuild --target=$(TARGET) - cp $@ . +all: clean kernel8.img -target/$(TARGET)/release/kernel8: src/main.rs +target/$(TARGET)/release/kernel8: $(SOURCES) cargo xbuild --target=$(TARGET) --release - cp $@ . - -ifeq ($(DEBUG),1) -kernel8: target/$(TARGET)/debug/kernel8 -else -kernel8: target/$(TARGET)/release/kernel8 -endif -kernel8.img: kernel8 +kernel8.img: target/$(TARGET)/release/kernel8 + cp $< . $(OBJCOPY) $(OBJCOPY_PARAMS) $< kernel8.img -qemu: +qemu: all $(DOCKER_CMD) $(UTILS_CONTAINER) $(QEMU_CMD) -serial stdio clippy: diff --git a/05_uart0/kernel8 b/05_uart0/kernel8 index 9f71b984b275a678e2401f3ad7baeddd197121c8..c647911a95c13b23b08e352f8fcd8404ea173f56 100755 GIT binary patch delta 1457 zcmZ`%U1$_n6h3EWwmZ9P)|zBpwrQL@pqQ+6SfZh}HgUTVO$6zcTMU!+TOALics zedjypeCJN#iuC(cX}m_L59-lIf42XvW4|Fwb3lhxQ0x`!~KoP9f80BBQ~`11py zd3J8{67I%3x98}K{roZF1KiK&1Po&XUlgzkqx`9WnU{hjHUvl)9q|~6!y!+rjQpI4 z(a1jl6Tg-4+ll{^&x!a-WR>XulRxBT67GpCZlb==-;zjuZxeNaUpCdZH&Nf@OQ!m> zP1I9-uZPq+(chGG9-_`K@<9)F!4{Fh7m@9arK0vcM9hd#V$dw5HBPu9?oPR zJu|q)eWB>flFbzf696jBN%zvQDz{0klxyNDl}Z{$n;DORACMn?&N~WAWw(*=M*5Y8JRN$!y z`sYG*e9RBCZX@QaZ6Ddu`Z~p#uVpqeMosw2pj_^Mxx7h*!KG(Ln}VVAH0>+ij^^3N zBE}W;rBwl}uGPCt?-Xs9Gt}u)Rr9RrAYjlrY@cO1TNBx-+U`V%duSRKR^wpgm~-@E zPd-oK4A^{8RH6m3;}@BRBTuWkkM>&Hn^0c+mj1kr`-kwCiG4@?KXJ7F_acS%OdVK_4o$6D8HJQ@8*K;~u-LME{Gq=DA8&I61JIC^vFUf9Hn)uA}*q3>WxP8P;ucUunT>S%iGT6vyA2*>(SzZnmzrEjpt}{zurvg9z%)Lk9i>F&ytOR{RFKDPo3m7hrHD%#UM#i~J&< zajvlaKYW>@44CQsbOil@$_z};96?XgBb9!B1pSQGRGN;U70Na;eVgsKVVyg;b01wb zVs&>BKyEcps~>y|>F{LNZm05f(dD+_-0p^$;I^-hwyvkb*hV*wwewKUb2_Q3@^H$k zR;6n_fk5S+2uh!j;BK(Ov;YvReu)N-adakDl3#Lq)+~C;|+0GoJJ!QArkj<*T)V^5!5w>ms^`1+zCvfJ!wcX)jS3 z(ftYb*IY%@YHVD9&+*#X&Sy+fgG(euHNT7CHgey=1ZQ>4l;9qrY!lXd?{K^f^5Uu} zWz31yU(Jk~{gPtgJ)QSLG;hA+f9UZ27VN9qd%p6H&X&|QHMPj)9c}HN+B#2jlC`u` zZmVl;^fbxM9hYnBTII&JeA!Cp%;=^YX1wma$K415LW;=scs22O)HO>n7XFpDDBXhf zI8F+`70;TqAT0#oZtx($LYRJE*FT5pL{2M8=?!7>Lk<@JVZf-R|HeJ3>m&7;xra4v z+YfHexS)w}B`k@H{8r3Cq8%<#d@an)W9kH#2vMPXxcIuN9%?D1%TyML@%dT09ZHw0 zH3n|hkAn!?VPy&qbsCAp#VOx0+(v4S#$ diff --git a/05_uart0/kernel8.img b/05_uart0/kernel8.img index 9180dac267ab142dda08228c95ca418724d8eb8e..246f1439c0a37277dddcc581b3eaf1f117c52ecb 100755 GIT binary patch delta 875 zcmZ`%O-vI}5PomB4cij@ftIH7vu_iV3d9B$6B7@DC%KSlTjGIW*^;$3{n>Q4RY{18 zBqkUyY#xS~XcR9B&|T?&1&OWFcsvoFpN7k#)8$9Ed&5y!qyv`DW(r9RGP@ zrWJ1(ZBh3!Mzj3HwRj$(5Kq{zt4x2cU_AEWcW(+ljFWU5uj2Exz<6*EU1M5sC*5O| zQ^$a2GALfG(x!ptaod9&rgzy+?_Y#wzaN2{0sc)3Y_GQj=>N!@w87TpU8}+UOt0E{ zy~{PYdHNK%Z)!S#r3&Va))AV43W`t4R zh%l3Z;uvEzu~UJj%?0(xzByOMUh&3;t%4OH#vtUfc6$?++TPaY6kA+y`iKr2{?JcemIU(Sh^3CALl6@}b3&ju#(6!9gg- zPYfL%(25OIWA~uJ9*c~ZOq)3EM7aYY*0q|)+k+P&&pMMOWEw;`8c-vbY;EilP1obBPo{G+p_CL!$X4le KR#p!Z1?N9&1}$g+ delta 720 zcmaDR@S1;u4CD2Qvgx9`85yR?*Mw&uU|+LCQR+5Kp476rPwVR9jBe7yq$gGoFvd^#B#E@?6>_#`YmJ?I6qv=JxcflsfP zWsQU%EH8SY&am=TJ>$v}U|_@mO_Q$)frl$dEF3D<`2T;%7iNZu9Za%D8C(oInHU&E zKw+N&R3lm`7wijlNg_~PMpN7lPF{w|+u8W*MY0$E1L|aV*eT516eRp)c@c_EL6%?} zB%O>53=`^sx)nFbO;loP2zrprG;!Cz|I=SEGaAij;>cEHVh91LQT!q|aS>F06Hxx4 zw8Ku2TCx8?wm5_>3}iE^fE0VkPXtLmVrDR61v(pSfDcrRUDjyPWL@_3>@J{k1qOvH z518e(4lu`G;{fX9I4D1n6G&?UX?sSF*N1>92hMM0_yH0-4D|3vs9ulMoSb}xpwi-! l#N^b(JVh?wN`>OoqRhk`g}l<-q|_pX%wj7AuE~BJ5&(vy^l1P9 diff --git a/05_uart0/src/main.rs b/05_uart0/src/main.rs index b1493f97..7ccca746 100644 --- a/05_uart0/src/main.rs +++ b/05_uart0/src/main.rs @@ -34,17 +34,22 @@ mod uart; use core::sync::atomic::{compiler_fence, Ordering}; -raspi3_boot::entry!(kernel_entry); - fn kernel_entry() -> ! { let mut mbox = mbox::Mbox::new(); let uart = uart::Uart::new(); // set up serial console - if uart.init(&mut mbox).is_err() { - unsafe { asm!("wfe" :::: "volatile") }; // If UART fails, abort early + match uart.init(&mut mbox) { + Ok(_) => uart.puts("\n[0] UART is live!\n"), + Err(_) => loop { + unsafe { asm!("wfe" :::: "volatile") }; // If UART fails, abort early + }, } + uart.puts("[1] Press a key to continue booting... "); + uart.getc(); + uart.puts("Greetings fellow Rustacean!\n"); + // get the board's unique serial number with a mailbox call mbox.buffer[0] = 8 * 4; // length of the message mbox.buffer[1] = mbox::REQUEST; // this is a request message @@ -66,16 +71,13 @@ fn kernel_entry() -> ! { Ok(()) => true, }; - uart.getc(); // Press a key first before being greeted - uart.puts("Hello Rustacean!\n"); - if serial_avail { - uart.puts("My serial number is: "); + uart.puts("[i] My serial number is: 0x"); uart.hex(mbox.buffer[6]); uart.hex(mbox.buffer[5]); uart.puts("\n"); } else { - uart.puts("Unable to query serial!\n"); + uart.puts("[i] Unable to query serial!\n"); } // echo everything back @@ -83,3 +85,5 @@ fn kernel_entry() -> ! { uart.send(uart.getc()); } } + +raspi3_boot::entry!(kernel_entry); diff --git a/06_raspbootin64/Makefile b/06_raspbootin64/Makefile index ee81d528..4797e77b 100644 --- a/06_raspbootin64/Makefile +++ b/06_raspbootin64/Makefile @@ -24,6 +24,8 @@ TARGET = aarch64-unknown-none +SOURCES = $(wildcard **/*.rs) $(wildcard **/*.S) link.ld + OBJCOPY = cargo objcopy -- OBJCOPY_PARAMS = --strip-all -O binary @@ -31,26 +33,18 @@ UTILS_CONTAINER = andrerichter/raspi3-utils DOCKER_CMD = docker run -it --rm -v $(shell pwd):/work -w /work QEMU_CMD = qemu-system-aarch64 -M raspi3 -kernel kernel8.img -all: clean kernel8.img +.PHONY: all qemu clippy clean objdump nm -target/$(TARGET)/debug/kernel8: src/main.rs - cargo xbuild --target=$(TARGET) - cp $@ . +all: clean kernel8.img -target/$(TARGET)/release/kernel8: src/main.rs +target/$(TARGET)/release/kernel8: $(SOURCES) cargo xbuild --target=$(TARGET) --release - cp $@ . - -ifeq ($(DEBUG),1) -kernel8: target/$(TARGET)/debug/kernel8 -else -kernel8: target/$(TARGET)/release/kernel8 -endif -kernel8.img: kernel8 +kernel8.img: target/$(TARGET)/release/kernel8 + cp $< . $(OBJCOPY) $(OBJCOPY_PARAMS) $< kernel8.img -qemu: +qemu: all $(DOCKER_CMD) $(UTILS_CONTAINER) $(QEMU_CMD) -serial stdio clippy: diff --git a/06_raspbootin64/src/main.rs b/06_raspbootin64/src/main.rs index 2396cb9a..ff0bb94e 100644 --- a/06_raspbootin64/src/main.rs +++ b/06_raspbootin64/src/main.rs @@ -32,8 +32,6 @@ mod gpio; mod mbox; mod uart; -raspi3_boot::entry!(kernel_entry); - fn kernel_entry() -> ! { let mut mbox = mbox::Mbox::new(); let uart = uart::Uart::new(); @@ -77,3 +75,5 @@ fn kernel_entry() -> ! { // Jump to loaded kernel and never return! kernel() } + +raspi3_boot::entry!(kernel_entry); diff --git a/07_abstraction/Makefile b/07_abstraction/Makefile index ac35bea6..b3e446c7 100644 --- a/07_abstraction/Makefile +++ b/07_abstraction/Makefile @@ -24,6 +24,8 @@ TARGET = aarch64-unknown-none +SOURCES = $(wildcard **/*.rs) $(wildcard **/*.S) link.ld + OBJCOPY = cargo objcopy -- OBJCOPY_PARAMS = --strip-all -O binary @@ -33,29 +35,21 @@ DOCKER_TTY = --privileged -v /dev:/dev QEMU_CMD = qemu-system-aarch64 -M raspi3 -kernel kernel8.img RASPBOOT_CMD = raspbootcom /dev/ttyUSB0 kernel8.img -all: clean kernel8.img +.PHONY: all qemu raspboot clippy clean objdump nm -target/$(TARGET)/debug/kernel8: src/main.rs - cargo xbuild --target=$(TARGET) - cp $@ . +all: clean kernel8.img -target/$(TARGET)/release/kernel8: src/main.rs +target/$(TARGET)/release/kernel8: $(SOURCES) cargo xbuild --target=$(TARGET) --release - cp $@ . - -ifeq ($(DEBUG),1) -kernel8: target/$(TARGET)/debug/kernel8 -else -kernel8: target/$(TARGET)/release/kernel8 -endif -kernel8.img: kernel8 +kernel8.img: target/$(TARGET)/release/kernel8 + cp $< . $(OBJCOPY) $(OBJCOPY_PARAMS) $< kernel8.img -qemu: +qemu: all $(DOCKER_CMD) $(UTILS_CONTAINER) $(QEMU_CMD) -serial stdio -raspboot: +raspboot: all $(DOCKER_CMD) $(DOCKER_TTY) $(UTILS_CONTAINER) $(RASPBOOT_CMD) clippy: diff --git a/07_abstraction/README.md b/07_abstraction/README.md index 29889b9d..0b223a77 100644 --- a/07_abstraction/README.md +++ b/07_abstraction/README.md @@ -64,20 +64,20 @@ replaced it with a Rust function. Why? Because we can, for the fun of it. #[link_section = ".text.boot"] #[no_mangle] pub unsafe extern "C" fn _boot_cores() -> ! { - use cortex_a::{asm, regs::mpidr_el1::*, regs::sp::*}; + use cortex_a::{asm, regs::*}; + const CORE_0: u64 = 0; const CORE_MASK: u64 = 0x3; const STACK_START: u64 = 0x80_000; - match MPIDR_EL1.get() & CORE_MASK { - 0 => { - SP.set(STACK_START); - reset() - } - _ => loop { - // if not core0, infinitely wait for events + if CORE_0 == MPIDR_EL1.get() & CORE_MASK { + SP.set(STACK_START); + reset() + } else { + // if not core0, infinitely wait for events + loop { asm::wfe(); - }, + } } } ``` @@ -93,7 +93,7 @@ should yield something like the following, where you can see that the stack pointer is not used apart from ourselves setting it. ```console -ferris@box:~$ cargo objdump --target aarch64-raspi3-none-elf.json -- -disassemble -print-imm-hex kernel8 +ferris@box:~$ cargo objdump --target aarch64-unknown-none -- -disassemble -print-imm-hex kernel8 [...] (Some output omitted) @@ -103,9 +103,9 @@ _boot_cores: 80008: 60 00 00 54 b.eq #0xc <_boot_cores+0x14> 8000c: 5f 20 03 d5 wfe 80010: ff ff ff 17 b #-0x4 <_boot_cores+0xc> - 80014: e8 03 09 32 orr w8, wzr, #0x800000 + 80014: e8 03 0d 32 orr w8, wzr, #0x80000 80018: 1f 01 00 91 mov sp, x8 - 8001c: 35 02 00 94 bl #0x8d4 + 8001c: e0 01 00 94 bl #0x780 ``` It is important to always manually check this, and not blindly rely on the diff --git a/07_abstraction/kernel8 b/07_abstraction/kernel8 index 3f058c28240ac7fbeb5de31a408bf0f872e28ca0..24771fac3a39276b391990a209930c3e6a7ded20 100755 GIT binary patch delta 1214 zcmZ9KO-NKx6vxlGZ*1Po(2$NMk?->U@M^2Y94EorzZWDA7LBh;{HIgFLOIV$lTe>p$DA zq$ooZZ#Zw*#78GK3eAZ*oD(@2%d_8|)+m?*0T+#(fm>eBFI&92fDc=|rGQ_v_<;g` z!{7*2VCXj)NBtu#LoHjMc!D^Cd;mD;b@laLpkBWn)=&_(U^pR+NbBW(TD-PsJ%2;5 z%NT;q6IPm4i`)9g>8vlB7u~-kpJ2i=tQd766UA;U-@*+_^H*@q+fB258xsX)AzCQ< zaI>DAdbiEH%-j$sUP9bfwOct#Md{qWLz}mYDU#b3CG#ebpsV0b;(0E?B#0iGqh6xA=|J67nlluFsZmTK z@QU&)2>zFw-i6FpaihKg|KDCyOhBrEy`iK_G3K*JWQY^s0&;+)8>T@%HpYod?{t(gQ zJL6aNlHUS^N@!NyE^y9dqL;5C_Ta=ykl}F2)djz5r+kp^R+Rp{r~UK)AHcrOKG6P8 z4m2)<{Pkiq9v_gyLxV}BGph6l9G6Gr!DymKiOc;%eYc|txo7aK?BMMZHt}HzM~^Rw zQtmyO=ZJAL$nZ)#x`UsJ(zFK!gU>}g&BsXI^w>z#My$|v$|yppgB)Kci5_cQmC&8C z%A}&QABG5_ODMEkH#w9P@^^Y?Mu*Ac^cwZZn%wfgZnk$*p7hRqgJ))9)0hkQbK}(* z6d_);w1>D2{%W}SRMY|%igNIqr*vPObm1>Nrlgr;_}Lsqgc=Q-EyqOCH}M=Pgh!> z&XP!zP_*)&giEa^+ajuC)x4ns8>+LWgk~_}2%R1tt-w<(>)=xrc-~P{nse!6{8u^p F{sHtg&$R#m diff --git a/07_abstraction/kernel8.img b/07_abstraction/kernel8.img index 63c5a4b060ff7bc9167c6d1b1d07b353e82e2180..038d6139c7d9aef0d0ea61eb4d93f76a705faf16 100755 GIT binary patch delta 495 zcmaFPe@|e74C8}|vd;A-3=C5e7#K|A6_~I7|Nmc{k%3`?qJ#XzB&LR-2gytmg_)az zgr6)gItWw;mg|w9_=p7}w+AT3#K0gT57e8%@a25hvq;Pp_C|jb5lTtbA3^ zxN<7cz-2(g2rvug9 zhdQKV;zLmd(d>o){)fC^ci8!onbAm|kuzJ7i2>|J#Tg0{lb9z5F{;b4C_-Gy%wWU{ z^cmR498fWCxyjQRGa2hQGcr}M);B6ntdNsgma51VZ5XQ%P?TC+tdOXXom#0-lCO}QpI4HZSDLDj zl%Ee|r0ePFDYzGq8I86D__+!t}J14*twOFVTycBNcI5+h7ft6UXa)Zs959w{~=$P876ix z$r@#FG3;bwU=RVR$pESmt&|I122{77i6J}j|Nr`sjHb99oV*M|9Jw+=_KFOJ5C8oS zk!KXiUI?VWusiG&W^M`+ezLp>#SlT3;Hd~hLKqnsCe#DXQCuK5QHiM`=s_~m#BQL+ zUNAEn&1d4sR%BuTt5JL+H*pbEz8NV0P ! { pub unsafe extern "C" fn _boot_cores() -> ! { use cortex_a::{asm, regs::*}; + const CORE_0: u64 = 0; const CORE_MASK: u64 = 0x3; const STACK_START: u64 = 0x80_000; - match MPIDR_EL1.get() & CORE_MASK { - 0 => { - SP.set(STACK_START); - reset() - } - _ => loop { - // if not core0, infinitely wait for events + if CORE_0 == MPIDR_EL1.get() & CORE_MASK { + SP.set(STACK_START); + reset() + } else { + // if not core0, infinitely wait for events + loop { asm::wfe(); - }, + } } } diff --git a/07_abstraction/src/main.rs b/07_abstraction/src/main.rs index 82237308..937b662d 100644 --- a/07_abstraction/src/main.rs +++ b/07_abstraction/src/main.rs @@ -33,19 +33,22 @@ mod uart; use core::sync::atomic::{compiler_fence, Ordering}; -raspi3_boot::entry!(kernel_entry); - fn kernel_entry() -> ! { let mut mbox = mbox::Mbox::new(); let uart = uart::Uart::new(); // set up serial console - if uart.init(&mut mbox).is_err() { - loop { - cortex_a::asm::wfe() - } // If UART fails, abort early + match uart.init(&mut mbox) { + Ok(_) => uart.puts("\n[0] UART is live!\n"), + Err(_) => loop { + cortex_a::asm::wfe() // If UART fails, abort early + }, } + uart.puts("[1] Press a key to continue booting... "); + uart.getc(); + uart.puts("Greetings fellow Rustacean!\n"); + // get the board's unique serial number with a mailbox call mbox.buffer[0] = 8 * 4; // length of the message mbox.buffer[1] = mbox::REQUEST; // this is a request message @@ -67,16 +70,13 @@ fn kernel_entry() -> ! { Ok(()) => true, }; - uart.getc(); // Press a key first before being greeted - uart.puts("Hello Rustacean!\n"); - if serial_avail { - uart.puts("My serial number is: "); + uart.puts("[i] My serial number is: 0x"); uart.hex(mbox.buffer[6]); uart.hex(mbox.buffer[5]); uart.puts("\n"); } else { - uart.puts("Unable to query serial!\n"); + uart.puts("[i] Unable to query serial!\n"); } // echo everything back @@ -84,3 +84,5 @@ fn kernel_entry() -> ! { uart.send(uart.getc()); } } + +raspi3_boot::entry!(kernel_entry); diff --git a/08_random/Makefile b/08_random/Makefile index ac35bea6..b3e446c7 100644 --- a/08_random/Makefile +++ b/08_random/Makefile @@ -24,6 +24,8 @@ TARGET = aarch64-unknown-none +SOURCES = $(wildcard **/*.rs) $(wildcard **/*.S) link.ld + OBJCOPY = cargo objcopy -- OBJCOPY_PARAMS = --strip-all -O binary @@ -33,29 +35,21 @@ DOCKER_TTY = --privileged -v /dev:/dev QEMU_CMD = qemu-system-aarch64 -M raspi3 -kernel kernel8.img RASPBOOT_CMD = raspbootcom /dev/ttyUSB0 kernel8.img -all: clean kernel8.img +.PHONY: all qemu raspboot clippy clean objdump nm -target/$(TARGET)/debug/kernel8: src/main.rs - cargo xbuild --target=$(TARGET) - cp $@ . +all: clean kernel8.img -target/$(TARGET)/release/kernel8: src/main.rs +target/$(TARGET)/release/kernel8: $(SOURCES) cargo xbuild --target=$(TARGET) --release - cp $@ . - -ifeq ($(DEBUG),1) -kernel8: target/$(TARGET)/debug/kernel8 -else -kernel8: target/$(TARGET)/release/kernel8 -endif -kernel8.img: kernel8 +kernel8.img: target/$(TARGET)/release/kernel8 + cp $< . $(OBJCOPY) $(OBJCOPY_PARAMS) $< kernel8.img -qemu: +qemu: all $(DOCKER_CMD) $(UTILS_CONTAINER) $(QEMU_CMD) -serial stdio -raspboot: +raspboot: all $(DOCKER_CMD) $(DOCKER_TTY) $(UTILS_CONTAINER) $(RASPBOOT_CMD) clippy: diff --git a/08_random/kernel8 b/08_random/kernel8 index f8cdc8477dbb93de435e87097043396a6d4f1dc6..f511cb964aa80716f08f4f09c17be5afb14f3e51 100755 GIT binary patch delta 1253 zcmZ9KUr19?9LLY^-p#wsKWuZiF;RC0l3Fm_5G%0KeDE#ivR=$;&RZwxZ3q_EW3~>xJ{oWCIi~h}GfA_u#1?*`^>LSy!220hGBTTasl9qwd$2$wbM`|dW}%G@lA>)AmR@PgqD!zYGK21I5Yw292n$Z(LMi$P(y z$uQ6Gj$uPbZb9E6plZ|N_?aT($aNciS+zaWtKj}-BhW;3H`Vzj`N_%_rt>T1dKJ^d zG@VIxMxos_;6x(YHZ7=$>%>(CU&{M~EvT+PxKDfSU)d~!4dGPkf{^#qxnYZ%H^>)EE z*DmFQ`k`Y!%>&lbN>^VRSSrTxM8`>h!U#amuquBx3?mkm?`Y8VUrDEzbz+( z4^n-)KenE8)$2E9DkD*OThGyC%(Z0ePW~%SdDfMk0*`FNwskJtBf57{FFGw1;j6p8 zT*@-zX~t#74aPmj6UHmXI-|zeVz@=dk1^cG=wkFUE;6PW4;il+-z?0`TQ@}5Y&e|L zQ?OfZxzXn@^~4;7ObRGlIe#>9WdzNS9_ diff --git a/08_random/kernel8.img b/08_random/kernel8.img index 1ca65a6b8b98d0936586eae2961a6e74e386b98e..43c230a60284d13351b365ea667638fa0099ca2d 100755 GIT binary patch delta 381 zcmcb__m+Qx4C8@`vd;A(3=C5e7#K|A6_~I7|Nmc{k%3`?qJ!+jB&LR-2gytmMVXs| zM4v1#S_o7Jmg|w7_=p7}HwP%j#K0gT57fJY$zi9kAWQH}MusW%ObpqH|Nn=8)bDSK z+o7l-HxXpkBW^jPX$&1fVvm*=^#b*t;B%1N`I4E>2yE~Hh$0R~2BSyJGDZ_Gh^RNf zEM<_N=)?-Kv>GTT3^Z5-h>KUrPn@zze&Y91#`&9b87o+&4$4pD1WITEX?sSF*M}Gw zLZJM~|Jg+AxuOkX6+#_@LKHHK6>>7mQWd$P4PzAoic*V<6%rM)Q!5op@)eTv^GY)F zN>de*^7Da=bUi&i1^1%VR1mvZAuTm0C%;@FsI<5wF*!9cPmzlO4x)`>6@vWS6^c?5 UQ!4eixS$5-RYHuOY{D)F03;E3dH?_b delta 226 zcmaFMe~E8`4CBU$vd)^W3=C5e7#K|A6_~I7|NmcHl({KL^vUufCI$u(d7#(|CWoEE zf-J#PCT?8G7Y9o0ZR!a%hmKwNAmJ8_De>||rcQpR ! { pub unsafe extern "C" fn _boot_cores() -> ! { use cortex_a::{asm, regs::*}; + const CORE_0: u64 = 0; const CORE_MASK: u64 = 0x3; const STACK_START: u64 = 0x80_000; - match MPIDR_EL1.get() & CORE_MASK { - 0 => { - SP.set(STACK_START); - reset() - } - _ => loop { - // if not core0, infinitely wait for events + if CORE_0 == MPIDR_EL1.get() & CORE_MASK { + SP.set(STACK_START); + reset() + } else { + // if not core0, infinitely wait for events + loop { asm::wfe(); - }, + } } } diff --git a/08_random/src/main.rs b/08_random/src/main.rs index 31d7c371..be364ab9 100644 --- a/08_random/src/main.rs +++ b/08_random/src/main.rs @@ -32,26 +32,28 @@ mod mbox; mod rand; mod uart; -raspi3_boot::entry!(kernel_entry); - fn kernel_entry() -> ! { let mut mbox = mbox::Mbox::new(); let uart = uart::Uart::new(); // set up serial console - if uart.init(&mut mbox).is_err() { - loop { - cortex_a::asm::wfe() - } // If UART fails, abort early + match uart.init(&mut mbox) { + Ok(_) => uart.puts("\n[0] UART is live!\n"), + Err(_) => loop { + cortex_a::asm::wfe() // If UART fails, abort early + }, } - uart.getc(); // Press a key first before being greeted - uart.puts("Hello Rustacean!\n"); + uart.puts("[1] Press a key to continue booting... "); + uart.getc(); + uart.puts("Greetings fellow Rustacean!\n"); // set up random number generator let rng = rand::Rng::new(); rng.init(); + uart.puts("[2] RNG ready.\n\n"); + uart.puts("Press any key to generate random numbers.\n"); // echo everything back @@ -63,3 +65,5 @@ fn kernel_entry() -> ! { uart.puts("\n"); } } + +raspi3_boot::entry!(kernel_entry); diff --git a/09_delays/Makefile b/09_delays/Makefile index ac35bea6..b3e446c7 100644 --- a/09_delays/Makefile +++ b/09_delays/Makefile @@ -24,6 +24,8 @@ TARGET = aarch64-unknown-none +SOURCES = $(wildcard **/*.rs) $(wildcard **/*.S) link.ld + OBJCOPY = cargo objcopy -- OBJCOPY_PARAMS = --strip-all -O binary @@ -33,29 +35,21 @@ DOCKER_TTY = --privileged -v /dev:/dev QEMU_CMD = qemu-system-aarch64 -M raspi3 -kernel kernel8.img RASPBOOT_CMD = raspbootcom /dev/ttyUSB0 kernel8.img -all: clean kernel8.img +.PHONY: all qemu raspboot clippy clean objdump nm -target/$(TARGET)/debug/kernel8: src/main.rs - cargo xbuild --target=$(TARGET) - cp $@ . +all: clean kernel8.img -target/$(TARGET)/release/kernel8: src/main.rs +target/$(TARGET)/release/kernel8: $(SOURCES) cargo xbuild --target=$(TARGET) --release - cp $@ . - -ifeq ($(DEBUG),1) -kernel8: target/$(TARGET)/debug/kernel8 -else -kernel8: target/$(TARGET)/release/kernel8 -endif -kernel8.img: kernel8 +kernel8.img: target/$(TARGET)/release/kernel8 + cp $< . $(OBJCOPY) $(OBJCOPY_PARAMS) $< kernel8.img -qemu: +qemu: all $(DOCKER_CMD) $(UTILS_CONTAINER) $(QEMU_CMD) -serial stdio -raspboot: +raspboot: all $(DOCKER_CMD) $(DOCKER_TTY) $(UTILS_CONTAINER) $(RASPBOOT_CMD) clippy: diff --git a/09_delays/kernel8 b/09_delays/kernel8 index 23cce42ccba9546833e697f4cd21352ea2c50262..12051a781c4813684cc43569b10afde57e480a87 100755 GIT binary patch delta 1169 zcmZ9MPe>F|9LImZnVofa-G$I(R@d|?Ybny^Ka4JE5lBT~i(WL-T^n;z+;Z2V4!H_} zgoO{>-oXMpM9`(AKNdTd_a@qz!@T!C-|z4De!n-5d9&hr z{?N75h>7q^7Al2U0&TBs5vl}J zL)ks-R2C{(GvXO7Q$_1Fb`vof`7dh5jtYlpy(+f8!r6XaYCC44%XdOdSMVH;ts4sZ z)gy01)XTLdK6are_YR=%-}*NEDX>k`>}xkoMu2S7x!{0ruw{t!pNRI6M2bu%t{HW{ z!PX(tJ8h&=Bt|BT8zh}1qsggsVrs@9@nn)uE=M8}(lc!sg?WmM8IzOA>m)jpO2x?Gc|wzNs}Tu%i|8`;zZD_=@CJ zjy$W9cRKiE$>V}Yt!3f$R0GS2O7>=sV(A}ubPwfSkm+jzJ@ zVVS6(3;RHYyyMJ=ZO&p|{Ghb9utpy?sFxzg*3bIz7t$q-b^DRvdlvKKp{6pK&%R_k znmC?PF-R4FUtvGimfG9p+(_ptSl*9~6?wPtj;O+2_`%e&!vSnodVOplfXBVJe8Mup I9tE)WFG^j?R{#J2 delta 1003 zcmZ9LPiPZC6vpSxrrT`Ngwon>LP@(RsZA(IlNPIuGznfLP|z6ZMQB43BoNbR({p3d zqmY$`0b4axLA;cf9x9$hJ@^N~q8^GKf`}K7UV4#rc6O%Nox=?C``-KBd&BPb1INpC zM?g;4hB zeg_?z?6qNJCk%sVNc(c3SS~MWndPNgE?>-5f-W*G!`Q%Fu2d^ku4z$ishD4^6tr+E zGpn7ycqKAT9?Ni&e3aqyN~^FB0qoH7C-_wzR+8?yYp(?i>9O zFa{*zuhP4@T-4U&B7TE&Ori>?;Ae+_ic#96ZRm4MUfE(+)Z8YECJ~>3h0$%!Y=+Jz z;wQPVN_h|EqKp{fENzl;KCIv~7LU<%3x&8*nhM=WLP^`3X9XuI7knT+ZV2w3al;=V z;~vnUMJ{<@)K7!h5}#13!+Ml;vhRT*vh9Ixw{VWjpx^2vZ4ZR|lCl*yE?N2JuNxo% WFO1=;LegHCQ64H*$O6&5F!T>>Yn#^q diff --git a/09_delays/kernel8.img b/09_delays/kernel8.img index 2e2db8f029d8162815d2980e767e54a72fecfb85..9d9e3d6e652dd1b2b4daa3f83f8496905314d501 100755 GIT binary patch delta 435 zcmdnZ^O|>p3}f6xS$l^*28JmK3=Agm3d~pk|Nk$}$iOf`u|a%d5>rFagJh*OlNd_5#Br7$fj(i4@KA+{C(#YBLvG-hlF zn$jgbS)9q2F>P}y6AyF!LFtK{Kp9OSZO_Q@`Va#{2%O)_@B<`v`2YV9Pl} zBr{Ds2~@_&z%W7ah}cA?i8oc`Qp6{M#2>LU80~_|6+p$f ! { pub unsafe extern "C" fn _boot_cores() -> ! { use cortex_a::{asm, regs::*}; + const CORE_0: u64 = 0; const CORE_MASK: u64 = 0x3; const STACK_START: u64 = 0x80_000; - match MPIDR_EL1.get() & CORE_MASK { - 0 => { - SP.set(STACK_START); - reset() - } - _ => loop { - // if not core0, infinitely wait for events + if CORE_0 == MPIDR_EL1.get() & CORE_MASK { + SP.set(STACK_START); + reset() + } else { + // if not core0, infinitely wait for events + loop { asm::wfe(); - }, + } } } diff --git a/09_delays/src/main.rs b/09_delays/src/main.rs index d9ce934e..23deae75 100644 --- a/09_delays/src/main.rs +++ b/09_delays/src/main.rs @@ -32,40 +32,42 @@ mod gpio; mod mbox; mod uart; -raspi3_boot::entry!(kernel_entry); - fn kernel_entry() -> ! { let mut mbox = mbox::Mbox::new(); let uart = uart::Uart::new(); // set up serial console - if uart.init(&mut mbox).is_err() { - loop { - cortex_a::asm::wfe() - } // If UART fails, abort early + match uart.init(&mut mbox) { + Ok(_) => uart.puts("\n[0] UART is live!\n"), + Err(_) => loop { + cortex_a::asm::wfe() // If UART fails, abort early + }, } - uart.getc(); // Press a key first before being greeted - uart.puts("Hello Rustacean!\n"); + uart.puts("[1] Press a key to continue booting... "); + uart.getc(); + uart.puts("Greetings fellow Rustacean!\n"); - uart.puts("Waiting 1_000_000 CPU cycles (ARM CPU): "); + uart.puts("[i] Waiting 1_000_000 CPU cycles (ARM CPU): "); delays::wait_cycles(1_000_000); uart.puts("OK\n"); - uart.puts("Waiting 1 second (ARM CPU): "); + uart.puts("[i] Waiting 1 second (ARM CPU): "); delays::wait_msec(1_000_000); uart.puts("OK\n"); let t = delays::SysTmr::new(); if t.get_system_timer() != 0 { - uart.puts("Waiting 1 second (BCM System Timer): "); + uart.puts("[i] Waiting 1 second (BCM System Timer): "); t.wait_msec_st(1_000_000); uart.puts("OK\n"); } - uart.puts("Looping forever now!\n"); + uart.puts("[i] Looping forever now!\n"); loop { delays::wait_msec(1_000_000); uart.puts("Tick: 1s\n"); } } + +raspi3_boot::entry!(kernel_entry); diff --git a/0A_power/Makefile b/0A_power/Makefile index ac35bea6..b3e446c7 100644 --- a/0A_power/Makefile +++ b/0A_power/Makefile @@ -24,6 +24,8 @@ TARGET = aarch64-unknown-none +SOURCES = $(wildcard **/*.rs) $(wildcard **/*.S) link.ld + OBJCOPY = cargo objcopy -- OBJCOPY_PARAMS = --strip-all -O binary @@ -33,29 +35,21 @@ DOCKER_TTY = --privileged -v /dev:/dev QEMU_CMD = qemu-system-aarch64 -M raspi3 -kernel kernel8.img RASPBOOT_CMD = raspbootcom /dev/ttyUSB0 kernel8.img -all: clean kernel8.img +.PHONY: all qemu raspboot clippy clean objdump nm -target/$(TARGET)/debug/kernel8: src/main.rs - cargo xbuild --target=$(TARGET) - cp $@ . +all: clean kernel8.img -target/$(TARGET)/release/kernel8: src/main.rs +target/$(TARGET)/release/kernel8: $(SOURCES) cargo xbuild --target=$(TARGET) --release - cp $@ . - -ifeq ($(DEBUG),1) -kernel8: target/$(TARGET)/debug/kernel8 -else -kernel8: target/$(TARGET)/release/kernel8 -endif -kernel8.img: kernel8 +kernel8.img: target/$(TARGET)/release/kernel8 + cp $< . $(OBJCOPY) $(OBJCOPY_PARAMS) $< kernel8.img -qemu: +qemu: all $(DOCKER_CMD) $(UTILS_CONTAINER) $(QEMU_CMD) -serial stdio -raspboot: +raspboot: all $(DOCKER_CMD) $(DOCKER_TTY) $(UTILS_CONTAINER) $(RASPBOOT_CMD) clippy: diff --git a/0A_power/kernel8 b/0A_power/kernel8 index 03daaaf5bddd4d5a4b443992b2d90297f0ea3a94..5d16cb6f09504bed7f0666053a329064738e1dd7 100755 GIT binary patch delta 886 zcmZ9J%WD%+6vpql6K9gt)GCaj51kwF(Wa2vv?<+a8#n4o8KWpk+oZ`@Vnae6t%!oD z;8MthmYe!02vUW*iL|uUO{(Z0AnL|VEv^&<34$9LZ)PTiLkv~+fl4KxqGtn`}52S)9JmJ9qNw7=q)owEf|iu&vmLb z@lMNO?;?XDGdakvDidCXyu8Zg<+azH>X$2B^b&@raEAWDFapJO9|wE6yWhH08*+^kD28)Ng|m=WjE0EqTmT59)1%mKi_5c-^HQ^Z|>abMr`bUZiCkIFBr` zb{pc*aMRpg>~i|U232d!<3mSdo}u-xcJN`fz|%Gd5ca$J9niPGWQHm6#z7y_G{Y@* sQ?CH(oJcDU=oW_sLlWkU;5;i5{pWyQT(VPlE1b4{Fvg8mX}T4p|3^x&e*gdg delta 699 zcmZ9KO=uHQ6ov136DKp1HvT{u6Ad#Fs;vrD5?mEqTqy|J5DH=?hEfU|H2$r0p%t;X znt_z7SPOzw6kJ5mQrrZE(4`A?;mUv;5mzE~H@?igDKu{}mpS))=bk%EdpY4fOL)WL z^MHTwnAOoKJRQAt>1}|8#XRORbx_l}bN+IhsN%TV*Qa7)ZEo=i98}+}p@`iTqUJ@S zQdKsCAh2z1zHI+|d7Tdn45ivx|Ae?({xKtbo)*aJR?h#nlH=O~&vBab8pg4-dO^d0 zHc{B)n?&A-tm80#f0Pq9-yhIMPx}-Em0}REOYWDGv-SE_w|wiy&DzXt?MlJoKRT*> zHVF^^xSPZoH2A0iJ3Fr%(Prw|3ag-3Tr-g26$81ElD3ukAQ?fR7l?EZ(dA#y%D>l9=pUr@5?Bmu2zcm1)j8E?`z8T4$^47Z}{@2&W|koU458B zQE+<@uKeuXL5%Kfs2dGET5gI9X^f^~qmB;$UWOZK3}@CAazu;5_Wr~?ze(ee*f9Bf Q8pqB3R^;-U3)|uR2g3M!P5=M^ diff --git a/0A_power/kernel8.img b/0A_power/kernel8.img index d82db789373ea95d199aef9550e142caff3a860f..580552a1bd66ffcf864f15b024faf6cdbe0731a7 100755 GIT binary patch delta 309 zcmX@cyNPdt4CADUvgx8_j0{ucYofCcFffG3D==T3&E&ANaN|a7jTs%{7#OA` zFff?J1Ev1||1ZwSz%W5EL26Qh~E`qTkXbW>g(AHhj6R(BIOb%vR$mlfrE0aCr zq|K(xJk0eEWhQb0)oKE1dq$4ehk(w6^II8yfW!{}{~u!f|NnFa28AnJ(FU;!p^iZz z3YouqyMusW!HPP7z7#Kq26_~HiW^&k>K5?czWBkUQ#*7jn3=C5e z7#K|Afl~kf{}&f$ZVD2Avb<=r4wEYP0m+F@ObtN~l9?t>j$x8y1hfjyZ)Nxa5 ! { pub unsafe extern "C" fn _boot_cores() -> ! { use cortex_a::{asm, regs::*}; + const CORE_0: u64 = 0; const CORE_MASK: u64 = 0x3; const STACK_START: u64 = 0x80_000; - match MPIDR_EL1.get() & CORE_MASK { - 0 => { - SP.set(STACK_START); - reset() - } - _ => loop { - // if not core0, infinitely wait for events + if CORE_0 == MPIDR_EL1.get() & CORE_MASK { + SP.set(STACK_START); + reset() + } else { + // if not core0, infinitely wait for events + loop { asm::wfe(); - }, + } } } diff --git a/0A_power/src/main.rs b/0A_power/src/main.rs index 015ef27d..b928ee51 100644 --- a/0A_power/src/main.rs +++ b/0A_power/src/main.rs @@ -33,8 +33,6 @@ mod mbox; mod power; mod uart; -raspi3_boot::entry!(kernel_entry); - fn kernel_entry() -> ! { let gpio = gpio::GPIO::new(); let mut mbox = mbox::Mbox::new(); @@ -42,14 +40,16 @@ fn kernel_entry() -> ! { let power = power::Power::new(); // set up serial console - if uart.init(&mut mbox, &gpio).is_err() { - loop { - cortex_a::asm::wfe() - } // If UART fails, abort early + match uart.init(&mut mbox, &gpio) { + Ok(_) => uart.puts("\n[0] UART is live!\n"), + Err(_) => loop { + cortex_a::asm::wfe() // If UART fails, abort early + }, } - uart.getc(); // Press a key first before being greeted - uart.puts("Hello Rustacean!\n\n"); + uart.puts("[1] Press a key to continue booting... "); + uart.getc(); + uart.puts("Greetings fellow Rustacean!\n"); loop { uart.puts("\n 1 - power off\n 2 - reset\nChoose one: "); @@ -67,3 +67,5 @@ fn kernel_entry() -> ! { } } } + +raspi3_boot::entry!(kernel_entry); diff --git a/0B_exception_levels/Makefile b/0B_exception_levels/Makefile index 98c6812a..b3e446c7 100644 --- a/0B_exception_levels/Makefile +++ b/0B_exception_levels/Makefile @@ -24,6 +24,8 @@ TARGET = aarch64-unknown-none +SOURCES = $(wildcard **/*.rs) $(wildcard **/*.S) link.ld + OBJCOPY = cargo objcopy -- OBJCOPY_PARAMS = --strip-all -O binary @@ -33,23 +35,15 @@ DOCKER_TTY = --privileged -v /dev:/dev QEMU_CMD = qemu-system-aarch64 -M raspi3 -kernel kernel8.img RASPBOOT_CMD = raspbootcom /dev/ttyUSB0 kernel8.img -all: clean kernel8.img +.PHONY: all qemu raspboot clippy clean objdump nm -target/$(TARGET)/debug/kernel8: src/main.rs - cargo xbuild --target=$(TARGET) - cp $@ . +all: clean kernel8.img -target/$(TARGET)/release/kernel8: src/main.rs +target/$(TARGET)/release/kernel8: $(SOURCES) cargo xbuild --target=$(TARGET) --release - cp $@ . - -ifeq ($(DEBUG),1) -kernel8: target/$(TARGET)/debug/kernel8 -else -kernel8: target/$(TARGET)/release/kernel8 -endif -kernel8.img: kernel8 +kernel8.img: target/$(TARGET)/release/kernel8 + cp $< . $(OBJCOPY) $(OBJCOPY_PARAMS) $< kernel8.img qemu: all diff --git a/0B_exception_levels/README.md b/0B_exception_levels/README.md index 29517ea9..5c78df4e 100644 --- a/0B_exception_levels/README.md +++ b/0B_exception_levels/README.md @@ -8,20 +8,20 @@ Cortex-A53 processor: `Exception levels`. TODO: Write rest of tutorial. ```text -raspi3_boot::setup_and_enter_el1_from_el2::hb2c2ac4f6a7ddb7e: - 80954: e8 03 1f aa mov x8, xzr - 80958: e9 07 00 32 orr w9, wzr, #0x3 - 8095c: 4a 00 80 52 mov w10, #0x2 - 80960: 0a 00 b0 72 movk w10, #0x8000, lsl #16 - 80964: 09 e1 1c d5 msr CNTHCTL_EL2, x9 - 80968: 68 e0 1c d5 msr CNTVOFF_EL2, x8 - 8096c: 08 00 00 90 adrp x8, #0x0 - 80970: ab 78 80 52 mov w11, #0x3c5 - 80974: 0a 11 1c d5 msr HCR_EL2, x10 - 80978: ec 03 0d 32 orr w12, wzr, #0x80000 - 8097c: 08 81 24 91 add x8, x8, #0x920 - 80980: 0b 40 1c d5 msr SPSR_EL2, x11 - 80984: 28 40 1c d5 msr ELR_EL2, x8 - 80988: 0c 41 1c d5 msr SP_EL1, x12 - 8098c: e0 03 9f d6 eret +raspi3_boot::setup_and_enter_el1_from_el2::h568f1410ae7cc9b8: + 808c0: e8 03 1f aa mov x8, xzr + 808c4: e9 07 00 32 orr w9, wzr, #0x3 + 808c8: 09 e1 1c d5 msr CNTHCTL_EL2, x9 + 808cc: 4a 00 80 52 mov w10, #0x2 + 808d0: 68 e0 1c d5 msr CNTVOFF_EL2, x8 + 808d4: 08 00 00 90 adrp x8, #0x0 + 808d8: 0a 00 b0 72 movk w10, #0x8000, lsl #16 + 808dc: 0a 11 1c d5 msr HCR_EL2, x10 + 808e0: ab 78 80 52 mov w11, #0x3c5 + 808e4: 0b 40 1c d5 msr SPSR_EL2, x11 + 808e8: ec 03 0d 32 orr w12, wzr, #0x80000 + 808ec: 08 31 22 91 add x8, x8, #0x88c + 808f0: 28 40 1c d5 msr ELR_EL2, x8 + 808f4: 0c 41 1c d5 msr SP_EL1, x12 + 808f8: e0 03 9f d6 eret ``` diff --git a/0B_exception_levels/kernel8 b/0B_exception_levels/kernel8 index dfedbd823a05c633c472e4ad8e5b280c5f39a935..123d60ff2a0d5250fecd4a8eb644f85406b122a5 100755 GIT binary patch literal 70672 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 V-Fo~rl$G26E3yBbmW|f^{|nF%zH$Hn literal 70512 zcmeI0du&tJ9mmhTH;-$VQj$0!O#^mN#u8Y)_}Y#gs+I66&}C?|(=x3a#<6dR8?cG( zvL(>B4{O5m*ODy?giYFl}168&S+MwfQ4s-b(Rz%*$@sL-kPe&_n! zJZ^1m)&AH&-z(kM_x#TH{Lbe*u9JhCx*m`viJ6DYUSWkd)sQ+x!HZRMF`X>PWY)ULFbYwwFrm1lOB>-7>a9Xw{_gGM>A1ryL$MV;rqx zTz^+_YBp2rTshXG7QD(x%e;Ctq)y*A6<+jATK)QuzpH-O`-b}NJyR|3-Z!O|Gp$8D z*V^Rp2NeGrX-oZ2~|`PWmw%35ao^(yHvue60WtIsNpl8(Ca&M~aC^s|9M z`A9>1ZF#s?CaBZ#7Mk$BBWMj1|Ez>U9*`(ReOBAzoczM`Qae3m! zbG=0UwB5<7)jf^XYiSR;@=?CqDb@7XDHB z{KFIDbq=rneBFfeymO+poDFau=gHG1bxy7-uhxt>iA~NgbJF{Jw6+s82T#?p$!nGO zXsdTppVvDlrWNO^qlcUmPhN0N9HYL^>|dX|8D5ur|B;Jl&nb~Nrxm7IwcD|uQn^HN zGVN9F>3omYlCAb!Fi2zix^ycrqp0J~)wFL`62lD} z2cpDso7mgV605suT(8kQS*sLSZRBN=}+}q%-mkJ(DxAWcR9N_(`r+&Re{c?(a zy-f4f?C%St-%^&Y;(caPVQ!gq_ P;W50g6I6HI&3yOF{tYw+>uD_31_ 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 yFh~U2Y&N_-B#LAm#)rhNuHaGZ>% literal 2631 zcmb7GZA=qq9DnYPm+Og4`Ucj*UCrhSZcS{(G0ddAxTtex=~Y=`qSRUi(XzG>b+A}i zTtN20W;nO(1I~TGvSnE^XIisG&@It#8(UqnWwDrL5m@#CLIfAR{ho3K>>!&YPwwvb z{GZ?R`@fb;q#_|^J108{ac`@^yM+WA@V;N-5{jY}zQU3|iAX;w9QQ-g%SM!6`RFJ| zBGa-EooZhZRg_$;9IR}tEG!O-#bU5XRN=_%2qAso+?eLnb6qa|?*l=W5WR?dx>;vj zSCA!JaMvl8GTCn@ z0)86fY~(S8In{GqvHi339jg|&1}N8BULJTtt`E~(<^`@k%2kpp!;vS_^-h}0y1>;5 z>?>1_+zBq4T|kWQ|)ZDkzAP6FyRqF z>U0@(=Ur1AGe~>uTvpiC%?wR$Cqt9{EQt^1UIg<{bnuC6x(kKB%b#3CTt2%mdNF>QxGqz^(Oq(tR!0gm|0te88Z4v zaf^(u`C~jAbDZ%pjU1IFaburcp->2GZ zqSJD9^#0x(mxj3gx04*PXJWJ7ud&a-j>TN#qSsfD%LdFT8qbY{?KME}72H*ibq~Fy zF$`5yAg8yOnHQ!weo$PGxtWU?*470)h~+MIwp~K3RwJ+DsFNygE>?APkI_#wu!P3u z#gITEf&sD9p+?^30=2+TvHFP%cs3cG6{XnQZZJ8-8(iQMb&qhweFS?uuxA9{IDDSs z^n+;*7I7B}OpX~&D5Kh{|5n^O*o~=nX}*gO5$6Iu>@+Dm<^jG{K31aD`>mXTr?YR{9K`1L-r=hWZ-A+3IP@n3tV=wNbb-K9M3W1+iaazCc(X%B4QgzcRS4%)A+ zDo#0Qzc%jE%e^YcICM}Bs^`c)y<=178Pjo`IlPP>)XjW9rS$AtwV-F$s>k%~Sw_!m znR>S5Ev;uu-n^dLW%Rt1smI1I=&|vS>9H@P=ebNhC0R@BDao4GBQB$7b*7$tqMgrI zK1u0uAYZ!?<9yg&%gC1jIIrR~U+*DbnR9^74mu-Xcb2!5M$ijqOYy8?_=)T2>-q1~ zWQJll!1KYQx%rHFG&qL;1vI1P#10a6H73mo$|I03f)^{=RHqH zta#6>HYbu?|7|+o3I5!^P-~O_u(WmO2Fc^~`a&V8wMA-eI_3*XLEqt~P^&K(vI%v* zqn?x0?odlma!4Vcx5a-jB>7v8+k_1^o84w}2=y(&=8#1YY8!ptW@_8y$Khbx8?DkY zPpDZs(9{~L6zVFa>Pl&QrSx*8g!^B`j_;sN*zKn_^lh8(=+PF*)fQ^?czqr}2)CZ_ PdD~JdoBR-3DG9# diff --git a/0B_exception_levels/raspi3_boot/src/lib.rs b/0B_exception_levels/raspi3_boot/src/lib.rs index d5ce1ae8..4c2de2a7 100644 --- a/0B_exception_levels/raspi3_boot/src/lib.rs +++ b/0B_exception_levels/raspi3_boot/src/lib.rs @@ -69,6 +69,8 @@ unsafe fn reset() -> ! { fn setup_and_enter_el1_from_el2() -> ! { use cortex_a::{asm, regs::*}; + const STACK_START: u64 = 0x80_000; + // Enable timer counter registers for EL1 CNTHCTL_EL2.write(CNTHCTL_EL2::EL1PCEN::SET + CNTHCTL_EL2::EL1PCTEN::SET); @@ -96,7 +98,7 @@ fn setup_and_enter_el1_from_el2() -> ! { // Set up SP_EL1 (stack pointer), which will be used by EL1 once // we "return" to it. - SP_EL1.set(0x80_000); + SP_EL1.set(STACK_START); // Use `eret` to "return" to EL1. This will result in execution of // `reset()` in EL1. @@ -116,10 +118,8 @@ pub unsafe extern "C" fn _boot_cores() -> ! { const CORE_MASK: u64 = 0x3; const EL2: u32 = CurrentEL::EL::EL2.value; - if let CORE_0 = MPIDR_EL1.get() & CORE_MASK { - if let EL2 = CurrentEL.get() { - setup_and_enter_el1_from_el2() - } + if (CORE_0 == MPIDR_EL1.get() & CORE_MASK) && (EL2 == CurrentEL.get()) { + setup_and_enter_el1_from_el2() } // if not core0 or EL != 2, infinitely wait for events diff --git a/0B_exception_levels/src/delays.rs b/0B_exception_levels/src/delays.rs index 693f21d9..130b8ae5 100644 --- a/0B_exception_levels/src/delays.rs +++ b/0B_exception_levels/src/delays.rs @@ -22,6 +22,7 @@ * SOFTWARE. */ +use cortex_a::asm; use cortex_a::regs::*; /* @@ -53,3 +54,15 @@ pub fn wait_msec(n: u32) { // Disable counting again CNTP_CTL_EL0.modify(CNTP_CTL_EL0::ENABLE::CLEAR); } + +/* + * + * Using the CPU's cycles + * + */ +/// Wait N CPU cycles (ARM CPU only) +pub fn wait_cycles(cyc: u32) { + for _ in 0..cyc { + asm::nop(); + } +} diff --git a/0B_exception_levels/src/gpio.rs b/0B_exception_levels/src/gpio.rs index da6a5be4..608ba532 100644 --- a/0B_exception_levels/src/gpio.rs +++ b/0B_exception_levels/src/gpio.rs @@ -23,6 +23,7 @@ */ use super::MMIO_BASE; +use core::ops; use register::{mmio::ReadWrite, register_bitfields}; // Descriptions taken from @@ -66,10 +67,55 @@ register_bitfields! { ] } -pub const GPFSEL1: *const ReadWrite = - (MMIO_BASE + 0x0020_0004) as *const ReadWrite; +const GPIO_BASE: u32 = MMIO_BASE + 0x200_000; -pub const GPPUD: *const ReadWrite = (MMIO_BASE + 0x0020_0094) as *const ReadWrite; +#[allow(non_snake_case)] +#[repr(C)] +pub struct RegisterBlock { + pub GPFSEL0: ReadWrite, // 0x00 + pub GPFSEL1: ReadWrite, // 0x04 + pub GPFSEL2: ReadWrite, // 0x08 + pub GPFSEL3: ReadWrite, // 0x0C + pub GPFSEL4: ReadWrite, // 0x10 + pub GPFSEL5: ReadWrite, // 0x14 + __reserved_0: u32, // 0x18 + GPSET0: ReadWrite, // 0x1C + GPSET1: ReadWrite, // 0x20 + __reserved_1: u32, // + GPCLR0: ReadWrite, // 0x28 + __reserved_2: [u32; 2], // + GPLEV0: ReadWrite, // 0x34 + GPLEV1: ReadWrite, // 0x38 + __reserved_3: u32, // + GPEDS0: ReadWrite, // 0x40 + GPEDS1: ReadWrite, // 0x44 + __reserved_4: [u32; 7], // + GPHEN0: ReadWrite, // 0x64 + GPHEN1: ReadWrite, // 0x68 + __reserved_5: [u32; 10], // + pub GPPUD: ReadWrite, // 0x94 + pub GPPUDCLK0: ReadWrite, // 0x98 + pub GPPUDCLK1: ReadWrite, // 0x9C +} + +/// Public interface to the GPIO MMIO area +pub struct GPIO; -pub const GPPUDCLK0: *const ReadWrite = - (MMIO_BASE + 0x0020_0098) as *const ReadWrite; +impl ops::Deref for GPIO { + type Target = RegisterBlock; + + fn deref(&self) -> &Self::Target { + unsafe { &*Self::ptr() } + } +} + +impl GPIO { + pub fn new() -> GPIO { + GPIO + } + + /// Returns a pointer to the register block + fn ptr() -> *const RegisterBlock { + GPIO_BASE as *const _ + } +} diff --git a/0B_exception_levels/src/main.rs b/0B_exception_levels/src/main.rs index 6e501672..810e2d90 100644 --- a/0B_exception_levels/src/main.rs +++ b/0B_exception_levels/src/main.rs @@ -36,17 +36,17 @@ use cortex_a::regs::*; fn check_timer(uart: &uart::Uart) { uart.puts( - "Testing EL1 access to timer registers.\n\ - Delaying for 3 seconds now.\n", + "Testing EL1 access to timer registers:\ + \n Delaying for 3 seconds now.\n", ); - delays::wait_msec(1000); - uart.puts("1.."); - delays::wait_msec(1000); + delays::wait_msec(1_000_000); + uart.puts(" 1.."); + delays::wait_msec(1_000_000); uart.puts("2.."); - delays::wait_msec(1000); + delays::wait_msec(1_000_000); uart.puts( - "3\n\ - Works!\n\n", + "3\ + \n Works!\n\n", ); } @@ -55,10 +55,10 @@ fn check_daif(uart: &uart::Uart) { let daif = DAIF.extract(); for x in &[ - ("D: ", DAIF::D), - ("A: ", DAIF::A), - ("I: ", DAIF::I), - ("F: ", DAIF::F), + (" D: ", DAIF::D), + (" A: ", DAIF::A), + (" I: ", DAIF::I), + (" F: ", DAIF::F), ] { uart.puts(x.0); if daif.is_set(x.1) { @@ -69,24 +69,25 @@ fn check_daif(uart: &uart::Uart) { } } -raspi3_boot::entry!(kernel_entry); - fn kernel_entry() -> ! { + let gpio = gpio::GPIO::new(); let mut mbox = mbox::Mbox::new(); let uart = uart::Uart::new(); // set up serial console - if uart.init(&mut mbox).is_err() { - loop { + match uart.init(&mut mbox, &gpio) { + Ok(_) => uart.puts("\n[0] UART is live!\n"), + Err(_) => loop { cortex_a::asm::wfe() // If UART fails, abort early - } + }, } - uart.getc(); // Press a key first before being greeted - uart.puts("Hello Rustacean!\n\n"); + uart.puts("[1] Press a key to continue booting... "); + uart.getc(); + uart.puts("Greetings fellow Rustacean!\n"); - uart.puts("Executing in EL: "); - uart.hex(CurrentEL.read(CurrentEL::EL)); + uart.puts("[i] Executing in EL: "); + uart.dec(CurrentEL.read(CurrentEL::EL)); uart.puts("\n\n"); check_timer(&uart); @@ -97,3 +98,5 @@ fn kernel_entry() -> ! { uart.send(uart.getc()); } } + +raspi3_boot::entry!(kernel_entry); diff --git a/0B_exception_levels/src/uart.rs b/0B_exception_levels/src/uart.rs index db4c639a..4172e059 100644 --- a/0B_exception_levels/src/uart.rs +++ b/0B_exception_levels/src/uart.rs @@ -23,6 +23,7 @@ */ use super::MMIO_BASE; +use crate::delays; use crate::gpio; use crate::mbox; use core::{ @@ -162,7 +163,7 @@ impl Uart { } ///Set baud rate and characteristics (115200 8N1) and map to GPIO - pub fn init(&self, mbox: &mut mbox::Mbox) -> Result<()> { + pub fn init(&self, mbox: &mut mbox::Mbox, gpio: &gpio::GPIO) -> Result<()> { // turn off UART0 self.CR.set(0); @@ -187,23 +188,18 @@ impl Uart { }; // map UART0 to GPIO pins - unsafe { - (*gpio::GPFSEL1).modify(gpio::GPFSEL1::FSEL14::TXD0 + gpio::GPFSEL1::FSEL15::RXD0); + gpio.GPFSEL1 + .modify(gpio::GPFSEL1::FSEL14::TXD0 + gpio::GPFSEL1::FSEL15::RXD0); - (*gpio::GPPUD).set(0); // enable pins 14 and 15 - for _ in 0..150 { - asm::nop(); - } + gpio.GPPUD.set(0); // enable pins 14 and 15 + delays::wait_cycles(150); - (*gpio::GPPUDCLK0).modify( - gpio::GPPUDCLK0::PUDCLK14::AssertClock + gpio::GPPUDCLK0::PUDCLK15::AssertClock, - ); - for _ in 0..150 { - asm::nop(); - } + gpio.GPPUDCLK0.modify( + gpio::GPPUDCLK0::PUDCLK14::AssertClock + gpio::GPPUDCLK0::PUDCLK15::AssertClock, + ); + delays::wait_cycles(150); - (*gpio::GPPUDCLK0).set(0); - } + gpio.GPPUDCLK0.set(0); self.ICR.write(ICR::ALL::CLEAR); self.IBRD.write(IBRD::IBRD.val(2)); // Results in 115200 baud @@ -264,23 +260,23 @@ impl Uart { } } - /// Display a binary value in hexadecimal - pub fn hex(&self, d: u32) { - let mut n; + /// Display a binary value in decimal + pub fn dec(&self, d: u32) { + let mut digits: [char; 10] = ['\0'; 10]; + let mut d = d; - for i in 0..8 { - // get highest tetrad - n = d.wrapping_shr(28 - i * 4) & 0xF; + for i in digits.iter_mut() { + *i = ((d % 10) + 0x30) as u8 as char; - // 0-9 => '0'-'9', 10-15 => 'A'-'F' - // Add proper offset for ASCII table - if n > 9 { - n += 0x37; - } else { - n += 0x30; + d /= 10; + + if d == 0 { + break; } + } - self.send(n as u8 as char); + for c in digits.iter().rev() { + self.send(*c); } } } diff --git a/0C_virtual_memory/Makefile b/0C_virtual_memory/Makefile index 98c6812a..b3e446c7 100644 --- a/0C_virtual_memory/Makefile +++ b/0C_virtual_memory/Makefile @@ -24,6 +24,8 @@ TARGET = aarch64-unknown-none +SOURCES = $(wildcard **/*.rs) $(wildcard **/*.S) link.ld + OBJCOPY = cargo objcopy -- OBJCOPY_PARAMS = --strip-all -O binary @@ -33,23 +35,15 @@ DOCKER_TTY = --privileged -v /dev:/dev QEMU_CMD = qemu-system-aarch64 -M raspi3 -kernel kernel8.img RASPBOOT_CMD = raspbootcom /dev/ttyUSB0 kernel8.img -all: clean kernel8.img +.PHONY: all qemu raspboot clippy clean objdump nm -target/$(TARGET)/debug/kernel8: src/main.rs - cargo xbuild --target=$(TARGET) - cp $@ . +all: clean kernel8.img -target/$(TARGET)/release/kernel8: src/main.rs +target/$(TARGET)/release/kernel8: $(SOURCES) cargo xbuild --target=$(TARGET) --release - cp $@ . - -ifeq ($(DEBUG),1) -kernel8: target/$(TARGET)/debug/kernel8 -else -kernel8: target/$(TARGET)/release/kernel8 -endif -kernel8.img: kernel8 +kernel8.img: target/$(TARGET)/release/kernel8 + cp $< . $(OBJCOPY) $(OBJCOPY_PARAMS) $< kernel8.img qemu: all diff --git a/0C_virtual_memory/kernel8 b/0C_virtual_memory/kernel8 index b4644b05badfe1d4acdffa21bc9ccaab6cf9a1cd..681263938ea55b78675fef9f771cd88445383824 100755 GIT binary patch delta 1952 zcmZ`)ZA@Eb6h7y@E!?(13v?|kNN?Fj0JEkorIgGp1%Av$mn?uz?Z_ys4g#UjGB&eC za8bitOz6UVlWB%=M1z@`MjauJ1Q%!g_%Vqvr-=^HANa#WhKq{{)^oo?xY0N1J@0*< zbDr~Y-+McL)ii&_G+xCE$%b+;6o_|13ae{Z!ucN*Cjo5vvcJ2AJpo2py4xrEE6qCdqMc zwenDCTA>QjI=MG?v~O`76|auo&9^Ac}l=o}d<*AyNKPV4#SH&v%( z?`)PAQiqH|ml+DXE5E#W zmTDIBqvx$ZLZQuE7WC|bwL>qQ+aB3wZrwxUo$v_IyG*6Z4UUm>2@!vjsEo(6*|t@| zRl^y~-fe90$lKlkyABL{dI}~`Aseu|ow3FS1~* zJ5ZLXik2EXi6`libv=jm)F}$J8?biGeg*%k`5tc z-YOT-MyumfiXXs}W_9Gc&VYvBP}1P{iYZNNs&{g>s@_v)tJ8lNXe-rB&mpT;zIm-u zdO{B`|2gTFR}5r`THJppJ3Nl*PKC6I@z`$sk6oQCTOLK=RJ@FMcp`!3P& zPCC;vt~P9=udhZNS5^GOHp&xyd! zlfIBb&Pav0z=}hmV5m0S5U!7e{gFtZHdJ571tZG^W1@-=P{;C;|5N>Z Z!-WsC2l>3lje9MX1**%_e9(=ae*u#=TS@=` delta 2347 zcmZ`*ZA@EL7(Va01xneVr7bOl(UuLym}}_AD4@fRn1w_kY#ofioODoE94VuNF*8Di z`GHdmbsHyBBYtd-`VsYqL84?^mKcBd!^NRyY8=ZFGkEhMlDM+&<6y z@x1SO?`1(s%Kii66c0^YOP+w4Q!Z3f)j52-mb^ zd{62ZZ9;qdVsts6OWZt4$%fy< zMgDn{K@<3jIVhMOnJteu(C7AuAugboF{@^=Yjpn)7l53x6_e-{LiVDNDMwdXT(r5B zXLG+PM$h%X{vI2^2pvC{#m6({2ytX2>%Yon>#Pm#R}t$=rI-;#i=0vOPSnw|Io^;Z z`y^+`{7JMCqb~`@$~!zpO$B>YfHFD`>}dhY>2YAM2~bcNMQOiNayXbu?LAA${9P>W z4i-7h76j-lXcd)@>^poJm5cTMME&zEz?>Qku?yzfG|&LB%+6)N`|usxkqH~&Dhp=9 zaO_^^LSi`piHecpfQk6$wZ9QV@&rxX$trel9oZ0w8OXpX>|RoU%4Nj1j1+qc#$GPk zXU+&rqv{ljx~XKHKsyWKQwlDMokp?Yh&3R_$i~=15v#{mMh3Qzoh@oJXVAb4Y*GMA zEQUU-3k)AH1zu5n{=~eZkC^|N113-P*r}pn%oBY;{yug7X8ryA&HB~(13@`2J1u}A z)~Oazziw?2_3KtdG(SK@qgsShdtZc8n**lHLnLN>eBeOGcuk-3GyPgR>^rin;T^4v; z@s05cfAQkFoyChcg_$4i#D2Z0skP4TwLjk5U_TTMMuz%A_M<~bj`T+dLp=^1`ydOv zm5rgkzJB|jp`(Mr?ocq|(CKu6;oiaSaBt+09Rt|=BlbxDu+!;ePiWyS*u~z}f(4$G zHrF7&E(oEdJzFc?@yoN)4JF4^_$Z5KgQXB3KU@MK_H?%ib_MC!B$6P~dWF_Y_GE$M z+)cr6pedz5Du`^qA0K;h?b2WzdS6|M43ifXoU8LH_+8vJCThl-4S#i*Yxv z%B@c_19D!I9&SLv8#B{!0XrggklUYE(%3R&oZE--r7o@}8P6v?@e#%0n4}9P#s(1w1;V~I!f2@a-?2TNgVoSMj7PhmlJg~BJ zdC-{SBb$ypz2Zee3!p|M3+DdKgKIRuwzj6q>vdOod@f&&yVmD(v88-)u7#Hxq2J;O zhmN~^;p(8Ty4&jt^@Kb@S5;4l?av3Rr8m+$h@{7T@SwNWk4+Jm`1i)iJ~6{q+LFg^ Qph@;90g$e9|COEG5`Po diff --git a/0C_virtual_memory/kernel8.img b/0C_virtual_memory/kernel8.img index c0cfc9e8588acd527652f08ca1b382371f185b2a..657c1789f10845154c7b387bd9982948f48abbf5 100755 GIT binary patch delta 641 zcmYL_UuaTc7{=f89c4$|3a9BB=K0RXBnQcM+Qp(>s9kgs!BAt-Nz%zFMNv|>5sm&` z8QpmHEd~V{EC`{fSOgM-?IwzD8qL*B&8!Q%95#ZWPTx_ZyO-yCp5ObtU(s4H7cqLx zJR68Hu4C*52R8!hSFX%`dzk$x8OyaCQg(x;@)s7A=H>2kJ%-3K<32eLuowXtJBQh- zs;YJdpeV$7Wg1-zXqk8Py`??pmAbC2y`@^Sz8_>@k#|6L9U#;Kf>ZH#fGb*wJ>CUOe8_sW;Oqbnh~iIz%Hduamcdt_{8@Uti9%rvj59YY*&7GUH zG1uc=Fn$8FN$(K(A=sI^eye|cpFVgLw5BX1YqY6$UV)nX=)*4x)%2*Uh8nDGcnLve z+Yc9o-)j4!z5((C4WR~*E#yL@oqlwd9AYKgON}`{m0auW z`hdKZ7eMZ@F7yaiUa@|Lk%&RR%!uT%evomK4gDN>%0-Z%l3v4M`=~=X=yg=PeU564 zEp1`In^Gc-$!UXA*BWLGV`q%gNEn~;1wuHH!>PoqEEuKHFrLiHxg3t-q y=M(7}8Bb?2bhzO0c<}M8ENgQPpO;gq%p4BPfP;em)PTc&)TDjK$>WL1~pny02aQI8UJ|lMw~qA=FAC6f<{Q zL`C!Ckg4LaVxHrC@PrIuw)2Zc99O3eL}+Y?e_PXHO>xCtsQG32p&p2po?bN%i}-;gdjilsG;vEq27n2+kv&?G!rlBR4asFg>Ij{LFPhK{@}eg4eL^9xcpL!lkWlC_SP@>wKp+vRCVB3e`XeL7rI=pp;9JImUfHSngTNZ)# z4Mrz+-7*gv`gCLCmm_e?#2@Q{Udb}RNtkr7y aaQ{e;uV3inV4e#IoDc}x?RIj3srd)WVNmb@ diff --git a/0C_virtual_memory/raspi3_boot/src/lib.rs b/0C_virtual_memory/raspi3_boot/src/lib.rs index d5ce1ae8..4c2de2a7 100644 --- a/0C_virtual_memory/raspi3_boot/src/lib.rs +++ b/0C_virtual_memory/raspi3_boot/src/lib.rs @@ -69,6 +69,8 @@ unsafe fn reset() -> ! { fn setup_and_enter_el1_from_el2() -> ! { use cortex_a::{asm, regs::*}; + const STACK_START: u64 = 0x80_000; + // Enable timer counter registers for EL1 CNTHCTL_EL2.write(CNTHCTL_EL2::EL1PCEN::SET + CNTHCTL_EL2::EL1PCTEN::SET); @@ -96,7 +98,7 @@ fn setup_and_enter_el1_from_el2() -> ! { // Set up SP_EL1 (stack pointer), which will be used by EL1 once // we "return" to it. - SP_EL1.set(0x80_000); + SP_EL1.set(STACK_START); // Use `eret` to "return" to EL1. This will result in execution of // `reset()` in EL1. @@ -116,10 +118,8 @@ pub unsafe extern "C" fn _boot_cores() -> ! { const CORE_MASK: u64 = 0x3; const EL2: u32 = CurrentEL::EL::EL2.value; - if let CORE_0 = MPIDR_EL1.get() & CORE_MASK { - if let EL2 = CurrentEL.get() { - setup_and_enter_el1_from_el2() - } + if (CORE_0 == MPIDR_EL1.get() & CORE_MASK) && (EL2 == CurrentEL.get()) { + setup_and_enter_el1_from_el2() } // if not core0 or EL != 2, infinitely wait for events diff --git a/0C_virtual_memory/src/delays.rs b/0C_virtual_memory/src/delays.rs new file mode 100644 index 00000000..63414e4f --- /dev/null +++ b/0C_virtual_memory/src/delays.rs @@ -0,0 +1,37 @@ +/* + * MIT License + * + * Copyright (c) 2018 Andre Richter + * + * 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. + */ + +use cortex_a::asm; + +/* + * + * Using the CPU's cycles + * + */ +/// Wait N CPU cycles (ARM CPU only) +pub fn wait_cycles(cyc: u32) { + for _ in 0..cyc { + asm::nop(); + } +} diff --git a/0C_virtual_memory/src/gpio.rs b/0C_virtual_memory/src/gpio.rs index da6a5be4..608ba532 100644 --- a/0C_virtual_memory/src/gpio.rs +++ b/0C_virtual_memory/src/gpio.rs @@ -23,6 +23,7 @@ */ use super::MMIO_BASE; +use core::ops; use register::{mmio::ReadWrite, register_bitfields}; // Descriptions taken from @@ -66,10 +67,55 @@ register_bitfields! { ] } -pub const GPFSEL1: *const ReadWrite = - (MMIO_BASE + 0x0020_0004) as *const ReadWrite; +const GPIO_BASE: u32 = MMIO_BASE + 0x200_000; -pub const GPPUD: *const ReadWrite = (MMIO_BASE + 0x0020_0094) as *const ReadWrite; +#[allow(non_snake_case)] +#[repr(C)] +pub struct RegisterBlock { + pub GPFSEL0: ReadWrite, // 0x00 + pub GPFSEL1: ReadWrite, // 0x04 + pub GPFSEL2: ReadWrite, // 0x08 + pub GPFSEL3: ReadWrite, // 0x0C + pub GPFSEL4: ReadWrite, // 0x10 + pub GPFSEL5: ReadWrite, // 0x14 + __reserved_0: u32, // 0x18 + GPSET0: ReadWrite, // 0x1C + GPSET1: ReadWrite, // 0x20 + __reserved_1: u32, // + GPCLR0: ReadWrite, // 0x28 + __reserved_2: [u32; 2], // + GPLEV0: ReadWrite, // 0x34 + GPLEV1: ReadWrite, // 0x38 + __reserved_3: u32, // + GPEDS0: ReadWrite, // 0x40 + GPEDS1: ReadWrite, // 0x44 + __reserved_4: [u32; 7], // + GPHEN0: ReadWrite, // 0x64 + GPHEN1: ReadWrite, // 0x68 + __reserved_5: [u32; 10], // + pub GPPUD: ReadWrite, // 0x94 + pub GPPUDCLK0: ReadWrite, // 0x98 + pub GPPUDCLK1: ReadWrite, // 0x9C +} + +/// Public interface to the GPIO MMIO area +pub struct GPIO; -pub const GPPUDCLK0: *const ReadWrite = - (MMIO_BASE + 0x0020_0098) as *const ReadWrite; +impl ops::Deref for GPIO { + type Target = RegisterBlock; + + fn deref(&self) -> &Self::Target { + unsafe { &*Self::ptr() } + } +} + +impl GPIO { + pub fn new() -> GPIO { + GPIO + } + + /// Returns a pointer to the register block + fn ptr() -> *const RegisterBlock { + GPIO_BASE as *const _ + } +} diff --git a/0C_virtual_memory/src/main.rs b/0C_virtual_memory/src/main.rs index 741cf4b2..caf70bab 100644 --- a/0C_virtual_memory/src/main.rs +++ b/0C_virtual_memory/src/main.rs @@ -29,14 +29,14 @@ const MMIO_BASE: u32 = 0x3F00_0000; +mod delays; mod gpio; mod mbox; mod mmu; mod uart; -raspi3_boot::entry!(kernel_entry); - fn kernel_entry() -> ! { + let gpio = gpio::GPIO::new(); let mut mbox = mbox::Mbox::new(); { @@ -44,18 +44,20 @@ fn kernel_entry() -> ! { let uart = uart::Uart::new(uart::UART_PHYS_BASE); // set up serial console - if uart.init(&mut mbox).is_err() { - loop { + match uart.init(&mut mbox, &gpio) { + Ok(_) => uart.puts("\n[0] UART is live!\n"), + Err(_) => loop { cortex_a::asm::wfe() // If UART fails, abort early - } + }, } - uart.getc(); // Press a key first before being greeted - uart.puts("Hello Rustacean!\n\n"); + uart.puts("[1] Press a key to continue booting... "); + uart.getc(); + uart.puts("Greetings fellow Rustacean!\n"); mmu::print_features(&uart); - uart.puts("\nSwitching MMU on now..."); + uart.puts("[2] Switching MMU on now... "); } // After this closure, the UART instance is not valid anymore. unsafe { mmu::init() }; @@ -66,7 +68,7 @@ fn kernel_entry() -> ! { let uart = uart::Uart::new(UART_VIRT_BASE); uart.puts("MMU is live \\o/\n\nWriting through the virtual mapping at 0x"); - uart.hex(UART_VIRT_BASE); + uart.hex(UART_VIRT_BASE as u64); uart.puts(".\n"); // echo everything back @@ -74,3 +76,5 @@ fn kernel_entry() -> ! { uart.send(uart.getc()); } } + +raspi3_boot::entry!(kernel_entry); diff --git a/0C_virtual_memory/src/mmu.rs b/0C_virtual_memory/src/mmu.rs index 8eebdaea..98f76816 100644 --- a/0C_virtual_memory/src/mmu.rs +++ b/0C_virtual_memory/src/mmu.rs @@ -34,13 +34,13 @@ pub fn print_features(uart: &uart::Uart) { if let Some(ID_AA64MMFR0_EL1::TGran4::Value::Supported) = mmfr.read_as_enum(ID_AA64MMFR0_EL1::TGran4) { - uart.puts("MMU: 4 KiB granule supported!\n"); + uart.puts("[i] MMU: 4 KiB granule supported!\n"); } if let Some(ID_AA64MMFR0_EL1::PARange::Value::Bits_40) = mmfr.read_as_enum(ID_AA64MMFR0_EL1::PARange) { - uart.puts("MMU: Up to 40 Bit physical address range supported!\n"); + uart.puts("[i] MMU: Up to 40 Bit physical address range supported!\n"); } } diff --git a/0C_virtual_memory/src/uart.rs b/0C_virtual_memory/src/uart.rs index 492b3b78..2c0e8a03 100644 --- a/0C_virtual_memory/src/uart.rs +++ b/0C_virtual_memory/src/uart.rs @@ -23,6 +23,7 @@ */ use super::MMIO_BASE; +use crate::delays; use crate::gpio; use crate::mbox; use core::{ @@ -164,7 +165,7 @@ impl Uart { } ///Set baud rate and characteristics (115200 8N1) and map to GPIO - pub fn init(&self, mbox: &mut mbox::Mbox) -> Result<()> { + pub fn init(&self, mbox: &mut mbox::Mbox, gpio: &gpio::GPIO) -> Result<()> { // turn off UART0 self.CR.set(0); @@ -189,23 +190,18 @@ impl Uart { }; // map UART0 to GPIO pins - unsafe { - (*gpio::GPFSEL1).modify(gpio::GPFSEL1::FSEL14::TXD0 + gpio::GPFSEL1::FSEL15::RXD0); + gpio.GPFSEL1 + .modify(gpio::GPFSEL1::FSEL14::TXD0 + gpio::GPFSEL1::FSEL15::RXD0); - (*gpio::GPPUD).set(0); // enable pins 14 and 15 - for _ in 0..150 { - asm::nop(); - } + gpio.GPPUD.set(0); // enable pins 14 and 15 + delays::wait_cycles(150); - (*gpio::GPPUDCLK0).modify( - gpio::GPPUDCLK0::PUDCLK14::AssertClock + gpio::GPPUDCLK0::PUDCLK15::AssertClock, - ); - for _ in 0..150 { - asm::nop(); - } + gpio.GPPUDCLK0.modify( + gpio::GPPUDCLK0::PUDCLK14::AssertClock + gpio::GPPUDCLK0::PUDCLK15::AssertClock, + ); + delays::wait_cycles(150); - (*gpio::GPPUDCLK0).set(0); - } + gpio.GPPUDCLK0.set(0); self.ICR.write(ICR::ALL::CLEAR); self.IBRD.write(IBRD::IBRD.val(2)); // Results in 115200 baud @@ -267,12 +263,12 @@ impl Uart { } /// Display a binary value in hexadecimal - pub fn hex(&self, d: u32) { + pub fn hex(&self, d: u64) { let mut n; - for i in 0..8 { + for i in 0..16 { // get highest tetrad - n = d.wrapping_shr(28 - i * 4) & 0xF; + n = d.wrapping_shr(60 - i * 4) & 0xF; // 0-9 => '0'-'9', 10-15 => 'A'-'F' // Add proper offset for ASCII table diff --git a/0D_cache_performance/Makefile b/0D_cache_performance/Makefile index 98c6812a..b3e446c7 100644 --- a/0D_cache_performance/Makefile +++ b/0D_cache_performance/Makefile @@ -24,6 +24,8 @@ TARGET = aarch64-unknown-none +SOURCES = $(wildcard **/*.rs) $(wildcard **/*.S) link.ld + OBJCOPY = cargo objcopy -- OBJCOPY_PARAMS = --strip-all -O binary @@ -33,23 +35,15 @@ DOCKER_TTY = --privileged -v /dev:/dev QEMU_CMD = qemu-system-aarch64 -M raspi3 -kernel kernel8.img RASPBOOT_CMD = raspbootcom /dev/ttyUSB0 kernel8.img -all: clean kernel8.img +.PHONY: all qemu raspboot clippy clean objdump nm -target/$(TARGET)/debug/kernel8: src/main.rs - cargo xbuild --target=$(TARGET) - cp $@ . +all: clean kernel8.img -target/$(TARGET)/release/kernel8: src/main.rs +target/$(TARGET)/release/kernel8: $(SOURCES) cargo xbuild --target=$(TARGET) --release - cp $@ . - -ifeq ($(DEBUG),1) -kernel8: target/$(TARGET)/debug/kernel8 -else -kernel8: target/$(TARGET)/release/kernel8 -endif -kernel8.img: kernel8 +kernel8.img: target/$(TARGET)/release/kernel8 + cp $< . $(OBJCOPY) $(OBJCOPY_PARAMS) $< kernel8.img qemu: all diff --git a/0D_cache_performance/README.md b/0D_cache_performance/README.md index 89577d03..6248a0a7 100644 --- a/0D_cache_performance/README.md +++ b/0D_cache_performance/README.md @@ -43,13 +43,13 @@ showcase how much faster it is to operate on DRAM with caching enabled. On my Raspberry, I get the following results: ```text -Benchmarking non-cacheable DRAM modifications at virtual 0x00200000, physical 0x00400000: +Benchmarking non-cacheable DRAM modifications at virtual 0x0000000000200000, physical 0x0000000000400000: 1040 miliseconds. -Benchmarking cacheable DRAM modifications at virtual 0x00400000, physical 0x00400000: +Benchmarking cacheable DRAM modifications at virtual 0x0000000000400000, physical 0x0000000000400000: 53 miliseconds. -With caching, the function is 1862% faster! +With caching, the function is 1800% faster! ``` Impressive, isn't it? diff --git a/0D_cache_performance/kernel8 b/0D_cache_performance/kernel8 index 3f0fed005c82e10ee645f07d5778d87d21a3b130..3b29dd0315ec2ba2035a793335335b111aa11619 100755 GIT binary patch delta 2797 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 D1bc=6 diff --git a/0D_cache_performance/kernel8.img b/0D_cache_performance/kernel8.img index 05fdca45799270f2545ea5e68f185705920a0c1f..f630951a21b5311eb6fa7e9776c9b6f41c745311 100755 GIT binary patch delta 1370 zcmbtUU1$?o6u$RPqUj`Bs!dDN+T2*})*`i?R6(tF8ig)sp(K&&W~-Zos39fMCT$ge zCP9UY4|cruhw4)4Q%4XKMG3M{SPCs7>_Y3pvdfmP4~qC8HC7QF&rDLOSP=2$F!P;z z&-cxD&Y4@KPi%cudO=V>MRej_U$f+ilenwp7jwWusG??csOO|m_eE0(2Wd6 z{RtwbpK|uORqs=-xcUk~Y1M@eJKn2aO_ZadP9DNZ z_Y}AM#>5vQ_-_(1^qB~ku0j`a?Q0?q)ydPGUC=~W#gyA>xZZgi#IPfL0}1D|dwjV> zpoT8^2%ODF`dI+7*j>ODWk2FPVBI+?{AX!t_J23>_`!`DR2bFxKqP&A8poTbcm z>DM{4<{7vSu>VN$^8iNPnPc0PjAxrN>vJh@gH6i2$msA0x9_oTdaY9)B1v~XLWTN! zp8!qBHmsLe9~S0K4wONyUQ4zKsgtJC)EuA5DZ6lTg+5{nku1fi@OD)a8>WLqX2W=u z)QnL7F9_A|gGp9ZwOFS-?UVx`VJc4KtB}{RKb-QkA&XrCY-UhQ6OgEFz(MF+VS&M; zwPKK{xOVZx2letR zAoIZH%n`!MrL92d#wweU&{cI!CMKE8k9IolP2qUDGc?RD&%+kbHv>LMZ<86_V z+#df0YAI&bTqP;Ocifx{lTpMj8HUI;#5NgM5{B4bV>fFs9m0FqO;ZJKWq(3!W*LZE zSxH_6UeC5bT+93rE7%!`Hl{!c0*vmXSTWhH&_dl?J#ko9HBUg!Kla{8k$tiB| zvGxaJ|63kOysx&M?rL&-X*f|B#K{1h^;oQ3W7#(+n6Y# z32p{I;z5*?MGq$R(nKPO@#IHhB6>1Zqej$&Nj08yeY5OhZQ$~<^M7yO`@MNH^TBby z^fGT)%%Kq;@voBKxEQ8K^OlJX2#p*-sCGZkP06xs&y4y~1R<*n)7(X7RJNeCAK`FQ`H&I6@pTbCp81? zNt(!SFWClOSAW})N%gNcK-);DL%)KoCrQ8FkI5%Y&l$$Z1g5KvmE-}Y&Bk8wSNlZb zr+^dH{Z7G(d?~|QRGc|Y5;JZAQq!zLqL$>@amtSt?GArOX3$CZ9sG$x{-58 z?V!h1osnJz(qLq%z;YNN_ld|-uWLCvRu{kG*lEiXg{0HP-0H`__s9ZNcP`Pdns5A#C$W9lVnN1_ofC|y#xtSFr1;`6CYlT=7 z#6HTIyA5=ms1Vu!Wjl2>Af^q@W#u=(PF42Q;Tx?9J^Kk~JA zoY|A+mW+RdZ{-@Etd+*#wlS?w@tYL?Tg`v3R(j956fFuGJ%Bfo83VnE%fq|1tNZ|B zijWc$(Ej@lTK;U_rmVb4&7W0wYnK16=Fh6z02=*HeE0&b;auX%dCIyVWSZE&R$|nW zy|0tp{?|&I;d*HdUYjC##gz54IzXOnYmnHUT8&dT3L(d!WfnPp#!y6~0SAWwNW^eP$byBs@Ib~^dPNlig*X&K*-W3i<`M`c sWD@#9J)OZ&BLNasU7T diff --git a/0D_cache_performance/raspi3_boot/src/lib.rs b/0D_cache_performance/raspi3_boot/src/lib.rs index d5ce1ae8..4c2de2a7 100644 --- a/0D_cache_performance/raspi3_boot/src/lib.rs +++ b/0D_cache_performance/raspi3_boot/src/lib.rs @@ -69,6 +69,8 @@ unsafe fn reset() -> ! { fn setup_and_enter_el1_from_el2() -> ! { use cortex_a::{asm, regs::*}; + const STACK_START: u64 = 0x80_000; + // Enable timer counter registers for EL1 CNTHCTL_EL2.write(CNTHCTL_EL2::EL1PCEN::SET + CNTHCTL_EL2::EL1PCTEN::SET); @@ -96,7 +98,7 @@ fn setup_and_enter_el1_from_el2() -> ! { // Set up SP_EL1 (stack pointer), which will be used by EL1 once // we "return" to it. - SP_EL1.set(0x80_000); + SP_EL1.set(STACK_START); // Use `eret` to "return" to EL1. This will result in execution of // `reset()` in EL1. @@ -116,10 +118,8 @@ pub unsafe extern "C" fn _boot_cores() -> ! { const CORE_MASK: u64 = 0x3; const EL2: u32 = CurrentEL::EL::EL2.value; - if let CORE_0 = MPIDR_EL1.get() & CORE_MASK { - if let EL2 = CurrentEL.get() { - setup_and_enter_el1_from_el2() - } + if (CORE_0 == MPIDR_EL1.get() & CORE_MASK) && (EL2 == CurrentEL.get()) { + setup_and_enter_el1_from_el2() } // if not core0 or EL != 2, infinitely wait for events diff --git a/0D_cache_performance/src/benchmark.rs b/0D_cache_performance/src/benchmark.rs index c63b343b..419684dd 100644 --- a/0D_cache_performance/src/benchmark.rs +++ b/0D_cache_performance/src/benchmark.rs @@ -53,9 +53,9 @@ pub fn run(uart: &uart::Uart) { let cacheable_addr: u64 = 2 * SIZE_2MIB; uart.puts("Benchmarking non-cacheable DRAM modifications at virtual 0x"); - uart.hex(non_cacheable_addr as u32); + uart.hex(non_cacheable_addr); uart.puts(", physical 0x"); - uart.hex(2 * SIZE_2MIB as u32); + uart.hex(2 * SIZE_2MIB); uart.puts(":\n"); let result_nc = match batch_modify_time(non_cacheable_addr) { @@ -71,9 +71,9 @@ pub fn run(uart: &uart::Uart) { }; uart.puts("Benchmarking cacheable DRAM modifications at virtual 0x"); - uart.hex(cacheable_addr as u32); + uart.hex(cacheable_addr); uart.puts(", physical 0x"); - uart.hex(2 * SIZE_2MIB as u32); + uart.hex(2 * SIZE_2MIB); uart.puts(":\n"); let result_c = match batch_modify_time(cacheable_addr) { diff --git a/0D_cache_performance/src/delays.rs b/0D_cache_performance/src/delays.rs new file mode 100644 index 00000000..63414e4f --- /dev/null +++ b/0D_cache_performance/src/delays.rs @@ -0,0 +1,37 @@ +/* + * MIT License + * + * Copyright (c) 2018 Andre Richter + * + * 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. + */ + +use cortex_a::asm; + +/* + * + * Using the CPU's cycles + * + */ +/// Wait N CPU cycles (ARM CPU only) +pub fn wait_cycles(cyc: u32) { + for _ in 0..cyc { + asm::nop(); + } +} diff --git a/0D_cache_performance/src/gpio.rs b/0D_cache_performance/src/gpio.rs index da6a5be4..608ba532 100644 --- a/0D_cache_performance/src/gpio.rs +++ b/0D_cache_performance/src/gpio.rs @@ -23,6 +23,7 @@ */ use super::MMIO_BASE; +use core::ops; use register::{mmio::ReadWrite, register_bitfields}; // Descriptions taken from @@ -66,10 +67,55 @@ register_bitfields! { ] } -pub const GPFSEL1: *const ReadWrite = - (MMIO_BASE + 0x0020_0004) as *const ReadWrite; +const GPIO_BASE: u32 = MMIO_BASE + 0x200_000; -pub const GPPUD: *const ReadWrite = (MMIO_BASE + 0x0020_0094) as *const ReadWrite; +#[allow(non_snake_case)] +#[repr(C)] +pub struct RegisterBlock { + pub GPFSEL0: ReadWrite, // 0x00 + pub GPFSEL1: ReadWrite, // 0x04 + pub GPFSEL2: ReadWrite, // 0x08 + pub GPFSEL3: ReadWrite, // 0x0C + pub GPFSEL4: ReadWrite, // 0x10 + pub GPFSEL5: ReadWrite, // 0x14 + __reserved_0: u32, // 0x18 + GPSET0: ReadWrite, // 0x1C + GPSET1: ReadWrite, // 0x20 + __reserved_1: u32, // + GPCLR0: ReadWrite, // 0x28 + __reserved_2: [u32; 2], // + GPLEV0: ReadWrite, // 0x34 + GPLEV1: ReadWrite, // 0x38 + __reserved_3: u32, // + GPEDS0: ReadWrite, // 0x40 + GPEDS1: ReadWrite, // 0x44 + __reserved_4: [u32; 7], // + GPHEN0: ReadWrite, // 0x64 + GPHEN1: ReadWrite, // 0x68 + __reserved_5: [u32; 10], // + pub GPPUD: ReadWrite, // 0x94 + pub GPPUDCLK0: ReadWrite, // 0x98 + pub GPPUDCLK1: ReadWrite, // 0x9C +} + +/// Public interface to the GPIO MMIO area +pub struct GPIO; -pub const GPPUDCLK0: *const ReadWrite = - (MMIO_BASE + 0x0020_0098) as *const ReadWrite; +impl ops::Deref for GPIO { + type Target = RegisterBlock; + + fn deref(&self) -> &Self::Target { + unsafe { &*Self::ptr() } + } +} + +impl GPIO { + pub fn new() -> GPIO { + GPIO + } + + /// Returns a pointer to the register block + fn ptr() -> *const RegisterBlock { + GPIO_BASE as *const _ + } +} diff --git a/0D_cache_performance/src/main.rs b/0D_cache_performance/src/main.rs index 112e1b69..47a823a7 100644 --- a/0D_cache_performance/src/main.rs +++ b/0D_cache_performance/src/main.rs @@ -30,28 +30,30 @@ const MMIO_BASE: u32 = 0x3F00_0000; mod benchmark; +mod delays; mod gpio; mod mbox; mod mmu; mod uart; -raspi3_boot::entry!(kernel_entry); - fn kernel_entry() -> ! { + let gpio = gpio::GPIO::new(); let mut mbox = mbox::Mbox::new(); let uart = uart::Uart::new(uart::UART_PHYS_BASE); // set up serial console - if uart.init(&mut mbox).is_err() { - loop { + match uart.init(&mut mbox, &gpio) { + Ok(_) => uart.puts("\n[0] UART is live!\n"), + Err(_) => loop { cortex_a::asm::wfe() // If UART fails, abort early - } + }, } - uart.getc(); // Press a key first before being greeted - uart.puts("Hello Rustacean!\n\n"); + uart.puts("[1] Press a key to continue booting... "); + uart.getc(); + uart.puts("Greetings fellow Rustacean!\n"); - uart.puts("\nSwitching MMU on now..."); + uart.puts("[2] Switching MMU on now... "); unsafe { mmu::init() }; @@ -64,3 +66,5 @@ fn kernel_entry() -> ! { uart.send(uart.getc()); } } + +raspi3_boot::entry!(kernel_entry); diff --git a/0D_cache_performance/src/uart.rs b/0D_cache_performance/src/uart.rs index b8e160e7..7287ec75 100644 --- a/0D_cache_performance/src/uart.rs +++ b/0D_cache_performance/src/uart.rs @@ -23,6 +23,7 @@ */ use super::MMIO_BASE; +use crate::delays; use crate::gpio; use crate::mbox; use core::{ @@ -164,7 +165,7 @@ impl Uart { } ///Set baud rate and characteristics (115200 8N1) and map to GPIO - pub fn init(&self, mbox: &mut mbox::Mbox) -> Result<()> { + pub fn init(&self, mbox: &mut mbox::Mbox, gpio: &gpio::GPIO) -> Result<()> { // turn off UART0 self.CR.set(0); @@ -189,23 +190,18 @@ impl Uart { }; // map UART0 to GPIO pins - unsafe { - (*gpio::GPFSEL1).modify(gpio::GPFSEL1::FSEL14::TXD0 + gpio::GPFSEL1::FSEL15::RXD0); + gpio.GPFSEL1 + .modify(gpio::GPFSEL1::FSEL14::TXD0 + gpio::GPFSEL1::FSEL15::RXD0); - (*gpio::GPPUD).set(0); // enable pins 14 and 15 - for _ in 0..150 { - asm::nop(); - } + gpio.GPPUD.set(0); // enable pins 14 and 15 + delays::wait_cycles(150); - (*gpio::GPPUDCLK0).modify( - gpio::GPPUDCLK0::PUDCLK14::AssertClock + gpio::GPPUDCLK0::PUDCLK15::AssertClock, - ); - for _ in 0..150 { - asm::nop(); - } + gpio.GPPUDCLK0.modify( + gpio::GPPUDCLK0::PUDCLK14::AssertClock + gpio::GPPUDCLK0::PUDCLK15::AssertClock, + ); + delays::wait_cycles(150); - (*gpio::GPPUDCLK0).set(0); - } + gpio.GPPUDCLK0.set(0); self.ICR.write(ICR::ALL::CLEAR); self.IBRD.write(IBRD::IBRD.val(2)); // Results in 115200 baud @@ -267,12 +263,12 @@ impl Uart { } /// Display a binary value in hexadecimal - pub fn hex(&self, d: u32) { + pub fn hex(&self, d: u64) { let mut n; - for i in 0..8 { + for i in 0..16 { // get highest tetrad - n = d.wrapping_shr(28 - i * 4) & 0xF; + n = d.wrapping_shr(60 - i * 4) & 0xF; // 0-9 => '0'-'9', 10-15 => 'A'-'F' // Add proper offset for ASCII table