commit 59737698a76411d4fd1d407846b70c03309d4125
parent f6681f83ad1eadc2f66a1ec907436afc33486fc9
Author: Matsuda Kenji <info@mtkn.jp>
Date: Tue, 12 Mar 2024 12:37:27 +0900
try to implement context switch.
find some weird error.
Diffstat:
4 files changed, 75 insertions(+), 11 deletions(-)
diff --git a/ex3/main.c b/ex3/main.c
@@ -4,9 +4,13 @@ void printh(void *);
void set_alarm(unsigned int);
void proc0(void);
void halt(void);
+void *get_sp(void);
+void wfi(void);
extern void proc0_start, proc0_size;
+extern void proc1_start, proc1_size;
extern char msg0;
+extern char msg1;
// A proc represents a process in execution.
typedef struct proc {
@@ -14,14 +18,14 @@ typedef struct proc {
unsigned int id;
// R is the registers of the process with r[13] be sp, r[14] lr, r[15] pc.
void *r[16];
+ // Next is the next process to execute.
+ struct proc *next;
} proc;
// A proc_tab is the queue of waiting processes.
typedef struct proc_tab {
// Head is the head of the queue.
proc *head;
- // Next is the next process to execute.
- proc *next;
// Tail is the tail of the queue.
proc *tail;
} proc_tab;
@@ -31,24 +35,48 @@ proc_tab *ptab;
int
main(void) {
init();
- puts("reset");
- proc *p0 = (proc *) 0x20041000, *p1 = (proc *) 0x20041100; // sram5
+ proc p0, p1;
memcpy((void *)0x20000000, (void *)&proc0_start, (long) &proc0_size);
- puts(&msg0);
- p0->r[13] = (void *) 0x20000100; // sp
- p0->r[14] = (void *) 0xdeadbeef; // lr
- p0->r[15] = (void *) 0x20000000; // pc
+ memcpy((void *)0x20000100, (void *)&proc1_start, (long) &proc1_size);
+
+ p0.r[13] = (void *) 0x20000100; // sp
+ p0.r[14] = (void *) 0xdeadbeef; // lr
+ p0.r[15] = (void *) 0x20000000; // pc
- p1->r[13] = (void *) 0x20000200; // sp
- p1->r[14] = (void *) 0xdeadbeef; // lr
- p1->r[15] = (void *) 0x20000100; // pc
+ p1.r[13] = (void *) 0x20000200; // sp
+ p1.r[14] = (void *) 0xdeadbeef; // lr
+ p1.r[15] = (void *) 0x20000100; // pc
+
+ for (;;) {
+ wfi();
+ setreg();
+ }
return 0;
}
void
+save_context(proc *p)
+{}
+
+void
+restore_context(proc *p)
+{
+
+}
+
+void
scheduler(void) {
+ int *sp1, *sp0;
+ sp1 = (int *)get_sp();
+ sp0 = sp1 + 16;
+ for (; sp1 <= sp0; sp1++) {
+ printh(sp1);
+ printh(*sp1);
+ puts("");
+ }
+ puts("");
puts("scheduler called");
}
diff --git a/ex3/memmap.ld b/ex3/memmap.ld
@@ -34,4 +34,7 @@ SECTIONS
.proc1 0x20000100 : {
*(.proc1)
} > SRAM AT > FLASH
+ proc1_start = LOADADDR(.proc1);
+ proc1_size = SIZEOF(.proc1);
+
}
diff --git a/ex3/proc.s b/ex3/proc.s
@@ -19,5 +19,33 @@ proc1:
bl puts
b proc1
.align 2
+ .global msg1
msg1:
.asciz "proc1"
+
+ .align 1
+ .section .text
+ // void *get_sp(void);
+ // Get_sp returns the current stack pointer.
+ .global get_sp
+get_sp:
+ mov r0, sp
+ bx lr
+
+ .align 1
+ // Set_reg sets registers for debugging.
+ // Modified registers are:
+ // ReturnAddress(), 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
+ bl printh // BUG: some alignment fault?
+ pop {pc}
diff --git a/ex3/start.s b/ex3/start.s
@@ -284,6 +284,11 @@ halt:
wfe
b halt
+ .global wfi
+wfi:
+ wfi
+ bx lr
+
// The following functions make no side effects and
// can be used anywhare without pushing and popping
// registers.