commit 1a94ee7b7fcc0b4c9a81ea605cf451879ab7836f
parent 6ca5a365f12207ef72e483c3fb1870763bb8f153
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sun, 17 Mar 2024 10:22:00 +0900
dump context
Diffstat:
| M | ex3/main.c | | | 60 | ++++++++++++++++++++---------------------------------------- | 
| M | ex3/proc.s | | | 107 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------- | 
2 files changed, 96 insertions(+), 71 deletions(-)
diff --git a/ex3/main.c b/ex3/main.c
@@ -2,26 +2,26 @@
 
 void init(void);
 int puts(char *);
-void printh(void *);
+void printh(unsigned int);
 void set_alarm(unsigned int);
 void proc0(void);
 void halt(void);
-void *get_sp(void);
 void wfi(void);
+void print_sp(void);
 void *memcpy(void *s1, void *s2, long n);
-void setreg(void);
 
 // A proc represents a process in execution.
 typedef struct proc {
 	// Id is the unique identifier of the process.
 	unsigned int id;
-	// R is the registers of the process with r[13] be sp, r[14] lr, r[15] pc.
-	void *r[16];
+	// R is the registers of the process with
+	// r[13] be sp, r[14] lr, r[15] pc, r16 xspr.
+	unsigned int r[17];
 	// Next is the next process to execute.
 	struct proc *next;
 } proc;
 
-proc *save_context(unsigned int pid, void *r[16]);
+void save_context(unsigned int r[17]);
 
 extern char proc0_start, proc0_size;
 extern char proc1_start, proc1_size;
@@ -51,56 +51,36 @@ main(void) {
 	ptab.tail = &p1;
 
 	p0.id = 0;
-	p0.r[13] = (void *) 0x20000100; // sp
-	p0.r[14] = (void *) main; // lr
-	p0.r[15] = (void *) 0x20000000; // pc
+	p0.r[13] = 0x20000100; // sp
+	p0.r[14] = (unsigned int) main; // lr
+	p0.r[15] = 0x20000000; // pc
 	p0.next = &p1;
 
 	p1.id = 1;
-	p1.r[13] = (void *) 0x20000200; // sp
-	p1.r[14] = (void *) main; // lr
-	p1.r[15] = (void *) 0x20000100; // pc
+	p1.r[13] = 0x20000200; // sp
+	p1.r[14] = (unsigned int) main; // lr
+	p1.r[15] = 0x20000100; // pc
 	p1.next = NULL;
 
 	for (;;) {
-		setreg();
 		wfi();
-		void *r[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
-		proc *p = save_context(0, r);
-		if (p == NULL) {
-			puts("process 0 not found");
-			continue;
-		}
-		for (int i = 0; i < 16; i++) {
-			printh(p0.r[i]);
+		for (int i = 0; i < 17; i++) {
+			printh(ptab.head->r[i]);
 			puts("");
 		}
-		puts("");
 	}
 	return 0;
 }
 
-// Save_context saves registers r to the proc struct specified by pid.
-// It returns the address of matching process, or NULL if no such process is found.
-proc *
-save_context(unsigned int pid, void *r[16])
+// Save_context saves the context starting at sp to the current proc struct.
+void
+save_context(unsigned int r[17])
 {
-	proc *p;
+	puts("save_context");
 	int i;
-
-	for (p = ptab.head; p; p = p->next) {
-		if (p->id == pid) {
-			break;
-		}
-	}
-	if (!p) {
-		return NULL;
-	}
-
-	for (i = 0; i < 16; i++) {
-		p->r[i] = r[i];
+	for (i = 0; i < 17; i++) {
+		ptab.head->r[i] = r[i];
 	}
-	return p;
 }
 
 void
diff --git a/ex3/proc.s b/ex3/proc.s
@@ -20,41 +20,86 @@ proc1:
 msg1:
 	.asciz "proc1"
 
-	.section .text
-	// void *get_sp(void);
-	// Get_sp returns the current stack pointer.
-	.global get_sp
-get_sp:
+	.global print_sp
+print_sp:
+	mov r4, lr
 	mov r0, sp
-	bx lr
-
-	// Setreg sets registers for debugging.
-	// Modified registers are:
-	//  LR, R12, R3, R2, R1 and R0.
-	.global setreg
-setreg:
-	push {lr}
-	mov r0, #0x12
-	mov r12, r0
-	mov r0, #0x14
-	mov lr, r0
-	mov r0, #0
-	mov r1, #1
-	mov r2, #2
-	mov r3, #3
-	nop
-	pop {pc}
-
-	.global print_sr
-print_sr:
-	push {lr}
-	mrs r0, ipsr
 	bl printh
-	pop {pc}
+	bx r4
 
 	.global isr_alarm
 isr_alarm:
-	push {r4, r5, r6, lr}
+	push {lr}
+	sub sp, sp, #(17*4) // unsigned int r[17];
+	mov r1, sp
+
+	mov r2, #(17*4 + 4) // +4 for pushed lr
+	mov r3, #0
+	ldr r0, [r1, r2] // r0
+	str r0, [r1, r3]
+	add r2, r2, #4
+	add r3, r3, #4
+	ldr r0, [r1, r2] // r1
+	str r0, [r1, r3]
+	add r2, r2, #4
+	add r3, r3, #4
+	ldr r0, [r1, r2] // r2
+	str r0, [r1, r3]
+	add r2, r2, #4
+	add r3, r3, #4
+	ldr r0, [r1, r2] // r3
+	str r0, [r1, r3]
+
+	add r3, r3, #4
+	str r4, [r1, r3] // r4
+	add r3, r3, #4
+	str r5, [r1, r3] // r5
+	add r3, r3, #4
+	str r6, [r1, r3] // r6
+	add r3, r3, #4
+	str r7, [r1, r3] // r7
+
+	add r3, r3, #4
+	mov r0, r8
+	str r0, [r1, r3] // r8
+	add r3, r3, #4
+	mov r0, r9
+	str r0, [r1, r3] // r9
+	add r3, r3, #4
+	mov r0, r10
+	str r0, [r1, r3] // r10
+	add r3, r3, #4
+	mov r0, r11
+	str r0, [r1, r3] // r11
+
+	add r2, r2, #4
+	add r3, r3, #4
+	ldr r0, [r1, r2]
+	str r0, [r1, r3] // r12
+
+	add r3, r3, #4
+	mov r0, sp
+	str r0, [r1, r3] // sp ???
+
+	add r2, r2, #4
+	add r3, r3, #4
+	ldr r0, [r1, r2]
+	str r0, [r1, r3] // lr
+
+	add r2, r2, #4
+	add r3, r3, #4
+	ldr r0, [r1, r2]
+	str r0, [r1, r3] // ReturnAddress(ExceptionType): The next pc at interrupt.
+
+	add r2, r2, #4
+	add r3, r3, #4
+	ldr r0, [r1, r2] // xpsr
+	str r0, [r1, r3]
+
+	mov r0, r1
+	bl save_context
+
+	add sp, sp, #(17*4)
 	ldr r0, =(1000 * 1000)
 	bl set_alarm
-	pop {r4, r5, r6, pc}
+	pop {pc}