Subversion Repositories shark

Rev

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