Skip to content

Commit efc5d73

Browse files
committed
Added PIT, PIC and HAL as well. PIT doesnt work yet.
1 parent a9c82d1 commit efc5d73

File tree

12 files changed

+268
-13
lines changed

12 files changed

+268
-13
lines changed

arch/idt.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <stdint.h>
33
#include "../include/x86/idt.h"
44
#include "../include/display.h"
5+
#include "../include/hal.h"
56

67
MODULE("IDT");
78

@@ -23,9 +24,9 @@ void idt_init()
2324
mprint("IDTR location: 0x%x\n", idtr_location);
2425
for(uint8_t i = 0; i < 255; i++)
2526
{
26-
idt_register_interrupt(i, __idt_default_handler);
27+
idt_register_interrupt(i, (uint32_t)&__idt_default_handler);
2728
}
28-
idt_register_interrupt(0x2f, __idt_test_handler);
29+
idt_register_interrupt(0x2f, (uint32_t)&__idt_test_handler);
2930
mprint("Registered all interrupts to default handler.\n");
3031
/* create IDTR now */
3132
*(uint16_t*)idtr_location = idt_size - 1;
@@ -34,12 +35,12 @@ void idt_init()
3435
_set_idtr();
3536
mprint("IDTR set, testing link.\n");
3637
asm volatile("int $0x2f");
37-
while(test_timeout != 0)
38+
while(test_timeout-- != 0)
3839
{
3940
if(test_success != 0)
4041
{
4142
mprint("Test succeeded, disabling INT#0x2F\n");
42-
idt_register_interrupt(0x2F, __idt_default_handler);
43+
idt_register_interrupt(0x2F, (uint32_t)&__idt_default_handler);
4344
break;
4445
}
4546
}
@@ -57,17 +58,20 @@ void __idt_test_handler()
5758

5859
void __idt_default_handler()
5960
{
61+
IRQ_START;
6062
panic("Unhandled interrupt!\n");
63+
//send_eoi(16);
64+
IRQ_END;
6165
}
6266

