Rev 1621 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | pj | 1 | /* Project: OSLib |
2 | * Description: The OS Construction Kit |
||
3 | * Date: 1.6.2000 |
||
4 | * Idea by: Luca Abeni & Gerardo Lamastra |
||
5 | * |
||
6 | * OSLib is an SO project aimed at developing a common, easy-to-use |
||
7 | * low-level infrastructure for developing OS kernels and Embedded |
||
8 | * Applications; it partially derives from the HARTIK project but it |
||
9 | * currently is independently developed. |
||
10 | * |
||
11 | * OSLib is distributed under GPL License, and some of its code has |
||
12 | * been derived from the Linux kernel source; also some important |
||
13 | * ideas come from studying the DJGPP go32 extender. |
||
14 | * |
||
15 | * We acknowledge the Linux Community, Free Software Foundation, |
||
16 | * D.J. Delorie and all the other developers who believe in the |
||
17 | * freedom of software and ideas. |
||
18 | * |
||
19 | * For legalese, check out the included GPL license. |
||
20 | */ |
||
21 | |||
22 | /* Routines that implements threads (creation, end, dump, and AS |
||
23 | assignment */ |
||
24 | |||
1621 | fabio | 25 | #include <arch/i386/stdio.h> |
2 | pj | 26 | #include <ll/i386/mem.h> |
27 | #include <ll/i386/cons.h> |
||
28 | #include <ll/i386/error.h> |
||
29 | |||
30 | #include <ll/i386/tss-ctx.h> |
||
40 | pj | 31 | #include <ll/sys/ll/ll-instr.h> /* Only for HW instr... */ |
2 | pj | 32 | #include <ll/sys/ll/ll-func.h> |
33 | |||
40 | pj | 34 | FILE(KL-Context-Switch); |
2 | pj | 35 | |
40 | pj | 36 | extern TSS TSS_table[TSSMax]; |
2 | pj | 37 | extern WORD TSS_control[TSSMax]; |
38 | extern BYTE ll_FPU_stdctx[FPU_CONTEXT_SIZE]; |
||
39 | |||
40 | #ifdef __VIRCSW__ |
||
41 | extern unsigned short int currCtx; |
||
42 | extern int activeInt; |
||
43 | #endif |
||
44 | |||
45 | extern DWORD entrypoint; |
||
46 | |||
47 | /* Just a debugging function; it dumps the status of the TSS */ |
||
48 | void dump_TSS(WORD sel) |
||
49 | { |
||
40 | pj | 50 | BYTE acc,gran; |
51 | DWORD base,lim; |
||
2 | pj | 52 | message("TR %x\n", sel); |
53 | sel = TSSsel2index(sel); |
||
54 | message("SS:SP %x:%lx\n", TSS_table[sel].ss, TSS_table[sel].esp); |
||
55 | message("Stack0 : %x:%lx\n", TSS_table[sel].ss0, TSS_table[sel].esp0); |
||
56 | message("Stack1 : %x:%lx\n", TSS_table[sel].ss1, TSS_table[sel].esp1); |
||
57 | message("Stack2 : %x:%lx\n", TSS_table[sel].ss2, TSS_table[sel].esp2); |
||
58 | message("CS : %x DS : %x\n", TSS_table[sel].cs, TSS_table[sel].ds); |
||
59 | sel = TSSindex2sel(sel); |
||
40 | pj | 60 | message("Descriptor [%x] Info",sel); |
61 | base = GDT_read(sel,&lim,&acc,&gran); |
||
62 | message("Base : %lx Lim : %lx Acc : %x Gran %x\n", base, lim, (unsigned)(acc),(unsigned)(gran)); |
||
2 | pj | 63 | } |
64 | |||
65 | |||
66 | void ll_context_setspace(CONTEXT c, WORD as) |
||
67 | { |
||
40 | pj | 68 | int index = TSSsel2index(c); |
2 | pj | 69 | |
70 | TSS_table[index].ss0 = as; |
||
71 | TSS_table[index].cs = as + 8; |
||
72 | TSS_table[index].es = as; |
||
73 | TSS_table[index].ds = as; |
||
74 | TSS_table[index].ss = as; |
||
75 | } |
||
76 | |||
77 | /* Initialize context -> TSS in 32 bit */ |
||
40 | pj | 78 | CONTEXT ll_context_create(void (*task)(void *p),BYTE *stack, |
79 | void *parm,void (*killer)(void),WORD control) |
||
2 | pj | 80 | { |
81 | CONTEXT index = 0; |
||
40 | pj | 82 | DWORD *stack_ptr = (DWORD *)stack; |
2 | pj | 83 | |
84 | /* Push onto stack the input parameter */ |
||
85 | /* And the entry point to the task killer procedure */ |
||
86 | stack_ptr--; |
||
40 | pj | 87 | *stack_ptr = (DWORD)(parm); |
2 | pj | 88 | stack_ptr--; |
40 | pj | 89 | *stack_ptr = (DWORD)(killer); |
2 | pj | 90 | /* Find a free TSS */ |
40 | pj | 91 | while ((TSS_control[index] & TSS_USED) && (index < TSSMain)) index++; |
2 | pj | 92 | /* This exception would signal an error */ |
93 | if (index >= TSSMain) { |
||
40 | pj | 94 | message("No more Descriptors...\n"); |
2 | pj | 95 | return 0; |
96 | } |
||
97 | TSS_control[index] |= (TSS_USED | control); |
||
98 | /* Fill the TSS structure */ |
||
99 | /* No explicit protection; use only one stack */ |
||
40 | pj | 100 | TSS_table[index].esp0 = (DWORD)(stack_ptr); |
2 | pj | 101 | TSS_table[index].esp1 = 0; |
102 | TSS_table[index].esp2 = 0; |
||
103 | TSS_table[index].ss0 = get_DS(); |
||
104 | TSS_table[index].ss1 = 0; |
||
105 | TSS_table[index].ss2 = 0; |
||
106 | /* No paging activated */ |
||
107 | TSS_table[index].cr3 = 0; |
||
108 | /* Task entry point */ |
||
40 | pj | 109 | TSS_table[index].eip = (DWORD)(task); |
2 | pj | 110 | /* Need only to unmask interrupts */ |
111 | TSS_table[index].eflags = 0x00000200; |
||
112 | TSS_table[index].eax = 0; |
||
113 | TSS_table[index].ebx = 0; |
||
114 | TSS_table[index].ecx = 0; |
||
115 | TSS_table[index].edx = 0; |
||
116 | TSS_table[index].esi = 0; |
||
117 | TSS_table[index].edi = 0; |
||
40 | pj | 118 | TSS_table[index].esp = (DWORD)(stack_ptr); |
119 | TSS_table[index].ebp = (DWORD)(stack_ptr); |
||
2 | pj | 120 | TSS_table[index].cs = get_CS(); |
121 | TSS_table[index].es = get_DS(); |
||
122 | TSS_table[index].ds = get_DS(); |
||
123 | TSS_table[index].ss = get_DS(); |
||
124 | TSS_table[index].gs = X_FLATDATA_SEL; |
||
125 | TSS_table[index].fs = X_FLATDATA_SEL; |
||
126 | /* Use only the GDT */ |
||
127 | TSS_table[index].ldt = 0; |
||
128 | TSS_table[index].trap = 0; |
||
129 | TSS_table[index].io_base = 0; |
||
130 | /* Fill in the coprocessor status */ |
||
40 | pj | 131 | memcpy(TSS_table[index].ctx_FPU,ll_FPU_stdctx,FPU_CONTEXT_SIZE); |
2 | pj | 132 | /* Convert the index into a valid selector */ |
133 | /* Which really represent CONTEXT */ |
||
40 | pj | 134 | return(TSSindex2sel(index)); |
2 | pj | 135 | } |
136 | |||
137 | |||
138 | /* Release the used TSS */ |
||
139 | |||
140 | void ll_context_delete(CONTEXT c) |
||
141 | { |
||
142 | int index = TSSsel2index(c); |
||
143 | TSS_control[index] = 0; |
||
144 | } |
||
145 | |||
40 | pj | 146 | #if 0 /* It does not work... Fix it!!! */ |
147 | DWORD ll_push_func(void (*func)(void)) |
||
2 | pj | 148 | { |
40 | pj | 149 | DWORD *p; |
150 | DWORD old; |
||
2 | pj | 151 | |
40 | pj | 152 | p = (DWORD *)entrypoint; |
153 | old = *p; |
||
2 | pj | 154 | |
40 | pj | 155 | *p = (DWORD)func; |
156 | |||
157 | return old; |
||
2 | pj | 158 | } |
159 | #endif |
||
160 | |||
161 | /* Well this is used for debug purposes mainly; as the context is an */ |
||
162 | /* abstract type, we must provide some function to convert in into a */ |
||
163 | /* printable form; anyway this depend from the architecture as the context */ |
||
164 | |||
165 | char *ll_context_sprintf(char *str, CONTEXT c) |
||
166 | { |
||
167 | ksprintf(str, "%x (Hex)", c); |
||
40 | pj | 168 | return(str); |
2 | pj | 169 | } |