summaryrefslogtreecommitdiff
path: root/kernel/task.c
blob: 8884079f986ff6773fc5bf512e3d40141ec5793c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// http://hosted.cjmovie.net/TutMultitask.htm
//
//
#include "kernel.h"
#include "../lib/logger/log.h"	// logger facilities
#define FOOLOS_MODULE_NAME "task"

int started;

void task_test1()
{
    uint8_t c1;

   while(1)
   {
       c1++;
       asm("cli");

	PutString("task1: %03d", 0,560,0xffffff, c1);

       asm("sti");
   }

}

void task_test2()
{
    uint8_t c2;

   while(1)
   {
       c2++;
       asm("cli");
	PutString("task2: %03d", 0,580,0xffffff, c2);

       asm("sti");
   }

}

//////////////
//
typedef struct{        //Simple structure for a thread
      unsigned int esp0;   //Stack for kernel
        unsigned int esp3;   //Stack for process
} Thread;


Thread Threads[2];     //Space for our simple threads. Just 2!
int CurrentTask = -1;  //The thread currenlty running (-1 == none) 


void task_create(int pid,void(*thread)())
{
     unsigned int *stack;

    Threads[pid].esp0 = pmmngr_alloc_block();
     stack = (unsigned int*)Threads[pid].esp0+4000; //This makes a pointer to the stack for us

 //First, this stuff is pushed by the processor
 *--stack = 0x0202; //This is EFLAGS
 *--stack = 0x08;   //This is CS, our code segment
 *--stack = (uint32_t)thread; //This is EIP
 
 //Next, the stuff pushed by 'pusha'
 *--stack = 0; //EDI
 *--stack = 0; //ESI
 *--stack = 0; //EBP
 *--stack = 0; //Just an offset, no value
 *--stack = 0; //EBX
 *--stack = 0; //EDX
 *--stack = 0; //ECX
 *--stack = 0; //EAX
 
 //Now these are the data segments pushed by the IRQ handler

 /*
 *--stack = 0x10; //DS
 *--stack = 0x10; //ES
 *--stack = 0x10; //FS
 *--stack = 0x10; //GS
 */
 
 
 Threads[pid].esp0 = (uint32_t)stack; //Update the stack pointer


};

uint32_t task_switch_next(uint32_t oldesp)
{

 
  if(started!=0xabcde) return oldesp;


 if(CurrentTask != -1){ //Were we even running a task?
  Threads[CurrentTask].esp0 =oldesp; //Save the new esp for the thread
  
  //Now switch what task we're on
  if(CurrentTask == 0)CurrentTask = 1;
  else CurrentTask = 0;
 } else{
  CurrentTask = 0; //We just started multi-tasking, start with task 0
 }
 
 uint32_t esp=0;
   log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"oldesp: 0x%08X saved / next task: %d (esp: 0x%08X) ",oldesp, CurrentTask,Threads[CurrentTask].esp0);
 
    return Threads[CurrentTask].esp0; //Return new stack pointer to ASM
}

void stack_trace(uint32_t *stack,int size)
{
    for(int i=size;i>=0;i--)
    {
	log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"stack: 0x%08X -> 0x%08X", stack, *stack);
	stack++;


    }
}

void task_init()
{
    started=0xabcde;
   log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"init multitasking.");
   task_create(0,task_test1);
   task_create(1,task_test2);
}