From: AceVest Date: Fri, 23 May 2014 17:38:15 +0000 (+0800) Subject: fix bugs when enable disable ack 8259 irq X-Git-Tag: 0.3.0~61 X-Git-Url: http://zhaoyanbai.com/repos/man.dig.html?a=commitdiff_plain;h=2a47de2632fe9d354812e47f38c045c94442592c;p=kernel.git fix bugs when enable disable ack 8259 irq --- diff --git a/drivers/hd.c b/drivers/hd.c index 0b44d34..4afd449 100644 --- a/drivers/hd.c +++ b/drivers/hd.c @@ -14,10 +14,13 @@ #include #include #include +unsigned long iobase = 0; //void hd_handler(pt_regs_t * regs, unsigned int irq) void hd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id) { - printk("\nhd_handler:%d\n", irq); + //printk("\nhd_handler:%d\n", irq); + unsigned int v = inw(iobase+2); + printk("[%04x]", v); } int hd_controller_ready(Dev dev) @@ -45,47 +48,100 @@ void hd_controller_reset(unsigned int dev) void hd_out(Dev dev, u32 nsect, u64 sect_nr, u32 cmd) { + + { + unsigned long long sect_nr = 0; + unsigned int nsect = 1; + + cli(); + outb(0x00, REG_CTL(dev)); + + outb(0, REG_NSECTOR(dev)); // High + outb((u8)nsect, REG_NSECTOR(dev)); // Low + + outb((u8)((sect_nr>>24)&0xFF), REG_LBAL(dev)); + outb((u8)((sect_nr>> 0)&0xFF), REG_LBAL(dev)); + + outb((u8)((sect_nr>>32)&0xFF), REG_LBAM(dev)); + outb((u8)((sect_nr>> 8)&0xFF), REG_LBAM(dev)); + + outb((u8)((sect_nr>>40)&0xFF), REG_LBAH(dev)); + outb((u8)((sect_nr>>16)&0xFF), REG_LBAH(dev)); + + outb(0xE0, REG_DEVICE(dev)); + outb(0x24, REG_CMD(dev)); + sti(); + return ; + } + + + + + + assert(nsect > 0); assert(HD_GET_DEV(dev) < 2); // 0: ata-master 1:ata-slave - unsigned char device = 0xE0; + unsigned char device = 0x40; device |= ((HD_GET_DEV(dev)) << 4); +#if 1 + //hd_controller_reset(dev); if(!hd_controller_ready(dev)) { printk("hd is not ready\n"); return ; } +#endif - if(system.debug) +#if 0 { - hd_controller_reset(dev); + printk("ho \n"); + outb_p(0x00, 0x3F6); + + outb_p(0xE0, 0x1F6); + outb_p(0x00, 0x1F1); + outb_p(0x01, 0x1F2); // Sec cnt + outb_p(0x01, 0x1F3); + outb_p(0x00, 0x1F4); + outb_p(0x00, 0x1F5); + + outb_p(0x20, 0x1F7); + + return ; + while(1); + printk("*[%02x]*", inb(REG_STATUS(dev))); } +#endif + printk("hdout\n"); - outb(0x00, REG_CTL(dev)); - outb(0x00, REG_FEATURES(dev)); - outb((u8)nsect, REG_NSECTOR(dev)); -#ifdef USE_LBA_48 - /* - * LBA-48 bit - * 先写高位.再写低位. - */ - outb((u8)((sect_nr>>0x18)&0xFF), REG_LBAL(dev)); - outb((u8)((sect_nr>>0x20)&0xFF), REG_LBAM(dev)); - outb((u8)((sect_nr>>0x28)&0xFF), REG_LBAH(dev)); - - outb((u8)((sect_nr>>0x00)&0xFF), REG_LBAL(dev)); - outb((u8)((sect_nr>>0x08)&0xFF), REG_LBAM(dev)); - outb((u8)((sect_nr>>0x10)&0xFF), REG_LBAH(dev)); -#else - outb((u8)((sect_nr>>0x00)&0xFF), REG_LBAL(dev)); - outb((u8)((sect_nr>>0x08)&0xFF), REG_LBAM(dev)); - outb((u8)((sect_nr>>0x10)&0xFF), REG_LBAH(dev)); -#endif - outb((u8)device, REG_DEVICE(dev)); - outb((u8)cmd, REG_CMD(dev)); + //outb(0x00, REG_CTL(dev)); + outb(0x00, REG_DATA(dev)); + + outb(0, REG_NSECTOR(dev)); + outb((u8)nsect, REG_NSECTOR(dev)); + + + outb((u8)((sect_nr>>24)&0xFF), REG_LBAL(dev)); + outb((u8)((sect_nr>> 0)&0xFF), REG_LBAL(dev)); + outb((u8)((sect_nr>>32)&0xFF), REG_LBAM(dev)); + outb((u8)((sect_nr>> 8)&0xFF), REG_LBAM(dev)); + + outb((u8)((sect_nr>>40)&0xFF), REG_LBAH(dev)); + outb((u8)((sect_nr>>16)&0xFF), REG_LBAH(dev)); + + //outb((u8)device, REG_DEVICE(dev)); + outb(0xE0, REG_DEVICE(dev)); + outb(0x24, REG_CMD(dev)); + + //asm("int $47;"); + return ; + while(1); + printk("*[%02x]*", inb(REG_STATUS(dev))); + printk("iobase %x\n", iobase); + outl(1, iobase); } void _hd_read(Dev dev, u64 sect_nr, void *buf, u32 count, u32 cmd) @@ -164,29 +220,90 @@ void hd_print_identify(const char *buf) panic("Your hard disk "); } +typedef struct prd +{ + unsigned int addr; + unsigned int cnt : 16; + unsigned int reserved : 15; + unsigned int eot : 1; +} prd_t; + +#define PRD_CNT 1 +prd_t hd_prd_tbl[PRD_CNT] __attribute__((aligned(64*1024))); + void hd_pci_init(pci_device_t *pci) { unsigned int v; + unsigned int progif; 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)); + progif = v & 0xFF; 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; + iobase = v & 0xFFF0; + + pci_write_config_word(2, pci_cmd(pci, PCI_COMMAND)); 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); + + + + + prd_t *p = (prd_t *) va2pa(hd_prd_tbl); + printk("hd_prd_tbl %08x physical %08x sizeof prd %d\n", hd_prd_tbl, p, sizeof(prd_t)); + p->addr = 0; + p->cnt = 512; + p->reserved = 0; + p->eot = 1; + + + outl(p, iobase+4); + outl(32, iobase+2); + v = inw(iobase+2); + printk(" ide bus master ide status register primary %04x\n", v); + + + pci_write_config_byte(0xFE, pci_cmd(pci, PCI_INTRLINE)); + v = pci_read_config_byte(pci_cmd(pci, PCI_INTRLINE)); + printk("---- %x\n", v); + if((v & 0xFF) == 0xFE) { + printk("This Device needs IRQ assignment.\n"); + } else { + if(progif == 0x8A || progif == 0x80) { + printk("This is a Parallel IDE Controller which use IRQ 14 and IRQ 15.\n"); + } + } + + pci_write_config_byte(14, pci_cmd(pci, PCI_INTRLINE)); + v = pci_read_config_byte(pci_cmd(pci, PCI_INTRLINE)); + printk("---- %x\n", v); } +/* + * Bus Master IDE Status Register + * Bit2 Bit0 + * 0 0 Error Condition + * 0 1 DMA transfer is in progress + * 1 0 The IDE device generated an interrupt and the Physical Region Descriptors exhausted + * 1 1 The IDE device generated an interrupt + */ + void setup_hd() { +#if 1 pci_device_t *pci = pci_find_device(PCI_VENDORID_INTEL, 0x2850); if(pci == 0) pci = pci_find_device(PCI_VENDORID_INTEL, 0x7010); // qemu +#else + pci_device_t *pci = pci_find_device(PCI_VENDORID_INTEL, 0x2922); +#endif + if(pci == 0) panic("can not find ide device"); @@ -194,15 +311,15 @@ void setup_hd() hd_pci_init(pci); - hd_controller_reset(ROOT_DEV); + //hd_controller_reset(ROOT_DEV); char *buf; buf = (unsigned char *) alloc_one_page(0); assert(buf != NULL); - hd_read_identify(ROOT_DEV, buf); + //hd_read_identify(ROOT_DEV, buf); - hd_print_identify(buf); + //hd_print_identify(buf); free_pages((unsigned long)buf); } diff --git a/drivers/hd.h b/drivers/hd.h index 44936b8..d9e6d60 100644 --- a/drivers/hd.h +++ b/drivers/hd.h @@ -68,6 +68,7 @@ #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_READ_DMA 0x25 /* read data DMA LBA48 */ #define HD_CMD_WRITE 0x30 #define HD_CMD_WRITE_EXT 0x34 #define HD_CMD_READ_VERIFY 0x40 diff --git a/include/i8259.h b/include/i8259.h index eb4e498..2959123 100644 --- a/include/i8259.h +++ b/include/i8259.h @@ -31,6 +31,8 @@ #define PIC_CASCADE_IR 0x2 //The IR2 on Master Connect to Slave. +#define PIC_AEOI 1 + extern void init_i8259(); extern void mask_i8259(); diff --git a/include/io.h b/include/io.h index 55f4672..26ed9fd 100644 --- a/include/io.h +++ b/include/io.h @@ -43,6 +43,7 @@ asm("inl %%dx,%%eax" \ _bt; \ }) + #define outb(value, port)({ \ __asm__("outb %%al,%%dx" \ : \ diff --git a/kernel/i8259.c b/kernel/i8259.c index bb9d542..133c3a9 100644 --- a/kernel/i8259.c +++ b/kernel/i8259.c @@ -24,6 +24,8 @@ void mask_i8259() //mask all of 8259 outb_p(0xFF, PIC_MASTER_IMR); outb_p(0xFF, PIC_SLAVE_IMR); + //outb_p(0x0, PIC_MASTER_IMR); + //outb_p(0x0, PIC_SLAVE_IMR); } void init_i8259() @@ -31,29 +33,37 @@ void init_i8259() //Master... outb_p(0x11, PIC_MASTER_CMD); // ICW1 outb_p(0x20, PIC_MASTER_IMR); // ICW2: IR0-7 mapped to 0x20-0x27 - outb_p(1U<irq; + if(irq >= NR_IRQS) { printk("invalid irq %d\n", irq); @@ -57,7 +58,6 @@ __attribute__ ((regparm(1))) void irq_handler(pt_regs_t *regs) p->chip->ack(irq); sti(); - while(action && action->handler) { action->handler(irq, regs, action->dev_id); diff --git a/pci/setuppci.c b/pci/setuppci.c index abc858f..648d4d0 100644 --- a/pci/setuppci.c +++ b/pci/setuppci.c @@ -48,7 +48,7 @@ void pci_write_config_byte(int value, int cmd) void pci_write_config_word(int value, int cmd) { outl(PCI_CONFIG_CMD(cmd), PCI_ADDR); - outb(value & 0xFFFF, PCI_DATA); + outw(value & 0xFFFF, PCI_DATA); } void pci_write_config_long(int value, int cmd) @@ -126,6 +126,19 @@ void scan_pci_bus(int bus) pci->bars[i] = pci_read_config_long(cmd); } + if(pci->classcode == 0x0601) + //|| pci->classcode == 0x0106) + { + cmd = PCI_CMD(bus, dev, devfn, 0x0A); + v = pci_read_config_byte(cmd); + printk("subclass code %02x ", v); + cmd = PCI_CMD(bus, dev, devfn, 0x0B); + v = pci_read_config_byte(cmd); + printk("class code %02x\n", v); + + //while(1); + } + #if 0 if(pci->hdr_type == PCI_HDRTYPE_BRIDGE) { @@ -174,6 +187,7 @@ void dump_pci_dev() { pci_device_t *pci = list_entry(p, pci_device_t, list); 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: diff --git a/scripts/qemu b/scripts/qemu new file mode 100644 index 0000000..8b6f184 --- /dev/null +++ b/scripts/qemu @@ -0,0 +1 @@ +qemu-system-i386 -drive file=/root/kernel/HD.IMG,if=none,id=mydisk -device ich9-ahci,id=ahci -device ide-drive,drive=mydisk,bus=ahci.0 diff --git a/setup/setup.c b/setup/setup.c index 385bf78..a701670 100644 --- a/setup/setup.c +++ b/setup/setup.c @@ -17,6 +17,7 @@ #include #include #include +#include extern void setup_gdt(); extern void setup_idt(); @@ -55,6 +56,52 @@ const char *version = BUIDER; +extern void hd_out(Dev dev, u32 nsect, u64 sect_nr, u32 cmd); + +#include "hd.h" +void hd() +{ + unsigned long long sect_nr = 0; + unsigned int nsect = 1; + + cli(); + outb(0x00, REG_CTL(dev)); + + outb(0, REG_NSECTOR(dev)); // High + outb((u8)nsect, REG_NSECTOR(dev)); // Low + + outb((u8)((sect_nr>>24)&0xFF), REG_LBAL(dev)); + outb((u8)((sect_nr>> 0)&0xFF), REG_LBAL(dev)); + + outb((u8)((sect_nr>>32)&0xFF), REG_LBAM(dev)); + outb((u8)((sect_nr>> 8)&0xFF), REG_LBAM(dev)); + + outb((u8)((sect_nr>>40)&0xFF), REG_LBAH(dev)); + outb((u8)((sect_nr>>16)&0xFF), REG_LBAH(dev)); + + outb(0xE0, REG_DEVICE(dev)); + outb(0x24, REG_CMD(dev)); + sti(); + + int drq_retires = 100000; + while(!hd_drq(dev) && --drq_retires) + /* do nothing */; + + if(drq_retires == 0) + printk("hard disk no ready\n"); + else + printk("read finished\n"); + + char buf[1024]; + memset(buf, 0, 1024); + hd_rd_data(0, buf, 512); + + printk("SECTOR %04x\n", *(unsigned short *)(buf+510)); + + while(1); +} + + void setup_kernel() { extern char kernel_begin, kernel_end; @@ -67,25 +114,28 @@ void setup_kernel() setup_idt(); setup_gate(); - //setup_i8253(); + setup_i8253(); detect_cpu(); set_tss(); setup_sysc(); - setup_pci(); + //setup_pci(); setup_tasks(); setup_irqs(); + asm("sti;"); + hd(); setup_hd(); printk("%s\n", version); - asm("cli;"); - while(1); + //asm("cli;"); + //while(1); return; + hd_out(0, 1, 1, HD_CMD_READ_EXT); while(1); // TODO MODIFY CODE BELOW diff --git a/setup/system.c b/setup/system.c index b57c2a6..1b9daee 100644 --- a/setup/system.c +++ b/setup/system.c @@ -102,6 +102,16 @@ do{ \ #endif } +#include +void sata_handler(unsigned int irq, pt_regs_t * regs, void *dev_id) +{ + printk("sata irq handler %d \n", irq); + inb(REG_STATUS(0)); + char buf[1024]; + memset(buf, 0, 1024); + hd_rd_data(0, buf, 512); +} + void setup_irqs() { extern void init_i8259(); @@ -118,33 +128,26 @@ void setup_irqs() //extern void kbd_handler(pt_regs_t *, unsigned int); //extern void clk_handler(pt_regs_t *, unsigned int); //extern void hd_handler(pt_regs_t *, unsigned int); + extern void hd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id); void kbd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id); void clk_handler(unsigned int irq, pt_regs_t * regs, void *dev_id); 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"); - for(i=2; i<16; i++) + for(i=3; i<256; i++) { - request_irq(i, hd_handler, "IDE", "IDE"); + //request_irq(i, hd_handler, "IDE", "IDE"); + request_irq(i, sata_handler, "Intel 8086", "SATA"); } - enable_irq(0x00); + //request_irq(11, sata_handler, "Intel 8086", "SATA"); + //request_irq(0x11, sata_handler, "Intel 8086", "SATA"); + + //enable_irq(0x00); enable_irq(0x01); - enable_irq(0x02); - enable_irq(0x03); - enable_irq(0x04); - enable_irq(0x05); - enable_irq(0x06); - enable_irq(0x07); - enable_irq(0x08); - enable_irq(0x09); - enable_irq(0x0A); - enable_irq(0x0B); - enable_irq(0x0C); - enable_irq(0x0D); - enable_irq(0x0F); - enable_irq(0x0E); + for(i=2; i<16; i++) + enable_irq(i); asm("sti"); //asm("cli");