33,10 → 33,8 |
ASMFILE(Exc) |
|
.globl SYMBOL_NAME(ll_irq_table) |
.globl SYMBOL_NAME(ll_exc_table) |
|
SYMBOL_NAME_LABEL(ll_irq_table) .space 64, 0 |
SYMBOL_NAME_LABEL(ll_exc_table) .space 64, 65 |
SYMBOL_NAME_LABEL(ll_irq_table) .space 1024, 0 |
|
.text |
|
48,6 → 46,7 |
|
/* These are the hardware handlers; they all jump to ll_handler setting */ |
/* the interrupt number into EAX & save the registers on stack */ |
INT(0) |
INT(1) |
INT(2) |
INT(3) |
54,7 → 53,6 |
INT(4) |
INT(5) |
INT(6) |
INT(7) |
INT(8) |
INT(9) |
INT(10) |
63,60 → 61,254 |
INT(13) |
INT(14) |
INT(15) |
INT(16) |
INT(17) |
INT(18) |
INT(19) |
INT(20) |
INT(21) |
INT(22) |
INT(23) |
INT(24) |
INT(25) |
INT(26) |
INT(27) |
INT(28) |
INT(29) |
INT(30) |
INT(31) |
|
#if 0 |
/* MPF... If we have an external FPU, it will generate |
* INT 13 instead of EXC 16... |
* We must remap it to EXC 16... |
*/ |
#if 1 |
SYMBOL_NAME_LABEL(h13_bis) |
/* Send EOI for 8086 coprocessor trick */ |
/* Send 0H on Coprocessor port 0F0H */ |
pushl %eax |
xorb %al, %al |
outb %al, $0x0F0 |
movb $0x020, %al |
outb %al, $0x0A0 |
outb %al, $0x020 |
popl %eax |
movl $16, %eax |
jmp ll_handler2 |
#else |
SYMBOL_NAME_LABEL(h13_bis) pushal |
/* Send EOI for 8086 coprocessor trick */ |
/* Send 0H on Coprocessor port 0F0H */ |
|
xorb %al,%al |
outb %al,$0x0F0 |
movb $0x020,%al |
outb %al,$0x0A0 |
outb %al,$0x020 |
pushl %ds |
pushl %ss |
pushl %es |
pushl %fs |
pushl %gs |
movw $(X_FLATDATA_SEL),%ax |
movw %ax,%es |
movw %ax,%ds |
movl $(MATH_EXC),%eax |
pushl %eax |
/* LL_ABORT OR EXC_HOOK?? */ |
/*THIS SURELY WRONG!!!! FIX IT!!!! Gerardo, help me!!! */ |
hlt |
/* call SYMBOL_NAME(ll_abort) */ |
addl $4,%esp |
popl %gs |
popl %fs |
popl %es |
popl %ss |
popl %ds |
popal |
ret |
#endif |
#endif |
INT(32) |
INT(33) |
INT(34) |
INT(35) |
INT(36) |
INT(37) |
INT(38) |
INT(39) |
INT(40) |
INT(41) |
INT(42) |
INT(43) |
INT(44) |
INT(45) |
INT(46) |
INT(47) |
INT(48) |
INT(49) |
INT(50) |
INT(51) |
INT(52) |
INT(53) |
INT(54) |
INT(55) |
INT(56) |
INT(57) |
INT(58) |
INT(59) |
INT(60) |
INT(61) |
INT(62) |
INT(63) |
|
/* Master PIC... (int 0x40, see ll/i386/pic.h)*/ |
INT_1(64) |
INT_1(65) |
INT_1(66) |
INT_1(67) |
INT_1(68) |
INT_1(69) |
INT_1(70) |
INT_1(71) |
|
INT(72) |
INT(73) |
INT(74) |
INT(75) |
INT(76) |
INT(77) |
INT(78) |
INT(79) |
INT(80) |
INT(81) |
INT(82) |
INT(83) |
INT(84) |
INT(85) |
INT(86) |
INT(87) |
INT(88) |
INT(89) |
INT(90) |
INT(91) |
INT(92) |
INT(93) |
INT(94) |
INT(95) |
INT(96) |
INT(97) |
INT(98) |
INT(99) |
INT(100) |
INT(101) |
INT(102) |
INT(103) |
INT(104) |
INT(105) |
INT(106) |
INT(107) |
INT(108) |
INT(109) |
INT(110) |
INT(111) |
|
/* Slave PIC... (int 0x70, see ll/i386/pic.h)*/ |
INT_2(112) |
INT_2(113) |
INT_2(114) |
INT_2(115) |
INT_2(116) |
INT_2(117) |
INT_2(118) |
INT_2(119) |
|
INT(120) |
INT(121) |
INT(122) |
INT(123) |
INT(124) |
INT(125) |
INT(126) |
INT(127) |
INT(128) |
INT(129) |
INT(130) |
INT(131) |
INT(132) |
INT(133) |
INT(134) |
INT(135) |
INT(136) |
INT(137) |
INT(138) |
INT(139) |
INT(140) |
INT(141) |
INT(142) |
INT(143) |
INT(144) |
INT(145) |
INT(146) |
INT(147) |
INT(148) |
INT(149) |
INT(150) |
INT(151) |
INT(152) |
INT(153) |
INT(154) |
INT(155) |
INT(156) |
INT(157) |
INT(158) |
INT(159) |
INT(160) |
INT(161) |
INT(162) |
INT(163) |
INT(164) |
INT(165) |
INT(166) |
INT(167) |
INT(168) |
INT(169) |
INT(170) |
INT(171) |
INT(172) |
INT(173) |
INT(174) |
INT(175) |
INT(176) |
INT(177) |
INT(178) |
INT(179) |
INT(180) |
INT(181) |
INT(182) |
INT(183) |
INT(184) |
INT(185) |
INT(186) |
INT(187) |
INT(188) |
INT(189) |
INT(190) |
INT(191) |
INT(192) |
INT(193) |
INT(194) |
INT(195) |
INT(196) |
INT(197) |
INT(198) |
INT(199) |
INT(200) |
INT(201) |
INT(202) |
INT(203) |
INT(204) |
INT(205) |
INT(206) |
INT(207) |
INT(208) |
INT(209) |
INT(210) |
INT(211) |
INT(212) |
INT(213) |
INT(214) |
INT(215) |
INT(216) |
INT(217) |
INT(218) |
INT(219) |
INT(220) |
INT(221) |
INT(222) |
INT(223) |
INT(224) |
INT(225) |
INT(226) |
INT(227) |
INT(228) |
INT(229) |
INT(230) |
INT(231) |
INT(232) |
INT(233) |
INT(234) |
INT(235) |
INT(236) |
INT(237) |
INT(238) |
INT(239) |
INT(240) |
INT(241) |
INT(242) |
INT(243) |
INT(244) |
INT(245) |
INT(246) |
INT(247) |
INT(248) |
INT(249) |
INT(250) |
INT(251) |
INT(252) |
INT(253) |
INT(254) |
INT(255) |
|
/* The ll_handler process the request using the kernel function act_int() */ |
/* Then sends EOI & schedules any eventual new task! */ |
|
128,7 → 320,7 |
pushl %ss |
pushl %es |
pushl %fs |
pushl %gs |
pushl %gs |
/* But we first transfer to the _act_int */ |
/* the interrupt number which is required */ |
/* as second argument */ |
136,6 → 328,8 |
movw $(X_FLATDATA_SEL),%ax |
movw %ax,%es |
mov %ax,%ds |
movw %ax, %fs |
movw %ax, %gs |
|
/* Now save the actual context on stack */ |
/* to pass it to _act_int (C caling convention) */ |
148,7 → 342,6 |
xorl %ebx, %ebx |
movw %ss, %bx |
/* We must switch to a ``safe stack'' */ |
#if 0 |
/* |
* OK, this is the idea: in %esp we have the address of the |
* stack pointer in the APPLICATION address space... |
171,11 → 364,10 |
addl %ebx, %esp |
/* Save EBX for returning to our stack... */ |
movw %ss, %dx |
movw %ds, %bx |
movw %bx, %ss |
movw %ds, %cx |
movw %cx, %ss |
pushl %ebx |
pushl %edx |
#endif |
pushl %eax |
|
movl SYMBOL_NAME(ll_irq_table)(, %eax, 4), %ebx |
182,20 → 374,10 |
call *%ebx |
|
popl %ebx /* Store in EBX the Int number */ |
#if 0 |
popl %eax |
popl %ecx /* We must subtract it from ESP...*/ |
subl %ecx, %esp |
movw %ax, %ss |
#endif |
/* Send EOI to master & slave (if necessary) PIC */ |
movb $0x20,%al |
cmpl $0x08,%ebx |
jb eoi_master |
eoi_slave: movl $0xA0,%edx |
outb %al,%dx |
eoi_master: movl $0x20,%edx |
outb %al,%dx |
|
/* Resume the return value of _act_int */ |
/* & do the context switch if necessary! */ |
213,41 → 395,89 |
popl %ds |
popal |
iret |
|
|
EXC(0) |
EXC(1) |
EXC(2) |
EXC(3) |
EXC(4) |
EXC(5) |
EXC(6) |
EXC(8) |
EXC(9) |
EXC(10) |
EXC(11) |
EXC(12) |
EXC(13) |
EXC(14) |
EXC(15) |
EXC(16) |
|
/* OK, this is Exception 7, and it is generated when an ESC or WAIT |
* intruction is reached, and the MP and TS bits are set... Basically, |
* it means that the FPU context must be switched |
*/ |
SYMBOL_NAME_LABEL(exc7) pushal |
pushl %ds |
ll_handler_master_pic: |
/* We do not know what is the DS value */ |
/* Then we save it & set it correctly */ |
|
pushl %ds |
pushl %ss |
pushl %es |
pushl %fs |
pushl %gs |
movw $(X_FLATDATA_SEL),%ax |
movw %ax,%es |
movw %ax,%ds |
/* But we first transfer to the _act_int */ |
/* the interrupt number which is required */ |
/* as second argument */ |
pushl %eax |
movw $(X_FLATDATA_SEL),%ax |
movw %ax,%es |
mov %ax,%ds |
movw %ax, %fs |
movw %ax, %gs |
|
/* Now save the actual context on stack */ |
/* to pass it to _act_int (C caling convention) */ |
/* CLD is necessary when calling a C function */ |
|
cld |
call SYMBOL_NAME(ll_FPU_hook) |
popl %gs |
|
/* The following could be optimized a little... */ |
popl %eax |
xorl %ebx, %ebx |
movw %ss, %bx |
/* We must switch to a ``safe stack'' */ |
/* |
* OK, this is the idea: in %esp we have the address of the |
* stack pointer in the APPLICATION address space... |
* We assume that address spaces are implemented through segments... |
* What we have to do is to add the segment base to %esp: |
* - Load the GDT base in a register |
* - Add DS * 8 to that value |
* - Read the corresponding GDT entry (the segment descriptor) |
* - Compute the base... |
* It is (*p & 0xFC) | (*(p +1) & 0x0F) << 16) | *(p + 2) |
*/ |
movl SYMBOL_NAME(GDT_base), %edi |
addl %ebx, %edi |
xorl %ebx, %ebx |
movb 7(%edi), %bh |
movb 4(%edi), %bl |
shl $16, %ebx |
movw 2(%edi), %bx |
/* Is it correct? I think so... Test it!!! */ |
addl %ebx, %esp |
/* Save EBX for returning to our stack... */ |
movw %ss, %dx |
movw %ds, %cx |
movw %cx, %ss |
pushl %ebx |
pushl %edx |
pushl %eax |
|
movl SYMBOL_NAME(ll_irq_table)(, %eax, 4), %ebx |
call *%ebx |
|
popl %ebx /* Store in EBX the Int number */ |
popl %eax |
popl %ecx /* We must subtract it from ESP...*/ |
subl %ecx, %esp |
movw %ax, %ss |
|
/* Send EOI to master PIC */ |
movb $0x20,%al |
movl $0x20,%edx |
outb %al,%dx |
|
/* Resume the return value of _act_int */ |
/* & do the context switch if necessary! */ |
#ifdef __VIRCSW__ |
movw SYMBOL_NAME(currCtx), %ax |
cmpw JmpSel,%ax |
je NoPreempt4 |
movw %ax,JmpSel |
ljmp JmpZone |
#endif |
NoPreempt4: popl %gs |
popl %fs |
popl %es |
popl %ss |
254,22 → 484,48 |
popl %ds |
popal |
iret |
|
ll_handler_slave_pic: |
/* We do not know what is the DS value */ |
/* Then we save it & set it correctly */ |
|
ll_handler2: |
pushl %eax |
movw $(X_FLATDATA_SEL),%ax |
movw %ax,%ds |
movw %ax,%es |
|
|
/* Again, the following could be optimized... */ |
/* |
If the Exception raised in a different address space, we have to |
access the task stack from the kernel address space (the linear one...) |
*/ |
pushl %ds |
pushl %ss |
pushl %es |
pushl %fs |
pushl %gs |
/* But we first transfer to the _act_int */ |
/* the interrupt number which is required */ |
/* as second argument */ |
pushl %eax |
movw $(X_FLATDATA_SEL),%ax |
movw %ax,%es |
mov %ax,%ds |
movw %ax, %fs |
movw %ax, %gs |
|
/* Now save the actual context on stack */ |
/* to pass it to _act_int (C caling convention) */ |
/* CLD is necessary when calling a C function */ |
|
cld |
|
/* The following could be optimized a little... */ |
popl %eax |
xorl %ebx, %ebx |
movw %ss, %bx |
/* We must switch to a ``safe stack'' */ |
/* |
* OK, this is the idea: in %esp we have the address of the |
* stack pointer in the APPLICATION address space... |
* We assume that address spaces are implemented through segments... |
* What we have to do is to add the segment base to %esp: |
* - Load the GDT base in a register |
* - Add DS * 8 to that value |
* - Read the corresponding GDT entry (the segment descriptor) |
* - Compute the base... |
* It is (*p & 0xFC) | (*(p +1) & 0x0F) << 16) | *(p + 2) |
*/ |
movl SYMBOL_NAME(GDT_base), %edi |
addl %ebx, %edi |
xorl %ebx, %ebx |
281,17 → 537,68 |
addl %ebx, %esp |
/* Save EBX for returning to our stack... */ |
movw %ss, %dx |
movw %ds, %bx |
movw %bx, %ss |
movw %ds, %cx |
movw %cx, %ss |
pushl %ebx |
pushl %edx |
pushl %eax |
call *SYMBOL_NAME(ll_exc_table)(, %eax, 4) |
addl $4,%esp |
|
/* Restore the stack pointer!!! */ |
popl %eax |
popl %ebx |
movw %ax, %ss |
subl %ebx, %esp |
movl SYMBOL_NAME(ll_irq_table)(, %eax, 4), %ebx |
call *%ebx |
|
popl %ebx /* Store in EBX the Int number */ |
popl %eax |
popl %ecx /* We must subtract it from ESP...*/ |
subl %ecx, %esp |
movw %ax, %ss |
|
/* Send EOI to master & slave PIC */ |
movb $0x20,%al |
movl $0xA0,%edx |
outb %al,%dx |
movl $0x20,%edx |
outb %al,%dx |
|
|
/* Resume the return value of _act_int */ |
/* & do the context switch if necessary! */ |
#ifdef __VIRCSW__ |
movw SYMBOL_NAME(currCtx), %ax |
cmpw JmpSel,%ax |
je NoPreempt5 |
movw %ax,JmpSel |
ljmp JmpZone |
#endif |
NoPreempt5: popl %gs |
popl %fs |
popl %es |
popl %ss |
popl %ds |
popal |
iret |
|
|
|
|
/* OK, this is Exception 7, and it is generated when an ESC or WAIT |
* intruction is reached, and the MP and TS bits are set... Basically, |
* it means that the FPU context must be switched |
*/ |
SYMBOL_NAME_LABEL(exc7) pushal |
pushl %ds |
pushl %ss |
pushl %es |
pushl %fs |
pushl %gs |
movw $(X_FLATDATA_SEL),%ax |
movw %ax,%es |
movw %ax,%ds |
cld |
call SYMBOL_NAME(ll_FPU_hook) |
popl %gs |
popl %fs |
popl %es |
popl %ss |
popl %ds |
popal |
iret |