aboutsummaryrefslogtreecommitdiff
path: root/src/arm/PL0
diff options
context:
space:
mode:
Diffstat (limited to 'src/arm/PL0')
-rw-r--r--src/arm/PL0/PL0_test.c34
-rw-r--r--src/arm/PL0/PL0_test.ld19
-rw-r--r--src/arm/PL0/PL0_utils.c19
-rw-r--r--src/arm/PL0/PL0_utils.h6
-rw-r--r--src/arm/PL0/svc.S5
5 files changed, 83 insertions, 0 deletions
diff --git a/src/arm/PL0/PL0_test.c b/src/arm/PL0/PL0_test.c
new file mode 100644
index 0000000..0bfebc7
--- /dev/null
+++ b/src/arm/PL0/PL0_test.c
@@ -0,0 +1,34 @@
+#include "PL0_utils.h"
+
+// entry point - must remain the only function in the file!
+void PL0_main(void)
+{
+ // If loading program to userspace and handling of svc are
+ // implemented correctly, this shall get printed
+ puts("Hello userspace! Type 'f' if you want me to try accessing "
+ "kernel memory!");
+
+ while (1)
+ {
+ char c = getchar();
+
+ if (c == '\r')
+ putchar('\n');
+
+ putchar(c);
+
+ if (c == 'f')
+ {
+ // if we're indeed in PL0, we should trigger the abort
+ // handler now, when trying to access memory we're not
+ // allowed to
+ puts("Attempting to read kernel memory from userspace :d");
+ char first_kernel_byte[2];
+
+ first_kernel_byte[0] = *(char*) 0x0;
+ first_kernel_byte[1] = '\0';
+
+ puts(first_kernel_byte);
+ }
+ }
+}
diff --git a/src/arm/PL0/PL0_test.ld b/src/arm/PL0/PL0_test.ld
new file mode 100644
index 0000000..b1d06f4
--- /dev/null
+++ b/src/arm/PL0/PL0_test.ld
@@ -0,0 +1,19 @@
+/* linker script for creating the example userspace program PL0_test
+ */
+
+/* no ENTRY() statement - this executable is run by jumping to it */
+
+SECTIONS
+{
+ /* my thought up address userspace programs should run from */
+ . = 0xaaa00000;
+
+ __start = .;
+ .another_weird_section_name_that_doesnt_matter :
+ {
+ /* have entry point at the beginning */
+ KEEP(PL0_test.o)
+ *(*)
+ }
+ __end = .;
+}
diff --git a/src/arm/PL0/PL0_utils.c b/src/arm/PL0/PL0_utils.c
new file mode 100644
index 0000000..d83edb9
--- /dev/null
+++ b/src/arm/PL0/PL0_utils.c
@@ -0,0 +1,19 @@
+#include <stddef.h>
+#include <stdint.h>
+
+#include "svc_interface.h"
+#include "PL0_utils.h"
+
+// most generic definition possible
+// the actual function defined in svc.S
+uint32_t svc(enum svc_type, ...);
+
+void putchar(char character)
+{
+ svc(UART_PUTCHAR, character);
+}
+
+char getchar(void)
+{
+ return svc(UART_GETCHAR);
+}
diff --git a/src/arm/PL0/PL0_utils.h b/src/arm/PL0/PL0_utils.h
new file mode 100644
index 0000000..c26a100
--- /dev/null
+++ b/src/arm/PL0/PL0_utils.h
@@ -0,0 +1,6 @@
+#ifndef PL0_UTILS_H
+#define PL0_UTILS_H
+
+#include "io.h"
+
+#endif // PL0_UTILS_H
diff --git a/src/arm/PL0/svc.S b/src/arm/PL0/svc.S
new file mode 100644
index 0000000..65200d8
--- /dev/null
+++ b/src/arm/PL0/svc.S
@@ -0,0 +1,5 @@
+.global svc
+
+svc:
+ svc #0
+ mov pc, lr