cos2000v2/include/interrupts.h

303 lines
7.6 KiB
C

/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */
#include "types.h"
#include "asm.h"
#ifndef _INTERRUPTS
#define _INTERRUPTS
#define PIC1_CMD 0x20 /*PIC 8259A Commandes n°1 */
#define PIC1_DATA 0x21 /*PIC 8259A Données n°1 */
#define PIC2_CMD 0xa0 /*PIC 8259A Commandes n°2 */
#define PIC2_DATA 0xa1 /*PIC 8259A Données n°1 */
#define ICW1_ICW4 0x01 /* ICW4 ou pas*/
#define ICW1_SINGLE 0x02 /* mode seul ou cascadé */
#define ICW1_INTERVAL4 0x04 /* adresses appel d'interval 4 ou 8 */
#define ICW1_LEVEL 0x08 /* déclenchement sur niveau ou sur front */
#define ICW1_INIT 0x10 /* Initialization */
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
#define ICW4_AUTO 0x02 /* Auto EOI ou normal */
#define ICW4_BUF_SLAVE 0x08 /* mode/slave avec tampon*/
#define ICW4_BUF_MASTER 0x0C /* mode/master avec tampon*/
#define ICW4_SFNM 0x10 /* Complètement lié ou non */
#define INTGATE 0x0E00 /* utilise pour gerer les interruptions */
#define TRAPGATE 0x0F00 /* utilise pour faire des appels systemes */
#define TASKGATE 0x0500 /* utilise pour commuter des taches */
#define CALLGATE 0x0C00 /* utilise pour appeler du code */
#define LDTDES 0x0200 /* utilise pour pointer une LDT */
#define ENTRY_PRESENT 0b1000000000000000 /* Segment défini (obligatoire) */
#define ENTRY_STORAGE 0b0001000000000000 /* Segment défini (obligatoire) */
#define ENTRY_RING0 0b0000000000000000 /* Segment anneau 0 */
#define ENTRY_RING1 0b0010000000000000 /* Segment anneau 1 */
#define ENTRY_RING2 0b0100000000000000 /* Segment anneau 2 */
#define ENTRY_RING3 0b0110000000000000 /* Segment anneau 3 */
/* 00-11-010-0 : Compteur 0 - LSB puis MSB - generateur taux - binaire */
#define TIMER0 0x40 /* port E/S pour le timer canal 0 */
#define TIMER_MODE 0x43 /* port E/S pour le mode controle du timer */
#define RATE_GENERATOR 0x34 /* générateur de fréquence */
#define SQUARE_WAVE 0x36 /* générateur d'onde carrée */
#define TIMER_FREQ 1193180 /* fréquence pour timer dans un PC ou AT */
#define HZ 100 /* Fréquence d'horloge (ajutste logiciellement sur IBM-PC) */
#define getESP(mem) ({ \
asm volatile ("movl %%esp,%[tomem];":: [tomem] "m" (mem)); \
})
#define getEBP(mem) ({ \
asm volatile ("movl %%ebp,%[tomem];":: [tomem] "m" (mem)); \
})
#define createdump(dump) ({ \
push(dump.ss);\
push(dump.esp);\
push(dump.eflags);\
push(dump.cs);\
push(dump.eip);\
push(dump.ds);\
push(dump.es);\
push(dump.fs);\
push(dump.gs);\
push(dump.eax);\
push(dump.ebx);\
push(dump.ecx);\
push(dump.edx);\
push(dump.esi);\
push(dump.edi);\
push(dump.ebp);\
push(dump.cr0);\
push(dump.cr2);\
push(dump.cr3);\
push(dump.cr4);\
push(dump.dr0);\
push(dump.dr1);\
push(dump.dr2);\
push(dump.dr3);\
push(dump.dr6);\
push(dump.dr7);\
u32 eferlow=(u32) dump.efer & 0xFFFF;\
u32 eferhigh=(u32) dump.efer >> 32;\
push(eferlow);\
push(eferhigh);\
})
#define dumpcpu() ({ \
asm("\
pushl %%ss\n \
pushl %%esp\n \
pushf \n \
pushl %%cs\n \
pushl $0x0\n \
pushl %%ds\n \
pushl %%es\n \
pushl %%fs\n \
pushl %%gs\n \
pushl %%eax\n \
pushl %%ebx\n \
pushl %%ecx\n \
pushl %%edx\n \
pushl %%esi\n \
pushl %%edi\n \
pushl %%ebp\n \
mov %%cr0, %%eax \n \
pushl %%eax\n \
mov %%cr2, %%eax \n \
pushl %%eax\n \
mov %%cr3, %%eax \n \
pushl %%eax\n \
mov %%cr4, %%eax \n \
pushl %%eax \n \
mov %%dr0, %%eax \n \
pushl %%eax\n \
mov %%dr1, %%eax \n \
pushl %%eax\n \
mov %%dr2, %%eax \n \
pushl %%eax\n \
mov %%dr3, %%eax \n \
pushl %%eax\n \
mov %%dr6, %%eax \n \
pushl %%eax\n \
mov %%dr7, %%eax \n \
pushl %%eax\n \
mov $0xC0000080, %%ecx \n \
rdmsr \n \
pushl %%edx \n \
pushl %%eax":::);\
})
#define restcpu() ({\
asm("\
popl %%eax \n \
popl %%edx \n \
mov $0xC0000080, %%ecx \n \
wrmsr\n \
popl %%eax\n \
mov %%eax,%%dr7 \n \
popl %%eax \n \
mov %%eax,%%dr6 \n \
popl %%eax \n \
mov %%eax,%%dr3 \n \
popl %%eax \n \
mov %%eax,%%dr2 \n \
popl %%eax \n \
mov %%eax,%%dr1 \n \
popl %%eax \n \
mov %%eax,%%dr0 \n \
popl %%eax \n \
popl %%eax \n \
mov %%eax,%%cr3 \n \
popl %%eax \n \
popl %%eax \n \
popl %%ebp\n \
popl %%edi\n \
popl %%esi\n \
popl %%edx\n \
popl %%ecx\n \
popl %%ebx\n \
popl %%eax\n \
popl %%gs\n \
popl %%fs\n \
popl %%es\n \
popl %%ds\n \"::);\
})
#define restdebugcpu() ({\
asm("\
popl %%eax \n \
popl %%edx \n \
mov $0xC0000080, %%ecx \n \
wrmsr\n \
popl %%eax\n \
popl %%eax \n \
popl %%eax \n \
popl %%eax \n \
popl %%eax \n \
popl %%eax \n \
popl %%eax \n \
popl %%eax \n \
mov %%eax,%%cr3 \n \
popl %%eax \n \
popl %%eax \n \
popl %%ebp\n \
popl %%edi\n \
popl %%esi\n \
popl %%edx\n \
popl %%ecx\n \
popl %%ebx\n \
popl %%eax\n \
popl %%gs\n \
popl %%fs\n \
popl %%es\n \
popl %%ds":::);\
})
/*
lors d'un iret en mode user:
pushl %%ss\n \
pushl %%esp\n \
lors d'un iret en mode kernel:
pushf \n \
pushl $cs\n \
pushl $0x0\
*/
/* save pile */
typedef struct regs {
u64 efer;
u32 dr7;
u32 dr6;
u32 dr3;
u32 dr2;
u32 dr1;
u32 dr0;
u32 cr4;
u32 cr3;
u32 cr2;
u32 cr0;
u32 ebp;
u32 edi;
u32 esi;
u32 edx;
u32 ecx;
u32 ebx;
u32 eax;
u32 gs;
u32 fs;
u32 es;
u32 ds;
u32 eip;
u32 cs;
u32 eflags;
u32 esp;
u32 ss;
} regs __attribute__ ((packed));
/* exception pile depuis code kernel*/
typedef struct exception_stack {
u32 error_code;
u32 eip;
u32 cs;
u32 eflags;
} exception_stack __attribute__ ((packed));
/* sans code erreur depuis code kernel*/
typedef struct exception_stack_noerror {
u32 eip;
u32 cs;
u32 eflags;
} exception_stack_noerror __attribute__ ((packed));
/* exception pile depuis code user */
typedef struct exception_stack_user {
u32 error_code;
u32 eip;
u32 cs;
u32 eflags;
u32 esp;
u32 ss;
} exception_stack_user __attribute__ ((packed));
/* sans code erreu depuis code user */
typedef struct exception_stack_noerror_user {
u32 eip;
u32 cs;
u32 eflags;
u32 esp;
u32 ss;
} exception_stack_noerror_user __attribute__ ((packed));
/* descripteur de segment */
typedef struct idtdes {
u16 offset0_15;
u16 select;
u16 type;
u16 offset16_31;
} idtdes __attribute__ ((packed));
struct idtr {
u16 limite;
u32 base;
} __attribute__ ((packed));
void initretry(u32 address);
void initidt(void);
u32 getinitretry(void);
void setidt(u32 offset, u16 select, u16 type,u16 index);
void makeidtdes(u32 offset, u16 select, u16 type, idtdes* desc);
void initpic(void);
void enableirq(u8 irq);
void disableirq(u8 irq);
void cpuerror(const u8 * src, const regs *stack);
#endif