aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvetch <vetch97@gmail.com>2019-12-17 17:16:40 +0100
committervetch <vetch97@gmail.com>2019-12-17 17:16:40 +0100
commit5cb10bcc7d0c6d4159103f05ba228a09ca365fac (patch)
treed248f2a519e7b2b4707b6889a971165c75c4af48
parent90d208f074626521118984902ca8d3ebfd17e62f (diff)
parent7dbdf1ee0a064e9b2c5fedd7bd4e2b67f0532b09 (diff)
downloadrpi-MMU-example-5cb10bcc7d0c6d4159103f05ba228a09ca365fac.tar.gz
rpi-MMU-example-5cb10bcc7d0c6d4159103f05ba228a09ca365fac.zip
Merge branch 'bob' of https://repo.or.cz/RPi-MMU-example into alice
# Conflicts: # kernel.c
-rw-r--r--Makefile4
-rw-r--r--boot.S6
-rw-r--r--demo_functionality.c7
-rw-r--r--demo_functionality.h2
-rw-r--r--kernel.c8
-rw-r--r--psr.h55
6 files changed, 15 insertions, 67 deletions
diff --git a/Makefile b/Makefile
index 0796ac8..d1d66fa 100644
--- a/Makefile
+++ b/Makefile
@@ -47,9 +47,9 @@ qemu-elf : kernel.elf
qemu-bin : loader.elf kernel.img pipe_image
./pipe_image --stdout | qemu-system-arm -m 256 -M raspi2 -serial stdio -kernel $<
-run-on-rpi : kernel7.img pipe_image
+run-on-rpi : kernel.img pipe_image
./pipe_image --stdout | sudo socat FILE:/dev/ttyUSB0,b115200,raw -
-# screen /dev/ttyUSB0 115200,cs8,-parenb,-cstopb,-hupcl
+ screen /dev/ttyUSB0 115200,cs8,-parenb,-cstopb,-hupcl
pipe_image : pipe_image.c lib/rs232/rs232.c
gcc -Wall -std=gnu99 -O3 $^ -o $@
diff --git a/boot.S b/boot.S
index 5cce37c..5e510f8 100644
--- a/boot.S
+++ b/boot.S
@@ -20,7 +20,11 @@ _start:
and r5, r5, #3
cmp r5, #0
bne halt
-
+
+ // go to system mode
+ cps #0b11111
+ isb
+
// Setup the stack.
// It shall be directly below our kernel image
ldr r5, =__start
diff --git a/demo_functionality.c b/demo_functionality.c
index d4b86db..691cdb1 100644
--- a/demo_functionality.c
+++ b/demo_functionality.c
@@ -25,11 +25,11 @@ void demo_paging_support(void)
uart_puts(paging);
}
-void demo_mode_to_system(void)
+void demo_current_mode(void)
{
// get content of current program status register to check the current
- // processor mode
+ // processor mode (should be system, as we set it in boot.S)
PSR_t CPSR = read_CPSR();
char *mode_name;
@@ -50,9 +50,6 @@ void demo_mode_to_system(void)
uart_puts("current mode: ");
uart_puts(mode_name);
-
- uart_puts("setting mode to system (PL1)...\r\n");
- set_system_mode();
}
extern char
diff --git a/demo_functionality.h b/demo_functionality.h
index 86e7902..57fd6f0 100644
--- a/demo_functionality.h
+++ b/demo_functionality.h
@@ -3,7 +3,7 @@
void demo_paging_support(void);
-void demo_mode_to_system(void);
+void demo_current_mode(void);
void demo_go_unprivileged(void);
diff --git a/kernel.c b/kernel.c
index a6f8790..096cd9a 100644
--- a/kernel.c
+++ b/kernel.c
@@ -15,7 +15,7 @@ void kernel_main(uint32_t r0, uint32_t r1, uint32_t atags)
// When we attach screen session after loading kernel with socat
// we miss kernel's greeting... So we'll make the kernel wait for
// one char we're going to send from within screen
- // uart_getc();
+ uart_getc();
uart_puts("Hello, kernel World!\r\n");
@@ -26,13 +26,15 @@ void kernel_main(uint32_t r0, uint32_t r1, uint32_t atags)
// prints some info and switches to system mode
demo_mode_to_system();
+ // prints some info
+ demo_current_mode();
// prints some info and sets upp translation table, turns on MMU
setup_flat_map();
-// demo_setup_libkernel();
+ demo_setup_libkernel();
-// demo_setup_PL0();
+ demo_setup_PL0();
enable_timer();
// enable interrupts
diff --git a/psr.h b/psr.h
index dfbb878..9809fc4 100644
--- a/psr.h
+++ b/psr.h
@@ -64,59 +64,4 @@ inline static PSR_t read_CPSR(void)
return CPSR;
}
-//// Write function not working for some reason... Assembly from gcc
-//// looks ok. Needs checking on real hw.
-
-//inline static void write_CPSR(PSR_t CPSR)
-//{
- // write to current program status register and synchronize context
- // asm("msr cpsr, %0\n\r"
- // "isb" :: "r" (CPSR.raw) : "memory");
-//}
-
-inline static void set_system_mode(void)
-{
- // hack to fix an unexplained bug; volatile needed in case of
- // compilation with optimizations
- volatile PSR_t CPSR __attribute__((unused)) = read_CPSR();
-
- //// there are 2 ways of changing mode, both with the same
- //// problem (see the long comment below)
-
- //// way 1
- // CPSR.fields.M_4_0 = MODE_SYSTEM;
- // write to current program status register and synchronize context
- // asm("msr cpsr, %0\n\r"
- // "isb":: "r" (CPSR.raw) : "memory");
-
- //// way 2
- asm("cps #0b11111\n\r"
- "isb" ::: "memory");
-}
-
-// The thing with writing to cpsr is weird. I used to have a single
-// function that would set the system mode by:
-// 1. reading the cpsr
-// 2. modifying the value using bit shifts and logical or
-// 3. writing the value back
-// When introducing structs and bitfields I wanted to have separate
-// functions for reading and writing the cpsr and have code up the
-// call stack handle value modification. For some reason this didn't
-// work - all would just hang when writing the CPSR. It turned out
-// everything works if i call read_CPSR() from the same function, in
-// which i write to cpsr. And I don't even need to use the value
-// I read. I can just discard it (we're compiling without
-// optimizations, so read_CPSR() is still called) and use the value
-// passed as argument. I noticed an even weirder thing: the 2nd way
-// of changing mode (cps instruction) doesn't work normally, but,
-// just as msr, it does work when I call read_CPSR() before it. Even
-// weirder - I cannot replace read_CPSR() with the actual assembly it
-// does, because it stops working again! Asm generated by gcc looks
-// ok, so Idk, maybe its some qemu issue (haven't tested on real RPi
-// yet). I seem to have experienced uart printing inserted here and
-// there do the same magic read_CPSR() does (but, again, not always).
-// Unfortunately, nop repeated several hundreds times (or a recursive
-// nop function, that just calls itself a given number of times)
-// doesn't have this magical property :(
-
#endif // PSR_H