Skip to content
Snippets Groups Projects
Commit 7807bc53 authored by Tom Feng's avatar Tom Feng
Browse files

Merge branch 'kernel1' of https://git.uwaterloo.ca/b26feng/cs452Trainee into kernel1

it's probably not necessary
parents 8aabee65 c854c032
No related branches found
No related tags found
1 merge request!16Withtime
#ifndef CONTEXT_SWITCH_H
#define CONTEXT_SWITCH_H
void SetUpRegs();
void kerent();
void kerxit(TD* Active);
void kerxit(int* sp, int* spsr, int RetVal);
#endif
\ No newline at end of file
#ifndef REQUEST_H
#define REQUEST_H
typedef struct req {
int n;
void* args[2];
} Request;
#endif
......@@ -9,9 +9,13 @@ typedef enum syscall {
SYS_Exit
}Syscall;
void handlerCreate (TD* Active);
void handlerCreate(TD* Active);
int Activate(KernelStruct* Colonel, TD* Task);
void Handle(KernelStruct* Colonel);
int syscallHandler (KernelStruct* Colonel);
#endif
......@@ -8,7 +8,8 @@ typedef enum taskstate {
Active,
Ready,
Blocked,
Init
Init,
Zombie
}State;
typedef enum prioritylvl {
......
......@@ -25,6 +25,7 @@ void kernelInit(KernelStruct* Colonel) {
Colonel->FirstFree = &(Colonel->Tasks[0]);
Colonel->LastFree = &(Colonel->Tasks[MAX_NUM_TD-1]);
Colonel->NumTDsAvail = MAX_NUM_TD;
Colonel->Active = NULL;
}
......
......@@ -4,28 +4,35 @@
int handlerCreate(KernelStruct* Colonel, TD* Active, int priority, void (*code)()) {
void handlerCreate(KernelStruct* Colonel) {
TD* NewTask = NewTask(priority,Active->TaskID),code);
return pushToScheduler(Colonel, NewTask);
}
int handle(TD* Active, Request* req) {
switch(req->n) {
void Handle(KernelStruct* Colonel, int n) {
switch(n) {
case SYS_Create:
return handlerCreate(Active, Active->TaskPriority, ???); // TODO
handlerCreate(Colonel);
break;
case SYS_MyTid:
return Active->TaskID;
(Colonel->Active)->RetVal = (Colonel->Active)->TaskID;
pushToScheduler(Colonel);
break;
case SYS_ParentTid:
if (isTaskAlive(Active->ParentID)) return Active->ParentID;
else return FAILURE;
(Colonel->Active)->RetVal = (Colonel->Active)->ParentID;
pushToScheduler(Colonel);
break;
case SYS_Pass:
Active->TaskState = Ready;
return SUCCESS;
pushToScheduler(Colonel);
break;
case SYS_Exit:
(Colonel->Active)->TaskState = Zombie;
break;
}
}
int Activate(KernelStruct* Colonel, TD* Task) {
int Request;
return Request;
}
......@@ -9,7 +9,6 @@ int Create (int priority, void (*code)()) {
);
register int RetVal asm("r0");
return RetVal;
// return TaskID of new Task
}
int MyTid() {
......
......@@ -15,7 +15,7 @@ kerent:
msr cpsr_c, #0xDF @or #223
@ push register contents onto users stack
stmfd sp!, {r0-r14}
stmfd sp!, {r4-r12,r14}
@ save user's sp
mov r3, sp
......@@ -42,9 +42,9 @@ kerxit:
@ when its ready to restart the active task
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 1, uses_anonymous_args = 0
mov ip, sp
@ push kernel's registers
stmfd sp!, {r4-r14}
stmfd sp!, {r3-r12, r14}
@ stmfd sp_svc!, {r0-r14} TODO
@ switching to system mode
msr cpsr_c, #0xDF
......
src/cs.s 0 → 100644
.file "context_switch.c"
.text
.align 2
.global init_regs
.type init_regs, %function
init_regs:
mov ip, sp
stmfd sp!, {fp, ip, lr}
mov r0, #0
mov r1, #0
mov r2, #0
mov r3, #0
mov r4, #0
mov r5, #0
mov r6, #0
mov r7, #0
mov r8, #0
mov r9, #0
@mov r10, #0 @ apparently we cannot clear this register @,@?
ldmfd sp, {fp, sp, pc}
@blah
.align 2
.global init_kernelentry
.type init_kernelentry, %function
init_kernelentry:
mov ip, sp
stmfd sp!, {fp, ip, lr}
ldr r1, =kernelentry
add r1, r1, #0x218000
mov r2, #0x28
str r1, [r2]
ldmfd sp, {fp, sp, pc}
.align 2
.global kernel_exit
.type kernel_exit, %function
@TODO: find out args etc settings
kernel_exit:
@ 1. push kregs onto stack
mov ip, sp
stmfd sp!, {r3-r12, r14}
@ Set spsr to saved value
msr spsr, r2
@ 2. switch to system mode
msr cpsr_c, #0xdf
@ 3. get retval, sp from TD
mov sp, r1
@ load the pc into r1
ldmfd sp!, {r1}
@ r0 is already retval
@ 4. pop the registers of the active task
ldmfd sp!, {r4-r12, r14}
@ 6. return to svc state
msr cpsr_c, #0xd3
@ 8. install the pc of the active task and change modes
movs pc, r1
@ldmfd sp, {r3-r12, pc}
@.align 2
@.global kernel_entry
@.type kernel_entry, %function
kernelentry:
@ 3. change to system state, sp lr are in user
msr cpsr_c, #0xdf
@ 5. store user's registers values onto user stack
stmfd sp!, {r4-r12, r14}
@ 6. save active user task's sp in r1
mov r1, sp
@ 7. back to service state
msr cpsr_c, #0xd3
@ Calculate address of SWI instruction and load it into r0.
ldr r0, [lr,#-4]
@ Mask off top 8 bits of instruction to give SWI number.
bic r0, r0,#0xFF000000
@ save user's next pc to stack which is stored in lr_svc, set by swi
stmfd r1!, {lr}
@ 8. getting spsr, user's values were set by swi
mrs r2, spsr
@ 9. pop kernel registers from stack, jump to kernel's lr instruction
ldmfd sp!, {r3-r12, r14}
mov sp, ip
mov pc, lr
@ r0: request_type, r1: user sp, r2: user spsr, arguments on user stack
\ No newline at end of file
......@@ -10,20 +10,27 @@
int main(int argc, char const *argv[])
{
KernelStruct Colonel;
Request* Req;
int i, Status;
KernelStruct Colonel;
int i, Status, req;
TD* Next;
int* kernelEntry = (int *)(0x8);
*kernelEntry = (int)&kerent;
SetUpRegs();
kerent();
kernelInit(&Colonel);
schedulerInit();
memoryInit();
// First User Task
Colonel->Active = Create(Prio4, &firstUserTaskChildren);
pushToScheduler(&Colonel);
FOREVER {
Task = getNextTaskScheduler(&Colonel);
req = Activate(&Colonel, Task);
Handle(&Colonel, req);
}
return 0;
}
src/sc.c 0 → 100644
#include "task-descriptor.h"
#include "kernel.h"
#include "syscall-handler.h"
void handlerCreate(KernelStruct* Colonel) {
register int Priority asm("r0");
register void (*Code)() asm ("r1");
register int* CurSP asm("r3") = (Colonel->Active)->sp;
asm volatile(
"msr cpsr_c, #0xDF\n\t"
"mov r1, %0\n\t" : "r" (CurSp)
"sub r2, r1, #44\n\t"
"ldmfd r2, {%0, %1}\n\t" : "r" (Priority), "r" (Code)
"msr cpsr_c, #0xD3\n\t"
);
TD* NewTask = NewTask(Colonel, (int)priority,(int)code);
if (NewTask == NULL) (Colonel->Active)->RetVal = FAILURE;
else {
(Colonel->Active)->RetVal = NewTask->TaskID;
pushToScheduler(Colonel, NewTask);
}
pushToScheduler(Colonel, Colonel->Active);
}
void Handle(KernelStruct* Colonel, int n) {
switch(n) {
case SYS_Create:
handlerCreate(Colonel);
break;
case SYS_MyTid:
(Colonel->Active)->RetVal = (Colonel->Active)->TaskID;
pushToScheduler(Colonel);
break;
case SYS_ParentTid:
(Colonel->Active)->RetVal = (Colonel->Active)->ParentID;
pushToScheduler(Colonel);
break;
case SYS_Pass:
pushToScheduler(Colonel);
break;
case SYS_Exit:
(Colonel->Active)->TaskState = Zombie;
break;
}
}
int Activate(KernelStruct* Colonel, TD* Task) {
register int Request asm ("r0");
register int* NewSP asm("r1");
register int NewSPSR asm("r2");
Colonel->Active = Task;
kerxit(Task->sp, Task0->spsr, Task->RetVal);
asm volatile (
"mov %0, r0\n\t" : "r" (Request) // TODO
"mov %1, r1\n\t" : "r" (NewSP)
"mov %2, r2\n\t": "r" (NewSPSR)
};
Task->sp = NewSP;
Task->spsr = NewSPSR;
return Request;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment