Subversion Repositories shark

Rev

Rev 3 | 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
/*	Exc/IRQ handlers (asm part)	*/
23
/* TODO: Unify the Exc/Int Mechanism... */
24
 
25
#include <ll/i386/sel.h>
26
#include <ll/i386/linkage.h>
27
#include <ll/i386/int.h>
28
#include <ll/i386/defs.h>
29
 
30
.extern SYMBOL_NAME(GDT_base)
31
.data
32
 
33
ASMFILE(Exc)
34
 
35
.globl SYMBOL_NAME(ll_irq_table)
36
 
40 pj 37
SYMBOL_NAME_LABEL(ll_irq_table)	.space  1024, 0
2 pj 38
 
39
.text
40
 
41
.extern  SYMBOL_NAME(ll_exc_hook)
42
.extern  SYMBOL_NAME(ll_FPU_hook)
43
 
44
.globl SYMBOL_NAME(h13_bis)
45
.globl SYMBOL_NAME(exc7)
46
 
47
/* These are the hardware handlers; they all jump to ll_handler setting */
48
/* the interrupt number into EAX & save the registers on stack		*/
40 pj 49
INT(0)
2 pj 50
INT(1)
51
INT(2)
52
INT(3)
53
INT(4)
54
INT(5)
55
INT(6)
56
INT(8)
57
INT(9)
58
INT(10)
59
INT(11)
60
INT(12)
61
INT(13)
62
INT(14)
63
INT(15)
40 pj 64
INT(16)
65
INT(17)
66
INT(18)
67
INT(19)
68
INT(20)
69
INT(21)
70
INT(22)
71
INT(23)
72
INT(24)
73
INT(25)
74
INT(26)
75
INT(27)
76
INT(28)
77
INT(29)
78
INT(30)
79
INT(31)
2 pj 80
 
40 pj 81
INT(32)
82
INT(33)
83
INT(34)
84
INT(35)
85
INT(36)
86
INT(37)
87
INT(38)
88
INT(39)
89
INT(40)
90
INT(41)
91
INT(42)
92
INT(43)
93
INT(44)
94
INT(45)
95
INT(46)
96
INT(47)
97
INT(48)
98
INT(49)
99
INT(50)
100
INT(51)
101
INT(52)
102
INT(53)
103
INT(54)
104
INT(55)
105
INT(56)
106
INT(57)
107
INT(58)
108
INT(59)
109
INT(60)
110
INT(61)
111
INT(62)
112
INT(63)
2 pj 113
 
40 pj 114
/* Master PIC... (int 0x40, see ll/i386/pic.h)*/
115
INT_1(64)
116
INT_1(65)
117
INT_1(66)
118
INT_1(67)
119
INT_1(68)
120
INT_1(69)
121
INT_1(70)
122
INT_1(71)
123
 
124
INT(72)
125
INT(73)
126
INT(74)
127
INT(75)
128
INT(76)
129
INT(77)
130
INT(78)
131
INT(79)
132
INT(80)
133
INT(81)
134
INT(82)
135
INT(83)
136
INT(84)
137
INT(85)
138
INT(86)
139
INT(87)
140
INT(88)
141
INT(89)
142
INT(90)
143
INT(91)
144
INT(92)
145
INT(93)
146
INT(94)
147
INT(95)
148
INT(96)
149
INT(97)
150
INT(98)
151
INT(99)
152
INT(100)
153
INT(101)
154
INT(102)
155
INT(103)
156
INT(104)
157
INT(105)
158
INT(106)
159
INT(107)
160
INT(108)
161
INT(109)
162
INT(110)
163
INT(111)
164
 
165
/* Slave PIC... (int 0x70, see ll/i386/pic.h)*/
166
INT_2(112)
167
INT_2(113)
168
INT_2(114)
169
INT_2(115)
170
INT_2(116)
171
INT_2(117)
172
INT_2(118)
173
INT_2(119)
174
 
