Subversion Repositories shark

Rev

Rev 2 | Rev 40 | Go to most recent revision | 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
/*      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
}