got interrupts working, added sys/{pic,timer,cpu} modules, ready to work on multitasking
git-svn-id: svn://anubis/hos/trunk@69 5b3e749e-e535-0410-8002-a9bb6afbdfca
This commit is contained in:
parent
2c5a5d7093
commit
bc7064e92a
@ -15,7 +15,7 @@ export CXXFLAGS := -Wall -O2 -fno-rtti -fno-exceptions
|
||||
export LDFLAGS := -T $(LDSCRIPT) -Map $(KERNEL).map
|
||||
export LDLIBS := `$(CC) -print-libgcc-file-name`
|
||||
|
||||
SUBDIRS := boot mm lang isr
|
||||
SUBDIRS := boot mm lang isr sys
|
||||
SUBDIRS_clean := $(SUBDIRS:%=%.clean)
|
||||
|
||||
.PHONY: all
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "mm/mm.h"
|
||||
#include "mm/stack.h"
|
||||
#include "lang/kio.h"
|
||||
#include "isr/interrupts.h"
|
||||
|
||||
#define DEBUG_LETTER(col,chr) *(u16_t *)(KERNEL_OFFSET + CONSOLE_MEMORY \
|
||||
+ 160 * 8 + (col) * 2) \
|
||||
@ -48,6 +49,7 @@ u32_t k_bootstrap(mb_info_t * mb_info, u32_t mb_magic)
|
||||
*/
|
||||
mm_bootstrap();
|
||||
stack_bootstrap();
|
||||
interrupts_bootstrap();
|
||||
kio_bootstrap();
|
||||
|
||||
return 0;
|
||||
|
@ -1,12 +1,27 @@
|
||||
|
||||
#include "lang/kio.h"
|
||||
#include "mm/mm.h"
|
||||
#include "sys/timer.h"
|
||||
#include "sys/pic.h"
|
||||
#include "isr/interrupts.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
void k_main()
|
||||
{
|
||||
kprintf("Kernel load address: 0x%08x\n", KERNEL_CODE);
|
||||
kprintf("Kernel code size: %d KB (%d bytes)\n",
|
||||
(KERNEL_DATA - KERNEL_CODE) >> 10, KERNEL_DATA - KERNEL_CODE);
|
||||
kprintf("Kernel data size: %d KB (%d bytes)\n",
|
||||
(KERNEL_BSS - KERNEL_DATA) >> 10, KERNEL_BSS - KERNEL_DATA);
|
||||
kprintf("Kernel bss size: %d KB (%d bytes)\n",
|
||||
(KERNEL_END - KERNEL_BSS) >> 10, KERNEL_END - KERNEL_BSS);
|
||||
mm_print_memory_map();
|
||||
timer_init(KERNEL_TIMER_FREQ);
|
||||
pic_remap(0x20, 0x28);
|
||||
pic_mask1(0x0);
|
||||
pic_mask2(0x0);
|
||||
interrupts_enable();
|
||||
}
|
||||
|
||||
} /* extern "C" */
|
||||
|
@ -18,10 +18,12 @@ extern "C" {
|
||||
#define CONSOLE_MEMORY 0xB8000
|
||||
|
||||
extern u8_t _code;
|
||||
extern u8_t _data;
|
||||
extern u8_t _bss;
|
||||
extern u8_t _end;
|
||||
|
||||
#define KERNEL_CODE (&_code)
|
||||
#define KERNEL_DATA (&_data)
|
||||
#define KERNEL_BSS (&_bss)
|
||||
#define KERNEL_END (&_end)
|
||||
|
||||
@ -31,6 +33,8 @@ extern u8_t _end;
|
||||
|
||||
#define KERNEL_STACK_TOP 0xF0000000
|
||||
|
||||
#define KERNEL_TIMER_FREQ 1000
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -42,8 +42,8 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u16_t length;
|
||||
u32_t phys_addr;
|
||||
u16_t limit;
|
||||
u32_t base;
|
||||
} __attribute__ ((packed)) gdtr_t;
|
||||
|
||||
typedef gdtr_t idtr_t;
|
||||
|
0
kernel/include/portio.h
Executable file → Normal file
0
kernel/include/portio.h
Executable file → Normal file
0
kernel/isr/Makefile
Executable file → Normal file
0
kernel/isr/Makefile
Executable file → Normal file
92
kernel/isr/interrupts.cc
Executable file → Normal file
92
kernel/isr/interrupts.cc
Executable file → Normal file
@ -1,13 +1,47 @@
|
||||
|
||||
#include "hos_types.h"
|
||||
#include "interrupts.h"
|
||||
#include "mm/mm.h"
|
||||
#include "lang/kio.h"
|
||||
#include "sys/pic.h"
|
||||
#include "sys/cpu.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
void isr(u8_t int_num, int_stack_t * int_stack)
|
||||
idtr_t idtr;
|
||||
|
||||
void isr(u8_t int_num, int_stack_t * istack)
|
||||
{
|
||||
switch (int_num)
|
||||
{
|
||||
case 0x20: /* timer interrupt */
|
||||
(*(u16_t *)CONSOLE_MEMORY)++;
|
||||
pic_eoi();
|
||||
break;
|
||||
case 0x21:
|
||||
/* TODO: keyboard hook */
|
||||
pic_eoi();
|
||||
break;
|
||||
default:
|
||||
kputs("--------------------------------------------------------------------------------");
|
||||
kprintf("Unhandled Interrupt #%d\n", int_num);
|
||||
kprintf(" ds: 0x%08x es: 0x%08x fs: 0x%08x gs: 0x%08x\n",
|
||||
istack->ds, istack->es, istack->fs, istack->gs);
|
||||
kprintf(" eax: 0x%08x ebx: 0x%08x ecx: 0x%08x edx: 0x%08x\n",
|
||||
istack->eax, istack->ebx, istack->ecx, istack->edx);
|
||||
kprintf(" ebp: 0x%08x esi: 0x%08x edi: 0x%08x eflags: 0x%08x\n",
|
||||
istack->ebp, istack->esi, istack->edi, istack->eflags);
|
||||
kprintf(" cs: 0x%08x eip: 0x%08x ss: 0x%08x esp: 0x%08x\n",
|
||||
istack->cs, istack->eip, istack->ss, istack->esp);
|
||||
kprintf(" cr0: 0x%08x cr2: 0x%08x cr3: 0x%08x\n",
|
||||
read_cr0(), read_cr2(), read_cr3());
|
||||
kprintf(" Error: 0x%08x (%d)\n", istack->error, istack->error);
|
||||
kputs("--------------------------------------------------------------------------------");
|
||||
|
||||
kprintf("Halting!\n");
|
||||
for (;;)
|
||||
;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,5 +49,59 @@ void isr(u8_t int_num, int_stack_t * int_stack)
|
||||
|
||||
void interrupts_bootstrap()
|
||||
{
|
||||
/* TODO: set up IDTR, IDT */
|
||||
u32_t idt_base = mm_early_page_alloc();
|
||||
u64_t * idt = (u64_t *) (idt_base + KERNEL_OFFSET);
|
||||
idt[0] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_0, 0);
|
||||
idt[1] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_1, 0);
|
||||
idt[2] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_2, 0);
|
||||
idt[3] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_3, 0);
|
||||
idt[4] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_4, 0);
|
||||
idt[5] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_5, 0);
|
||||
idt[6] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_6, 0);
|
||||
idt[7] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_7, 0);
|
||||
idt[8] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_8, 0);
|
||||
idt[9] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_9, 0);
|
||||
idt[10] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_10, 0);
|
||||
idt[11] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_11, 0);
|
||||
idt[12] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_12, 0);
|
||||
idt[13] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_13, 0);
|
||||
idt[14] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_14, 0);
|
||||
idt[15] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_15, 0);
|
||||
idt[16] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_16, 0);
|
||||
idt[17] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_17, 0);
|
||||
idt[18] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_18, 0);
|
||||
idt[19] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_19, 0);
|
||||
idt[20] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_20, 0);
|
||||
idt[21] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_21, 0);
|
||||
idt[22] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_22, 0);
|
||||
idt[23] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_23, 0);
|
||||
idt[24] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_24, 0);
|
||||
idt[25] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_25, 0);
|
||||
idt[26] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_26, 0);
|
||||
idt[27] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_27, 0);
|
||||
idt[28] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_28, 0);
|
||||
idt[29] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_29, 0);
|
||||
idt[30] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_30, 0);
|
||||
idt[31] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_31, 0);
|
||||
idt[32] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_32, 0);
|
||||
idt[33] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_33, 0);
|
||||
idt[34] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_34, 0);
|
||||
idt[35] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_35, 0);
|
||||
idt[36] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_36, 0);
|
||||
idt[37] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_37, 0);
|
||||
idt[38] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_38, 0);
|
||||
idt[39] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_39, 0);
|
||||
idt[40] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_40, 0);
|
||||
idt[41] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_41, 0);
|
||||
idt[42] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_42, 0);
|
||||
idt[43] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_43, 0);
|
||||
idt[44] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_44, 0);
|
||||
idt[45] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_45, 0);
|
||||
idt[46] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_46, 0);
|
||||
idt[47] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_47, 0);
|
||||
idt[48] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_48, 0);
|
||||
idt[49] = MAKE_IDT_DESCRIPTOR(KERNEL_CODE_SEGMENT, isr_49, 0);
|
||||
idtr.base = idt_base;
|
||||
idtr.limit = 49 * sizeof(idt[0]) - 1;
|
||||
__asm__ __volatile__ ("lidt (idtr)");
|
||||
}
|
||||
|
@ -8,10 +8,72 @@ extern "C" {
|
||||
|
||||
void isr(u8_t int_num, int_stack_t * int_stack);
|
||||
|
||||
extern void isr_0();
|
||||
extern void isr_1();
|
||||
extern void isr_2();
|
||||
extern void isr_3();
|
||||
extern void isr_4();
|
||||
extern void isr_5();
|
||||
extern void isr_6();
|
||||
extern void isr_7();
|
||||
extern void isr_8();
|
||||
extern void isr_9();
|
||||
extern void isr_10();
|
||||
extern void isr_11();
|
||||
extern void isr_12();
|
||||
extern void isr_13();
|
||||
extern void isr_14();
|
||||
extern void isr_15();
|
||||
extern void isr_16();
|
||||
extern void isr_17();
|
||||
extern void isr_18();
|
||||
extern void isr_19();
|
||||
extern void isr_20();
|
||||
extern void isr_21();
|
||||
extern void isr_22();
|
||||
extern void isr_23();
|
||||
extern void isr_24();
|
||||
extern void isr_25();
|
||||
extern void isr_26();
|
||||
extern void isr_27();
|
||||
extern void isr_28();
|
||||
extern void isr_29();
|
||||
extern void isr_30();
|
||||
extern void isr_31();
|
||||
extern void isr_32();
|
||||
extern void isr_33();
|
||||
extern void isr_34();
|
||||
extern void isr_35();
|
||||
extern void isr_36();
|
||||
extern void isr_37();
|
||||
extern void isr_38();
|
||||
extern void isr_39();
|
||||
extern void isr_40();
|
||||
extern void isr_41();
|
||||
extern void isr_42();
|
||||
extern void isr_43();
|
||||
extern void isr_44();
|
||||
extern void isr_45();
|
||||
extern void isr_46();
|
||||
extern void isr_47();
|
||||
extern void isr_48();
|
||||
extern void isr_49();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MAKE_IDT_DESCRIPTOR(selector, offset, dpl) \
|
||||
(u64_t) ( ( (((u64_t) offset) & 0xFFFF0000ull) << 32 ) /* offset 31:16 */ \
|
||||
| ( ( (u64_t) 0x1ull) << 47 ) /* present */ \
|
||||
| ( (((u64_t) dpl) & 0x3) << 45 ) /* DPL */ \
|
||||
| ( ( (u64_t) 0xEull) << 40 ) /* TODO: gate? */ \
|
||||
| ( (((u64_t) selector) & 0xFFFFull) << 16 ) /* selector */ \
|
||||
| ( (((u64_t) offset) & 0x0000FFFFull) ) ) /* offset 15:0 */
|
||||
|
||||
void interrupts_bootstrap();
|
||||
|
||||
#define interrupts_enable() __asm__ __volatile__ ("sti");
|
||||
#define interrupts_disable() __asm__ __volatile__ ("cli");
|
||||
|
||||
#endif
|
||||
|
@ -33,8 +33,7 @@ isr_common:
|
||||
|
||||
push esp ; pointer to interrupt stack
|
||||
push eax ; interrupt number
|
||||
; TODO: uncomment when isr() is defined so the build won't break
|
||||
; call isr
|
||||
call isr
|
||||
pop eax ; restore stack pointer (this is shorter
|
||||
pop eax ; than "add esp, 8" and "lea esp, [esp+8]")
|
||||
|
||||
|
@ -12,6 +12,11 @@ SECTIONS
|
||||
*(.rodata*)
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
.other : {
|
||||
*(.eh_*)
|
||||
*(.rel*)
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
.data : {
|
||||
data = .; _data = .; __data = .;
|
||||
*(.data*)
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "boot/k_early_panic.h"
|
||||
#include "lang/string.h"
|
||||
#include "lang/kio.h"
|
||||
#include "sys/cpu.h"
|
||||
|
||||
#define MM_MAX_MMAP_ENTRIES 64
|
||||
|
||||
@ -148,10 +149,10 @@ void mm_bootstrap()
|
||||
u32_t gdt_base = mm_early_page_alloc();
|
||||
mm_gdt = (u64_t *) ((u32_t) gdt_base + (u32_t) KERNEL_OFFSET);
|
||||
mm_gdt[0] = 0x0ull;
|
||||
mm_gdt[1] = MAKE_DESCRIPTOR(0, 0xFFFFF, 1, 0, 1, 1);
|
||||
mm_gdt[2] = MAKE_DESCRIPTOR(0, 0xFFFFF, 1, 0, 1, 0);
|
||||
mm_gdtr.length = 3*sizeof(mm_gdt[0]) - 1;
|
||||
mm_gdtr.phys_addr = gdt_base;
|
||||
mm_gdt[1] = MAKE_DESCRIPTOR(0, 0xFFFFF, 1, 0, 1, 1); /* kernel code */
|
||||
mm_gdt[2] = MAKE_DESCRIPTOR(0, 0xFFFFF, 1, 0, 1, 0); /* kernel data */
|
||||
mm_gdtr.limit = 3 * sizeof(mm_gdt[0]) - 1;
|
||||
mm_gdtr.base = gdt_base;
|
||||
|
||||
/* set the page directory base register */
|
||||
set_cr3(page_directory);
|
||||
|
@ -6,6 +6,9 @@
|
||||
#include "hos_defines.h"
|
||||
#include "multiboot.h"
|
||||
|
||||
#define KERNEL_CODE_SEGMENT 0x08
|
||||
#define KERNEL_DATA_SEGMENT 0x10
|
||||
|
||||
typedef u32_t pagedirectory_entry_t;
|
||||
|
||||
#define NUM_PAGETABLE_ENTRIES (PAGE_SIZE / sizeof(pagedirectory_entry_t))
|
||||
@ -29,9 +32,6 @@ int mm_map(u32_t virtual_address, u32_t physical_address,
|
||||
u32_t mm_early_page_alloc();
|
||||
u32_t mm_page_alloc();
|
||||
|
||||
#define set_cr3(address) \
|
||||
__asm__ __volatile__ ("movl %0, %%cr3" : : "r" (address));
|
||||
|
||||
/* http://courses.ece.illinois.edu/ece391/references/descriptors.pdf */
|
||||
/* granularity: 0: limit in bytes; 1: limit in pages */
|
||||
/* dpl: 0: system mode; 3: user mode */
|
||||
|
0
kernel/mm/stack.cc
Executable file → Normal file
0
kernel/mm/stack.cc
Executable file → Normal file
0
kernel/mm/stack.h
Executable file → Normal file
0
kernel/mm/stack.h
Executable file → Normal file
2
kernel/sys/Makefile
Normal file
2
kernel/sys/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
include $(HOS_TOPLEVEL)/subdir.mak
|
34
kernel/sys/cpu.h
Normal file
34
kernel/sys/cpu.h
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
#ifndef CPU_H
|
||||
#define CPU_H
|
||||
|
||||
#include "hos_types.h"
|
||||
|
||||
static u32_t read_cr0()
|
||||
{
|
||||
u32_t val;
|
||||
__asm__ __volatile__ ("movl %%cr0, %0" : "=r" (val));
|
||||
return val;
|
||||
}
|
||||
|
||||
static u32_t read_cr2()
|
||||
{
|
||||
u32_t val;
|
||||
__asm__ __volatile__ ("movl %%cr2, %0" : "=r" (val));
|
||||
return val;
|
||||
}
|
||||
|
||||
static u32_t read_cr3()
|
||||
{
|
||||
u32_t val;
|
||||
__asm__ __volatile__ ("movl %%cr3, %0" : "=r" (val));
|
||||
return val;
|
||||
}
|
||||
|
||||
#define set_cr0(val) \
|
||||
__asm__ __volatile__ ("movl %0, %%cr0" : : "r" (val));
|
||||
|
||||
#define set_cr3(val) \
|
||||
__asm__ __volatile__ ("movl %0, %%cr3" : : "r" (val));
|
||||
|
||||
#endif
|
29
kernel/sys/pic.cc
Normal file
29
kernel/sys/pic.cc
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
#include "pic.h"
|
||||
#include "portio.h"
|
||||
|
||||
/*
|
||||
* Re-maps the Programmable Interrupr Controllers
|
||||
* so IRQ0->pic1 base address, IRG8->pic2 base address
|
||||
*/
|
||||
void pic_remap(u8_t base1, u8_t base2)
|
||||
{
|
||||
u8_t 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, base1); /* 0x21, pic1 */
|
||||
outportb(PIC2_DATA, base2); /* 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 */
|
||||
}
|
||||
|
||||
|
46
kernel/sys/pic.h
Normal file
46
kernel/sys/pic.h
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
#ifndef PIC_H
|
||||
#define PIC_H
|
||||
|
||||
#include "hos_types.h"
|
||||
#include "portio.h"
|
||||
|
||||
#define PIC1 0x20
|
||||
#define PIC2 0xA0
|
||||
#define PIC1_COMMAND PIC1
|
||||
#define PIC1_DATA (PIC1+1)
|
||||
#define PIC2_COMMAND PIC2
|
||||
#define PIC2_DATA (PIC2+1)
|
||||
#define PIC_EOI 0x20
|
||||
|
||||
#define ICW1_ICW4 0x01 /* ICW4 (not) needed */
|
||||
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
|
||||
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
|
||||
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
|
||||
#define ICW1_INIT 0x10 /* Initialization - required! */
|
||||
|
||||
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
|
||||
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
|
||||
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
|
||||
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
|
||||
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
|
||||
|
||||
void pic_remap(u8_t base1, u8_t base2);
|
||||
|
||||
/* Masks interrupts on first Programmable Interrupt Controller */
|
||||
#define pic_mask1(mask) outportb(PIC1_DATA, mask) /* 0x21, maskfield *OCW1* */
|
||||
|
||||
/* Masks interrupts on second Programmable Interrupt Controller */
|
||||
#define pic_mask2(mask) outportb(PIC2_DATA, mask) /* 0xA1, maskfield *OCW1* */
|
||||
|
||||
/* Signals an End Of Interrupt signal to the first PIC */
|
||||
#define pic_eoi() outportb(0x20, 0x20)
|
||||
|
||||
/* Signals an End Of Interrupt signal to both the second and first PIC unit */
|
||||
static inline void pic_eoi2()
|
||||
{
|
||||
outportb(0xA0, 0x20);
|
||||
outportb(0x20, 0x20);
|
||||
}
|
||||
|
||||
#endif
|
12
kernel/sys/timer.cc
Normal file
12
kernel/sys/timer.cc
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
#include "timer.h"
|
||||
#include "portio.h"
|
||||
|
||||
void timer_init(u32_t freq)
|
||||
{
|
||||
/* how many ticks the PIT must wait before issuing an interrupt */
|
||||
u32_t wait = 1193180 / freq;
|
||||
outportb(0x43, 0x34);
|
||||
outportb(0x40, wait); /* LSB */
|
||||
outportb(0x40, wait >> 8); /* MSB */
|
||||
}
|
9
kernel/sys/timer.h
Normal file
9
kernel/sys/timer.h
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
#include "hos_types.h"
|
||||
|
||||
void timer_init(u32_t freq);
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user