Subversion Repositories shark

Rev

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