diff --git a/kernel/8259A.c b/kernel/8259A.c new file mode 100644 index 0000000000000000000000000000000000000000..142570f4c6f3782266afb504045fac1e178d0220 --- /dev/null +++ b/kernel/8259A.c @@ -0,0 +1,50 @@ +#include "interrupt.h" +#include "linkage.h" +#include "lib.h" +#include "printk.h" +#include "memory.h" +#include "gate.h" +#include "ptrace.h" + +void init_8259A() +{ + int i; + for(i = 32;i < 56;i++) + { + set_intr_gate(i , 2 , interrupt[i - 32]); + } + + color_printk(RED,BLACK,"8259A init \n"); + + //8259A-master ICW1-4 + io_out8(0x20,0x11); + io_out8(0x21,0x20); + io_out8(0x21,0x04); + io_out8(0x21,0x01); + + //8259A-slave ICW1-4 + io_out8(0xa0,0x11); + io_out8(0xa1,0x28); + io_out8(0xa1,0x02); + io_out8(0xa1,0x01); + + //8259A-M/S OCW1 + io_out8(0x21,0xfd); + io_out8(0xa1,0xff); + + sti(); +} + +/* + +*/ + +void do_IRQ(struct pt_regs * regs,unsigned long nr) //regs,nr +{ + unsigned char x; + color_printk(RED,BLACK,"do_IRQ:%#018lx\t",nr); + x = io_in8(0x60); + color_printk(RED,BLACK,"key code:%#018lx\t",x); + io_out8(0x20,0x20); + color_printk(RED,BLACK,"regs:%#018lx\t\n",regs,regs->rip,regs->rsp); +} \ No newline at end of file diff --git a/kernel/8259A.h b/kernel/8259A.h new file mode 100644 index 0000000000000000000000000000000000000000..ce29314f752b54f0b41dd1ed038a73506838bb62 --- /dev/null +++ b/kernel/8259A.h @@ -0,0 +1,11 @@ +#ifndef __8259A_H__ +#define __8259A_H__ + +#include "linkage.h" +#include "ptrace.h" + +void init_8259A(); + +void do_IRQ(struct pt_regs * regs,unsigned long nr); + +#endif diff --git a/kernel/APIC.c b/kernel/APIC.c new file mode 100755 index 0000000000000000000000000000000000000000..c36314b7eada1d8cb99fdeebb187835f20693b06 --- /dev/null +++ b/kernel/APIC.c @@ -0,0 +1,410 @@ +/*************************************************** +* 版权声明 +* +* 本操作系统名为:MINE +* 该操作系统未经授权不得以盈利或非盈利为目的进行开发, +* 只允许个人学习以及公开交流使用 +* +* 代码最终所有权及解释权归田宇所有; +* +* 本模块作者: 田宇 +* EMail: 345538255@qq.com +* +* +***************************************************/ + +#include "interrupt.h" +#include "linkage.h" +#include "lib.h" +#include "printk.h" +#include "memory.h" +#include "gate.h" +#include "ptrace.h" +#include "cpu.h" +#include "APIC.h" + +/* + +*/ + +void IOAPIC_enable(unsigned long irq) +{ + unsigned long value = 0; + value = ioapic_rte_read((irq - 32) * 2 + 0x10); + value = value & (~0x10000UL); + ioapic_rte_write((irq - 32) * 2 + 0x10,value); +} + +void IOAPIC_disable(unsigned long irq) +{ + unsigned long value = 0; + value = ioapic_rte_read((irq - 32) * 2 + 0x10); + value = value | 0x10000UL; + ioapic_rte_write((irq - 32) * 2 + 0x10,value); +} + +unsigned long IOAPIC_install(unsigned long irq,void * arg) +{ + struct IO_APIC_RET_entry *entry = (struct IO_APIC_RET_entry *)arg; + ioapic_rte_write((irq - 32) * 2 + 0x10,*(unsigned long *)entry); + + return 1; +} + +void IOAPIC_uninstall(unsigned long irq) +{ + ioapic_rte_write((irq - 32) * 2 + 0x10,0x10000UL); +} + +void IOAPIC_level_ack(unsigned long irq) +{ + __asm__ __volatile__( "movq $0x00, %%rdx \n\t" + "movq $0x00, %%rax \n\t" + "movq $0x80b, %%rcx \n\t" + "wrmsr \n\t" + :::"memory"); + + *ioapic_map.virtual_EOI_address = 0; +} + +void IOAPIC_edge_ack(unsigned long irq) +{ + __asm__ __volatile__( "movq $0x00, %%rdx \n\t" + "movq $0x00, %%rax \n\t" + "movq $0x80b, %%rcx \n\t" + "wrmsr \n\t" + :::"memory"); +} + +/* + +*/ + +unsigned long ioapic_rte_read(unsigned char index) +{ + unsigned long ret; + + *ioapic_map.virtual_index_address = index + 1; + io_mfence(); + ret = *ioapic_map.virtual_data_address; + ret <<= 32; + io_mfence(); + + *ioapic_map.virtual_index_address = index; + io_mfence(); + ret |= *ioapic_map.virtual_data_address; + io_mfence(); + + return ret; +} + +/* + +*/ + +void ioapic_rte_write(unsigned char index,unsigned long value) +{ + *ioapic_map.virtual_index_address = index; + io_mfence(); + *ioapic_map.virtual_data_address = value & 0xffffffff; + value >>= 32; + io_mfence(); + + *ioapic_map.virtual_index_address = index + 1; + io_mfence(); + *ioapic_map.virtual_data_address = value & 0xffffffff; + io_mfence(); +} + +/* + +*/ + +void IOAPIC_pagetable_remap() +{ + unsigned long * tmp; + unsigned char * IOAPIC_addr = (unsigned char *)Phy_To_Virt(0xfec00000); + + ioapic_map.physical_address = 0xfec00000; + ioapic_map.virtual_index_address = IOAPIC_addr; + ioapic_map.virtual_data_address = (unsigned int *)(IOAPIC_addr + 0x10); + ioapic_map.virtual_EOI_address = (unsigned int *)(IOAPIC_addr + 0x40); + + Global_CR3 = Get_gdt(); + + tmp = Phy_To_Virt(Global_CR3 + (((unsigned long)IOAPIC_addr >> PAGE_GDT_SHIFT) & 0x1ff)); + if (*tmp == 0) + { + unsigned long * virtual = kmalloc(PAGE_4K_SIZE,0); + set_mpl4t(tmp,mk_mpl4t(Virt_To_Phy(virtual),PAGE_KERNEL_GDT)); + } + + color_printk(YELLOW,BLACK,"1:%#018lx\t%#018lx\n",(unsigned long)tmp,(unsigned long)*tmp); + + tmp = Phy_To_Virt((unsigned long *)(*tmp & (~ 0xfffUL)) + (((unsigned long)IOAPIC_addr >> PAGE_1G_SHIFT) & 0x1ff)); + if(*tmp == 0) + { + unsigned long * virtual = kmalloc(PAGE_4K_SIZE,0); + set_pdpt(tmp,mk_pdpt(Virt_To_Phy(virtual),PAGE_KERNEL_Dir)); + } + + color_printk(YELLOW,BLACK,"2:%#018lx\t%#018lx\n",(unsigned long)tmp,(unsigned long)*tmp); + + tmp = Phy_To_Virt((unsigned long *)(*tmp & (~ 0xfffUL)) + (((unsigned long)IOAPIC_addr >> PAGE_2M_SHIFT) & 0x1ff)); + set_pdt(tmp,mk_pdt(ioapic_map.physical_address,PAGE_KERNEL_Page | PAGE_PWT | PAGE_PCD)); + + color_printk(BLUE,BLACK,"3:%#018lx\t%#018lx\n",(unsigned long)tmp,(unsigned long)*tmp); + + color_printk(BLUE,BLACK,"ioapic_map.physical_address:%#010x\t\t\n",ioapic_map.physical_address); + color_printk(BLUE,BLACK,"ioapic_map.virtual_address:%#018lx\t\t\n",(unsigned long)ioapic_map.virtual_index_address); + + flush_tlb(); +} + +/* + +*/ + +void Local_APIC_init() +{ + unsigned int x,y; + unsigned int a,b,c,d; + + //check APIC & x2APIC support + get_cpuid(1,0,&a,&b,&c,&d); + //void get_cpuid(unsigned int Mop,unsigned int Sop,unsigned int * a,unsigned int * b,unsigned int * c,unsigned int * d) + color_printk(WHITE,BLACK,"CPUID\t01,eax:%#010x,ebx:%#010x,ecx:%#010x,edx:%#010x\n",a,b,c,d); + + if((1<<9) & d) + color_printk(WHITE,BLACK,"HW support APIC&xAPIC\t"); + else + color_printk(WHITE,BLACK,"HW NO support APIC&xAPIC\t"); + + if((1<<21) & c) + color_printk(WHITE,BLACK,"HW support x2APIC\n"); + else + color_printk(WHITE,BLACK,"HW NO support x2APIC\n"); + + //enable xAPIC & x2APIC + __asm__ __volatile__( "movq $0x1b, %%rcx \n\t" + "rdmsr \n\t" + "bts $10, %%rax \n\t" + "bts $11, %%rax \n\t" + "wrmsr \n\t" + "movq $0x1b, %%rcx \n\t" + "rdmsr \n\t" + :"=a"(x),"=d"(y) + : + :"memory"); + + color_printk(WHITE,BLACK,"eax:%#010x,edx:%#010x\t",x,y); + + if(x&0xc00) + color_printk(WHITE,BLACK,"xAPIC & x2APIC enabled\n"); + + //enable SVR[8] + __asm__ __volatile__( "movq $0x80f, %%rcx \n\t" + "rdmsr \n\t" + "bts $8, %%rax \n\t" +// "bts $12, %%rax\n\t" + "wrmsr \n\t" + "movq $0x80f, %%rcx \n\t" + "rdmsr \n\t" + :"=a"(x),"=d"(y) + : + :"memory"); + + color_printk(WHITE,BLACK,"eax:%#010x,edx:%#010x\t",x,y); + + if(x&0x100) + color_printk(WHITE,BLACK,"SVR[8] enabled\n"); + if(x&0x1000) + color_printk(WHITE,BLACK,"SVR[12] enabled\n"); + + //get local APIC ID + __asm__ __volatile__( "movq $0x802, %%rcx \n\t" + "rdmsr \n\t" + :"=a"(x),"=d"(y) + : + :"memory"); + + color_printk(WHITE,BLACK,"eax:%#010x,edx:%#010x\tx2APIC ID:%#010x\n",x,y,x); + + //get local APIC version + __asm__ __volatile__( "movq $0x803, %%rcx \n\t" + "rdmsr \n\t" + :"=a"(x),"=d"(y) + : + :"memory"); + + color_printk(WHITE,BLACK,"local APIC Version:%#010x,Max LVT Entry:%#010x,SVR(Suppress EOI Broadcast):%#04x\t",x & 0xff,(x >> 16 & 0xff) + 1,x >> 24 & 0x1); + + if((x & 0xff) < 0x10) + color_printk(WHITE,BLACK,"82489DX discrete APIC\n"); + + else if( ((x & 0xff) >= 0x10) && ((x & 0xff) <= 0x15) ) + color_printk(WHITE,BLACK,"Integrated APIC\n"); + + //mask all LVT + __asm__ __volatile__( //"movq $0x82f, %%rcx \n\t" //CMCI + //"wrmsr \n\t" + "movq $0x832, %%rcx \n\t" //Timer + "wrmsr \n\t" + "movq $0x833, %%rcx \n\t" //Thermal Monitor + "wrmsr \n\t" + "movq $0x834, %%rcx \n\t" //Performance Counter + "wrmsr \n\t" + "movq $0x835, %%rcx \n\t" //LINT0 + "wrmsr \n\t" + "movq $0x836, %%rcx \n\t" //LINT1 + "wrmsr \n\t" + "movq $0x837, %%rcx \n\t" //Error + "wrmsr \n\t" + : + :"a"(0x10000),"d"(0x00) + :"memory"); + + color_printk(GREEN,BLACK,"Mask ALL LVT\n"); + + //TPR + __asm__ __volatile__( "movq $0x808, %%rcx \n\t" + "rdmsr \n\t" + :"=a"(x),"=d"(y) + : + :"memory"); + + color_printk(GREEN,BLACK,"Set LVT TPR:%#010x\t",x); + + //PPR + __asm__ __volatile__( "movq $0x80a, %%rcx \n\t" + "rdmsr \n\t" + :"=a"(x),"=d"(y) + : + :"memory"); + + color_printk(GREEN,BLACK,"Set LVT PPR:%#010x\n",x); +} + +/* + +*/ + +void IOAPIC_init() +{ + int i ; + // I/O APIC + // I/O APIC ID + *ioapic_map.virtual_index_address = 0x00; + io_mfence(); + *ioapic_map.virtual_data_address = 0x0f000000; + io_mfence(); + color_printk(GREEN,BLACK,"Get IOAPIC ID REG:%#010x,ID:%#010x\n",*ioapic_map.virtual_data_address, *ioapic_map.virtual_data_address >> 24 & 0xf); + io_mfence(); + + // I/O APIC Version + *ioapic_map.virtual_index_address = 0x01; + io_mfence(); + color_printk(GREEN,BLACK,"Get IOAPIC Version REG:%#010x,MAX redirection enties:%#08d\n",*ioapic_map.virtual_data_address ,((*ioapic_map.virtual_data_address >> 16) & 0xff) + 1); + + //RTE + for(i = 0x10;i < 0x40;i += 2) + ioapic_rte_write(i,0x10020 + ((i - 0x10) >> 1)); + + color_printk(GREEN,BLACK,"I/O APIC Redirection Table Entries Set Finished.\n"); +} + +/* + +*/ + +void APIC_IOAPIC_init() +{ + cli(); + // init trap abort fault + int i ; + unsigned int x; + unsigned int * p; + + IOAPIC_pagetable_remap(); + + for(i = 32;i < 56;i++) + { + set_intr_gate(i , 2 , interrupt[i - 32]); + } + + //8259A-master ICW1-4 + io_out8(0x20,0x11); + io_out8(0x21,0x20); + io_out8(0x21,0x04); + io_out8(0x21,0x01); + + //8259A-slave ICW1-4 + io_out8(0xa0,0x11); + io_out8(0xa1,0x28); + io_out8(0xa1,0x02); + io_out8(0xa1,0x01); + + // //复位主/从8259A中断控制器的中断屏蔽寄存器酌盟的全部中断屏蔽位 + // io_out8(0x21,0x00); + // io_out8(0xa1,0x00); + + // //8259A-M/S OCW1 + // io_out8(0x21,0xfd); + // io_out8(0xa1,0xff); + + //mask 8259A + color_printk(GREEN,BLACK,"MASK 8259A\n"); + io_out8(0x21,0xff); + io_out8(0xa1,0xff); + + //enable IMCR + io_out8(0x22,0x70); + io_out8(0x23,0x01); + + //init local apic + Local_APIC_init(); + + //init ioapic + IOAPIC_init(); + + // //get RCBA address + // io_out32(0xcf8,0x8000f8f0); + // x = io_in32(0xcfc); + // color_printk(RED,BLACK,"Get RCBA Address:%#010x\n",x); + // x = x & 0xffffc000; + // color_printk(RED,BLACK,"Get RCBA Address:%#010x\n",x); + + // x=0xfed1c000; + // //get OIC address + // if(x > 0xfec00000 && x < 0xfee00000) + // { + // p = (unsigned int *)Phy_To_Virt(x + 0x31feUL); + // } + + // //enable IOAPIC + // x = (*p & 0xffffff00) | 0x100; + // io_mfence(); + // *p = x; + // io_mfence(); + + memset(interrupt_desc,0,sizeof(irq_desc_T)*NR_IRQS); + + //open IF eflages + sti(); +} + +/* + +*/ + +void do_IRQ(struct pt_regs * regs,unsigned long nr) //regs:rsp,nr +{ + irq_desc_T * irq = &interrupt_desc[nr - 32]; + + if(irq->handler != NULL) + irq->handler(nr,irq->parameter,regs); + + if(irq->controller != NULL && irq->controller->ack != NULL) + irq->controller->ack(nr); +} + diff --git a/kernel/APIC.h b/kernel/APIC.h new file mode 100755 index 0000000000000000000000000000000000000000..ff67485bb0801c3b699a05f37618eb68b6d0a75f --- /dev/null +++ b/kernel/APIC.h @@ -0,0 +1,280 @@ +/*************************************************** +* 版权声明 +* +* 本操作系统名为:MINE +* 该操作系统未经授权不得以盈利或非盈利为目的进行开发, +* 只允许个人学习以及公开交流使用 +* +* 代码最终所有权及解释权归田宇所有; +* +* 本模块作者: 田宇 +* EMail: 345538255@qq.com +* +* +***************************************************/ + +#ifndef __APIC_H__ +#define __APIC_H__ + +#include "linkage.h" +#include "ptrace.h" +#include "interrupt.h" + +/* + +0~255 IDT + +0 ~ 31 trap fault abort for system + 0 devide error + 1 debug + 2 NMI + 3 breakpoint + 4 overflow + 5 bound range + 6 undefined opcode + 7 device not available + 8 double fault + 9 coprocessor segment overrun + 10 invalid TSS + 11 segment not present + 12 stack segment fault + 13 general protection + 14 page fault + 15 + 16 x87 FPU error + 17 alignment check + 18 machine check + 19 SIMD exception + 20 virtualization exception +21 ~ 31 Do not use + +32 ~ 55 I/O APIC + 32 8259A + 33 keyboard + 34 HPET timer 0,8254 counter 0 + 35 serial port A + 36 serial port B + 37 parallel port + 38 floppy + 39 parallel port + 40 RTC,HPET timer 1 + 41 Generic + 42 Generic + 43 HPET timer 2 + 44 HPET timer 3 + 45 FERR# + 46 SATA primary + 47 SATA secondary + 48 PIRQA + 49 PIRQB + 50 PIRQC + 51 PIRQD + 52 PIRQE + 53 PIRQF + 54 PIRQG + 55 PIRQH + + +0x80 system call + +150 ~ 200 Local APIC + 150 CMCI + 151 Timer + 152 Thermal Monitor + 153 Performance Counter + 154 LINT0 + 155 LINT1 + 156 Error + +200 ~ 255 MP IPI + +*/ + +/* + +1: LVT CMCI +2: LVT Timer +3: LVT Thermal Monitor +4: LVT Performace Counter +5: LVT LINT0 +6: LVT LINT1 +7: LVT Error + +*/ + +/* + LVT +*/ + +struct APIC_LVT +{ + unsigned int vector :8, //0~7 ALL + deliver_mode :3, //8~10 CMCI LINT0 LINT1 PerformCounter ThermalSensor + res_1 :1, //11 + deliver_status :1, //12 ALL + polarity:1, //13 LINT0 LINT1 + irr :1, //14 LINT0 LINT1 + trigger :1, //15 LINT0 LINT1 + mask :1, //16 ALL + timer_mode :2, //17~18 Timer + res_2 :13; //19~31 +}__attribute__((packed)); //disable align in struct + +/* + ICR +*/ + +struct INT_CMD_REG +{ + unsigned int vector :8, //0~7 + deliver_mode :3, //8~10 + dest_mode :1, //11 + deliver_status :1, //12 + res_1 :1, //13 + level :1, //14 + trigger :1, //15 + res_2 :2, //16~17 + dest_shorthand :2, //18~19 + res_3 :12; //20~31 + + union { + struct { + unsigned int res_4 :24, //32~55 + dest_field :8; //56~63 + }apic_destination; + + unsigned int x2apic_destination; //32~63 + }destination; + +}__attribute__((packed)); + +/* + RTE +*/ + +struct IO_APIC_RET_entry +{ + unsigned int vector :8, //0~7 + deliver_mode :3, //8~10 + dest_mode :1, //11 + deliver_status :1, //12 + polarity:1, //13 + irr :1, //14 + trigger :1, //15 + mask :1, //16 + reserved:15; //17~31 + + union{ + struct { + unsigned int reserved1 :24, //32~55 + phy_dest :4, //56~59 + reserved2 :4; //60~63 + }physical; + + struct { + unsigned int reserved1 :24, //32~55 + logical_dest :8; //56~63 + }logical; + }destination; +}__attribute__((packed)); + +/* + +*/ + +//delivery mode +#define APIC_ICR_IOAPIC_Fixed 0 //LAPIC IOAPIC ICR +#define IOAPIC_ICR_Lowest_Priority 1 // IOAPIC ICR +#define APIC_ICR_IOAPIC_SMI 2 //LAPIC IOAPIC ICR + +#define APIC_ICR_IOAPIC_NMI 4 //LAPIC IOAPIC ICR +#define APIC_ICR_IOAPIC_INIT 5 //LAPIC IOAPIC ICR +#define ICR_Start_up 6 // ICR +#define IOAPIC_ExtINT 7 // IOAPIC + + +/* + +*/ +//timer mode +#define APIC_LVT_Timer_One_Shot 0 +#define APIC_LVT_Timer_Periodic 1 +#define APIC_LVT_Timer_TSC_Deadline 2 + +//mask +#define APIC_ICR_IOAPIC_Masked 1 +#define APIC_ICR_IOAPIC_UN_Masked 0 + +//trigger mode +#define APIC_ICR_IOAPIC_Edge 0 +#define APIC_ICR_IOAPIC_Level 1 + +//delivery status +#define APIC_ICR_IOAPIC_Idle 0 +#define APIC_ICR_IOAPIC_Send_Pending 1 + +//destination shorthand +#define ICR_No_Shorthand 0 +#define ICR_Self 1 +#define ICR_ALL_INCLUDE_Self 2 +#define ICR_ALL_EXCLUDE_Self 3 + +//destination mode +#define ICR_IOAPIC_DELV_PHYSICAL 0 +#define ICR_IOAPIC_DELV_LOGIC 1 + +//level +#define ICR_LEVEL_DE_ASSERT 0 +#define ICR_LEVLE_ASSERT 1 + +//remote irr +#define APIC_IOAPIC_IRR_RESET 0 +#define APIC_IOAPIC_IRR_ACCEPT 1 + +//pin polarity +#define APIC_IOAPIC_POLARITY_HIGH 0 +#define APIC_IOAPIC_POLARITY_LOW 1 + +/* + +*/ + +struct IOAPIC_map +{ + unsigned int physical_address; + unsigned char * virtual_index_address; + unsigned int * virtual_data_address; + unsigned int * virtual_EOI_address; +}ioapic_map; + +unsigned long ioapic_rte_read(unsigned char index); +void ioapic_rte_write(unsigned char index,unsigned long value); + +/* + +*/ + +void IOAPIC_pagetable_remap(); + +/* + +*/ + +void do_IRQ(struct pt_regs * regs,unsigned long nr); + +/* + +*/ + +void APIC_IOAPIC_init(); +void Local_APIC_init(); +void IOAPIC_init(); + +void IOAPIC_enable(unsigned long irq); +void IOAPIC_disable(unsigned long irq); +unsigned long IOAPIC_install(unsigned long irq,void * arg); +void IOAPIC_uninstall(unsigned long irq); +void IOAPIC_level_ack(unsigned long irq); +void IOAPIC_edge_ack(unsigned long irq); + +#endif diff --git a/kernel/interrupt.c b/kernel/interrupt.c old mode 100644 new mode 100755 index 904f6e7e6560fda8cdad1de4a535458edb00d160..2ed3f3b246b81f6b45eca961546659d4c55af701 --- a/kernel/interrupt.c +++ b/kernel/interrupt.c @@ -1,9 +1,15 @@ /*************************************************** -* Copyright (c) 2018 MINE 田宇 +* 版权声明 +* +* 本操作系统名为:MINE +* 该操作系统未经授权不得以盈利或非盈利为目的进行开发, +* 只允许个人学习以及公开交流使用 +* +* 代码最终所有权及解释权归田宇所有; +* +* 本模块作者: 田宇 +* EMail: 345538255@qq.com * -* This program is free software; you can redistribute it and/or -* modify it under the terms of version 2 of the GNU General Public -* License as published by the Free Software Foundation. * ***************************************************/ @@ -130,47 +136,48 @@ void (* interrupt[24])(void)= IRQ0x37_interrupt, }; -void init_interrupt() -{ - int i; - for(i = 32;i < 56;i++) - { - set_intr_gate(i , 2 , interrupt[i - 32]); - } - - color_printk(RED,BLACK,"8259A init \n"); - - //8259A-master ICW1-4 - io_out8(0x20,0x11); - io_out8(0x21,0x20); - io_out8(0x21,0x04); - io_out8(0x21,0x01); - - //8259A-slave ICW1-4 - io_out8(0xa0,0x11); - io_out8(0xa1,0x28); - io_out8(0xa1,0x02); - io_out8(0xa1,0x01); - - //8259A-M/S OCW1 - io_out8(0x21,0xfd); - io_out8(0xa1,0xff); - - sti(); + +/* + +*/ + +int register_irq(unsigned long irq, + void * arg, + void (*handler)(unsigned long nr, unsigned long parameter, struct pt_regs * regs), + unsigned long parameter, + hw_int_controller * controller, + char * irq_name) +{ + irq_desc_T * p = &interrupt_desc[irq - 32]; + + p->controller = controller; + p->irq_name = irq_name; + p->parameter = parameter; + p->flags = 0; + p->handler = handler; + + p->controller->install(irq,arg); + p->controller->enable(irq); + + return 1; } /* */ -void do_IRQ(struct pt_regs * regs,unsigned long nr) //regs,nr +int unregister_irq(unsigned long irq) { - unsigned char x; - color_printk(RED,BLACK,"do_IRQ:%#018lx\t",nr); - x = io_in8(0x60); - color_printk(RED,BLACK,"key code:%#018lx\t",x); - io_out8(0x20,0x20); - color_printk(RED,BLACK,"regs:%#018lx\t\n",regs,regs->rip,regs->rsp); -} + irq_desc_T * p = &interrupt_desc[irq - 32]; + + p->controller->disable(irq); + p->controller->uninstall(irq); + p->controller = NULL; + p->irq_name = NULL; + p->parameter = NULL; + p->flags = 0; + p->handler = NULL; + return 1; +} diff --git a/kernel/interrupt.h b/kernel/interrupt.h old mode 100644 new mode 100755 index 06ac07f83329f5c18d40d3ed0af6c8976f2f3c95..5340d2c91f448e730cac09c85c2ca6cdd779ec2c --- a/kernel/interrupt.h +++ b/kernel/interrupt.h @@ -1,9 +1,15 @@ /*************************************************** -* Copyright (c) 2018 MINE 田宇 +* 版权声明 +* +* 本操作系统名为:MINE +* 该操作系统未经授权不得以盈利或非盈利为目的进行开发, +* 只允许个人学习以及公开交流使用 +* +* 代码最终所有权及解释权归田宇所有; +* +* 本模块作者: 田宇 +* EMail: 345538255@qq.com * -* This program is free software; you can redistribute it and/or -* modify it under the terms of version 2 of the GNU General Public -* License as published by the Free Software Foundation. * ***************************************************/ #ifndef __INTERRUPT_H__ @@ -15,12 +21,57 @@ */ -void init_interrupt(); +typedef struct hw_int_type +{ + void (*enable)(unsigned long irq); + void (*disable)(unsigned long irq); + + unsigned long (*install)(unsigned long irq,void * arg); + void (*uninstall)(unsigned long irq); + + void (*ack)(unsigned long irq); +}hw_int_controller; + +/* + +*/ + +typedef struct { + hw_int_controller * controller; + + char * irq_name; + unsigned long parameter; + void (*handler)(unsigned long nr, unsigned long parameter, struct pt_regs * regs); + unsigned long flags; +}irq_desc_T; + +/* + +*/ + +#define NR_IRQS 24 + +irq_desc_T interrupt_desc[NR_IRQS] = {0}; + +/* + +*/ + +int register_irq(unsigned long irq, + void * arg, + void (*handler)(unsigned long nr, unsigned long parameter, struct pt_regs * regs), + unsigned long parameter, + hw_int_controller * controller, + char * irq_name); /* */ -void do_IRQ(struct pt_regs * regs,unsigned long nr); +int unregister_irq(unsigned long irq); + +extern void (* interrupt[24])(void); + +extern void do_IRQ(struct pt_regs * regs,unsigned long nr); #endif