Commit 3e410fcd by triazo

Merge branch 'PICPIT' into 'master'

PICPIT



See merge request !14
parents 2e2aa845 133caddd
......@@ -19,3 +19,13 @@ inline uint8_t inb(uint16_t port)
asm volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}
inline void disable_int()
{
asm volatile ("cli");
}
inline void enable_int()
{
asm volatile ("sti");
}
......@@ -45,20 +45,28 @@ void load_error_handlers()
void default_handler(struct reg_state reg, uint32_t interrupt, uint32_t error, struct stack_state stack)
{
/*for(uint32_t i=stack.eip-16;i<=stack.eip+16;i+=4)
{
serial_hexword(i);
serial_writestring(": ");
serial_hexword(*((uint32_t*)(void*)i));
serial_writestring("\n");
}*/
if(interrupt<32)
stack.eip+=2;
serial_writestring("int caught ");
char f[20];
serial_val(interrupt);
serial_val(error);
serial_val(stack.eip);
serial_val(stack.cd);
serial_val(stack.eflags);
serial_writestring("\n");
//serial_writestring("int caught ");
//char f[20];
//serial_val(interrupt);
//serial_hexword(error);serial_writestring(" ");
//serial_hexword(stack.eip);serial_writestring(" ");
//serial_val(stack.cd);
//serial_val(stack.eflags);
//serial_writestring("\n");
if(handlers[interrupt]!=NULL)
{
handlers[interrupt](error);
}
//asm("hlt");
return;
}
......
#include "io.h"
#include "pic.h"
#include "serial.h"
#include "idt.h"
char scan_map[256] = {' ','E','1','2','3','4','5','6','7','8','9','0','-','=','\b','\t','q','w','e','r','t','y','u','i','o','p',
'[',']','\n','^','a','s','d','f','g','h','j','k','l',';','\'','`','S','\\','z','x','c','v','b','n','m',
',','.','/','S','O','A',' ','C','F','F','F','F','F','F','F','F','F','F','L','L',};
void kbd_irq()
{
int a = inb(0x60);
serial_hexword(a);
if(a==0x4b)
terminal_adjustcursor(-1,0);
else if(a==0x4d)
terminal_adjustcursor(1,0);
else if(a==0x48)
terminal_adjustcursor(0,-1);
else if(a==0x50)
terminal_adjustcursor(0,1);
else if(a<0x80)
terminal_putchar(scan_map[a]);
//else
//terminal_putchar(scan_map[a-0x80]);
serial_writestring("\n");
pic_command(0, PIC_OCW2_EOI);
}
void io_init()
{
install_c_ir(33, kbd_irq);
}
#ifndef _IO_INC
#define _IO_INC
void kbd_irq();
void io_init();
#endif
......@@ -15,6 +15,9 @@
#include "idt.h"
#include "test.h"
#include "multiboot.h"
#include "pic.h"
#include "pit.h"
#include "io.h"
// The parameters passed here ultimately come through the bootloader
void kernel_main(multiboot_info* mbt, uint32_t magic)
......@@ -24,12 +27,20 @@ void kernel_main(multiboot_info* mbt, uint32_t magic)
serial_init();
gdt_init();
idt_init(0x8);
serial_writestring("IDT initialized\n");
disable_int();
pic_init(0x20,0x28);
pit_init();
io_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
* yet, '\n' will produce some VGA specific character instead.
* This is normal.
*/
serial_writestring("IDT initialized\n");
serial_writestring("Hello, kernel World!\n");
terminal_writestring("Hello, kernel World!\n");
// Abort if magic is not correct.
......@@ -49,7 +60,11 @@ void kernel_main(multiboot_info* mbt, uint32_t magic)
serial_writestring("Finished Initilizing memory\n");
int o=0;
int j=5/o;
serial_hexword(j);
serial_hexword(j);
test_mem();
test_idt();
while(true)
{
asm("hlt");
}
}
......@@ -48,7 +48,7 @@ void populate_page_table(page_table_entry* table, void* start, int num, int offs
// TODO: put this as a label at the end of the code, so we can take
// its address
#define KERN_END 0x104000
#define KERN_END 0x204000
page_directory_entry* mem_init_kern_tables(multiboot_memory_map* mmap, multiboot_memory_map* mmap_end)
{
......
#include "pic.h"
#include "asm.h"
#pragma GCC push_options
#pragma GCC optimize ("0")
uint8_t pic_read(uint16_t pic)
{
if(pic>1)
{
return 0;
}
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);
}
#pragma GCC pop_options
#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
//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);
#endif
#include "pit.h"
#include "pic.h"
#include "idt.h"
#include "asm.h"
#include "serial.h"
#pragma GCC push_options
#pragma GCC optimize ("0")
static volatile uint32_t _pit_ticks = 0;
static bool _pit_is_init = false;
void pit_irq()
{
//asm volatile ("pusha");
_pit_ticks++;
//serial_writestring("PIT tick\n");
pic_command(0, PIC_OCW2_EOI);
//serial_writestring("PIT tickn\n");
//asm volatile("nop;nop;nop;popa; iret;");
}
void pit_command(uint8_t cmd)
{
outb(PIT_REG_COMD, cmd);
}
void pit_write(uint16_t data, uint8_t counter)
{
uint16_t port= (counter == PIT_OCW_CONT_0) ? PIT_REG_CONT_0 :
((counter == PIT_OCW_CONT_1) ? PIT_REG_CONT_1 : PIT_REG_CONT_2);
outb(port, (uint8_t)data);
}
uint8_t pit_read(uint16_t counter)
{
uint16_t port= (counter == PIT_OCW_CONT_0) ? PIT_REG_CONT_0 :
((counter == PIT_OCW_CONT_1) ? PIT_REG_CONT_1 : PIT_REG_CONT_2);
return inb(port);
}
uint32_t pit_set_tick(uint32_t i)
{
uint32_t ret = _pit_ticks;
_pit_ticks = i;
return ret;
}
uint32_t pit_get_tick()
{
return _pit_ticks;
}
void pit_start_counter(uint32_t freq, uint8_t counter, uint8_t mode)
{
if(freq == 0)
{
return;
}
uint16_t div = (uint16_t)(1193181 / (uint16_t)freq);
uint8_t ocw = 0;
ocw = (ocw & ~PIT_OCW_MODE) | mode;
ocw = (ocw & ~PIT_OCW_RL) | PIT_OCW_RL_DATA;
ocw = (ocw & ~PIT_OCW_CONT) | counter;
pit_command(ocw);
pit_write(div & 0xFF, 0);
pit_write((div >> 8)& 0xFF, 0);
_pit_ticks = 0;
}
void pit_init()
{
//install_ir(32, IDT_PR|IDT_32, 0x8, pit_irq);
install_c_ir(32, pit_irq);
_pit_is_init = true;
}
bool pit_is_init()
{
return _pit_is_init;
}
#pragma GCC pop_options
#ifndef _PIT_INC
#define _PIT_INC
#include <stdint.h>
#include <stdbool.h>
//OCW masks
#define PIT_OCW_BINC 0x01
#define PIT_OCW_MODE 0x0E
#define PIT_OCW_RL 0x30
#define PIT_OCW_CONT 0xC0
//OCW control bits
#define PIT_OCW_BINC_BIN 0x0
#define PIT_OCW_BINC_BCD 0x1
#define PIT_OCW_MODE_TERMCNT 0x0
#define PIT_OCW_MODE_ONESHOT 0x2
#define PIT_OCW_MODE_RATEGEN 0x4
#define PIT_OCW_MODE_SQWVGEN 0x6
#define PIT_OCW_MODE_SOFTTRG 0x8
#define PIT_OCW_MODE_HARDTRG 0xA
#define PIT_OCW_RL_LATH 0x00
#define PIT_OCW_RL_LSB 0x10
#define PIT_OCW_RL_MSB 0x20
#define PIT_OCW_RL_DATA 0x30
#define PIT_OCW_CONT_0 0x00
#define PIT_OCW_CONT_1 0x40
#define PIT_OCW_CONT_2 0x80
#define PIT_REG_CONT_0 0x40
#define PIT_REG_CONT_1 0x41
#define PIT_REG_CONT_2 0x42
#define PIT_REG_COMD 0x43
void pit_command(uint8_t cmd);
void pit_write(uint16_t data, uint8_t counter);
uint8_t pit_read(uint16_t counter);
uint32_t pit_set_tick(uint32_t i);
uint32_t pit_get_tick();
void pit_start_counter(uint32_t frequency, uint8_t counter, uint8_t mode);
void pit_init();
bool pit_is_init();
#endif
......@@ -5,6 +5,7 @@
*/
#include "term.h"
#include "asm.h"
uint8_t make_color(enum vga_color fg, enum vga_color bg)
{
......@@ -26,6 +27,15 @@ size_t terminal_column;
uint8_t terminal_color;
uint16_t* terminal_buffer;
void update_csr()
{
unsigned temp = terminal_row*80+terminal_column;
outb(0x3D4,14);
outb(0x3D5,temp>>8);
outb(0x3D4, 15);
outb(0x3D5, temp);
}
void terminal_initialize()
{
terminal_row = 0;
......@@ -55,15 +65,38 @@ void terminal_putentryat(char c, uint8_t color, size_t x, size_t y)
void terminal_putchar(char c)
{
terminal_putentryat(c, terminal_color, terminal_column, terminal_row);
if (++terminal_column == VGA_WIDTH)
if(c=='\b')
{
terminal_column = 0;
if (++terminal_row == VGA_HEIGHT)
if(terminal_column == 0)
{
terminal_row = 0;
terminal_row--;
terminal_column=VGA_WIDTH;
}
terminal_column--;
terminal_putentryat(' ',terminal_color, terminal_column,terminal_row);
}
else if(c=='\n')
{
terminal_column=0;
terminal_row++;
}
else if(c=='\t')
{
terminal_writestring(" ");
}
else
{
terminal_putentryat(c, terminal_color, terminal_column, terminal_row);
if (++terminal_column == VGA_WIDTH)
{
terminal_column = 0;
if (++terminal_row == VGA_HEIGHT)
{
terminal_row = 0;
}
}
}
update_csr();
}
void terminal_writestring(const char* data)
......@@ -74,3 +107,18 @@ void terminal_writestring(const char* data)
terminal_putchar(data[i]);
}
}
void terminal_movecursor(size_t x, size_t y)
{
if(x>=VGA_WIDTH || y>= VGA_HEIGHT) return;
terminal_column=x;
terminal_row=y;
update_csr();
}
void terminal_adjustcursor(int x, int y)
{
terminal_column+=x;
terminal_row+=y;
if(terminal_column>VGA_WIDTH) terminal_column=VGA_WIDTH;
if(terminal_row>VGA_HEIGHT) terminal_row=VGA_HEIGHT;
update_csr();
}
......@@ -36,3 +36,5 @@ void terminal_setcolor(uint8_t color);
void terminal_putentryat(char c, uint8_t color, size_t x, size_t y);
void terminal_putchar(char c);
void terminal_writestring(const char* data);
void terminal_movecursor(size_t x, size_t y);
void terminal_adjustcursor(int x, int y);
......@@ -8,7 +8,6 @@ void test_idt()
{
asm ("int $0x80");
asm ("int $0x90");
asm ("hlt");
}
void test_mem()
......
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