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-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)
|
|
|
|
{
|
|
|
|
retry_address=address;
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
u16 port;
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
u16 port;
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
idtdes temp;
|
|
|
|
makeidtdes(offset, select, type, &temp);
|
|
|
|
idt[index] = temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
/* Affiche une erreur CPU et fige l'ordinateur */
|
|
|
|
|
2018-10-03 22:50:54 +02:00
|
|
|
void cpuerror(const u8 * src, const save_stack *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-10-04 14:55:41 +02: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");
|
|
|
|
sti();
|
2018-10-02 13:49:10 +02:00
|
|
|
waitascii();
|
|
|
|
initselectors(retry_address);
|
2018-10-02 02:16:14 +02:00
|
|
|
/*while (true) {
|
2018-08-17 16:46:56 +02:00
|
|
|
nop();
|
2018-10-02 02:16:14 +02:00
|
|
|
}*/
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
/* Déclenché lors de l'appel d'une interruption */
|
|
|
|
|
|
|
|
void interruption()
|
|
|
|
{
|
|
|
|
cli();
|
|
|
|
pushf();
|
|
|
|
pushad();
|
|
|
|
print("Appel d'une interruption\r\n");
|
|
|
|
popad();
|
|
|
|
popf();
|
|
|
|
sti();
|
|
|
|
iret();
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
/* Les expections */
|
|
|
|
|
|
|
|
void exception0()
|
|
|
|
{
|
2018-10-04 14:55:41 +02:00
|
|
|
cli();
|
2018-10-03 22:50:54 +02:00
|
|
|
save_stack dump;
|
2018-10-04 14:55:41 +02:00
|
|
|
exception_stack_noerror *current = getESP()+0x28+sizeof(save_stack);
|
2018-10-03 22:50:54 +02:00
|
|
|
dump_cpu(&dump);
|
|
|
|
dump.eip=current->eip;
|
|
|
|
dump.cs=current->cs;
|
|
|
|
dump.esp=(current+1);
|
|
|
|
cpuerror("divide error",&dump);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception1()
|
|
|
|
{
|
2018-10-03 22:50:54 +02:00
|
|
|
cpuerror("debug exception",NULL);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception2()
|
|
|
|
{
|
2018-10-03 22:50:54 +02:00
|
|
|
cpuerror("non-maskable hardware interrupt",NULL);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception3()
|
|
|
|
{
|
2018-10-04 14:55:41 +02:00
|
|
|
cli();
|
|
|
|
save_stack dump;
|
|
|
|
exception_stack_noerror *current = getESP()+0x28+sizeof(save_stack);
|
|
|
|
dump_cpu(&dump);
|
|
|
|
dump.eip=current->eip;
|
|
|
|
dump.cs=current->cs;
|
|
|
|
dump.esp=(current+1);
|
|
|
|
cpuerror("INT3 instruction",&dump);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception4()
|
|
|
|
{
|
2018-10-03 22:50:54 +02:00
|
|
|
cpuerror("INTO instruction detected overflow",NULL);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception5()
|
|
|
|
{
|
2018-10-03 22:50:54 +02:00
|
|
|
cpuerror("BOUND instruction detected overrange",NULL);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception6()
|
|
|
|
{
|
2018-10-04 14:55:41 +02:00
|
|
|
cli();
|
|
|
|
save_stack dump;
|
|
|
|
exception_stack_noerror *current = getESP()+0x28+sizeof(save_stack);
|
|
|
|
dump_cpu(&dump);
|
|
|
|
dump.eip=current->eip;
|
|
|
|
dump.cs=current->cs;
|
|
|
|
dump.esp=(current+1);
|
|
|
|
cpuerror("Invalid instruction opcode",&dump);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception7()
|
|
|
|
{
|
2018-10-03 22:50:54 +02:00
|
|
|
cpuerror("no coprocessor",NULL);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception8()
|
|
|
|
{
|
2018-10-03 22:50:54 +02:00
|
|
|
cpuerror("double fault",NULL);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception9()
|
|
|
|
{
|
2018-10-03 22:50:54 +02:00
|
|
|
cpuerror("coprocessor segment overrun",NULL);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception10()
|
|
|
|
{
|
2018-10-03 22:50:54 +02:00
|
|
|
cpuerror("invalid task state segment (TSS)",NULL);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception11()
|
|
|
|
{
|
2018-10-04 14:55:41 +02:00
|
|
|
cli();
|
|
|
|
save_stack dump;
|
|
|
|
exception_stack_noerror *current = getESP()+0x30+sizeof(save_stack);
|
|
|
|
dump_cpu(&dump);
|
|
|
|
dump.eip=current->eip;
|
|
|
|
dump.cs=current->cs;
|
|
|
|
dump.esp=(current+1);
|
|
|
|
cpuerror("segment not present",&dump);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception12()
|
|
|
|
{
|
2018-10-03 22:50:54 +02:00
|
|
|
cpuerror("stack fault",NULL);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception13()
|
|
|
|
{
|
2018-10-04 14:55:41 +02:00
|
|
|
cli();
|
|
|
|
save_stack dump;
|
|
|
|
exception_stack_noerror *current = getESP()+0x30+sizeof(save_stack);
|
|
|
|
dump_cpu(&dump);
|
|
|
|
dump.eip=current->eip;
|
|
|
|
dump.cs=current->cs;
|
|
|
|
dump.esp=(current+1);
|
|
|
|
cpuerror("general protection fault (GPF)",&dump);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception14()
|
|
|
|
{
|
2018-10-04 14:55:41 +02:00
|
|
|
cli();
|
2018-10-03 22:50:54 +02:00
|
|
|
save_stack dump;
|
2018-10-04 14:55:41 +02:00
|
|
|
exception_stack *current = getESP()+0x28+sizeof(save_stack);
|
2018-10-03 22:50:54 +02:00
|
|
|
dump_cpu(&dump);
|
|
|
|
dump.eip=current->eip;
|
|
|
|
dump.cs=current->cs;
|
|
|
|
dump.esp=(current+1);
|
|
|
|
u8 *errorstring="page fault";
|
|
|
|
switch (current->error_code) {
|
2018-10-02 17:16:23 +02:00
|
|
|
case 0:
|
|
|
|
errorstring="page fault - Supervisory process tried to read a non-present page entry";
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
errorstring="Page fault - Supervisory process tried to read a page and caused a protection fault";
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
errorstring="Page fault - Supervisory process tried to write to a non-present page entry";
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
errorstring="Page fault - Supervisory process tried to write a page and caused a protection fault";
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
errorstring="Page fault - User process tried to read a non-present page entry";
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
errorstring="Page fault - User process tried to read a page and caused a protection fault";
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
errorstring="Page fault - User process tried to write to a non-present page entry";
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
errorstring="Page fault - User process tried to write a page and caused a protection fault";
|
|
|
|
break;
|
|
|
|
}
|
2018-10-03 22:50:54 +02:00
|
|
|
cpuerror(errorstring,&dump);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception15()
|
|
|
|
{
|
2018-10-03 22:50:54 +02:00
|
|
|
cpuerror("(reserved)",NULL);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception16()
|
|
|
|
{
|
2018-10-03 22:50:54 +02:00
|
|
|
cpuerror("coprocessor error",NULL);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception17()
|
|
|
|
{
|
2018-10-03 22:50:54 +02:00
|
|
|
cpuerror("alignment check",NULL);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void exception18()
|
|
|
|
{
|
2018-10-03 22:50:54 +02:00
|
|
|
cpuerror("machine check",NULL);
|
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-08-20 16:35:36 +02:00
|
|
|
asm("addl $0x0C, %esp;");
|
2018-08-17 16:46:56 +02:00
|
|
|
iret();
|
|
|
|
}
|
|
|
|
|
|
|
|
void irq1()
|
|
|
|
{
|
|
|
|
cli();
|
|
|
|
pushf();
|
|
|
|
pushad();
|
|
|
|
print("irq 1");
|
|
|
|
while ((inb(0x64) & 1) == 0) ;
|
|
|
|
inb(0x60);
|
|
|
|
irqendmaster();
|
|
|
|
popad();
|
|
|
|
popf();
|
|
|
|
sti();
|
|
|
|
asm("addl $0x01C, %esp;");
|
|
|
|
iret();
|
|
|
|
}
|
|
|
|
|
|
|
|
void irq2()
|
|
|
|
{
|
|
|
|
cli();
|
|
|
|
pushf();
|
|
|
|
pushad();
|
|
|
|
print("irq 2");
|
|
|
|
irqendmaster();
|
|
|
|
popad();
|
|
|
|
popf();
|
|
|
|
sti();
|
2018-08-20 16:35:36 +02:00
|
|
|
asm("addl $0x0C, %esp;");
|
2018-08-17 16:46:56 +02:00
|
|
|
iret();
|
|
|
|
}
|
|
|
|
|
|
|
|
void irq3()
|
|
|
|
{
|
|
|
|
cli();
|
|
|
|
pushf();
|
|
|
|
pushad();
|
|
|
|
print("irq 3");
|
|
|
|
irqendmaster();
|
|
|
|
popad();
|
|
|
|
popf();
|
|
|
|
sti();
|
2018-08-20 16:35:36 +02:00
|
|
|
asm("addl $0x0C, %esp;");
|
2018-08-17 16:46:56 +02:00
|
|
|
iret();
|
|
|
|
}
|
|
|
|
|
|
|
|
void irq4()
|
|
|
|
{
|
|
|
|
cli();
|
|
|
|
pushf();
|
|
|
|
pushad();
|
|
|
|
print("irq 4");
|
|
|
|
irqendmaster();
|
|
|
|
popad();
|
|
|
|
popf();
|
|
|
|
sti();
|
2018-08-20 16:35:36 +02:00
|
|
|
asm("addl $0x0C, %esp;");
|
2018-08-17 16:46:56 +02:00
|
|
|
iret();
|
|
|
|
}
|
|
|
|
|
|
|
|
void irq5()
|
|
|
|
{
|
|
|
|
cli();
|
|
|
|
pushf();
|
|
|
|
pushad();
|
|
|
|
print("irq 5");
|
|
|
|
irqendmaster();
|
|
|
|
popad();
|
|
|
|
popf();
|
|
|
|
sti();
|
2018-08-20 16:35:36 +02:00
|
|
|
asm("addl $0x0C, %esp;");
|
2018-08-17 16:46:56 +02:00
|
|
|
iret();
|
|
|
|
}
|
|
|
|
|
|
|
|
void irq6()
|
|
|
|
{
|
|
|
|
cli();
|
|
|
|
pushf();
|
|
|
|
pushad();
|
|
|
|
print("irq 6");
|
|
|
|
irqendmaster();
|
|
|
|
popad();
|
|
|
|
popf();
|
|
|
|
sti();
|
2018-08-20 16:35:36 +02:00
|
|
|
asm("addl $0x0C, %esp;");
|
2018-08-17 16:46:56 +02:00
|
|
|
iret();
|
|
|
|
}
|
|
|
|
|
|
|
|
void irq7()
|
|
|
|
{
|
|
|
|
cli();
|
|
|
|
pushf();
|
|
|
|
pushad();
|
|
|
|
print("irq 7");
|
|
|
|
irqendmaster();
|
|
|
|
popad();
|
|
|
|
popf();
|
|
|
|
sti();
|
2018-08-20 16:35:36 +02:00
|
|
|
asm("addl $0x0C, %esp;");
|
2018-08-17 16:46:56 +02:00
|
|
|
iret();
|
|
|
|
}
|
|
|
|
|
|
|
|
void irq8()
|
|
|
|
{
|
|
|
|
cli();
|
|
|
|
pushf();
|
|
|
|
pushad();
|
|
|
|
print("irq 8");
|
|
|
|
irqendslave();
|
|
|
|
irqendmaster();
|
|
|
|
popad();
|
|
|
|
popf();
|
|
|
|
sti();
|
2018-08-20 16:35:36 +02:00
|
|
|
asm("addl $0x0C, %esp;");
|
2018-08-17 16:46:56 +02:00
|
|
|
iret();
|
|
|
|
}
|
|
|
|
|
|
|
|
void irq9()
|
|
|
|
{
|
|
|
|
cli();
|
|
|
|
pushf();
|
|
|
|
pushad();
|
|
|
|
print("irq 9");
|
|
|
|
irqendslave();
|
|
|
|
irqendmaster();
|
|
|
|
popad();
|
|
|
|
popf();
|
|
|
|
sti();
|
2018-08-20 16:35:36 +02:00
|
|
|
asm("addl $0x0C, %esp;");
|
2018-08-17 16:46:56 +02:00
|
|
|
iret();
|
|
|
|
}
|
|
|
|
|
|
|
|
void irq10()
|
|
|
|
{
|
|
|
|
cli();
|
|
|
|
pushf();
|
|
|
|
pushad();
|
|
|
|
print("irq 10");
|
|
|
|
irqendslave();
|
|
|
|
irqendmaster();
|
|
|
|
popad();
|
|
|
|
popf();
|
|
|
|
sti();
|
2018-08-20 16:35:36 +02:00
|
|
|
asm("addl $0x0C, %esp;");
|
2018-08-17 16:46:56 +02:00
|
|
|
iret();
|
|
|
|
}
|
|
|
|
|
|
|
|
void irq11()
|
|
|
|
{
|
|
|
|
cli();
|
|
|
|
pushf();
|
|
|
|
pushad();
|
|
|
|
print("irq 11");
|
|
|
|
irqendslave();
|
|
|
|
irqendmaster();
|
|
|
|
popad();
|
|
|
|
popf();
|
|
|
|
sti();
|
2018-08-20 16:35:36 +02:00
|
|
|
asm("addl $0x0C, %esp;");
|
2018-08-17 16:46:56 +02:00
|
|
|
iret();
|
|
|
|
}
|
|
|
|
|
|
|
|
void irq12()
|
|
|
|
{
|
|
|
|
cli();
|
|
|
|
pushf();
|
|
|
|
pushad();
|
|
|
|
print("irq 12");
|
|
|
|
while ((inb(0x64) & 1) == 0) ;
|
|
|
|
inb(0x60);
|
|
|
|
irqendslave();
|
|
|
|
irqendmaster();
|
|
|
|
popad();
|
|
|
|
popf();
|
|
|
|
sti();
|
2018-08-20 16:35:36 +02:00
|
|
|
asm("addl $0x1C, %esp;");
|
2018-08-17 16:46:56 +02:00
|
|
|
iret();
|
|
|
|
}
|
|
|
|
|
|
|
|
void irq13()
|
|
|
|
{
|
|
|
|
cli();
|
|
|
|
pushf();
|
|
|
|
pushad();
|
|
|
|
print("irq 13");
|
|
|
|
irqendslave();
|
|
|
|
irqendmaster();
|
|
|
|
popad();
|
|
|
|
popf();
|
|
|
|
sti();
|
2018-08-20 16:35:36 +02:00
|
|
|
asm("addl $0x0C, %esp;");
|
2018-08-17 16:46:56 +02:00
|
|
|
iret();
|
|
|
|
}
|
|
|
|
|
|
|
|
void irq14()
|
|
|
|
{
|
|
|
|
cli();
|
|
|
|
pushf();
|
|
|
|
pushad();
|
|
|
|
print("irq 14");
|
|
|
|
irqendslave();
|
|
|
|
irqendmaster();
|
|
|
|
popad();
|
|
|
|
popf();
|
|
|
|
sti();
|
2018-08-20 16:35:36 +02:00
|
|
|
asm("addl $0x0C, %esp;");
|
2018-08-17 16:46:56 +02:00
|
|
|
iret();
|
|
|
|
}
|
|
|
|
|
|
|
|
void irq15()
|
|
|
|
{
|
|
|
|
cli();
|
|
|
|
print("irq 15");
|
|
|
|
irqendslave();
|
|
|
|
irqendmaster();
|
|
|
|
popad();
|
|
|
|
popf();
|
|
|
|
sti();
|
2018-08-20 16:35:36 +02:00
|
|
|
asm("addl $0x0C, %esp;");
|
2018-08-17 16:46:56 +02:00
|
|
|
iret();
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
/* Initialise une IDT */
|
|
|
|
|
|
|
|
void initidt(void)
|
|
|
|
{
|
|
|
|
u16 i;
|
2018-10-04 14:55:41 +02:00
|
|
|
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);
|
2018-08-17 16:46:56 +02:00
|
|
|
for (i = 19; i < 32; i++) {
|
2018-10-04 14:55:41 +02:00
|
|
|
putidt((u32) interruption, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING3 | TRAPGATE, i);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
2018-10-04 14:55:41 +02: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);
|
2018-08-17 16:46:56 +02:00
|
|
|
for (i = 40; i < 96; i++) {
|
2018-10-04 14:55:41 +02:00
|
|
|
putidt((u32) interruption, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING3 | TRAPGATE, i);
|
2018-08-17 16:46:56 +02:00
|
|
|
}
|
2018-10-04 14:55:41 +02: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);
|
2018-10-02 02:16:14 +02:00
|
|
|
for (i = 104; i < IDT_SIZE; i++) {
|
2018-10-04 14:55:41 +02:00
|
|
|
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-09-27 17:47:27 +02:00
|
|
|
outb(TIMER_MODE, RATE_GENERATOR);
|
|
|
|
outb(TIMER0, (u8) (TIMER_FREQ / HZ));
|
|
|
|
outb(TIMER0, (u8) ((TIMER_FREQ / HZ) >> 8));
|
2018-08-28 15:22:43 +02:00
|
|
|
}
|
2018-09-28 20:35:51 +02:00
|
|
|
/*******************************************************************************/
|