]> Zhao Yanbai Git Server - kernel.git/commitdiff
fix bugs when enable disable ack 8259 irq
authorAceVest <zhaoyanbai@126.com>
Fri, 23 May 2014 17:38:15 +0000 (01:38 +0800)
committerAceVest <zhaoyanbai@126.com>
Fri, 23 May 2014 17:38:15 +0000 (01:38 +0800)
drivers/hd.c
drivers/hd.h
include/i8259.h
include/io.h
kernel/i8259.c
kernel/irq.c
pci/setuppci.c
scripts/qemu [new file with mode: 0644]
setup/setup.c
setup/system.c

index 0b44d34d328f730648875907619d794ac3beb104..4afd4495d22f57bbae5d3554ea76b003b9033272 100644 (file)
 #include <irq.h>
 #include <pci.h>
 #include <system.h>
+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);
 }
index 44936b8a301f12d02bad4a938454ba027edfd434..d9e6d6027da58a3535285e83b2a078105e084ec8 100644 (file)
@@ -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
index eb4e4980e634bfaa4bf5100b679605cbccac4c5a..29591235e1d58021ebd91dc53e710a5c099d391f 100644 (file)
@@ -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();
 
index 55f4672229e309ad8dcf4532dffba0426fb8ff69..26ed9fd6000887293d3436f8722b9d0ac838d622 100644 (file)
@@ -43,6 +43,7 @@ asm("inl %%dx,%%eax"            \
 _bt;                            \
 })
 
+
 #define outb(value, port)({     \
 __asm__("outb %%al,%%dx"        \
 :                               \
index bb9d542f69a4df3b7e00295042ee6736293609e2..133c3a9bfbae21d90a592fc0410a523603f2440a 100644 (file)
@@ -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<<PIC_CASCADE_IR, PIC_MASTER_IMR); //IR2 Connect Slave.
+    outb_p((1U<<PIC_CASCADE_IR), PIC_MASTER_IMR); //IR2 Connect Slave.
+#if PIC_AEOI
+    outb_p(0x03, PIC_MASTER_IMR);
+#else
     outb_p(0x01, PIC_MASTER_IMR);    // Normal EOI
-    //Auto EOI:outb_p(0x03, PIC_MASTER_CMDB);
+#endif
     
     //Slave...
     outb_p(0x11, PIC_SLAVE_CMD);
     outb_p(0x28, PIC_SLAVE_IMR); // IR0-7 mapped to 0x28-0x2F
     outb_p(PIC_CASCADE_IR, PIC_SLAVE_IMR);
+#if PIC_AEOI
+    outb_p(0x03, PIC_SLAVE_IMR);
+#else
     outb_p(0x01, PIC_SLAVE_IMR);
-    //Auto EOI:outb_p(0x01, PIC_SLAVE_CMDB);
+#endif
     mask_i8259();
 }
 
 int enable_i8259_irq(unsigned int irq)
 {
-    unsigned char mask = ~(1 << irq);
+    unsigned char mask = 0;
     if(irq & 8)
     {
+        mask = ~(1 << (irq-8));
         mask &= inb(PIC_SLAVE_IMR);
         outb( mask, PIC_SLAVE_IMR);
     }
     else
     {
+        mask = ~(1 << irq);
         mask &= inb(PIC_MASTER_IMR);
         outb_p( mask, PIC_MASTER_IMR);
     }
@@ -61,14 +71,16 @@ int enable_i8259_irq(unsigned int irq)
 
 int disable_i8259_irq(unsigned int irq)
 {
-    unsigned char mask = 1 << irq;
+    unsigned char mask = 0;
     if(irq & 8)
     {
+        mask |= (1 << (irq-8));
         mask |= inb(PIC_SLAVE_IMR);
         outb( mask, PIC_SLAVE_IMR);
     }
     else
     {
+        mask |= (1 << irq);
         mask |= inb(PIC_MASTER_IMR);
         outb( mask, PIC_MASTER_IMR);
     }
@@ -76,25 +88,35 @@ int disable_i8259_irq(unsigned int irq)
 
 void mask_ack_i8259_irq(unsigned int irq)
 {
-    unsigned int mask = 1 << irq;
+    unsigned char mask = 0;
 
     if(irq & 8) // Slave
     {
+        mask |= (1 << (irq-8));
         mask |= inb(PIC_SLAVE_IMR);
         // Mask
         outb(mask, PIC_SLAVE_IMR);
+#if PIC_AEOI
+        // ...
+#else
         // Specific EOI to slave
         outb(0x60 + (irq & 0x07), PIC_SLAVE_CMD);
         // Specific EOI to master
         outb(0x60 + (PIC_CASCADE_IR & 0x07), PIC_MASTER_CMD);
+#endif
     }
     else        // Master
     {
+        mask |= (1 << irq);
         mask |= inb(PIC_MASTER_IMR);
         // Mask
         outb(mask, PIC_MASTER_IMR);
+#if PIC_AEOI
+        // ...
+#else
         // Specific EOI to master
         outb(0x60 + irq, PIC_MASTER_CMD);
+#endif
     }
 }
 
index 713f95aa295532f11dea773f37472e8f99f5b6ac..43c63d0913bb14293589af1cc4c7767737fdf7b7 100644 (file)
@@ -43,6 +43,7 @@ __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);
@@ -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);
index abc858f66ecc1e14416bb414447eb89938c7b77d..648d4d02d8a48f0b77041af2f6f3423e4de94bd6 100644 (file)
@@ -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 (file)
index 0000000..8b6f184
--- /dev/null
@@ -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
index 385bf781e192e2ecb2475069691c617e3a5ced90..a701670d3744fa12c2198257224b6d2c6c4e25a9 100644 (file)
@@ -17,6 +17,7 @@
 #include <printk.h>
 #include <system.h>
 #include <io.h>
+#include <hd.h>
 
 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
 
 
index b57c2a624e8f2375abb4cc561d89e9ac64059419..1b9daeee772ff4f1b3b4bd349b5d974e06a7e470 100644 (file)
@@ -102,6 +102,16 @@ do{                            \
 #endif
 }
 
+#include<hd.h>
+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");