175
INT(120)
176
INT(121)
177
INT(122)
178
INT(123)
179
INT(124)
180
INT(125)
181
INT(126)
182
INT(127)
183
INT(128)
184
INT(129)
185
INT(130)
186
INT(131)
187
INT(132)
188
INT(133)
189
INT(134)
190
INT(135)
191
INT(136)
192
INT(137)
193
INT(138)
194
INT(139)
195
INT(140)
196
INT(141)
197
INT(142)
198
INT(143)
199
INT(144)
200
INT(145)
201
INT(146)
202
INT(147)
203
INT(148)
204
INT(149)
205
INT(150)
206
INT(151)
207
INT(152)
208
INT(153)
209
INT(154)
210
INT(155)
211
INT(156)
212
INT(157)
213
INT(158)
214
INT(159)
215
INT(160)
216
INT(161)
217
INT(162)
218
INT(163)
219
INT(164)
220
INT(165)
221
INT(166)
222
INT(167)
223
INT(168)
224
INT(169)
225
INT(170)
226
INT(171)
227
INT(172)
228
INT(173)
229
INT(174)
230
INT(175)
231
INT(176)
232
INT(177)
233
INT(178)
234
INT(179)
235
INT(180)
236
INT(181)
237
INT(182)
238
INT(183)
239
INT(184)
240
INT(185)
241
INT(186)
242
INT(187)
243
INT(188)
244
INT(189)
245
INT(190)
246
INT(191)
247
INT(192)
248
INT(193)
249
INT(194)
250
INT(195)
251
INT(196)
252
INT(197)
253
INT(198)
254
INT(199)
255
INT(200)
256
INT(201)
257
INT(202)
258
INT(203)
259
INT(204)
260
INT(205)
261
INT(206)
262
INT(207)
263
INT(208)
264
INT(209)
265
INT(210)
266
INT(211)
267
INT(212)
268
INT(213)
269
INT(214)
270
INT(215)
271
INT(216)
272
INT(217)
273
INT(218)
274
INT(219)
275
INT(220)
276
INT(221)
277
INT(222)
278
INT(223)
279
INT(224)
280
INT(225)
281
INT(226)
282
INT(227)
283
INT(228)
284
INT(229)
285
INT(230)
286
INT(231)
287
INT(232)
288
INT(233)
289
INT(234)
290
INT(235)
291
INT(236)
292
INT(237)
293
INT(238)
294
INT(239)
295
INT(240)
296
INT(241)
297
INT(242)
298
INT(243)
299
INT(244)
300
INT(245)
301
INT(246)
302
INT(247)
303
INT(248)
304
INT(249)
305
INT(250)
306
INT(251)
307
INT(252)
308
INT(253)
309
INT(254)
310
INT(255)
311
 
2 pj 312
/* The ll_handler process the request using the kernel function act_int() */
313
/* Then sends EOI & schedules any eventual new task!			  */
314
 
315
ll_handler:
316
			/* We do not know what is the DS value	*/
317
			/* Then we save it & set it correctly  	*/
318
 
319
			pushl	%ds
320
			pushl	%ss
321
			pushl	%es
322
			pushl	%fs
40 pj 323
			pushl	%gs
2 pj 324
			/* But we first transfer to the _act_int  */
325
			/* the interrupt number which is required */
326
			/* as second argument			  */
327
			pushl   %eax
328
			movw    $(X_FLATDATA_SEL),%ax
329
			movw    %ax,%es
330
			mov     %ax,%ds
40 pj 331
        movw    %ax, %fs
332
        movw    %ax, %gs
2 pj 333
 
334
			/* Now save the actual context on stack		*/
335
			/* to pass it to _act_int (C caling convention)	*/
336
			/* CLD is necessary when calling a C function	*/
337
 
338
			cld
339
 
340
			/* The following could be optimized a little... */
341
			popl %eax
342
			xorl %ebx, %ebx
343
			movw %ss, %bx
344
			/* We must switch to a ``safe stack'' */
345
	/*
346
	 * OK, this is the idea: in %esp we have the address of the
347
	 * stack pointer in the APPLICATION address space...
348
	 * We assume that address spaces are implemented through segments...
349
	 * What we have to do is to add the segment base to %esp:
350
	 *	- Load the GDT base in a register
351
	 *	- Add DS * 8 to that value
352
	 *	- Read the corresponding GDT entry (the segment descriptor)
353
	 *	- Compute the base...
354
	 *	It is (*p & 0xFC) | (*(p +1)  & 0x0F) << 16) | *(p + 2)
355
	 */
356
			movl SYMBOL_NAME(GDT_base), %edi
357
			addl %ebx, %edi
358
			xorl %ebx, %ebx
359
			movb 7(%edi), %bh
360
			movb 4(%edi), %bl
361
			shl $16, %ebx
362
			movw 2(%edi), %bx
363
			/* Is it correct? I think so... Test it!!! */
364
			addl %ebx, %esp
365
			/* Save EBX for returning to our stack... */
366
			movw %ss, %dx
