Commit 9aaa9875 by malcolm

Added PIC code and init in kernel. Needs PIT to function.

parent 2e2aa845
Showing with 170 additions and 3 deletions
...@@ -19,3 +19,13 @@ inline uint8_t inb(uint16_t port) ...@@ -19,3 +19,13 @@ inline uint8_t inb(uint16_t port)
asm volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port)); asm volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret; return ret;
} }
inline void disable_int()
{
asm volatile ("cli");
}
inline void enable_int()
{
asm volatile ("sti");
}
...@@ -15,7 +15,8 @@ ...@@ -15,7 +15,8 @@
#include "idt.h" #include "idt.h"
#include "test.h" #include "test.h"
#include "multiboot.h" #include "multiboot.h"
#include "pic.h"
#include "pit.h"
// The parameters passed here ultimately come through the bootloader // The parameters passed here ultimately come through the bootloader
void kernel_main(multiboot_info* mbt, uint32_t magic) void kernel_main(multiboot_info* mbt, uint32_t magic)
{ {
...@@ -24,12 +25,18 @@ void kernel_main(multiboot_info* mbt, uint32_t magic) ...@@ -24,12 +25,18 @@ void kernel_main(multiboot_info* mbt, uint32_t magic)
serial_init(); serial_init();
gdt_init(); gdt_init();
idt_init(0x8); idt_init(0x8);
serial_writestring("IDT initialized\n");
disable_int();
pic_init(0x20,0x28);
pit_init();
pit_start_counter(100, PIT_OCW_CONT_0, PIT_OCW_MODE_SQWVGEN);
enable_int();
/* Since there is no support for newlines in terminal_putchar /* Since there is no support for newlines in terminal_putchar
* yet, '\n' will produce some VGA specific character instead. * yet, '\n' will produce some VGA specific character instead.
* This is normal. * This is normal.
*/ */
serial_writestring("IDT initialized\n");
serial_writestring("Hello, kernel World!\n");
terminal_writestring("Hello, kernel World!\n"); terminal_writestring("Hello, kernel World!\n");
// Abort if magic is not correct. // Abort if magic is not correct.
......
#include "pic.h"
#include "asm.h"
uint8_t pic_read(uint16_t pic)
{
if(pic>1)
{
return;
}
uint16_t reg = (pic==0)? PIC1_REG_DATA:PIC2_REG_DATA;
return inb(reg);
}
void pic_write(uint16_t pic, uint8_t data)
{
if(pic>1)
{
return;
}
uint16_t reg = (pic==0)? PIC1_REG_DATA:PIC2_REG_DATA;
outb(reg, data);
}
void pic_command(uint16_t pic, uint8_t cmd)
{
if(pic>1)
{
return;
}
uint16_t reg = (pic==0)? PIC1_REG_COMD:PIC2_REG_COMD;
outb(reg, cmd);
}
//void pic_mask_irq(uint16_t pic, uint8_t irqmask)
//{
// //TODO
//}
void pic_init(uint8_t base0, uint8_t base1)
{
uint8_t icw=0;
//enab,e init and expect mode on both
icw = (icw & ~PIC_ICW1_INIT) | PIC_ICW1_INIT_YES;
icw = (icw & ~PIC_ICW1_IC4) | PIC_ICW1_IC4_EXPECT;
pic_command(0, icw);
pic_command(1, icw);
//send ICW2 (base irq address)
pic_write(0, base0);
pic_write(1, base1);
//now for magic flags to make the PICs connect
pic_write(0,0x04);
pic_write(1,0x02);
//enable x86 mode on PICs
icw = (icw & ~PIC_ICW4_UPM) | PIC_ICW4_UPM_86;
pic_write(0, icw);
pic_write(1, icw);
}
#ifndef _PIC_INC
#define _PIC_INC
#include <stdint.h>
//PIC 1
#define PIC_IRQ_TIMER 0
#define PIC_IRQ_KEYBD 1
#define PIC_IRQ_SERL2 3
#define PIC_IRQ_SERL1 4
#define PIC_IRQ_PARL2 5
#define PIC_IRQ_DISKT 6
#define PIC_IRQ_PARL1 7
//PIC 2
#define PIC_IRQ_CMOST 0
#define PIC_IRQ_CGART 1
#define PIC_IRQ_AUXIL 4
#define PIC_IRQ_FPU 5
#define PIC_IRQ_HDC 6
#endif
//OCW2 masks
#define PIC_OCW2_L1 0x01
#define PIC_OCW2_L2 0x02
#define PIC_OCW2_L3 0x04
#define PIC_OCW2_EOI 0x20
#define PIC_OCW2_SL 0x40
#define PIC_OCW2_ROT 0x80
//OCW3 masks
#define PIC_OCW3_RIS 0x01
#define PIC_OCW3_RIR 0x02
#define PIC_OCW3_MODE 0x04
#define PIC_OCW3_SMM 0x20
#define PIC_OCW3_ESMM 0x40
#define PIC_OCW3_D7 0x80
//PIC1 reg ports
#define PIC1_REG_COMD 0x20
#define PIC1_REG_STAT 0x20
#define PIC1_REG_DATA 0x21
#define PIC1_REG_IMR 0x21
//PIC2 reg ports
#define PIC2_REG_COMD 0xA0
#define PIC2_REG_STAT 0xA0
#define PIC2_REG_DATA 0xA1
#define PIC2_REG_IMR 0xA1
//ICW1 masks
#define PIC_ICW1_IC4 0x01
#define PIC_ICW1_SNGL 0x02
#define PIC_ICW1_ADI 0x04
#define PIC_ICW1_LRIM 0x08
#define PIC_ICW1_INIT 0x10
//ICW4 masks
#define PIC_ICW4_UPM 0x01
#define PIC_ICW4_AEOI 0x02
#define PIC_ICW4_MS 0x04
#define PIC_ICW4_BUF 0x08
#define PIC_ICW4_SFNM 0x10
//ICW1 control bits
#define PIC_ICW1_IC4_EXPECT 0x01
#define PIC_ICW1_IC4_NO 0x00
#define PIC_ICW1_SNGL_YES 0x02
#define PIC_ICW1_SNGL_NO 0x00
#define PIC_ICW1_ADI_INTVL4 0x04
#define PIC_ICW1_ADI_INTVL8 0x00
#define PIC_ICW1_LTIM_LEVEL 0x08
#define PIC_ICW1_LTIM_EDGE 0x00
#define PIC_ICW1_INIT_YES 0x10
#define PIC_ICW1_INIT_NO 0x00
//ICW4 control bits
#define PIC_ICW4_UPM_86 0x01
#define PIC_ICW4_UPM_MCS 0x00
#define PIC_ICW4_AEOI_AUTO 0x02
#define PIC_ICW4_AEOI_NO 0x00
#define PIC_ICW4_MS_MASTER 0x04
#define PIC_ICW4_MS_SLAVE 0x00
#define PIC_ICW4_BUF_YES 0x08
#define PIC_ICW4_BUF_NO 0x00
#define PIC_ICW4_SFNM_NEST 0x10
#define PIC_ICW4_SFNM_NOT 0x00
uint8_t pic_read(uint16_t pic);
void pic_write(uint16_t pic, uint8_t data);
void pic_command(uint16_t pic, uint8_t cmd);
void pic_mask_irq(uint16_t pic, uint8_t irqmask);
void pic_init(uint8_t base0, uint8_t base1);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment