Details | 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 | |||
25 | #include <ll/i386/stdio.h> |
||
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> |
||
31 | #include <ll/sys/ll/ll-instr.h> /* Only for HW instr... */ |
||
32 | #include <ll/sys/ll/ll-func.h> |
||
33 | |||
34 | FILE(KL - Context - Switch); |
||
35 | |||
36 | extern TSS TSS_table[TSSMax]; |
||
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 | { |
||
50 | BYTE acc, gran; |
||
51 | DWORD base, lim; |
||
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); |
||
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, |
||
63 | (unsigned) (acc), (unsigned) (gran)); |
||
64 | } |
||
65 | |||
66 | |||
67 | void ll_context_setspace(CONTEXT c, WORD as) |
||
68 | { |
||
69 | int index = TSSsel2index(c); |
||
70 | |||
71 | TSS_table[index].ss0 = as; |
||
72 | TSS_table[index].cs = as + 8; |
||
73 | TSS_table[index].es = as; |
||
74 | TSS_table[index].ds = as; |
||
75 | TSS_table[index].ss = as; |
||
76 | } |
||
77 | |||
78 | /* Initialize context -> TSS in 32 bit */ |
||
79 | CONTEXT ll_context_create(void (*task) (void *p), BYTE * stack, |
||
80 | void *parm, void (*killer) (void), WORD control) |
||
81 | { |
||
82 | CONTEXT index = 0; |
||
83 | DWORD *stack_ptr = (DWORD *) stack; |
||
84 | |||
85 | /* Push onto stack the input parameter */ |
||
86 | /* And the entry point to the task killer procedure */ |
||
87 | stack_ptr--; |
||
88 | *stack_ptr = (DWORD) (parm); |
||
89 | stack_ptr--; |
||
90 | *stack_ptr = (DWORD) (killer); |
||
91 | /* Find a free TSS */ |
||
92 | while ((TSS_control[index] & TSS_USED) && (index < TSSMain)) |
||
93 | index++; |
||
94 | /* This exception would signal an error */ |
||
95 | if (index >= TSSMain) { |
||
96 | message("No more Descriptors...\n"); |
||
97 | return 0; |
||
98 | } |
||
99 | TSS_control[index] |= (TSS_USED | control); |
||
100 | /* Fill the TSS structure */ |
||
101 | /* No explicit protection; use only one stack */ |
||
102 | TSS_table[index].esp0 = (DWORD) (stack_ptr); |
||
103 | TSS_table[index].esp1 = 0; |
||
104 | TSS_table[index].esp2 = 0; |
||
105 | TSS_table[index].ss0 = get_DS(); |
||
106 | TSS_table[index].ss1 = 0; |
||
107 | TSS_table[index].ss2 = 0; |
||
108 | /* No paging activated */ |
||
109 | TSS_table[index].cr3 = 0; |
||
110 | /* Task entry point */ |
||
111 | TSS_table[index].eip = (DWORD) (task); |
||
112 | /* Need only to unmask interrupts */ |
||
113 | TSS_table[index].eflags = 0x00000200; |
||
114 | TSS_table[index].eax = 0; |
||
115 | TSS_table[index].ebx = 0; |
||
116 | TSS_table[index].ecx = 0; |
||
117 | TSS_table[index].edx = 0; |
||
118 | TSS_table[index].esi = 0; |
||
119 | TSS_table[index].edi = 0; |
||
120 | TSS_table[index].esp = (DWORD) (stack_ptr); |
||
121 | TSS_table[index].ebp = (DWORD) (stack_ptr); |
||
122 | TSS_table[index].cs = get_CS(); |
||
123 | TSS_table[index].es = get_DS(); |
||
124 | TSS_table[index].ds = get_DS(); |
||
125 | TSS_table[index].ss = get_DS(); |
||
126 | TSS_table[index].gs = X_FLATDATA_SEL; |
||
127 | TSS_table[index].fs = X_FLATDATA_SEL; |
||
128 | /* Use only the GDT */ |
||
129 | TSS_table[index].ldt = 0; |
||
130 | TSS_table[index].trap = 0; |
||
131 | TSS_table[index].io_base = 0; |
||
132 | /* Fill in the coprocessor status */ |
||
133 | memcpy(TSS_table[index].ctx_FPU, ll_FPU_stdctx, FPU_CONTEXT_SIZE); |
||
134 | /* Convert the index into a valid selector */ |
||
135 | /* Which really represent CONTEXT */ |
||
136 | return (TSSindex2sel(index)); |
||
137 | } |
||
138 | |||
139 | |||
140 | /* Release the used TSS */ |
||
141 | |||
142 | void ll_context_delete(CONTEXT c) |
||
143 | { |
||
144 | int index = TSSsel2index(c); |
||
145 | TSS_control[index] = 0; |
||
146 | } |
||
147 | |||
148 | #if 0 /* It does not work... Fix it!!! */ |
||
149 | DWORD ll_push_func(void (*func) (void)) |
||
150 | { |
||
151 | DWORD *p; |
||
152 | DWORD old; |
||
153 | |||
154 | p = (DWORD *) entrypoint; |
||
155 | old = *p; |
||
156 | |||
157 | *p = (DWORD) func; |
||
158 | |||
159 | return old; |
||
160 | } |
||
161 | #endif |
||
162 | |||
163 | /* Well this is used for debug purposes mainly; as the context is an */ |
||
164 | /* abstract type, we must provide some function to convert in into a */ |
||
165 | /* printable form; anyway this depend from the architecture as the context */ |
||
166 | |||
167 | char *ll_context_sprintf(char *str, CONTEXT c) |
||
168 | { |
||
169 | ksprintf(str, "%x (Hex)", c); |
||
170 | return (str); |
||
171 | } |