40 pj 367
			movw %ds, %cx
368
			movw %cx, %ss
2 pj 369
			pushl %ebx
370
			pushl %edx
371
			pushl %eax
372
 
373
			movl	SYMBOL_NAME(ll_irq_table)(, %eax, 4), %ebx
374
			call    *%ebx
375
 
376
			popl	%ebx    /* Store in EBX the Int number	*/
377
			popl	%eax
378
			popl	%ecx	/* We must subtract it from ESP...*/
379
			subl	%ecx, %esp
380
			movw	%ax, %ss
381
 
382
			/* Resume the return value of _act_int 		*/
383
			/* & do the context switch if necessary!	*/
384
#ifdef __VIRCSW__
385
			movw SYMBOL_NAME(currCtx), %ax
386
			cmpw    JmpSel,%ax
387
			je      NoPreempt3
388
			movw    %ax,JmpSel
389
			ljmp    JmpZone
390
#endif
391
NoPreempt3:             popl	%gs
392
			popl	%fs
393
			popl	%es
394
			popl	%ss
395
			popl	%ds
396
			popal
397
			iret
398
 
40 pj 399
ll_handler_master_pic:
400
			/* We do not know what is the DS value	*/
401
			/* Then we save it & set it correctly  	*/
402
 
403
			pushl	%ds
2 pj 404
			pushl	%ss
405
			pushl	%es
406
			pushl	%fs
407
			pushl	%gs
40 pj 408
			/* But we first transfer to the _act_int  */
409
			/* the interrupt number which is required */
410
			/* as second argument			  */
411
			pushl   %eax
412
			movw    $(X_FLATDATA_SEL),%ax
413
			movw    %ax,%es
414
			mov     %ax,%ds
415
        movw    %ax, %fs
416
        movw    %ax, %gs
417
 
418
			/* Now save the actual context on stack		*/
419
			/* to pass it to _act_int (C caling convention)	*/
420
			/* CLD is necessary when calling a C function	*/
421
 
2 pj 422
			cld
40 pj 423
 
424
			/* The following could be optimized a little... */
425
			popl %eax
426
			xorl %ebx, %ebx
427
			movw %ss, %bx
428
			/* We must switch to a ``safe stack'' */
429
	/*
430
	 * OK, this is the idea: in %esp we have the address of the
431
	 * stack pointer in the APPLICATION address space...
432
	 * We assume that address spaces are implemented through segments...
433
	 * What we have to do is to add the segment base to %esp:
434
	 *	- Load the GDT base in a register
435
	 *	- Add DS * 8 to that value
436
	 *	- Read the corresponding GDT entry (the segment descriptor)
437
	 *	- Compute the base...
438
	 *	It is (*p & 0xFC) | (*(p +1)  & 0x0F) << 16) | *(p + 2)
439
	 */
440
			movl SYMBOL_NAME(GDT_base), %edi
441
			addl %ebx, %edi
442
			xorl %ebx, %ebx
443
			movb 7(%edi), %bh
444
			movb 4(%edi), %bl
445
			shl $16, %ebx
446
			movw 2(%edi), %bx
447
			/* Is it correct? I think so... Test it!!! */
448
			addl %ebx, %esp
449
			/* Save EBX for returning to our stack... */
450
			movw %ss, %dx
451
			movw %ds, %cx
452
			movw %cx, %ss
453
			pushl %ebx
454
			pushl %edx
455
			pushl %eax
456
 
457
			movl	SYMBOL_NAME(ll_irq_table)(, %eax, 4), %ebx
458
			call    *%ebx
459
 
460
			popl	%ebx    /* Store in EBX the Int number	*/
461
			popl	%eax
462
			popl	%ecx	/* We must subtract it from ESP...*/
463
			subl	%ecx, %esp
464
			movw	%ax, %ss
465
 
466
			/* Send EOI to master PIC */
467
			movb	$0x20,%al
468
			movl	$0x20,%edx
469
			outb	%al,%dx
470
 
471
			/* Resume the return value of _act_int 		*/
472
			/* & do the context switch if necessary!	*/
473
#ifdef __VIRCSW__
474
			movw SYMBOL_NAME(currCtx), %ax
475
			cmpw    JmpSel,%ax
476
			je      NoPreempt4
477
			movw    %ax,JmpSel
478
			ljmp    JmpZone
479
#endif
480
NoPreempt4:             popl	%gs
2 pj 481
			popl	%fs
482
			popl	%es
483
			popl	%ss
