commit 5ca7441102daf5ab906359f8f45e3d74979b470a
parent 7e304f12d94a6d4ea5cc5518f2e093508cb746f4
Author: Matsuda Kenji <info@mtkn.jp>
Date: Sat, 16 Mar 2024 09:39:54 +0900
implement save_context
Diffstat:
M | ex3/main.c | | | 74 | +++++++++++++++++++++++++++++++++++++++++++++++++++----------------------- |
M | ex3/proc.s | | | 18 | +----------------- |
2 files changed, 52 insertions(+), 40 deletions(-)
diff --git a/ex3/main.c b/ex3/main.c
@@ -1,3 +1,5 @@
+#define NULL 0L // TODO: Should fail when dereferenced.
+
void init(void);
int puts(char *);
void printh(void *);
@@ -9,11 +11,6 @@ void wfi(void);
void *memcpy(void *s1, void *s2, long n);
void setreg(void);
-extern char proc0_start, proc0_size;
-extern char proc1_start, proc1_size;
-extern char msg0;
-extern char msg1;
-
// A proc represents a process in execution.
typedef struct proc {
// Id is the unique identifier of the process.
@@ -24,6 +21,14 @@ typedef struct proc {
struct proc *next;
} proc;
+proc *save_context(unsigned int pid, void *r[16]);
+
+extern char proc0_start, proc0_size;
+extern char proc1_start, proc1_size;
+extern char msg0;
+extern char msg1;
+
+
// A proc_tab is the queue of waiting processes.
typedef struct proc_tab {
// Head is the head of the queue.
@@ -32,7 +37,7 @@ typedef struct proc_tab {
proc *tail;
} proc_tab;
-proc_tab *ptab;
+proc_tab ptab;
int
main(void) {
@@ -42,24 +47,61 @@ main(void) {
memcpy((void *)0x20000000, &proc0_start, (long) &proc0_size);
memcpy((void *)0x20000100, &proc1_start, (long) &proc1_size);
+ ptab.head = &p0;
+ 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.next = &p1;
+ p1.id = 1;
p1.r[13] = (void *) 0x20000200; // sp
p1.r[14] = (void *) main; // lr
p1.r[15] = (void *) 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]);
+ puts("");
+ }
+ puts("");
}
return 0;
}
-void
-save_context(proc *p)
-{}
+// 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])
+{
+ proc *p;
+ 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];
+ }
+ return p;
+}
void
restore_context(proc *p)
@@ -80,16 +122,3 @@ void
isr_svcall(void) {
puts("svcall");
}
-/*
-void
-isr_alarm(void) {
- int *sp = get_sp();
- for (int i = 0; i < 12; i += 1) {
- printh(sp+i);
- printh((void *)*(sp+i));
- puts("");
- }
- scheduler();
- set_alarm(1000 * 1000);
-}
-*/
-\ No newline at end of file
diff --git a/ex3/proc.s b/ex3/proc.s
@@ -55,21 +55,6 @@ print_sr:
.global isr_alarm
isr_alarm:
push {r4, r5, r6, lr}
- bl get_sp
- mov r4, r0
- mov r5, sp
- add r5, #16
- mov r6, r5
- add r6, #32 // 8 words
-isr_alarm_loop:
- ldr r0, [r5, #0]
- bl printh
- mov r0, #'\n'
- bl putbyte
- add r5, r5, #4
- cmp r5, r6
- blt isr_alarm_loop
- bl scheduler
ldr r0, =(1000 * 1000)
bl set_alarm
- pop {r4, r5, r6, pc}
-\ No newline at end of file
+ pop {r4, r5, r6, pc}