//Functions.c //05/07/03 Josh Holtrop //for HOS //Modified: 10/30/03 //Writes a byte out to a port inline void outportb(unsigned int port, unsigned char value) // Output a byte to a port { asm volatile ("outb %%al,%%dx"::"d" (port), "a" (value)); }; //Writes a word out to a port inline void outportw(unsigned int port, unsigned int value) // Output a word to a port { asm volatile ("outw %%ax,%%dx"::"d" (port), "a" (value)); }; //Reads a byte from a port inline byte inportb(unsigned short port) { unsigned char ret_val; asm volatile("inb %w1,%b0" : "=a"(ret_val) : "d"(port)); return ret_val; }; //Enables (SeTs) Interrupt Flag on the processor inline void enable_ints() { asm("sti"); }; //Disables (CLears) Interrupt Flag on the processor inline void disable_ints() { asm("cli"); }; //Re-maps the Programmable Interrupr Controllers so IRQ0->pic1 base address, IRG8->pic2 base address void remap_pics(int pic1, int pic2) { byte a1, a2; a1 = inportb(PIC1_DATA); //0x21 a2 = inportb(PIC2_DATA); //0xA1 outportb(PIC1_COMMAND, ICW1_INIT+ICW1_ICW4); //0x20, 0x10+0x01 00010001b outportb(PIC2_COMMAND, ICW1_INIT+ICW1_ICW4); //0xA0, 0x10+0x01 00010001b outportb(PIC1_DATA, pic1); //0x21, pic1 outportb(PIC2_DATA, pic2); //0xA1, pic2 outportb(PIC1_DATA, 4); //0x21, 0x04 00000100b outportb(PIC2_DATA, 2); //0xA1, 0x02 00000010b outportb(PIC1_DATA, ICW4_8086); //0x21, 0x01 00000001b outportb(PIC2_DATA, ICW4_8086); //0xA1, 0x01 00000001b outportb(PIC1_DATA, a1); //0x21 outportb(PIC2_DATA, a2); //0xA1 } //Masks interrupts on first Programmable Interrupt Controller inline void pic1_mask(byte mask) { outportb(PIC1_DATA, mask); //0x21, maskfield *OCW1* } //Masks interrupts on second Programmable Interrupt Controller inline void pic2_mask(byte mask) { outportb(PIC2_DATA, mask); //0xA1, maskfield *OCW1* } //Restarts the computer inline void restart() { enable_ints(); byte temp; do { temp = inportb(0x64); if (temp & 1) inportb(0x60); } while(temp & 2); outportb (0x64, 0xfe); for (;;) { } } //Halts (freezes) the computer inline void halt() { asm("cli"); asm("hlt"); while (1) ; } //Initializes 8253 Programmable Interrupt Timer inline void init_timer() { //set timer : 2e9c = 100hz outportb(0x43, 0x34); outportb(0x40, 0x9c); //lsb outportb(0x40, 0x2e); //msb } //Invalidates the page tables to re-cache the Translation Lookaside Buffer /*inline void invlpg() { asm("invlpg"); }*/ //Signals an End Of Interrupt signal to the first PIC inline void eoi() { outportb(0x20, 0x20); } //Signals an End Of Interrupt signal to both the second and first PIC unit inline void eoi2() { outportb(0xA0, 0x20); outportb(0x20, 0x20); } //Returns the size of the kernel (code & data) // - this does not include the bss section // - this should be 4kb aligned per the linker script // - this should be the size of kernel.bin inline dword kernel_size() { return (dword)(&_bss)-(dword)(&_code); }