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 | /* Xlib initialization code */ |
||
23 | |||
24 | #include <ll/i386/mem.h> |
||
25 | #include <ll/i386/cons.h> |
||
26 | #include <ll/i386/mb-info.h> |
||
27 | #include <ll/i386/error.h> |
||
28 | #include <ll/i386/pit.h> |
||
29 | #include <ll/i386/pic.h> |
||
30 | |||
31 | #include <ll/i386/tss-ctx.h> |
||
32 | #include <ll/i386/hw-arch.h> |
||
33 | |||
34 | FILE(X - Init); |
||
35 | |||
36 | extern DWORD ll_irq_table[16]; |
||
37 | extern DWORD ll_exc_table[16]; |
||
38 | |||
39 | #ifdef __VIRCSW__ |
||
40 | int activeInt = 0; |
||
41 | #endif |
||
42 | |||
43 | /* Architecture definition */ |
||
44 | LL_ARCH ll_arch; |
||
45 | |||
46 | /* These are declared in llCx32b.C */ |
||
47 | TSS TSS_table[TSSMax]; |
||
48 | WORD TSS_control[TSSMax]; |
||
49 | BYTE ll_FPU_stdctx[FPU_CONTEXT_SIZE]; |
||
50 | |||
51 | /* The following stuff is in llCxA.Asm/S */ |
||
52 | |||
53 | /* Assembly external routines! */ |
||
54 | /* Setup the TR register of the 80386, to initialize context switch */ |
||
55 | |||
56 | extern void init_TR(WORD v); |
||
57 | |||
58 | /* ll hardware interrupt hooks */ |
||
59 | extern void h1(void); |
||
60 | extern void h2(void); |
||
61 | extern void h3(void); |
||
62 | extern void h4(void); |
||
63 | extern void h5(void); |
||
64 | extern void h6(void); |
||
65 | extern void h7(void); |
||
66 | extern void h8(void); |
||
67 | extern void h9(void); |
||
68 | extern void h10(void); |
||
69 | extern void h11(void); |
||
70 | extern void h12(void); |
||
71 | extern void h13(void); |
||
72 | extern void h13_bis(void); |
||
73 | extern void h14(void); |
||
74 | extern void h15(void); |
||
75 | |||
76 | /* ll hardware exception hooks */ |
||
77 | /* In llCtx1.Asm/s */ |
||
78 | extern void exc0(void); |
||
79 | extern void exc1(void); |
||
80 | extern void exc2(void); |
||
81 | extern void exc3(void); |
||
82 | extern void exc4(void); |
||
83 | extern void exc5(void); |
||
84 | extern void exc6(void); |
||
85 | extern void exc7(void); |
||
86 | extern void exc8(void); |
||
87 | extern void exc9(void); |
||
88 | extern void exc10(void); |
||
89 | extern void exc11(void); |
||
90 | extern void exc12(void); |
||
91 | extern void exc13(void); |
||
92 | extern void exc14(void); |
||
93 | extern void exc15(void); |
||
94 | extern void exc16(void); |
||
95 | |||
96 | static void dummyfun(int i) |
||
97 | { |
||
98 | cputs("Unhandled Exc or Int occured!!!\n"); |
||
99 | /* |
||
100 | message("Unhandled Exc or Int %d occured!!!\n", i); |
||
101 | */ |
||
102 | halt(); |
||
103 | } |
||
104 | |||
105 | void l1_exc_bind(int i, void (*f) (int n)) |
||
106 | { |
||
107 | ll_exc_table[i] = (DWORD) f; |
||
108 | } |
||
109 | |||
110 | void l1_irq_bind(int i, void (*f) (int n)) |
||
111 | { |
||
112 | ll_irq_table[i] = (DWORD) f; |
||
113 | } |
||
114 | |||
115 | void *l1_init(void) |
||
116 | { |
||
117 | register int i; |
||
118 | struct ll_cpuInfo cpuInfo; |
||
119 | LIN_ADDR b; |
||
120 | extern BYTE X86_fpu; |
||
121 | |||
122 | TSS dummy_tss; /* Very dirty, but we need it, in order to |
||
123 | get an initial value for the FPU |
||
124 | context... |
||
125 | */ |
||
126 | |||
127 | |||
128 | /* First of all, init the exc and irq tables... */ |
||
129 | for (i = 0; i < 16; i++) { |
||
130 | ll_irq_table[i] = (DWORD) dummyfun; |
||
131 | ll_exc_table[i] = (DWORD) dummyfun; |
||
132 | } |
||
133 | |||
134 | X86_get_CPU(&cpuInfo); |
||
135 | X86_get_FPU(); |
||
136 | ll_arch.x86.arch = __LL_ARCH__; |
||
137 | ll_arch.x86.cpu = cpuInfo.X86_cpu; |
||
138 | ll_arch.x86.fpu = X86_fpu; |
||
139 | memcpy(&(ll_arch.x86.vendor), &(cpuInfo.X86_vendor_1), 12); |
||
140 | |||
141 | /* TODO! Need to map featuresXXX & Signature onto ll_arch! */ |
||
142 | /* TODO! Need to check for CPU bugs!! */ |
||
143 | |||
144 | #ifdef __LL_DEBUG__ |
||
145 | message("LL Architecture: %s\n", __LL_ARCH__); |
||
146 | message("CPU : %u\nFPU : %u\n", cpuInfo.X86_cpu, X86_fpu); |
||
147 | message("Signature : 0x%lx\nVendor: %s\n", cpuInfo.X86_signature, |
||
148 | ll_arch.x86.vendor); |
||
149 | message("Features #1: 0x%lx\n", cpuInfo.X86_IntelFeature_1); |
||
150 | message("Features #2: 0x%lx\n", cpuInfo.X86_IntelFeature_2); |
||
151 | message("Features #3: 0x%lx\n", cpuInfo.X86_StandardFeature); |
||
152 | #endif /* __LL_DEBUG__ */ |
||
153 | |||
154 | /* Insert the Exceptions handler into IDT */ |
||
155 | IDT_place(0x00, exc0); |
||
156 | IDT_place(0x01, exc1); |
||
157 | IDT_place(0x02, exc2); |
||
158 | IDT_place(0x03, exc3); |
||
159 | IDT_place(0x04, exc4); |
||
160 | IDT_place(0x05, exc5); |
||
161 | IDT_place(0x06, exc6); |
||
162 | IDT_place(0x07, exc7); |
||
163 | IDT_place(0x08, exc8); |
||
164 | IDT_place(0x09, exc9); |
||
165 | IDT_place(0x0A, exc10); |
||
166 | IDT_place(0x0B, exc11); |
||
167 | IDT_place(0x0C, exc12); |
||
168 | IDT_place(0x0D, exc13); |
||
169 | IDT_place(0x0E, exc14); |
||
170 | IDT_place(0x0F, exc15); |
||
171 | IDT_place(0x10, exc16); |
||
172 | /* Insert HW timer handler into IDT */ |
||
173 | /* Now it is done in event.c |
||
174 | IDT_place(0x40,ll_timer); |
||
175 | */ |
||
176 | IDT_place(0x41, h1); |
||
177 | IDT_place(0x42, h2); |
||
178 | IDT_place(0x43, h3); |
||
179 | IDT_place(0x44, h4); |
||
180 | IDT_place(0x45, h5); |
||
181 | IDT_place(0x46, h6); |
||
182 | IDT_place(0x47, h7); |
||
183 | IDT_place(0x70, h8); |
||
184 | IDT_place(0x71, h9); |
||
185 | IDT_place(0x72, h10); |
||
186 | IDT_place(0x73, h11); |
||
187 | IDT_place(0x74, h12); |
||
188 | |||
189 | #if 0 |
||
190 | /* If FPU is on-chip IRQ #13 is free to use */ |
||
191 | /* Else IRQ #13 vectors the coprocessor errors */ |
||
192 | if (check_fpu()) |
||
193 | ll_arch.x86.capabilities |= LL_X86_INTERNAL_FPU; |
||
194 | |||
195 | #ifdef __LL_DEBUG__ |
||
196 | message("Check FPU : %s\n", |
||
197 | ll_arch.x86. |
||
198 | capabilities & LL_X86_INTERNAL_FPU ? "Internal" : "External"); |
||
199 | #endif |
||
200 | |||
201 | if (ll_arch.x86.capabilities & LL_X86_INTERNAL_FPU) { |
||
202 | /* Install the generic handler */ |
||
203 | IDT_place(0x75, h13); |
||
204 | } else { |
||
205 | /* Install the external FPU error handler */ |
||
206 | IDT_place(0x75, h13_bis); |
||
207 | irq_unmask(13); |
||
208 | } |
||
209 | #else |
||
210 | IDT_place(0x75, h13); |
||
211 | #endif |
||
212 | IDT_place(0x76, h14); |
||
213 | IDT_place(0x77, h15); |
||
214 | |||
215 | /* Init TSS table & put the corrispondent selectors into GDT */ |
||
216 | TSS_control[TSSMain] |= TSS_USED; |
||
217 | for (i = 0; i < TSSMax; i++) { |
||
218 | /* b = appl2linear(&TSS_table[i]); */ |
||
219 | b = (LIN_ADDR) (&TSS_table[i]); |
||
220 | GDT_place(TSSindex2sel(i), (DWORD) b, sizeof(TSS), FREE_TSS386, |
||
221 | GRAN_16); |
||
222 | } |
||
223 | /* Set the TR initial value */ |
||
224 | init_TR(TSSindex2sel(TSSMain)); |
||
225 | |||
226 | /* Init coprocessor & assign it to main() */ |
||
227 | /* OK... Now I know the sense of all this... : |
||
228 | We need a initial value for the FPU context (to be used for creating |
||
229 | new FPU contexts, as init value)... |
||
230 | ... And we get it in this strange way!!!! |
||
231 | */ |
||
232 | reset_fpu(); |
||
233 | #if 0 |
||
234 | ll_FPU_save(); |
||
235 | memcpy(ll_FPU_stdctx, ll_FPU_savearea, FPU_CONTEXT_SIZE); |
||
236 | #else |
||
237 | save_fpu(&dummy_tss); /* OK??? */ |
||
238 | memcpy(ll_FPU_stdctx, dummy_tss.ctx_FPU, FPU_CONTEXT_SIZE); |
||
239 | #endif |
||
240 | init_fpu(); |
||
241 | |||
242 | /* Init PIC controllers & unmask timer */ |
||
243 | PIC_init(); |
||
244 | |||
245 | return mbi_address(); |
||
246 | } |
||
247 | |||
248 | |||
249 | void l1_end(void) |
||
250 | { |
||
251 | outp(0x21, 0xFF); |
||
252 | outp(0xA1, 0xFF); |
||
253 | /* Back to DOS settings */ |
||
254 | PIC_end(); |
||
255 | /* Reset the timer chip according DOS specification */ |
||
256 | /* Mode: Binary/Mode 3/16 bit Time_const/Counter 0 */ |
||
257 | #if 0 |
||
258 | outp(0x43, 0x36); |
||
259 | /* Time_const = 65536; write 0 in CTR */ |
||
260 | outp(0x40, 0); |
||
261 | outp(0x40, 0); |
||
262 | #endif |
||
263 | pit_init(0, TMR_MD3, 0); /* Timer 0, Mode 3, Time constant 0 */ |
||
264 | if (ll_arch.x86.cpu > 4) { |
||
265 | pit_init(1, TMR_MD2, 18); |
||
266 | } else { |
||
267 | pit_init(2, TMR_MD0, 0); |
||
268 | outp(0x61, 0); /* Stop channel 2 */ |
||
269 | } |
||
270 | } |