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