484
			popl	%ds
485
			popal
486
			iret
40 pj 487
 
488
ll_handler_slave_pic:
489
			/* We do not know what is the DS value	*/
490
			/* Then we save it & set it correctly  	*/
2 pj 491
 
40 pj 492
			pushl	%ds
493
			pushl	%ss
494
			pushl	%es
495
			pushl	%fs
496
			pushl	%gs
497
			/* But we first transfer to the _act_int  */
498
			/* the interrupt number which is required */
499
			/* as second argument			  */
500
			pushl   %eax
501
			movw    $(X_FLATDATA_SEL),%ax
502
			movw    %ax,%es
503
			mov     %ax,%ds
504
        movw    %ax, %fs
505
        movw    %ax, %gs
506
 
507
			/* Now save the actual context on stack		*/
508
			/* to pass it to _act_int (C caling convention)	*/
509
			/* CLD is necessary when calling a C function	*/
510
 
511
			cld
512
 
513
			/* The following could be optimized a little... */
2 pj 514
			popl %eax
40 pj 515
			xorl %ebx, %ebx
2 pj 516
			movw %ss, %bx
517
			/* We must switch to a ``safe stack'' */
40 pj 518
	/*
519
	 * OK, this is the idea: in %esp we have the address of the
520
	 * stack pointer in the APPLICATION address space...
521
	 * We assume that address spaces are implemented through segments...
522
	 * What we have to do is to add the segment base to %esp:
523
	 *	- Load the GDT base in a register
524
	 *	- Add DS * 8 to that value
525
	 *	- Read the corresponding GDT entry (the segment descriptor)
526
	 *	- Compute the base...
527
	 *	It is (*p & 0xFC) | (*(p +1)  & 0x0F) << 16) | *(p + 2)
528
	 */
2 pj 529
			movl SYMBOL_NAME(GDT_base), %edi
530
			addl %ebx, %edi
531
			xorl %ebx, %ebx
532
			movb 7(%edi), %bh
533
			movb 4(%edi), %bl
534
			shl $16, %ebx
535
			movw 2(%edi), %bx
536
			/* Is it correct? I think so... Test it!!! */
537
			addl %ebx, %esp
538
			/* Save EBX for returning to our stack... */
539
			movw %ss, %dx
40 pj 540
			movw %ds, %cx
541
			movw %cx, %ss
2 pj 542
			pushl %ebx
543
			pushl %edx
544
			pushl %eax
545
 
40 pj 546
			movl	SYMBOL_NAME(ll_irq_table)(, %eax, 4), %ebx
547
			call    *%ebx
548
 
549
			popl	%ebx    /* Store in EBX the Int number	*/
550
			popl	%eax
551
			popl	%ecx	/* We must subtract it from ESP...*/
552
			subl	%ecx, %esp
553
			movw	%ax, %ss
554
 
555
			/* Send EOI to master & slave PIC */
556
			movb	$0x20,%al
557
			movl	$0xA0,%edx
558
			outb	%al,%dx
559
			movl	$0x20,%edx
560
			outb	%al,%dx
561
 
562
 
563
			/* Resume the return value of _act_int 		*/
564
			/* & do the context switch if necessary!	*/
565
#ifdef __VIRCSW__
566
			movw SYMBOL_NAME(currCtx), %ax
567
			cmpw    JmpSel,%ax
568
			je      NoPreempt5
569
			movw    %ax,JmpSel
570
			ljmp    JmpZone
571
#endif
572
NoPreempt5:             popl	%gs
573
			popl	%fs
574
			popl	%es
575
			popl	%ss
576
			popl	%ds
577
			popal
2 pj 578
			iret
40 pj 579
 
580
 
581
 
582
 
583
/* OK, this is Exception 7, and it is generated when an ESC or WAIT
584
 * intruction is reached, and the MP and TS bits are set... Basically,
585
 * it means that the FPU context must be switched
586
 */
587
SYMBOL_NAME_LABEL(exc7)	pushal
588
            		pushl	%ds
589
			pushl	%ss
590
			pushl	%es
591
			pushl	%fs
592
			pushl	%gs
593
			movw	$(X_FLATDATA_SEL),%ax
594
			movw	%ax,%es
595
			movw	%ax,%ds
596
			cld
597
			call	SYMBOL_NAME(ll_FPU_hook)
598
			popl	%gs
599
			popl	%fs
600
			popl	%es
601
			popl	%ss
602
			popl	%ds
603
			popal
604
			iret