diff --git a/.vscode/settings.json b/.vscode/settings.json index 965a59912bf1ef3b56437df777a690a1dcc3251a..ba6819fb151abe4904017b8f9cfea44dca3d92ab 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,9 @@ { "files.associations": { "task-descriptor.h": "c", - "bwio.h": "c" + "bwio.h": "c", + "kernel.h": "c", + "scheduler.h": "c", + "k1.h": "c" } } \ No newline at end of file diff --git a/include/context-switch.h b/include/context-switch.h index c14ce4997ac0defcb8cd1769470f6a74cc0ed6f3..70308618e127c776eba309c423f523f0137bff97 100644 --- a/include/context-switch.h +++ b/include/context-switch.h @@ -3,6 +3,6 @@ void kerent(); -Request* kerxit(TD* Active); +void kerxit(TD* Active); #endif \ No newline at end of file diff --git a/include/k1.h b/include/k1.h new file mode 100644 index 0000000000000000000000000000000000000000..654471fcf8b68cda706a24195b92fceb2631ba53 --- /dev/null +++ b/include/k1.h @@ -0,0 +1,8 @@ +#ifdef K1_H +#ifndef K1_H + +void someK1Fn(); + +void firstUserTaskChildren(); + +#endif \ No newline at end of file diff --git a/include/kernel.h b/include/kernel.h index a72e3890137a027fd1c8355d8aebe11a3f8c1bce..2d908ac3fd24cca6c980e3a011968453f0970890 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -2,23 +2,27 @@ #define KERNEL_H #define MAX_NUM_PRIORITY 8 -#define MAX_NUM_TD 10 +#define MAX_NUM_TD 60 +#define KERNEL_STACK (0xFFFFFFFF - 0x200000) typedef struct kernel { TDPQ* ArrayPQ[MAX_NUM_PRIORITY]; - int AliveTasks[MAX_NUM_TD]; //index is TaskID; value of 1 = alive + TD Tasks[MAX_NUM_TD]; + //index is TaskID; value of 1 = alive // a free list of pointers to free TDs. This might take the form of bits set in a couple of words. WHAT? // a structure for keeping the request currently being serviced, including its arguments. - Request syscalReq; + TD* FirstOfFreeList; + TD* LastOfFreeList; TD* Active; + int NumTDsAvail; }KernelStruct; void kernelInit (KernelStruct* Colonel); -void activate(KernelStruct* Colonel); // TODO Will have to return a request +int activate(KernelStruct* Colonel); -void handle(KernelStruct* Colonel, Request* syscallRequest); +void handle(KernelStruct* Colonel, int syscallRequest); #endif diff --git a/include/scheduler.h b/include/scheduler.h index e6cba82abcef17ff5a03fb3639fd81c15a8ea170..b487d28fef080153e99546bed7d521fa5e2baec4 100644 --- a/include/scheduler.h +++ b/include/scheduler.h @@ -1,7 +1,7 @@ #ifndef SCHEDULER_H #define SCHEDULER_H -int schedulerInit(); // add the IDLE task with lowest priority and first USER task maybe +int schedulerInit(KernelStruct* Colonel); int pushToScheduler (KernelStruct* Colonel, TD* Task); diff --git a/include/syscall-handler.h b/include/syscall-handler.h index d562ecc38c385752505013283a72635dbc8b7209..8aa8983509fc5b694b309f09dd4e3a3caef4bf17 100644 --- a/include/syscall-handler.h +++ b/include/syscall-handler.h @@ -7,11 +7,11 @@ typedef enum syscall { SYS_ParentTid, SYS_Pass, SYS_Exit -} Syscall; +}Syscall; void handlerCreate (TD* Active); -int syscallHandler (KernelStruct* Colonel, TD* Active); +int syscallHandler (KernelStruct* Colonel); #endif diff --git a/include/task-descriptor.h b/include/task-descriptor.h index 4827cb97ef1519ea82271e56c4850f9742200ef9..a9e8dda3e4bd093da041668b5e7d21b314fff323 100644 --- a/include/task-descriptor.h +++ b/include/task-descriptor.h @@ -1,12 +1,14 @@ #ifndef TASK_DESCRIPTOR_H #define TASK_DESCRIPTOR_H -#define USER_STACK_SIZE 1024*64 // 64KB +#define STACK_SIZE 0x80000 // 512KB +#define USER_STACK_TOP (0xFFDFFFFF - STACK_SIZE) typedef enum taskstate { Active, Ready, - Blocked + Blocked, + Init }State; typedef enum prioritylvl { @@ -23,24 +25,24 @@ typedef enum prioritylvl { struct taskDescriptor { int TaskID; int ParentID; - State TaskState; + PrioLvl TaskPriority; + + struct taskDescriptor* NextFree; + struct taskDescriptor* NextInPQ; - int* spsr; + int spsr; // int* lr; - int* sp; - - struct taskDescriptor* Next; + int* sp; // + int RetVal; // - PrioLvl TaskPriority; - struct taskDescriptor* Parent; -// Request* Req; - void* RetVal; }; typedef struct taskDescriptor TD; -TD* TDinit(PrioLvl Priority); +TD* CreateTask(KernelStruct* Colonel, PrioLvl Priority); + +void RemoveTask(KernelStruct* Colonel, TD* Task); int isTaskAlive(int TaskID); diff --git a/lib/kernel.c b/lib/kernel.c index 8ff203af512e36e11fd718503e7309d021f533fa..e688cee72443cee292533bb86ce0767f5850bd40 100644 --- a/lib/kernel.c +++ b/lib/kernel.c @@ -3,14 +3,35 @@ #include "kernel.h" void kernelInit(KernelStruct* Colonel) { + int i; + TD* temp; + for (i = 0; i < MAX_NUM_TD; i++) { + temp = &(Colonel->Tasks[i]); + temp->TaskID = i; + temp->ParentID = 0; + temp->TaskState = Init; + temp->TaskPriority = Prio0; + + if (i == MAX_NUM_TD-1) temp->NextFree = NULL; + else temp->NextFree = &(Colonel->Tasks[i+1]); + temp->NextInPQ = NULL; + + temp->sp = USER_STACK_TOP - (STACK_SIZE*i); + temp->spsr = 208; // or 0xd0; + temp->RetVal = 0; + temp->lr = 0; + } + Colonel->FirstFree = &(Colonel->Tasks[0]); + Colonel->LastFree = &(Colonel->Tasks[MAX_NUM_TD-1]); + Colonel->NumTDsAvail = MAX_NUM_TD; } void activate(KernelStruct* Colonel, TD* Active) { - + kerxit(Active); } void handle(KernelStruct* Colonel, Request* syscallRequest) { - + }; \ No newline at end of file diff --git a/lib/syscall-handler.c b/lib/syscall-handler.c index e7c6b3e219930a1d9aeccb4b7ed1d3d313a43261..ef93eb44296dc5e8287d15d0af2b6cd5da099cad 100644 --- a/lib/syscall-handler.c +++ b/lib/syscall-handler.c @@ -2,26 +2,29 @@ #include "kernel.h" #include "syscall-handler.h" -int handlerCreate(TD* Active, int priority, fn_ptr) { - if -} +int handlerCreate(KernelStruct* Colonel, TD* Active, int priority, void (*code)()) { + + TD* NewTask = NewTask(priority,Active->TaskID),code); + return pushToScheduler(Colonel, NewTask); +} + int handle(TD* Active, Request* req) { switch(req->n) { case SYS_Create: - return handlerCreate(Active); + return handlerCreate(Active, Active->TaskPriority, ???); // TODO case SYS_MyTid: return Active->TaskID; case SYS_ParentTid: - if (isTaskAlive(Active->ParentID)) return Active->ParentID; - else return -1; + if (isTaskAlive(Active->ParentID)) return Active->ParentID; + else return FAILURE; case SYS_Pass: Active->TaskState = Ready; - return 0; + return SUCCESS; case SYS_Exit: - // TODO + } } diff --git a/lib/syscall.c b/lib/syscall.c index 869732942713c3c584b91c60f8afa7606b34b240..0822f65a076302c607e4776dcf7da057c0b16e20 100644 --- a/lib/syscall.c +++ b/lib/syscall.c @@ -2,7 +2,11 @@ #include "syscall.h" int Create (int priority, void (*code)()) { - asm volatile ("swi %0" : "r" (SYS_Create)); + asm volatile ( + // "stmfd sp!, {r0, r1}\n\t" + "swi %0" : "r" (SYS_Create) + // "ldmfd sp!, {r1, r2}\n\t" + ); register int RetVal asm("r0"); return RetVal; // return TaskID of new Task diff --git a/lib/task-descriptor.c b/lib/task-descriptor.c index 2476e6cf7d6a7869a137ccdbd54b1fd3e5939e7e..60ec7d6f61982fa7d1a3ae6733373fd74b1d8efb 100644 --- a/lib/task-descriptor.c +++ b/lib/task-descriptor.c @@ -1,7 +1,45 @@ #include "task-descriptor.h" +TD* TDinit(KernelStruct* Colonel, PrioLvl Priority, int TaskID, int ParentID) { +<<<<<<< HEAD int TaskInit(); +======= + TD* Task = &(Colonel->Tasks[TaskID]); + + Task->TaskID = TaskID; + Task->ParentID = ParentID; + Task->TaskState = Active; + Task->TaskPriority = Priority; + Task->sp = NULL; + Task->lr = NULL; + Task->spsr = 0; + Task->RetVal = 0; + + return Task; +} + +TD* CreateTask(KernelStruct* Colonel, PrioLvl Priority, int code) { + if (Colonel->NumTDsAvail == 0) return NULL; + TD* NewTask = Colonel->FirstFree; + + Colonel->FirstOfFreeList = NewTask->NextFree; + NewTask->NextFree = NULL; + + + NewTask->TaskState = Ready; + NewTask->TaskPriority = Priority; + NewTask->TaskID = // TODO + if (Colonel->Active == NULL) NewTask->ParentID = 0; + else NewTask->ParentID = (Colonel->Active)->TaskID; + + Colonel->NumTDsAvail -= 1; + + return NewTask; +} + +void RemoveTask(KernelStruct* Colonel, TD* Task) {} // IF NECESSARY +>>>>>>> 698d3cdd94aa71c7ae90252230240feed1876156 int isTaskAlive(int TaskID) { return TaskID >> 31; @@ -14,11 +52,13 @@ int GetGeneration(TD* Task) { return ((TID << 1) >> 17); } +// to see if this task is active int GetAvailability(TD* Task) { int mask = 1 <<31; return mask & (Task->TaskID); } +// for sp calculation int GetMemoryIndex(TD* Task){ int mask = 1 << 16 - 1; return mask & (Task->TaskID); diff --git a/src/context-switch.s b/src/context-switch.s index 4ee433b3ddedaee1807abec8f137fb9e846ae257..3f5b9c3f3703367dcadfb0e1887c886aaa71ba01 100644 --- a/src/context-switch.s +++ b/src/context-switch.s @@ -15,7 +15,7 @@ kerent: msr cpsr_c, #0xDF @or #223 @ push register contents onto users stack - stmfd sp!, {r4-r14} + stmfd sp!, {r0-r14} @ save user's sp mov r3, sp @@ -30,8 +30,7 @@ kerent: str r3!, {r2, r1} @ pop kernels stack - ldmfd sp!, {r3-r12, lr} - + ldmfd sp!, {r4-r14} .text @@ -46,12 +45,14 @@ kerxit: @ push kernel's registers stmfd sp!, {r4-r14} - + @ stmfd sp_svc!, {r0-r14} TODO @ switching to system mode msr cpsr_c, #0xDF - @ restore user's sp, spsr and lr - + @ restore user's spsr and lr + ldr r1, [sp, #0] @ lr + ldr r2, [sp, #4] @ spsr + sub sp, sp, #4 @ restore user's registers ldmfd sp!, {r4-r14} @@ -60,7 +61,7 @@ kerxit: msr cpsr, #0xD3 @ restore user's spsr - msr spsr, r3 + msr spsr, r2 @ restore user's lr to continue execution; also put spsr_svc into cpsr movs pc, r1 diff --git a/src/k1.c b/src/k1.c index c924ff827282c503037180a99d1c5610e47468bb..9a3184a883a85e98ac1217f3241601cab5748b62 100644 --- a/src/k1.c +++ b/src/k1.c @@ -9,14 +9,18 @@ void someK1Fn() { void firstUserTaskChildren() { int TaskID; - TaskID = Create(Prio1, someK1Fn); + TaskID = Create(Prio1, &someK1Fn); bwprintf(COM2, "Created: <%d>\n", TaskID); - TaskID = Create(Prio1, someK1Fn); + + TaskID = Create(Prio1, &someK1Fn); bwprintf(COM2, "Created: <%d>\n", TaskID); - TaskID = Create(Prio5, someK1Fn); + + TaskID = Create(Prio5, &someK1Fn); bwprintf(COM2, "Created: <%d>\n", TaskID); - TaskID = Create(Prio5, someK1Fn); + + TaskID = Create(Prio5, &someK1Fn); bwprintf(COM2, "Created: <%d>\n", TaskID); bwprintf(COM2, "FirstUserTask: exiting"); + Exit(); } \ No newline at end of file diff --git a/src/main.c b/src/main.c index b575e84f07596e62dd50af9986664391f05305bd..6232fe9bc9bd99141914099f5cb7ab0852a40919 100644 --- a/src/main.c +++ b/src/main.c @@ -1,52 +1,29 @@ // #include "kernel.h" #include "task-descriptor.h" #include "scheduler.h" -// #include "error.h" +#include "k1.h" #include "bwio.h" #include "request.h" #define FOREVER while(1) -// void kerent() { - -// } - -// void kerxit(TD* Active, Request* req) { -// bwprintf(COM2, "kerxit.c: Hello\n\r"); -// bwprintf(COM2, "kerxit.c: Activating\n\r"); -// kerent(); -// bwprintf(COM2, "kerxit.c: Goodbye\n\r"); -// } - -// void initialize(TD* Active) { - -// } - -// void handle(TD* Active, Request* req) { - -// } - int main(int argc, char const *argv[]) { KernelStruct Colonel; Request* Req; int i, Status; + int* kernelEntry = (int *)(0x8); + *kernelEntry = (int)&kerent; + + kernelInit(&Colonel); schedulerInit(); memoryInit(); - kernelInit(&Colonel); // which will call kerent; - // disableInterrupts(); - Colonel->Active = Create(Prio4, firstUserTaskChildren); - // tds is an array of TDs - for (i = 0; i < 4; i++ ) { - Colonel->Active = getNextTaskScheduler(Colonel); - Req = kerxit(Active); - Status = handle(Active, Req); - } - return 0; - + + Colonel->Active = Create(Prio4, &firstUserTaskChildren); + return 0; } diff --git a/src/scheduler.c b/src/scheduler.c deleted file mode 100644 index 1b389b55717f11156c3ca00837dcb06021d89517..0000000000000000000000000000000000000000 --- a/src/scheduler.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "scheduler.h" - -// int schedulerInit() { -// return 0; -// } // add the IDLE task with lowest priority and first USER task maybe - -// int pushToScheduler (KernelStruct* Colonel, TD* Task) { -// return 0; -// } - -// TD* getNextTaskScheduler (KernelStruct* Colonel) { -// return NULL; -// } diff --git a/src/task-descriptor.c b/src/task-descriptor.c deleted file mode 100644 index 43e70426a1f385810a17e334cfd68ff63b6934a8..0000000000000000000000000000000000000000 --- a/src/task-descriptor.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "task-descriptor.h" - - -//void TaskInit(); - -int isTaskAlive(int TaskID) { - return 0; -} - - - - - -