#include <types64.h>
struct __attribute__ ((__packed__)) isr
{
	u_int16_t offset_ll;
	u_int16_t selector;
	int 	present	:1;
	int	pl	:2;
	int	zero	:1;
	int 	type	:4;
	int	reserved1:5;
	int	ist	:3;
	u_int16_t offset_lh;
	u_int32_t offset_high;
	u_int32_t reserved0;
} ;

struct __attribute__ ((__packed__)) isr_tbl_desc
{
	u_int16_t size;
	int64_t addr;
} ;

struct __attribute__ ((__packed__)) isr_info
{
	u_int8_t num;
	int64_t addr;
};

struct __attribute__ ((__packed__)) mp_float_p
{
	char sig[4];
	u_int32_t ptr;
	u_int8_t len;
	u_int8_t rev;
	u_int8_t cksum;
	u_int8_t features[5];
};

typedef void (*isr_t) ();

void def_int();
void * find_MP();
void init_leg_irq();
void init_apic();

extern struct isr_info * isr;
extern u_int8_t isr_size;
isr_t ints[255] = {&def_int};

struct mp_float_p * mp_p;



void def_int()
{
	panic("kernel panic, run away interrupt on the loose");
}

void isr_init ()
{		
	if((mp_p = find_MP()) == 0)
	{
		cons_writes("initializing legacy irq");
		init_leg_irq();
	}
	else
	{
		cons_writes("Muliprocessing Pointer Found:");
		write_numh(mp_p);
		cons_write("\n",1);
		cons_write(mp_p,4);
		cons_writes("\n");
		cons_writes("MP pointer version: ");
		write_numh(mp_p->rev);
		cons_writes("\n");
		cons_writes("MP pointer type: ");
		write_numh(mp_p->features[0]);
		cons_writes("\n");
		cons_writes("initializing apic\n");
		init_apic();
	}
}

void * find_MP()
{
	//search the first kilobyte
	char * ret;
	char * i;
	int64_t sum;
	ret = strstrn_n(0x9fc00,0x400,"_MP_",4);
	if(ret == 0)
		ret = strstrn_n(0xf0000,0x0FFFF,"_MP_",4);
	for(i = ret,sum = 0; i < sizeof(struct mp_float_p);++i)
	{
		sum += *i;
	}
	if(sum == 0)
		return ret;
	//return 0;
}

void init_leg_irq()
{
	//icw1
	outb(0x20,0x11);
	outb(0xA0,0x11);
	//icw2
	outb(0x21,0x20);
	outb(0xA1,0x28);
	//icw3
	outb(0x21,0x4);
	outb(0xA1,0x2);
	//icw4
	outb(0x21,0x1);
	outb(0xA1,0x1);
	//enable all interrupts
	outb(0x21,0x00);
	outb(0xA1,0x00);
}

void init_apic()
{
}
