From: AceVest Date: Tue, 20 May 2014 15:56:41 +0000 (+0800) Subject: fix no_irq_handler X-Git-Tag: 0.3.0~62 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/zlib_tech.html?a=commitdiff_plain;h=f2f99fed8d8e43ebcc66cd871c3a2ae7f9deb6d0;p=kernel.git fix no_irq_handler --- diff --git a/drivers/hd.c b/drivers/hd.c index 092726e..0b44d34 100644 --- a/drivers/hd.c +++ b/drivers/hd.c @@ -12,6 +12,7 @@ #include #include #include +#include #include //void hd_handler(pt_regs_t * regs, unsigned int irq) void hd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id) @@ -52,6 +53,7 @@ void hd_out(Dev dev, u32 nsect, u64 sect_nr, u32 cmd) if(!hd_controller_ready(dev)) { + printk("hd is not ready\n"); return ; } @@ -83,6 +85,7 @@ void hd_out(Dev dev, u32 nsect, u64 sect_nr, u32 cmd) #endif outb((u8)device, REG_DEVICE(dev)); outb((u8)cmd, REG_CMD(dev)); + } void _hd_read(Dev dev, u64 sect_nr, void *buf, u32 count, u32 cmd) @@ -161,8 +164,36 @@ void hd_print_identify(const char *buf) panic("Your hard disk "); } +void hd_pci_init(pci_device_t *pci) +{ + unsigned int v; + v = pci_read_config_word(pci_cmd(pci, PCI_COMMAND)); + printk(" ide pci command %04x\n", v); + v = pci_read_config_byte(pci_cmd(pci, PCI_PROGIF)); + printk(" ide pci program interface %02x\n", v); + v = pci_read_config_long(pci_cmd(pci, PCI_BAR4)); + printk(" ide pci Base IO Address Register %08x\n", v); + unsigned long iobase = v & 0xFFF0; + + v = inw(iobase+0); + printk(" ide bus master ide command register primary %04x\n", v); + v = inw(iobase+2); + printk(" ide bus master ide status register primary %04x\n", v); +} + void setup_hd() { + pci_device_t *pci = pci_find_device(PCI_VENDORID_INTEL, 0x2850); + if(pci == 0) + pci = pci_find_device(PCI_VENDORID_INTEL, 0x7010); // qemu + + if(pci == 0) + panic("can not find ide device"); + + printk("found ide pci device\n"); + + hd_pci_init(pci); + hd_controller_reset(ROOT_DEV); char *buf; diff --git a/drivers/hd.h b/drivers/hd.h index 5ea9f0d..44936b8 100644 --- a/drivers/hd.h +++ b/drivers/hd.h @@ -14,7 +14,7 @@ *-------------------------------------------------------------------------- */ -#ifndef _HD_H +#ifndef _HD_H #define _HD_H #include @@ -40,20 +40,20 @@ #define HD_CHL0_CMD_BASE 0x1F0 #define HD_CHL1_CMD_BASE 0x170 -#define HD_DATA 0 -#define HD_ERR 1 +#define HD_DATA 0 +#define HD_ERR 1 #define HD_ERR_BB 0x80 -#define HD_ERR_ECC 0x40 +#define HD_ERR_ECC 0x40 #define HD_ERR_ID 0x10 #define HD_ERR_AC 0x04 #define HD_ERR_TK 0x02 #define HD_ERR_DM 0x01 -#define HD_NSECTOR 2 -#define HD_LBAL 3 -#define HD_LBAM 4 -#define HD_LBAH 5 -#define HD_DEVICE 6 -#define HD_STATUS 7 /* controller status */ +#define HD_NSECTOR 2 +#define HD_LBAL 3 +#define HD_LBAM 4 +#define HD_LBAH 5 +#define HD_DEVICE 6 +#define HD_STATUS 7 /* controller status */ #define HD_STATUS_BSY 0x80 /* controller busy */ #define HD_STATUS_RDY 0x40 /* drive ready */ #define HD_STATUS_WF 0x20 /* write fault */ @@ -62,31 +62,31 @@ #define HD_STATUS_CRD 0x04 /* correct data */ #define HD_STATUS_IDX 0x02 /* index pulse */ #define HD_STATUS_ERR 0x01 /* error */ -#define HD_FEATURES HD_ERR -#define HD_CMD HD_STATUS -#define HD_CMD_IDLE 0x00 -#define HD_CMD_RECALIBRATE 0x10 -#define HD_CMD_READ 0x20 /* read data */ -#define HD_CMD_READ_EXT 0x24 /* read data (LBA-48 bit)*/ +#define HD_FEATURES HD_ERR +#define HD_CMD HD_STATUS +#define HD_CMD_IDLE 0x00 +#define HD_CMD_RECALIBRATE 0x10 +#define HD_CMD_READ 0x20 /* read data */ +#define HD_CMD_READ_EXT 0x24 /* read data (LBA-48 bit)*/ #define HD_CMD_WRITE 0x30 #define HD_CMD_WRITE_EXT 0x34 -#define HD_CMD_READ_VERIFY 0x40 -#define HD_CMD_FORMAT 0x50 -#define HD_CMD_SEEK 0x70 -#define HD_CMD_DIAG 0x90 -#define HD_CMD_SPECIFY 0x91 -#define HD_CMD_IDENTIFY 0xEC +#define HD_CMD_READ_VERIFY 0x40 +#define HD_CMD_FORMAT 0x50 +#define HD_CMD_SEEK 0x70 +#define HD_CMD_DIAG 0x90 +#define HD_CMD_SPECIFY 0x91 +#define HD_CMD_IDENTIFY 0xEC /* 硬盘控制寄存器 */ #define HD_CHL0_CTL_BASE 0x3F6 #define HD_CHL1_CTL_BASE 0x376 #define HD_CTL 0 -#define HD_CTL_NORETRY 0x80 /* disable access retry */ +#define HD_CTL_NORETRY 0x80 /* disable access retry */ #define HD_CTL_NOECC 0x40 /* disable ecc retry */ #define HD_CTL_EIGHTHEADS 0x08 /* more than 8 heads */ #define HD_CTL_RESET 0x04 /* reset controller */ -#define HD_CTL_DISABLE_INT 0x02 /* disable interrupts */ +#define HD_CTL_DISABLE_INT 0x02 /* disable interrupts */ #define HD_GET_CHL(dev) (0) /* 暂时还是只支持通道0 */ #define HD_GET_DEV(dev) (0) /* 暂时还是只支持一个硬盘 */ @@ -207,6 +207,6 @@ static inline void hd_rd_port(int port, void *buf, unsigned long count) #define hd_err(dev) ((inb(REG_STATUS(dev)) & HD_STATUS_ERR)) -#define USE_LBA_48 /* 使用LBA-48bit 模式操作硬盘 */ +#define USE_LBA_48 1 /* 使用LBA-48bit 模式操作硬盘 */ #endif //_HD_H diff --git a/drivers/keyboard.c b/drivers/keyboard.c index 6da523d..80a802c 100644 --- a/drivers/keyboard.c +++ b/drivers/keyboard.c @@ -18,6 +18,7 @@ #include #include #include +#include #define KBD_BUF_SIZE 256 static struct @@ -43,8 +44,9 @@ void kbd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id) ScanCode = inb(0x60); printk("%02x", ScanCode); - hd_out(0, 1, 1, 0x24); - return; // debug + + hd_out(0, 1, 1, HD_CMD_READ_EXT); + if(count < KBD_BUF_SIZE) { count++; diff --git a/include/io.h b/include/io.h index b2da013..55f4672 100644 --- a/include/io.h +++ b/include/io.h @@ -14,46 +14,14 @@ *-------------------------------------------------------------------------- */ -#ifndef _IO_H +#ifndef _IO_H #define _IO_H #include -#define outb_p(value,port)({ \ -__asm__("outb %%al,%%dx;nop;nop;nop;nop" \ -: \ -:"a" (value),"d" (port)); \ -}) - -#define inb_p(port)({ \ -u8 _bt; \ -__asm__("inb %%dx,%%al;nop;nop;nop;nop" \ -:"=a" (_bt) \ -:"d" (port)); \ -_bt; \ -}) - - -#define outb(value,port)({ \ -__asm__("outb %%al,%%dx" \ -: \ -:"a" (value),"d" (port)); \ -}) - -#define outw(value,port)({ \ -__asm__("outw %%ax,%%dx" \ -: \ -:"a" (value),"d" (port)); \ -}) -#define outl(value,port)({ \ -__asm__("outl %%eax,%%dx" \ -: \ -:"a" (value),"d" (port)); \ -}) - #define inb(port)({ \ u8 _bt; \ -asm("inb %%dx,%%al" \ +asm("inb %%dx,%%al" \ :"=a" (_bt) \ :"d" (port)); \ _bt; \ @@ -61,7 +29,7 @@ _bt; \ #define inw(port)({ \ u16 _bt; \ -asm("inw %%dx,%%ax" \ +asm("inw %%dx,%%ax" \ :"=a" (_bt) \ :"d" (port)); \ _bt; \ @@ -69,17 +37,47 @@ _bt; \ #define inl(port)({ \ u32 _bt; \ -asm("inl %%dx,%%eax" \ +asm("inl %%dx,%%eax" \ :"=a" (_bt) \ :"d" (port)); \ _bt; \ }) +#define outb(value, port)({ \ +__asm__("outb %%al,%%dx" \ +: \ +:"a" (value),"d" (port)); \ +}) + +#define outw(value, port)({ \ +__asm__("outw %%ax,%%dx" \ +: \ +:"a" (value),"d" (port)); \ +}) +#define outl(value, port)({ \ +__asm__("outl %%eax,%%dx" \ +: \ +:"a" (value),"d" (port)); \ +}) + +#define outb_p(value, port)({ \ +__asm__("outb %%al,%%dx;nop;nop;nop;nop" \ +: \ +:"a" (value),"d" (port)); \ +}) + +#define inb_p(port)({ \ +u8 _bt; \ +__asm__("inb %%dx,%%al;nop;nop;nop;nop" \ +:"=a" (_bt) \ +:"d" (port)); \ +_bt; \ +}) #define BUILDIO(bwl, type) \ static inline void ins##bwl(int port, void *buf, unsigned long count) \ { \ - asm volatile( "cld;rep;ins" #bwl \ + asm volatile("cld;rep;ins" #bwl \ : "+c"(count), "+D"(buf) : "d"(port)); \ } diff --git a/include/pci.h b/include/pci.h index 7910edc..4405aef 100644 --- a/include/pci.h +++ b/include/pci.h @@ -62,23 +62,30 @@ extern list_head_t pci_devs; +#define BARS_CNT 6 + typedef struct pci_device { list_head_t list; - unsigned long vendor; - unsigned long device; - unsigned long command; - unsigned long status; - unsigned long revision; - unsigned long classcode; - unsigned long hdr_type; - unsigned long bar0, bar1, bar2, bar3, bar4, bar5; - unsigned long sub_system_id; - unsigned long system_id; - unsigned long intr_line; - unsigned long intr_pin; - - unsigned long primary_bus_nr; /* only for pci bridge */ + unsigned int bus, dev, devfn; + + + unsigned int vendor; + unsigned int device; + unsigned int command; + unsigned int status; + unsigned int revision; + unsigned int classcode; + unsigned int hdr_type; + //unsigned int bar0, bar1, bar2, bar3, bar4, bar5; + unsigned int bars[BARS_CNT]; + unsigned int sub_system_id; + unsigned int system_id; + unsigned int intr_line; + unsigned int intr_pin; + + unsigned int primary_bus_nr; /* only for pci bridge */ + unsigned int secondary_bus_nr; } __attribute__((packed)) pci_device_t; @@ -118,6 +125,12 @@ typedef union pci_device #define PCI_HDRTYPE_NORMAL 0x00 #define PCI_HDRTYPE_BRIDGE 0x01 /* PCI-to-PCI Bridge */ #define PCI_HDRTYPE_CARDBUS 0x02 /* CardBus Bridge */ +#define PCI_BAR0 0x10 +#define PCI_BAR1 0x14 +#define PCI_BAR2 0x18 +#define PCI_BAR3 0x1C +#define PCI_BAR4 0x20 +#define PCI_BAR5 0x24 #define PCI_PRIMARY_BUS_NUMBER 0x18 #define PCI_SECONDARY_BUS_NUMBER 0x19 #define PCI_INTRLINE 0x3C @@ -157,6 +170,21 @@ typedef union pci_device #define PCI_VENDORID_NVIDIA 0x10DE #define PCI_VENDORID_REALTEK 0x10EC +pci_device_t *pci_find_device(unsigned int vendor, unsigned int device); + +static inline u32 pci_cmd(pci_device_t *pci, unsigned int reg) { + return PCI_CMD(pci->bus, pci->dev, pci->devfn, reg); +} + +int pci_read_config_byte(int cmd); +int pci_read_config_word(int cmd); +int pci_read_config_long(int cmd); +void pci_write_config_byte(int value, int cmd); +void pci_write_config_word(int value, int cmd); +void pci_write_config_long(int value, int cmd); + + + // PCI Bridge /* diff --git a/include/printk.h b/include/printk.h index 68ffed9..48a707b 100644 --- a/include/printk.h +++ b/include/printk.h @@ -14,9 +14,6 @@ *-------------------------------------------------------------------------- */ -#ifndef _PRINTK_H -#define _PRINTK_H +#pragma once int printk(char *fmtstr, ...); - -#endif //_PRINTK_H diff --git a/include/system.h b/include/system.h index 61c8167..b595f55 100644 --- a/include/system.h +++ b/include/system.h @@ -76,7 +76,11 @@ static inline void free_phys_pages(void *p) free_virt_pages((void*)va2pa(p)); } -extern inline void panic(char *msg); +#define panic(msg) do { \ + printk("PANIC:\"%s\" file:%s function:%s line:%d\n", \ + msg, __FILE__, __FUNCTION__, __LINE__); \ + while(1); \ +} while(0); extern char etext, edata, end; diff --git a/kernel/interrupts.S b/kernel/interrupts.S index 8ddd209..1bad6ad 100644 --- a/kernel/interrupts.S +++ b/kernel/interrupts.S @@ -18,31 +18,18 @@ #include #include -#define IRQ_SYMBL(a,b) irq_0x##a##b_handler -#define IRQ_LIST(x) \ -IRQ_SYMBL(x,0), \ -IRQ_SYMBL(x,1), \ -IRQ_SYMBL(x,2), \ -IRQ_SYMBL(x,3), \ -IRQ_SYMBL(x,4), \ -IRQ_SYMBL(x,5), \ -IRQ_SYMBL(x,6), \ -IRQ_SYMBL(x,7), \ -IRQ_SYMBL(x,8), \ -IRQ_SYMBL(x,9), \ -IRQ_SYMBL(x,A), \ -IRQ_SYMBL(x,B), \ -IRQ_SYMBL(x,C), \ -IRQ_SYMBL(x,D), \ -IRQ_SYMBL(x,E), \ -IRQ_SYMBL(x,F) - -#define DEF_IRQ(a,b) \ -.align 0x04,0x90; \ -.global irq_0x##a##b##_handler; \ -irq_0x##a##b##_handler: \ -pushl $0x##a##b; \ -jmp _irq_handler; +#define DEF_IRQ(a,b) \ +.align 0x04,0x90; \ +.global irq_0x##a##b##_handler; \ +irq_0x##a##b##_handler: \ +pushl $0x##a##b; \ +jmp _irq_handler; + +.align 0x04,0x90 +.global no_irq_handler +no_irq_handler: +pushl $0xFFFFFFFF +jmp _irq_handler DEF_IRQ(0,0) @@ -65,7 +52,7 @@ DEF_IRQ(0,F) .global _irq_handler .extern irq_handler -.extern schedule +.extern schedule _irq_handler: SAVE_REGS diff --git a/kernel/irq.c b/kernel/irq.c index f92fac0..713f95a 100644 --- a/kernel/irq.c +++ b/kernel/irq.c @@ -43,7 +43,14 @@ __attribute__ ((regparm(1))) void irq_handler(pt_regs_t *regs) { unsigned int irq = regs->irq; + if(irq >= NR_IRQS) + { + printk("invalid irq %d\n", irq); + return ; + } + irq_desc_t *p = irq_desc + irq; + irq_action_t *action = p->action; current->preempt_cnt++; @@ -51,9 +58,8 @@ __attribute__ ((regparm(1))) void irq_handler(pt_regs_t *regs) p->chip->ack(irq); sti(); - while(action) + while(action && action->handler) { - //action->handler(regs, irq); action->handler(irq, regs, action->dev_id); action = action->next; } diff --git a/kernel/system.c b/kernel/system.c index 7d9fe73..21cf10f 100644 --- a/kernel/system.c +++ b/kernel/system.c @@ -33,9 +33,3 @@ int sysc_reboot(int mode) } -void panic(char *msg) -{ - printk("PANIC:\"%s\" file:%s function:%s line:%d\n", - msg, __FILE__, __FUNCTION__, __LINE__); - while(1); -} diff --git a/pci/setuppci.c b/pci/setuppci.c index fdeaa35..abc858f 100644 --- a/pci/setuppci.c +++ b/pci/setuppci.c @@ -21,30 +21,48 @@ LIST_HEAD(pci_devs); -static int pci_read_config_byte(int cmd) +int pci_read_config_byte(int cmd) { outl(PCI_CONFIG_CMD(cmd), PCI_ADDR); return inb(PCI_DATA + (PCI_GET_CMD_REG(cmd) & 3)); } -static int pci_read_config_word(int cmd) +int pci_read_config_word(int cmd) { outl(PCI_CONFIG_CMD(cmd), PCI_ADDR); return inw(PCI_DATA + (PCI_GET_CMD_REG(cmd) & 2)); } -static int pci_read_config_long(int cmd) +int pci_read_config_long(int cmd) { outl(PCI_CONFIG_CMD(cmd), PCI_ADDR); return inl(PCI_DATA); } +void pci_write_config_byte(int value, int cmd) +{ + outl(PCI_CONFIG_CMD(cmd), PCI_ADDR); + outb(value & 0xFF, PCI_DATA); +} + +void pci_write_config_word(int value, int cmd) +{ + outl(PCI_CONFIG_CMD(cmd), PCI_ADDR); + outb(value & 0xFFFF, PCI_DATA); +} + +void pci_write_config_long(int value, int cmd) +{ + outl(PCI_CONFIG_CMD(cmd), PCI_ADDR); + outl(value, PCI_DATA); +} void scan_pci_bus(int bus) { u8 dev, devfn; u32 cmd; u32 v; + int i; printk("scanning PCI bus %d\n", bus); for(dev=0; dev<32; dev++) @@ -76,6 +94,10 @@ void scan_pci_bus(int bus) continue; } + pci->bus = bus; + pci->dev = dev; + pci->devfn = devfn; + pci->vendor = v; cmd = PCI_CMD(bus, dev, devfn, PCI_DEVICEID); @@ -93,46 +115,81 @@ void scan_pci_bus(int bus) cmd = PCI_CMD(bus, dev, devfn, PCI_INTRPIN); pci->intr_pin = pci_read_config_byte(cmd); + cmd = PCI_CMD(bus, dev, devfn, PCI_HDRTYPE); pci->hdr_type = pci_read_config_byte(cmd); pci->hdr_type &= PCI_HDRTYPE_MASK; + for(i=0; ibars[i] = pci_read_config_long(cmd); + } + +#if 0 if(pci->hdr_type == PCI_HDRTYPE_BRIDGE) { cmd = PCI_CMD(bus, dev, devfn, PCI_PRIMARY_BUS_NUMBER); pci->primary_bus_nr = pci_read_config_byte(cmd); - scan_pci_bus(pci->primary_bus_nr); + + cmd = PCI_CMD(bus, dev, devfn, PCI_SECONDARY_BUS_NUMBER); + pci->secondary_bus_nr = pci_read_config_byte(cmd); + + printk(" PCI BUS: %d %d\n", pci->primary_bus_nr, pci->secondary_bus_nr); + + scan_pci_bus(pci->secondary_bus_nr); } +#endif list_add(&pci->list, &pci_devs); } } } + +pci_device_t *pci_find_device(unsigned int vendor, unsigned int device) +{ + int i; + list_head_t *p; + pci_device_t *pci = 0; + + list_for_each(p, &pci_devs) + { + pci = list_entry(p, pci_device_t, list); + + if(pci->vendor == vendor && pci->device == device) + return pci; + } + + + return 0; +} + void dump_pci_dev() { list_head_t *p; + int i; + list_for_each(p, &pci_devs) { pci_device_t *pci = list_entry(p, pci_device_t, list); - printk("Vendor %x Device %x Class %x Revision %x IntrLine %d ", pci->vendor, pci->device, pci->classcode, pci->revision, pci->intr_line); + printk("Vendor %x Device %x Class %x Revision %x IntrLine %d Pin %d ", pci->vendor, pci->device, pci->classcode, pci->revision, pci->intr_line, pci->intr_pin); switch(pci->hdr_type) { case PCI_HDRTYPE_NORMAL: printk("Normal Device\n"); break; case PCI_HDRTYPE_BRIDGE: - printk("Aha PCI-PCI Bridge\n"); + printk("PCI-PCI Bridge\n"); break; case PCI_HDRTYPE_CARDBUS: - printk("Wow PCI-CardBus\n"); + printk("PCI-CardBus\n"); break; default: printk("Not Support!\n"); break; } } - while(1); } int probe_pci_bus() diff --git a/setup/setup.c b/setup/setup.c index b7d224f..385bf78 100644 --- a/setup/setup.c +++ b/setup/setup.c @@ -80,10 +80,11 @@ void setup_kernel() setup_irqs(); - setup_hd(); + setup_hd(); printk("%s\n", version); - + asm("cli;"); + while(1); return; while(1); // TODO MODIFY CODE BELOW diff --git a/setup/system.c b/setup/system.c index 69fa0d1..b57c2a6 100644 --- a/setup/system.c +++ b/setup/system.c @@ -49,11 +49,6 @@ void setup_idt() *((unsigned long *)(idtr+2)) = (unsigned long)idt; lidt(); } -void no_irq_handler() -{ - printk("no_irq_handler"); - //while(1); -} void setup_gate() { int i; @@ -86,6 +81,7 @@ do{ \ for(i=0x20; i<256; i++) set_sys_int(i, INTR_GATE, PL_KRNL, no_irq_handler); +#if 1 set_sys_int(0x20, INTR_GATE, PL_KRNL, irq_0x00_handler); set_sys_int(0x21, INTR_GATE, PL_KRNL, irq_0x01_handler); set_sys_int(0x22, INTR_GATE, PL_KRNL, irq_0x02_handler); @@ -103,6 +99,7 @@ do{ \ set_sys_int(0x2E, INTR_GATE, PL_KRNL, irq_0x0E_handler); set_sys_int(0x2F, INTR_GATE, PL_KRNL, irq_0x0F_handler); #endif +#endif } void setup_irqs() @@ -126,7 +123,12 @@ void setup_irqs() void hd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id); request_irq(0x00, clk_handler, "Intel 8254", "Clock Chip"); request_irq(0x01, kbd_handler, "Intel 8042", "PS/2 Keyboard"); - request_irq(0x0E, hd_handler, "IDE", "IDE"); + //request_irq(0x0E, hd_handler, "IDE", "IDE"); + for(i=2; i<16; i++) + { + request_irq(i, hd_handler, "IDE", "IDE"); + } + enable_irq(0x00); enable_irq(0x01); enable_irq(0x02);