commit 89bbd49c16d6f6cff682163057f7abb1338193ed
parent 1a94ee7b7fcc0b4c9a81ea605cf451879ab7836f
Author: Matsuda Kenji <info@mtkn.jp>
Date: Mon, 18 Mar 2024 11:12:34 +0900
hard fault
Diffstat:
M | ex3/main.c | | | 25 | +++++++++++++++++-------- |
M | ex3/proc.s | | | 53 | +++++++++++++++++++++++++++++++++++++++++++++++++++-- |
2 files changed, 68 insertions(+), 10 deletions(-)
diff --git a/ex3/main.c b/ex3/main.c
@@ -9,6 +9,7 @@ void halt(void);
void wfi(void);
void print_sp(void);
void *memcpy(void *s1, void *s2, long n);
+void restore_context(unsigned int [17]);
// A proc represents a process in execution.
typedef struct proc {
@@ -52,16 +53,18 @@ main(void) {
p0.id = 0;
p0.r[13] = 0x20000100; // sp
- p0.r[14] = (unsigned int) main; // lr
- p0.r[15] = 0x20000000; // pc
+ p0.r[14] = (unsigned int) 0xdeadbeef; // lr
+ p0.r[15] = 0x20000001; // pc
p0.next = &p1;
p1.id = 1;
p1.r[13] = 0x20000200; // sp
p1.r[14] = (unsigned int) main; // lr
- p1.r[15] = 0x20000100; // pc
+ p1.r[15] = 0x20000101; // pc
p1.next = NULL;
+ restore_context(ptab.head->r);
+
for (;;) {
wfi();
for (int i = 0; i < 17; i++) {
@@ -76,7 +79,6 @@ main(void) {
void
save_context(unsigned int r[17])
{
- puts("save_context");
int i;
for (i = 0; i < 17; i++) {
ptab.head->r[i] = r[i];
@@ -84,15 +86,22 @@ save_context(unsigned int r[17])
}
void
-restore_context(proc *p)
-{}
-
-void
scheduler(void) {
puts("scheduler called");
}
void
+switch_context(void) {
+ proc *p;
+ p = ptab.head;
+ ptab.head = ptab.head->next;
+ ptab.tail->next = p;
+ ptab.tail = p;
+ ptab.tail->next = NULL;
+ restore_context(ptab.head->r);
+}
+
+void
isr_hard_fault(void) {
puts("hard fault");
halt();
diff --git a/ex3/proc.s b/ex3/proc.s
@@ -1,10 +1,27 @@
.section .proc0, "a"
.global proc0
proc0:
- ldr r0, msg0
- bl puts
+// ldr r0, msg0
+// bl puts
+
+ mov r0, sp
+ bl printh
+ mov r0, #'\n'
+ bl putbyte
+ mov r0, pc
+ bl printh
+ mov r0, #'\n'
+ bl putbyte
+ mrs r0, xpsr
+ bl printh
+ mov r0, #'\n'
+ bl putbyte
+ bl putbyte
+
+ wfi
b proc0
+ .align 2
.global msg0
msg0:
.asciz "proc0"
@@ -16,6 +33,7 @@ proc1:
bl puts
b proc1
+ .align 2
.global msg1
msg1:
.asciz "proc1"
@@ -30,6 +48,11 @@ print_sp:
.global isr_alarm
isr_alarm:
push {lr}
+
+ // debug:
+ ldr r0, alarm_msg
+ bl puts
+
sub sp, sp, #(17*4) // unsigned int r[17];
mov r1, sp
@@ -90,6 +113,8 @@ isr_alarm:
add r3, r3, #4
ldr r0, [r1, r2]
str r0, [r1, r3] // ReturnAddress(ExceptionType): The next pc at interrupt.
+ ldr r0, =0x20000101 // The entry point of proc1
+ str r0, [r1, r2]
add r2, r2, #4
add r3, r3, #4
@@ -102,4 +127,28 @@ isr_alarm:
add sp, sp, #(17*4)
ldr r0, =(1000 * 1000)
bl set_alarm
+
pop {pc}
+
+ .align 2
+alarm_msg:
+ .asciz "alarm"
+
+ // void restore_context(unsigned int r[17]);
+ // This function does not return, and needs not to save any registers.
+ // How to restore all of the registers?
+ // At least one is needed to branch back to the process to be restored.
+ .global restore_context
+restore_context:
+ ldr r1, [r0, #48]
+ mov r12, r1
+ ldr r1, [r0, #52]
+ mov sp, r1
+ ldr r1, [r0, #56]
+ mov lr, r1
+ ldr r1, [r0, #60]
+ mov r8, r1 // The next instruction to execute after restoring the context.
+ ldr r1, [r0, #64] // xpsr
+ msr xpsr, r1
+ ldm r0, {r0-r7}
+ bx r8