63-
void idt_register_interrupt(uint8_t i, void(*callback)())
67+
void idt_register_interrupt(uint8_t i, uint32_t callback)
6468
{
6569
idt_descriptor desc = {0};
66-
desc.offset_0_15 = (uint16_t)callback;
70+
desc.offset_0_15 = (uint16_t)(callback & 0x0000ffff);
6771
desc.selector = 0x8;
6872
desc.zero = 0;
69-
desc.type_attr = 0 | IDT_32BIT_INTERRUPT_GATE | IDT_DPL_3 | IDT_PRESENT;
70-
desc.offset_16_31 = (uint16_t)((uint32_t)callback >> 16);
73+
desc.type_attr = 0 | IDT_32BIT_INTERRUPT_GATE | IDT_PRESENT;
74+
desc.offset_16_31 = (uint16_t)(callback >> 16);
7175
/*mprint("Descriptor: id%d offset 0x%x, orig 0x%x\n",
7276
i,
7377
desc.offset_16_31 << 16 | desc.offset_0_15,
@@ -82,5 +86,6 @@ void add_idt_descriptor(uint8_t id, idt_descriptor desc)
8286
*(uint8_t*) (idt_location + sizeof(idt_descriptor)*id + 4) = desc.zero;
8387
*(uint8_t*) (idt_location + sizeof(idt_descriptor)*id + 5) = desc.type_attr;
8488
*(uint16_t*)(idt_location + sizeof(idt_descriptor)*id + 6) = desc.offset_16_31;
89+
if(test_success) mprint("Registered INT#%d\n", id);
8590
return;
8691
}

include/hal.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/** @author Levente Kurusa <[email protected]> **/
2+
#ifndef __HAL_H_
3+
#define __HAL_H_
4+
5+
#include <stdint.h>
6+
7+
#define INT_START asm volatile("pusha");
8+
#define INT_END asm volatile("popa"); \
9+
asm volatile("iret");
10+
11+
#define IRQ_START asm volatile("add $12, %esp");\
12+
asm volatile("pushal");
13+
14+
#define IRQ_END asm volatile("popal"); \
15+
asm volatile("iretl");
16+
extern void hal_init();
17+
18+
extern void send_eoi(uint8_t irq);
19+
20+
extern void set_int(int i, uint32_t addr);
21+
22+
extern uint8_t inportb(uint16_t portid);
23+
extern void outportb(uint16_t portid, uint8_t value);
24+
#endif

include/pic.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/** @author Levente Kurusa <[email protected]> **/
2+
#ifndef __PIC_H_
3+
#define __PIC_H_
4+
5+
#define PIC_MASTER_CMD 0x20
6+
#define PIC_MASTER_DATA 0x21
7+
#define PIC_SLAVE_CMD 0xA0
8+
#define PIC_SLAVE_DATA 0xA1
9+
10+
#define PIC_CMD_EOI 0x20
11+
12+
#include <stdint.h>
13+
14+
extern void pic_init();
15+
extern void pic_send_eoi(uint8_t irq);
16+
17+
#endif

include/pit.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/** @author Levente Kurusa <[email protected]> **/
2+
#ifndef __PIT_H_
3+
#define __PIT_H_
4+
5+
#define PIT_REG_COUNTER0 0x40
6+
#define PIT_REG_COUNTER1 0x41
7+
#define PIT_REG_COUNTER2 0x42
8+
#define PIT_REG_COMMAND 0x43
9+
10+
#define PIT_OCW_MASK_BINCOUNT 1 //00000001
11+
#define PIT_OCW_MASK_MODE 0xE //00001110
12+
#define PIT_OCW_MASK_RL 0x30 //00110000
13+
#define PIT_OCW_MASK_COUNTER 0xC0 //11000000
14+
15+
#define PIT_OCW_BINCOUNT_BINARY 0 //0
16+
#define PIT_OCW_BINCOUNT_BCD 1 //1
17+
18+
#define PIT_OCW_MODE_TERMINALCOUNT 0 //0000
19+
#define PIT_OCW_MODE_ONESHOT 0x2 //0010
20+
#define PIT_OCW_MODE_RATEGEN 0x4 //0100
21+
#define PIT_OCW_MODE_SQUAREWAVEGEN 0x6 //0110
22+
#define PIT_OCW_MODE_SOFTWARETRIG 0x8 //1000
23+
#define PIT_OCW_MODE_HARDWARETRIG 0xA //1010
24+
25+
#define PIT_OCW_RL_LATCH 0 //000000
26+
#define PIT_OCW_RL_LSBONLY 0x10 //010000
27+
#define PIT_OCW_RL_MSBONLY 0x20 //100000
28+
#define PIT_OCW_RL_DATA 0x30 //110000
29+
30+
#define PIT_OCW_COUNTER_0 0 //00000000
31+
#define PIT_OCW_COUNTER_1 0x40 //01000000
32+
#define PIT_OCW_COUNTER_2 0x80 //10000000
33+
34+
35+
36+
extern void pit_init();
37+
38+
#endif

include/x86/idt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ typedef struct {
2020
asm volatile("iret");
2121

2222
extern void idt_init();
23-
extern void idt_register_interrupt(uint8_t i, void(*callback)());
23+
extern void idt_register_interrupt(uint8_t i, uint32_t addr);
2424
extern void add_idt_descriptor(uint8_t id, idt_descriptor desc);
2525

2626
#endif

kernel.o

1.95 KB
Binary file not shown.

kernel/hal.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/** @author Levente Kurusa <[email protected]> **/
2+
#include "../include/hal.h"
3+
#include "../include/display.h"
4+
#include "../include/pic.h"
5+
#include "../include/x86/idt.h"
6+
7+
#include <stdint.h>
8+
9+
MODULE("HAL");
10+
11+
void hal_init()
12+
{
13+
mprint("Init done.\n");
14+
}
15+
16+
void send_eoi(uint8_t irq)
17+
{
18+
pic_send_eoi(irq);
19+
}
20+
21+
void set_int(int i, uint32_t addr)
22+
{
23+
mprint("Installing INT#%d to address: 0x%x\n", i, addr);
24+
idt_register_interrupt(i, addr);
25+
}
26+
27+
uint8_t inportb(uint16_t portid)
28+
{
29+
uint8_t ret;
30+
asm volatile("push %eax");
31+
asm volatile("push %edx");
32+
asm volatile("movw %0, %%dx":"=a"(portid));
33+
asm volatile("in %dx, %al");
34+
asm volatile("movb %%al, %0":"=a"(ret));
35+
asm volatile("pop %edx");
36+
asm volatile("pop %eax");
37+
return ret;
38+
}
39+
void outportb(uint16_t portid, uint8_t value)
40+
{
41+
asm volatile("push %eax");
42+
asm volatile("push %edx");
43+
asm volatile("mov %0, %%al":"=a"(value));
44+
asm volatile("mov %0, %%dx":"=a"(portid));
45+
asm volatile("out %al, %dx");
46+
asm volatile("pop %edx");
47+
asm volatile("pop %eax");
48+
}

kernel/makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
all:
2+
echo -n "kernel/pic.o kernel/pit.o kernel/hal.o " >> ../objs.txt
3+
i586-elf-gcc -c pic.c -o pic.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
4+
i586-elf-gcc -c pit.c -o pit.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
5+
i586-elf-gcc -c hal.c -o hal.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra

kernel/pic.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/** @author Levente Kurusa <[email protected]> **/
2+
#include "../include/pic.h"
3+
#include "../include/display.h"
4+
#include "../include/hal.h"
5+
#include <stdint.h>
6+
7+
MODULE("PIC");
8+
9+
void pic_init()
10+
{
11+
/* We have to remap the IRQs to be able to process
12+
* hardware-related interrupt requests and to service
13+
* exceptions as well.
14+
*/
15+
16+
17+
/* First step is to save current masks, set by BIOS */
18+
uint8_t m1 = inportb(PIC_MASTER_DATA), m2 = inportb(PIC_SLAVE_DATA);
19+
mprint("Existing masks: Master: 0x%x Slave: 0x%x\n", m1, m2);
20+
mprint("Beginning initialization\n");
21+
/* set up cascading mode */
22+
outportb(PIC_MASTER_CMD, 0x10 + 0x01);
23+
outportb(PIC_SLAVE_CMD, 0x10 + 0x01);
24+
/* Setup master's vector offset */
25+
outportb(PIC_MASTER_DATA, 0x20);
26+
/* Tell the slave its vector offset */
27+
outportb(PIC_SLAVE_DATA, 0x28);
28+
/* Tell the master that he has a slave */
29+
outportb(PIC_MASTER_DATA, 4);
30+
outportb(PIC_SLAVE_DATA, 2);
31+
/* Enabled 8086 mode */
32+
outportb(PIC_MASTER_DATA, 0x01);
33+
outportb(PIC_SLAVE_DATA, 0x01);
34+
35+
mprint("Resetting masks\n");
36+
outportb(PIC_MASTER_DATA, m1);
37+
outportb(PIC_SLAVE_DATA, m2);
38+
mprint("Init done.\n");
39+
}
40+
41+
void pic_send_eoi(uint8_t irq)
42+
{
43+
if(irq >= 8)
44+
outportb(PIC_SLAVE_CMD, PIC_CMD_EOI);
45+
outportb(PIC_MASTER_CMD, PIC_CMD_EOI);
46+
}

kernel/pit.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/** @author Levente Kurusa <[email protected]> **/
2+
#include "../include/pit.h"
3+
#include "../include/hal.h"
4+
#include "../include/display.h"
5+
#include <stdint.h>
6+
7+
MODULE("PIT");
8+
9+
void pit_irq()
10+
{
11+
IRQ_START;
12+
mprint("PIT IRQ!\n");
13+
send_eoi(0);
14+
IRQ_END;
15+
}
16+
17+
static inline void __pit_send_cmd(uint8_t cmd)
18+
{
19+
outportb(PIT_REG_COMMAND, cmd);
20+
}
21+
22+
static inline void __pit_send_data(uint16_t data, uint8_t counter)
23+
{
24+
uint8_t port = (counter==PIT_OCW_COUNTER_0) ? PIT_REG_COUNTER0 :
25+
((counter==PIT_OCW_COUNTER_1) ? PIT_REG_COUNTER1 : PIT_REG_COUNTER2);
26+
27+
outportb (port, (uint8_t)data);
28+
}
29+
30+
static inline uint8_t __pit_read_data (uint16_t counter) {
31+
32+
uint8_t port = (counter==PIT_OCW_COUNTER_0) ? PIT_REG_COUNTER0 :
33+
((counter==PIT_OCW_COUNTER_1) ? PIT_REG_COUNTER1 : PIT_REG_COUNTER2);
34+
35+
return inportb (port);
36+
}
37+
38+
static void pit_start_counter (uint32_t freq, uint8_t counter, uint8_t mode) {
39+
40+
if (freq==0)
41+
return;
42+
mprint("Starting counter %d with frequency %dHz\n", counter/0x40, freq);
43+
uint16_t divisor = (uint16_t)( 1193181 / (uint16_t)freq);
44+
45+
// send operational command words
46+
uint8_t ocw = 0;
47+
ocw = (ocw & ~PIT_OCW_MASK_MODE) | mode;
48+
ocw = (ocw & ~PIT_OCW_MASK_RL) | PIT_OCW_RL_DATA;
49+
ocw = (ocw & ~PIT_OCW_MASK_COUNTER) | counter;
50+
__pit_send_cmd (ocw);
51+
52+
// set frequency rate
53+
__pit_send_data (divisor & 0xff, 0);
54+
__pit_send_data ((divisor >> 8) & 0xff, 0);
55+
}
56+
57+
void pit_init()
58+
{
59+
set_int(32, (uint32_t)pit_irq);
60+
pit_start_counter (200,PIT_OCW_COUNTER_0, PIT_OCW_MODE_SQUAREWAVEGEN);
61+
mprint("Init done.\n");
62+
}

0 commit comments

Comments
 (0)