2018-09-28 20:35:51 +02:00
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */
2018-08-17 16:46:56 +02:00
# include "interrupts.h"
# include "types.h"
# include "asm.h"
# include "memory.h"
# include "video.h"
2018-10-02 02:16:14 +02:00
# include "gdt.h"
2018-10-02 13:49:10 +02:00
# include "system.h"
2018-10-09 18:13:04 +02:00
# include "debug.h"
2018-12-10 17:03:52 +01:00
# include "process.h"
2018-08-17 16:46:56 +02:00
2018-10-02 02:16:14 +02:00
# define IDT_SIZE 256 /* nombre de descripteurs */
2018-09-01 22:58:05 +02:00
2018-08-17 16:46:56 +02:00
/* registre idt */
2018-08-31 02:48:03 +02:00
static struct idtr idtreg ;
2018-08-17 16:46:56 +02:00
/* table de IDT */
2018-10-02 02:16:14 +02:00
static idtdes idt [ IDT_SIZE ] ;
2018-08-17 16:46:56 +02:00
2018-10-02 13:49:10 +02:00
static u32 retry_address ;
/******************************************************************************/
/* Initialise la reprise après erreur */
void initretry ( u32 address )
{
2018-12-12 15:25:04 +01:00
retry_address = address ;
2018-10-02 13:49:10 +02:00
}
2018-12-12 10:14:31 +01:00
/******************************************************************************/
/* Récupère l'adresse de reprise après erreur */
u32 getinitretry ( void )
{
2018-12-12 15:25:04 +01:00
return retry_address ;
2018-12-12 10:14:31 +01:00
}
2018-08-17 16:46:56 +02:00
/******************************************************************************/
/* Initialise le controleur d'interruption 8259A */
void initpic ( void )
{
/* MASTER */
/* Initialisation de ICW1 */
2018-08-28 15:22:43 +02:00
outb ( PIC1_CMD , ICW1_INIT + ICW1_ICW4 ) ;
2018-08-17 16:46:56 +02:00
nop ( ) ;
/* Initialisation de ICW2 - vecteur de depart = 32 */
2018-08-28 15:22:43 +02:00
outb ( PIC1_DATA , 0x20 ) ;
2018-08-17 16:46:56 +02:00
nop ( ) ;
/* Initialisation de ICW3 */
2018-08-28 15:22:43 +02:00
outb ( PIC1_DATA , 0x04 ) ;
2018-08-17 16:46:56 +02:00
nop ( ) ;
/* Initialisation de ICW4 */
2018-08-28 15:22:43 +02:00
outb ( PIC1_DATA , ICW4_8086 ) ;
2018-08-17 16:46:56 +02:00
nop ( ) ;
/* masquage des interruptions */
2018-08-28 15:22:43 +02:00
outb ( PIC1_DATA , 0xFF ) ;
2018-08-17 16:46:56 +02:00
nop ( ) ;
/* SLAVE */
/* Initialisation de ICW1 */
2018-08-28 15:22:43 +02:00
outb ( PIC2_CMD , ICW1_INIT + ICW1_ICW4 ) ;
2018-08-17 16:46:56 +02:00
nop ( ) ;
/* Initialisation de ICW2 - vecteur de depart = 96 */
2018-08-28 15:22:43 +02:00
outb ( PIC2_DATA , 0x60 ) ;
2018-08-17 16:46:56 +02:00
nop ( ) ;
/* Initialisation de ICW3 */
2018-08-28 15:22:43 +02:00
outb ( PIC2_DATA , 0x02 ) ;
2018-08-17 16:46:56 +02:00
nop ( ) ;
/* Initialisation de ICW4 */
2018-08-28 15:22:43 +02:00
outb ( PIC2_DATA , ICW4_8086 ) ;
2018-08-17 16:46:56 +02:00
nop ( ) ;
/* masquage des interruptions */
2018-08-28 15:22:43 +02:00
outb ( PIC2_DATA , 0xFF ) ;
2018-08-17 16:46:56 +02:00
nop ( ) ;
/* Demasquage des irqs sauf clavier
2018-08-28 15:22:43 +02:00
outb ( PIC1_DATA , 0xFD ) ;
2018-08-17 16:46:56 +02:00
nop ( ) ;
*/
}
/******************************************************************************/
/* Active une IRQ */
void enableirq ( u8 irq )
{
2018-12-12 15:25:04 +01:00
u16 port ;
2018-08-17 16:46:56 +02:00
cli ( ) ;
2018-08-28 15:22:43 +02:00
port = ( ( ( irq & 0x08 ) < < 4 ) + PIC1_DATA ) ;
2018-08-17 16:46:56 +02:00
outb ( port , inb ( port ) & ~ ( 1 < < ( irq & 7 ) ) ) ;
sti ( ) ;
}
/******************************************************************************/
/* Désactive une IRQ */
void disableirq ( u8 irq )
{
2018-12-12 15:25:04 +01:00
u16 port ;
2018-08-17 16:46:56 +02:00
cli ( ) ;
2018-08-28 15:22:43 +02:00
port = ( ( ( irq & 0x08 ) < < 4 ) + PIC1_DATA ) ;
2018-08-17 16:46:56 +02:00
outb ( port , inb ( port ) | ( 1 < < ( irq & 7 ) ) ) ;
sti ( ) ;
}
/******************************************************************************/
/* Créé un descripteur pour l'IDT */
void makeidtdes ( u32 offset , u16 select , u16 type , idtdes * desc )
{
desc - > offset0_15 = ( offset & 0xffff ) ;
desc - > select = select ;
desc - > type = type ;
desc - > offset16_31 = ( offset & 0xffff0000 ) > > 16 ;
return ;
}
/******************************************************************************/
/* Change une entrée dans l'IDT */
void setidt ( u32 offset , u16 select , u16 type , u16 index )
{
cli ( ) ;
idtdes * desc ;
desc = idtreg . base ;
desc [ index ] . offset0_15 = ( offset & 0xffff ) ;
desc [ index ] . select = select ;
desc [ index ] . type = type ;
desc [ index ] . offset16_31 = ( offset & 0xffff0000 ) > > 16 ;
sti ( ) ;
}
/******************************************************************************/
/* Met une entrée dans l'IDT */
void putidt ( u32 offset , u16 select , u16 type , u16 index )
{
2018-12-12 15:25:04 +01:00
idtdes temp ;
2018-08-17 16:46:56 +02:00
makeidtdes ( offset , select , type , & temp ) ;
idt [ index ] = temp ;
}
2018-12-10 19:12:20 +01:00
/******************************************************************************/
2018-08-17 16:46:56 +02:00
/* Affiche une erreur CPU et fige l'ordinateur */
2018-12-12 15:25:04 +01:00
void cpuerror ( const u8 * src , const regs * stack )
2018-08-17 16:46:56 +02:00
{
2018-10-02 17:16:23 +02:00
printf ( " \033 [31m*** ERREUR CPU : %s *** \r \n " , src ) ;
2018-12-12 15:25:04 +01:00
if ( stack ! = NULL )
show_cpu ( stack ) ;
2018-10-03 22:50:54 +02:00
print ( " <Appuyer une touche pour continuer> \033 [0m \r \n " ) ;
2018-12-12 15:25:04 +01:00
sti ( ) ;
waitascii ( ) ;
initselectors ( retry_address ) ;
2018-10-02 02:16:14 +02:00
/*while (true) {
2018-12-12 15:25:04 +01:00
nop ( ) ;
} */
2018-08-17 16:46:56 +02:00
}
/******************************************************************************/
/* Déclenché lors de l'appel d'une interruption */
void interruption ( )
{
2018-12-12 17:57:23 +01:00
regs * dump ;
exception_stack_noerror * caller ;
u32 * oldesp ;
savecpu_noerror ( dump , caller , oldesp ) ;
2018-08-17 16:46:56 +02:00
print ( " Appel d'une interruption \r \n " ) ;
2018-12-12 17:57:23 +01:00
restdebugcpu ( ) ;
2018-08-17 16:46:56 +02:00
iret ( ) ;
}
/******************************************************************************/
/* Les expections */
void exception0 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack_noerror * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu_noerror ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
cpuerror ( " #DE Divide error " , dump ) ;
2018-08-17 16:46:56 +02:00
}
void exception1 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack_noerror * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu_noerror ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
changevc ( 6 ) ;
clearscreen ( ) ;
show_lightcpu ( dump ) ;
printf ( " \r \n \033 [7m[P] \033 [0m PAS A PAS \033 [7m D \033 [0m PAS A PAS DETAILLE \033 [7m C \033 [0m CONTINUER \033 [7m S \033 [0m STOPPER \033 [7m V \033 [0m VOIR \033 [7m S \033 [0m SCINDER " ) ;
2018-10-09 18:13:04 +02:00
sti ( ) ;
2018-12-12 15:25:04 +01:00
u8 ascii = waitascii ( ) ;
cli ( ) ;
if ( ascii = = ' P ' | | ascii = = ' p ' )
setdebugreg ( 0 ,
2018-12-12 17:57:23 +01:00
caller - > eip + disasm ( caller - > eip , NULL , false ) ,
DBG_EXEC ) ;
2018-12-12 15:25:04 +01:00
else if ( ascii = = ' D ' | | ascii = = ' d ' )
setdebugreg ( 0 , 0 , DBG_CLEAR ) ;
else if ( ascii = = ' C ' | | ascii = = ' c ' )
setdebugreg ( 0 , 0 , DBG_CLEAR ) ;
else if ( ascii = = ' S ' | | ascii = = ' s ' )
{
changevc ( 0 ) ;
sti ( ) ;
initselectors ( retry_address ) ;
}
changevc ( 0 ) ;
restdebugcpu ( ) ;
iret ( ) ;
2018-08-17 16:46:56 +02:00
}
void exception2 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack_noerror * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu_noerror ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
cpuerror ( " NMI Non-maskable hardware interrupt " , dump ) ;
2018-08-17 16:46:56 +02:00
}
void exception3 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack_noerror * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu_noerror ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
cpuerror ( " #BP INT3 instruction " , dump ) ;
2018-08-17 16:46:56 +02:00
}
void exception4 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack_noerror * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu_noerror ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
cpuerror ( " #OF INTO instruction detected overflow " , dump ) ;
2018-08-17 16:46:56 +02:00
}
void exception5 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack_noerror * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu_noerror ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
cpuerror ( " #BR BOUND instruction detected overrange " , dump ) ;
2018-08-17 16:46:56 +02:00
}
void exception6 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack_noerror * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu_noerror ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
cpuerror ( " #UD Invalid instruction opcode " , dump ) ;
2018-08-17 16:46:56 +02:00
}
void exception7 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack_noerror * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu_noerror ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
cpuerror ( " #NM No coprocessor " , dump ) ;
2018-08-17 16:46:56 +02:00
}
void exception8 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack_noerror * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu_noerror ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
cpuerror ( " #DF Double fault " , dump ) ;
2018-08-17 16:46:56 +02:00
}
void exception9 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack_noerror * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu_noerror ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
cpuerror ( " Coprocessor segment overrun " , dump ) ;
2018-08-17 16:46:56 +02:00
}
void exception10 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack_noerror * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu_noerror ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
cpuerror ( " #TS Invalid task state segment (TSS) " , dump ) ;
2018-08-17 16:46:56 +02:00
}
void exception11 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack_noerror * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu_noerror ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
cpuerror ( " #NP Segment not present " , dump ) ;
2018-08-17 16:46:56 +02:00
}
void exception12 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack_noerror * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu_noerror ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
cpuerror ( " #SS Stack fault " , dump ) ;
2018-08-17 16:46:56 +02:00
}
void exception13 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
cpuerror ( " #GP General protection fault (GPF) " , dump ) ;
}
static u8 ex14_errors1 [ ] =
" Supervisory process tried to read a non-present page entry " ;
static u8 ex14_errors2 [ ] =
" Supervisory process tried to read a page and caused a protection fault " ;
static u8 ex14_errors3 [ ] =
" Supervisory process tried to write to a non-present page entry " ;
static u8 ex14_errors4 [ ] =
" Supervisory process tried to write a page and caused a protection fault " ;
static u8 ex14_errors5 [ ] =
" User process tried to read a non-present page entry " ;
static u8 ex14_errors6 [ ] =
" User process tried to read a page and caused a protection fault " ;
static u8 ex14_errors7 [ ] =
" User process tried to write to a non-present page entry " ;
static u8 ex14_errors8 [ ] =
" User process tried to write a page and caused a protection fault " ;
static u8 * ex14_errors [ ] =
{ & ex14_errors1 , & ex14_errors2 , & ex14_errors3 , & ex14_errors4 ,
2018-12-12 17:57:23 +01:00
& ex14_errors5 , & ex14_errors6 , & ex14_errors7 , & ex14_errors8
} ;
2018-12-10 17:03:52 +01:00
2018-08-17 16:46:56 +02:00
void exception14 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
getEBP ( oldesp ) ;
dumpcpu ( ) ;
getESP ( dump ) ;
2018-12-12 17:57:23 +01:00
caller = ( exception_stack * ) ( oldesp + 1 ) ;
2018-12-12 15:25:04 +01:00
dump - > ebp = * oldesp ;
2018-12-12 17:57:23 +01:00
dump - > eip = caller - > eip ;
dump - > cs = caller - > cs ;
if ( caller - > cs = = SEL_KERNEL_CODE )
dump - > esp = ( u32 ) oldesp + sizeof ( exception_stack ) ;
else
{
dump - > esp = ( u32 ) ( ( exception_stack_user * ) caller ) - > esp ;
dump - > ss = ( u32 ) ( ( exception_stack_user * ) caller ) - > ss ;
}
2018-12-12 15:25:04 +01:00
if ( dump - > cr2 > = USER_CODE & & dump - > cr2 < USER_STACK )
{
virtual_range_new ( getcurrentprocess ( ) - > pdd ,
( u8 * ) ( dump - > cr2 & 0xFFFFF000 ) ,
PAGESIZE , PAGE_ALL ) ;
2018-12-10 17:03:52 +01:00
}
2018-12-12 15:25:04 +01:00
else
{
printf ( " Page fault - %s at adress %Y cs:eip - %Y:%Y \r \n " ,
2018-12-12 17:57:23 +01:00
ex14_errors [ caller - > error_code & 0xF ] , dump - > cr2 ,
2018-12-12 15:25:04 +01:00
dump - > cs , dump - > eip ) ;
cpuerror ( " #PGF Page fault " , dump ) ;
}
restdebugcpu ( ) ;
iret ( ) ;
2018-08-17 16:46:56 +02:00
}
void exception15 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack_noerror * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu_noerror ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
cpuerror ( " (reserved) " , dump ) ;
2018-08-17 16:46:56 +02:00
}
void exception16 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack_noerror * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu_noerror ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
cpuerror ( " #MF Coprocessor error " , dump ) ;
2018-08-17 16:46:56 +02:00
}
void exception17 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack_noerror * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu_noerror ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
cpuerror ( " #AC Alignment check " , dump ) ;
2018-08-17 16:46:56 +02:00
}
void exception18 ( )
{
2018-12-12 15:25:04 +01:00
regs * dump ;
2018-12-12 17:57:23 +01:00
exception_stack_noerror * caller ;
2018-12-12 15:25:04 +01:00
u32 * oldesp ;
2018-12-12 17:57:23 +01:00
savecpu_noerror ( dump , caller , oldesp ) ;
2018-12-12 15:25:04 +01:00
cpuerror ( " #MC Machine check " , dump ) ;
2018-08-17 16:46:56 +02:00
}
/******************************************************************************/
/* Les IRQ par défaut */
void irq0 ( )
{
cli ( ) ;
pushf ( ) ;
pushad ( ) ;
print ( " irq 0 " ) ;
irqendmaster ( ) ;
popad ( ) ;
popf ( ) ;
sti ( ) ;
2018-12-05 14:00:43 +01:00
leave ( ) ;
2018-08-17 16:46:56 +02:00
iret ( ) ;
}
void irq1 ( )
{
cli ( ) ;
pushf ( ) ;
pushad ( ) ;
print ( " irq 1 " ) ;
2018-12-12 15:25:04 +01:00
while ( ( inb ( 0x64 ) & 1 ) = = 0 ) ;
2018-08-17 16:46:56 +02:00
inb ( 0x60 ) ;
irqendmaster ( ) ;
popad ( ) ;
popf ( ) ;
sti ( ) ;
2018-12-05 14:00:43 +01:00
leave ( ) ;
2018-08-17 16:46:56 +02:00
iret ( ) ;
}
void irq2 ( )
{
cli ( ) ;
pushf ( ) ;
pushad ( ) ;
print ( " irq 2 " ) ;
irqendmaster ( ) ;
popad ( ) ;
popf ( ) ;
sti ( ) ;
2018-12-05 14:00:43 +01:00
leave ( ) ;
2018-08-17 16:46:56 +02:00
iret ( ) ;
}
void irq3 ( )
{
cli ( ) ;
pushf ( ) ;
pushad ( ) ;
print ( " irq 3 " ) ;
irqendmaster ( ) ;
popad ( ) ;
popf ( ) ;
sti ( ) ;
2018-12-05 14:00:43 +01:00
leave ( ) ;
2018-08-17 16:46:56 +02:00
iret ( ) ;
}
void irq4 ( )
{
cli ( ) ;
pushf ( ) ;
pushad ( ) ;
print ( " irq 4 " ) ;
irqendmaster ( ) ;
popad ( ) ;
popf ( ) ;
sti ( ) ;
2018-12-05 14:00:43 +01:00
leave ( ) ;
2018-08-17 16:46:56 +02:00
iret ( ) ;
}
void irq5 ( )
{
cli ( ) ;
pushf ( ) ;
pushad ( ) ;
print ( " irq 5 " ) ;
irqendmaster ( ) ;
popad ( ) ;
popf ( ) ;
sti ( ) ;
2018-12-05 14:00:43 +01:00
leave ( ) ;
2018-08-17 16:46:56 +02:00
iret ( ) ;
}
void irq6 ( )
{
cli ( ) ;
pushf ( ) ;
pushad ( ) ;
print ( " irq 6 " ) ;
irqendmaster ( ) ;
popad ( ) ;
popf ( ) ;
sti ( ) ;
2018-12-05 14:00:43 +01:00
leave ( ) ;
2018-08-17 16:46:56 +02:00
iret ( ) ;
}
void irq7 ( )
{
cli ( ) ;
pushf ( ) ;
pushad ( ) ;
print ( " irq 7 " ) ;
irqendmaster ( ) ;
popad ( ) ;
popf ( ) ;
sti ( ) ;
2018-12-05 14:00:43 +01:00
leave ( ) ;
2018-08-17 16:46:56 +02:00
iret ( ) ;
}
void irq8 ( )
{
cli ( ) ;
pushf ( ) ;
pushad ( ) ;
print ( " irq 8 " ) ;
irqendslave ( ) ;
irqendmaster ( ) ;
popad ( ) ;
popf ( ) ;
sti ( ) ;
2018-12-05 14:00:43 +01:00
leave ( ) ;
2018-08-17 16:46:56 +02:00
iret ( ) ;
}
void irq9 ( )
{
cli ( ) ;
pushf ( ) ;
pushad ( ) ;
print ( " irq 9 " ) ;
irqendslave ( ) ;
irqendmaster ( ) ;
popad ( ) ;
popf ( ) ;
sti ( ) ;
2018-12-05 14:00:43 +01:00
leave ( ) ;
2018-08-17 16:46:56 +02:00
iret ( ) ;
}
void irq10 ( )
{
cli ( ) ;
pushf ( ) ;
pushad ( ) ;
print ( " irq 10 " ) ;
irqendslave ( ) ;
irqendmaster ( ) ;
popad ( ) ;
popf ( ) ;
sti ( ) ;
2018-12-05 14:00:43 +01:00
leave ( ) ;
2018-08-17 16:46:56 +02:00
iret ( ) ;
}
void irq11 ( )
{
cli ( ) ;
pushf ( ) ;
pushad ( ) ;
print ( " irq 11 " ) ;
irqendslave ( ) ;
irqendmaster ( ) ;
popad ( ) ;
popf ( ) ;
sti ( ) ;
2018-12-05 14:00:43 +01:00
leave ( ) ;
2018-08-17 16:46:56 +02:00
iret ( ) ;
}
void irq12 ( )
{
cli ( ) ;
pushf ( ) ;
pushad ( ) ;
print ( " irq 12 " ) ;
2018-12-12 15:25:04 +01:00
while ( ( inb ( 0x64 ) & 1 ) = = 0 ) ;
2018-08-17 16:46:56 +02:00
inb ( 0x60 ) ;
irqendslave ( ) ;
irqendmaster ( ) ;
popad ( ) ;
popf ( ) ;
sti ( ) ;
2018-12-05 14:00:43 +01:00
leave ( ) ;
2018-08-17 16:46:56 +02:00
iret ( ) ;
}
void irq13 ( )
{
cli ( ) ;
pushf ( ) ;
pushad ( ) ;
print ( " irq 13 " ) ;
irqendslave ( ) ;
irqendmaster ( ) ;
popad ( ) ;
popf ( ) ;
sti ( ) ;
2018-12-05 14:00:43 +01:00
leave ( ) ;
2018-08-17 16:46:56 +02:00
iret ( ) ;
}
void irq14 ( )
{
cli ( ) ;
pushf ( ) ;
pushad ( ) ;
print ( " irq 14 " ) ;
irqendslave ( ) ;
irqendmaster ( ) ;
popad ( ) ;
popf ( ) ;
sti ( ) ;
2018-12-05 14:00:43 +01:00
leave ( ) ;
2018-08-17 16:46:56 +02:00
iret ( ) ;
}
void irq15 ( )
{
cli ( ) ;
print ( " irq 15 " ) ;
irqendslave ( ) ;
irqendmaster ( ) ;
popad ( ) ;
popf ( ) ;
sti ( ) ;
2018-12-05 14:00:43 +01:00
leave ( ) ;
2018-08-17 16:46:56 +02:00
iret ( ) ;
}
/******************************************************************************/
/* Initialise une IDT */
void initidt ( void )
{
2018-12-12 15:25:04 +01:00
u16 i ;
putidt ( ( u32 ) exception0 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 0 ) ;
putidt ( ( u32 ) exception1 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 1 ) ;
putidt ( ( u32 ) exception2 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 2 ) ;
putidt ( ( u32 ) exception3 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 3 ) ;
putidt ( ( u32 ) exception4 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 4 ) ;
putidt ( ( u32 ) exception5 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 5 ) ;
putidt ( ( u32 ) exception6 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 6 ) ;
putidt ( ( u32 ) exception7 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 7 ) ;
putidt ( ( u32 ) exception8 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 8 ) ;
putidt ( ( u32 ) exception9 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 9 ) ;
putidt ( ( u32 ) exception10 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 10 ) ;
putidt ( ( u32 ) exception11 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 11 ) ;
putidt ( ( u32 ) exception12 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 12 ) ;
putidt ( ( u32 ) exception13 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 13 ) ;
putidt ( ( u32 ) exception14 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 14 ) ;
putidt ( ( u32 ) exception15 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 15 ) ;
putidt ( ( u32 ) exception16 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 16 ) ;
putidt ( ( u32 ) exception17 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 17 ) ;
putidt ( ( u32 ) exception18 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 18 ) ;
for ( i = 19 ; i < 32 ; i + + )
{
putidt ( ( u32 ) interruption , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING3 | TRAPGATE , i ) ;
2018-08-17 16:46:56 +02:00
}
2018-12-12 15:25:04 +01:00
putidt ( ( u32 ) irq0 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 32 ) ;
putidt ( ( u32 ) irq1 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 33 ) ;
putidt ( ( u32 ) irq2 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 34 ) ;
putidt ( ( u32 ) irq3 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 35 ) ;
putidt ( ( u32 ) irq4 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 36 ) ;
putidt ( ( u32 ) irq5 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 37 ) ;
putidt ( ( u32 ) irq6 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 38 ) ;
putidt ( ( u32 ) irq7 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 39 ) ;
for ( i = 40 ; i < 96 ; i + + )
{
putidt ( ( u32 ) interruption , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING3 | TRAPGATE , i ) ;
2018-08-17 16:46:56 +02:00
}
2018-12-12 15:25:04 +01:00
putidt ( ( u32 ) irq8 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 96 ) ;
putidt ( ( u32 ) irq9 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 97 ) ;
putidt ( ( u32 ) irq10 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 98 ) ;
putidt ( ( u32 ) irq11 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 99 ) ;
putidt ( ( u32 ) irq12 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 100 ) ;
putidt ( ( u32 ) irq13 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 101 ) ;
putidt ( ( u32 ) irq14 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 102 ) ;
putidt ( ( u32 ) irq15 , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE , 103 ) ;
for ( i = 104 ; i < IDT_SIZE ; i + + )
{
putidt ( ( u32 ) interruption , SEL_KERNEL_CODE ,
ENTRY_PRESENT | ENTRY_RING0 | TRAPGATE , i ) ;
2018-08-17 16:46:56 +02:00
}
/* initialise le registre idt */
2018-10-04 14:55:41 +02:00
idtreg . limite = IDT_SIZE * sizeof ( idtdes ) ;
2018-10-02 02:16:14 +02:00
idtreg . base = IDT_ADDR ;
2018-08-17 16:46:56 +02:00
/* recopie de la IDT a son adresse */
memcpy ( & idt , ( u8 * ) idtreg . base , idtreg . limite , 1 ) ;
/* chargement du registre IDTR */
lidt ( & idtreg ) ;
}
2018-08-28 15:22:43 +02:00
/******************************************************************************/
/* 8253/8254 PIT (Programmable Interval Timer) Timer ajustable */
2018-09-28 20:35:51 +02:00
void inittimer ( void )
2018-08-28 15:22:43 +02:00
{
2018-12-12 15:25:04 +01:00
u32 divisor = TIMER_FREQ / HZ ;
2018-09-27 17:47:27 +02:00
outb ( TIMER_MODE , RATE_GENERATOR ) ;
2018-11-14 22:23:10 +01:00
outb ( TIMER0 , ( u8 ) divisor ) ;
outb ( TIMER0 , ( u8 ) ( divisor > > 8 ) ) ;
2018-08-28 15:22:43 +02:00
}
2018-09-28 20:35:51 +02:00
/*******************************************************************************/