]> Zhao Yanbai Git Server - kernel.git/commitdiff
ide
authorAceVest <zhaoyanbai@126.com>
Sat, 24 May 2014 12:02:46 +0000 (20:02 +0800)
committerAceVest <zhaoyanbai@126.com>
Sat, 24 May 2014 12:02:46 +0000 (20:02 +0800)
drivers/hd.c
drivers/hd.h
drivers/ide.c [new file with mode: 0644]
drivers/keyboard.c
include/fs.h
pci/setuppci.c
scripts/qemu
setup/setup.c
setup/system.c

index 4afd4495d22f57bbae5d3554ea76b003b9033272..257abdb6344a702dc03f890d6ae87ffec8fc3ba0 100644 (file)
 #include <irq.h>
 #include <pci.h>
 #include <system.h>
+
+
+#define IDE_COMMAND 0
+#define IDE_STATUS  2
+#define IDE_PRDT    4
+
+
+
 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)
@@ -39,10 +47,10 @@ int    hd_controller_ready(Dev dev)
 void    hd_controller_reset(unsigned int dev)
 {
     outb_p(HD_CTL_RESET,    REG_CTL(dev));
-    outb_p(0,    REG_CTL(dev));
+    outb_p(0,               REG_CTL(dev));
     while(hd_bsy(dev))
     {
-        printk("bsy");
+        //printk("bsy");
     }
 }
 
@@ -54,7 +62,7 @@ void hd_out(Dev dev, u32 nsect, u64 sect_nr, u32 cmd)
     unsigned int nsect = 1;
 
     cli();
-    outb(0x00, REG_CTL(dev));
+    outb_p(0x00, REG_CTL(dev));
 
     outb(0,           REG_NSECTOR(dev));    // High
     outb((u8)nsect,   REG_NSECTOR(dev));    // Low
@@ -68,80 +76,12 @@ void hd_out(Dev dev, u32 nsect, u64 sect_nr, u32 cmd)
     outb((u8)((sect_nr>>40)&0xFF),    REG_LBAH(dev));
     outb((u8)((sect_nr>>16)&0xFF),    REG_LBAH(dev));
 
-    outb(0xE0,    REG_DEVICE(dev));
+    outb(0xE0,    REG_DEVSEL(dev));
     outb(0x24,    REG_CMD(dev));
     sti();
+    outl(4, iobase);
     return ;
     }
-
-
-
-
-
-
-    assert(nsect > 0);
-    assert(HD_GET_DEV(dev) < 2);    // 0: ata-master 1:ata-slave
-
-    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 0
-    {
-        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_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)
@@ -181,6 +121,15 @@ void    hd_read_identify(Dev dev, void *buf)
     _hd_read(dev, 0, buf, SECT_SIZE, HD_CMD_IDENTIFY);
 }
 
+typedef struct _ide_ident {
+    u16_t   dev_type;
+    u8_t    _space_[18];
+    u8_t    serial[34];
+    u8_t    model[44];
+    u8_t    capabilites[8];
+    u8_t    filed_valid[4];
+} ide_ident_t;
+
 void    hd_print_identify(const char *buf)
 {
     char    *p;
@@ -231,6 +180,15 @@ typedef struct prd
 #define PRD_CNT 1
 prd_t hd_prd_tbl[PRD_CNT] __attribute__((aligned(64*1024)));
 
+void dump()
+{
+    unsigned char *p = (unsigned char *) hd_prd_tbl[0].addr;
+    int i;
+    for(i=510; i<512; ++i)
+        printk("[%02x] ", p[i]);
+}
+
+
 void hd_pci_init(pci_device_t *pci)
 {
     unsigned int v;
@@ -252,8 +210,6 @@ void hd_pci_init(pci_device_t *pci)
     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;
@@ -311,15 +267,17 @@ void setup_hd()
 
     hd_pci_init(pci);
 
-    //hd_controller_reset(ROOT_DEV);
+    hd_controller_reset(ROOT_DEV);
+
+    return ;
 
     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 d9e6d6027da58a3535285e83b2a078105e084ec8..d5830bcbbaeeefaedce2946d2293975e6806f3fa 100644 (file)
 #include <printk.h>
 #include <assert.h>
 
-#if 0
-#define HD_CHL0_DATA        0x1F0
-#define HD_CHL0_ERR        0x1F1
-#define HD_CHL0_NSECTOR    0x1F2
-#define HD_CHL0_SECTOR    0x1F3
-#define HD_CHL0_CYLL        0x1F4
-#define HD_CHL0_CYLH        0x1F5
-#define HD_CHL0_CURRENT    0x1F6    /*101nhhhh
-                 n:0--First Hardisk, 1--Second Hardisk.
-                 hhhh: head*/
-#define HD_STATUS    0x1F7
-#define HD_CMD        HD_STATUS
-#endif
-
-
-/* 命令寄存器的起始值 */
+/* hard disk command base register */
 #define HD_CHL0_CMD_BASE    0x1F0
 #define HD_CHL1_CMD_BASE    0x170
 
 #define HD_DATA         0
+#define HD_FEATURES     1
 #define HD_ERR          1
 #define     HD_ERR_BB        0x80
 #define     HD_ERR_ECC       0x40
@@ -52,7 +38,8 @@
 #define HD_LBAL         3
 #define HD_LBAM         4
 #define HD_LBAH         5
-#define HD_DEVICE       6
+#define HD_DEVSEL       6
+#define HD_CMD          7
 #define HD_STATUS       7        /* controller status */
 #define     HD_STATUS_BSY       0x80    /* controller busy */
 #define     HD_STATUS_RDY       0x40    /* drive ready */
@@ -62,8 +49,6 @@
 #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_SPECIFY      0x91
 #define     HD_CMD_IDENTIFY     0xEC
 
-/* 硬盘控制寄存器 */
+/* hard disk control register */
 #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_NOECC        0x40    /* disable ecc retry */
 #define     HD_CTL_RESET        0x04    /* reset controller */
 #define     HD_CTL_DISABLE_INT  0x02    /* disable interrupts */
 
-#define     HD_GET_CHL(dev)        (0)    /* 暂时还是只支持通道0 */
-#define     HD_GET_DEV(dev)        (0)    /* 暂时还是只支持一个硬盘 */
+#define     HD_GET_CHL(dev)     (0)     /* only support channel 0 */
+#define     HD_GET_DEV(dev)     (0)     /* only support one hard disk */
 
 #define REG_CMD_BASE(dev, offset)  ( HD_GET_CHL(dev) ? (HD_CHL1_CMD_BASE+offset) : (HD_CHL0_CMD_BASE+offset) )
-
 #define REG_CTL_BASE(dev, offset)  ( HD_GET_CHL(dev) ? (HD_CHL1_CTL_BASE+offset) : (HD_CHL0_CTL_BASE+offset) )
 
-#if 1
-#define REG_DATA(dev)        REG_CMD_BASE(dev, HD_DATA)
+#define REG_DATA(dev)       REG_CMD_BASE(dev, HD_DATA)
 #define REG_ERR(dev)        REG_CMD_BASE(dev, HD_ERR)
 #define REG_NSECTOR(dev)    REG_CMD_BASE(dev, HD_NSECTOR)
-#define REG_LBAL(dev)        REG_CMD_BASE(dev, HD_LBAL)
-#define REG_LBAM(dev)        REG_CMD_BASE(dev, HD_LBAM)
-#define REG_LBAH(dev)        REG_CMD_BASE(dev, HD_LBAH)
-#define REG_DEVICE(dev)        REG_CMD_BASE(dev, HD_DEVICE)
-#define REG_STATUS(dev)        REG_CMD_BASE(dev, HD_STATUS)
-#define REG_FEATURES(dev)    REG_CMD_BASE(dev, HD_FEATURES)
+#define REG_LBAL(dev)       REG_CMD_BASE(dev, HD_LBAL)
+#define REG_LBAM(dev)       REG_CMD_BASE(dev, HD_LBAM)
+#define REG_LBAH(dev)       REG_CMD_BASE(dev, HD_LBAH)
+#define REG_DEVSEL(dev)     REG_CMD_BASE(dev, HD_DEVSEL)
+#define REG_STATUS(dev)     REG_CMD_BASE(dev, HD_STATUS)
+#define REG_FEATURES(dev)   REG_CMD_BASE(dev, HD_FEATURES)
 #define REG_CMD(dev)        REG_CMD_BASE(dev, HD_CMD)
-
 #define REG_CTL(dev)        REG_CTL_BASE(dev, HD_CTL)
-#else    
-#define REG_DATA    REG_CMD_BASE(0, HD_DATA)
-#define REG_ERR        REG_CMD_BASE(0, HD_ERR)
-#define REG_NSECTOR    REG_CMD_BASE(0, HD_NSECTOR)
-#define REG_LBAL    REG_CMD_BASE(0, HD_LBAL)
-#define REG_LBAM    REG_CMD_BASE(0, HD_LBAM)
-#define REG_LBAH    REG_CMD_BASE(0, HD_LBAH)
-#define REG_DEVICE    REG_CMD_BASE(0, HD_DEVICE)
-#define REG_STATUS    REG_CMD_BASE(0, HD_STATUS)
-#define REG_FEATURES    REG_CMD_BASE(0, HD_FEATURES)
-#define REG_CMD        REG_CMD_BASE(0, HD_CMD)
-
-#define REG_CTL        REG_CTL_BASE(0, HD_CTL)
-#endif
-
-/* 一个扇区包含的字节数 */
+
 #define SECT_SIZE    512
 
 
@@ -147,59 +115,8 @@ static inline void hd_rd_port(int port, void *buf, unsigned long count)
         for(i=0; i<n; i++)
             p[count+i] = value[i];
     }
-
-#if 0    
-    unsigned char *p =(unsigned char *)buf;
-    int l, w, b;
-    l = count & (~3UL);
-    w = count - l;
-    b = w & 0x01;
-    w = w - b;
-    printk("l:%d w:%d b:%d\n", l, w, b);
-    if(l)
-    {
-        insl(port, p, l);
-        p += l;
-    }
-    if(w)
-    {
-        insw(port, p+l, w);
-        p += w;
-    }
-    if(b)
-    {
-        insb(port, p+l+w, b);
-    }
-#endif
-#if 0
-    int i, rest;
-    unsigned char *p =(unsigned char *)buf;
-
-    rest = count & 3UL;
-    count-= rest;
-
-    printk("count:%d rest:%d\n", count, rest);
-
-    insl(port, p, count>>2);
-
-    for(i=0; i<rest; i++)
-        insb(port, p+count+i, 1);
-#endif
-#if 0
-    if(!(count & 0x3UL))
-    {
-        count >>= 2;
-        insl(port, buf, count-2);
-    }
-    else if(!(count & 0x1UL))
-    {
-        count >>= 1;
-        insw(port, buf, count);
-    }
-#endif
 }
 
-/* 从硬盘数据端口读取数据 */
 #define hd_rd_data(dev, buf, count) hd_rd_port(REG_DATA(dev), buf, count)
 
 #define hd_bsy(dev) ((inb(REG_STATUS(dev)) & HD_STATUS_BSY))
@@ -207,7 +124,4 @@ static inline void hd_rd_port(int port, void *buf, unsigned long count)
 #define hd_drq(dev) ((inb(REG_STATUS(dev)) & HD_STATUS_DRQ))
 #define hd_err(dev) ((inb(REG_STATUS(dev)) & HD_STATUS_ERR))
 
-
-#define USE_LBA_48   1 /* 使用LBA-48bit 模式操作硬盘 */
-
 #endif //_HD_H
diff --git a/drivers/ide.c b/drivers/ide.c
new file mode 100644 (file)
index 0000000..07610a4
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: ide.c
+ *      Author: Zhao Yanbai
+ *              Sat May 24 16:30:38 2014
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#include <types.h>
+#include <printk.h>
+#include <assert.h>
+#include <io.h>
+#include <hd.h>
+#include <irq.h>
+#include <pci.h>
+#include <system.h>
+
+/* ata command base register */
+#define HD_CHL0_CMD_BASE    0x1F0
+#define HD_CHL1_CMD_BASE    0x170
+
+#define HD_DATA         0
+#define HD_FEATURES     1
+#define HD_ERR          1
+#define     HD_ERR_BB        0x80
+#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_DEVSEL       6
+#define HD_CMD          7
+#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 */
+#define     HD_STATUS_SEEK_CMPT 0x10    /* seek complete */
+#define     HD_STATUS_DRQ       0x08    /* data transfer request */
+#define     HD_STATUS_CRD       0x04    /* correct data */
+#define     HD_STATUS_IDX       0x02    /* index pulse */
+#define     HD_STATUS_ERR       0x01    /* error */
+#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_READ_DMA     0x25    /* read data DMA LBA48 */
+#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
+
+/* hard disk control register */
+#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_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_GET_CHL(dev)     (0)     /* only support channel 0 */
+#define     HD_GET_DEV(dev)     (0)     /* only support one hard disk */
+
+#define REG_CMD_BASE(dev, offset)  ( HD_GET_CHL(dev) ? (HD_CHL1_CMD_BASE+offset) : (HD_CHL0_CMD_BASE+offset) )
+#define REG_CTL_BASE(dev, offset)  ( HD_GET_CHL(dev) ? (HD_CHL1_CTL_BASE+offset) : (HD_CHL0_CTL_BASE+offset) )
+
+#define REG_DATA(dev)       REG_CMD_BASE(dev, HD_DATA)
+#define REG_ERR(dev)        REG_CMD_BASE(dev, HD_ERR)
+#define REG_NSECTOR(dev)    REG_CMD_BASE(dev, HD_NSECTOR)
+#define REG_LBAL(dev)       REG_CMD_BASE(dev, HD_LBAL)
+#define REG_LBAM(dev)       REG_CMD_BASE(dev, HD_LBAM)
+#define REG_LBAH(dev)       REG_CMD_BASE(dev, HD_LBAH)
+#define REG_DEVSEL(dev)     REG_CMD_BASE(dev, HD_DEVSEL)
+#define REG_STATUS(dev)     REG_CMD_BASE(dev, HD_STATUS)
+#define REG_FEATURES(dev)   REG_CMD_BASE(dev, HD_FEATURES)
+#define REG_CMD(dev)        REG_CMD_BASE(dev, HD_CMD)
+#define REG_CTL(dev)        REG_CTL_BASE(dev, HD_CTL)
+
+#define SECT_SIZE    512
+
+
+#define hd_rd_data(dev, buf, count) hd_rd_port(REG_DATA(dev), buf, count)
+
+#define hd_bsy(dev) ((inb(REG_STATUS(dev)) & HD_STATUS_BSY))
+#define hd_rdy(dev) ((inb(REG_STATUS(dev)) & HD_STATUS_RDY))
+#define hd_drq(dev) ((inb(REG_STATUS(dev)) & HD_STATUS_DRQ))
+#define hd_err(dev) ((inb(REG_STATUS(dev)) & HD_STATUS_ERR))
+
+
+
+#define ATA_IDENT_DEVTYPE               0
+#define ATA_IDENT_CYLINDERS             2
+#define ATA_IDENT_HEADS                 6
+#define ATA_IDENT_SECTORS               12
+#define ATA_IDENT_SERIAL                20
+#define ATA_IDENT_MODEL                 54
+#define ATA_IDENT_CAPABILITIES          98
+#define ATA_IDENT_FIELDVALID            106
+#define ATA_IDENT_MAX_LBA               120
+#define ATA_IDENT_COMMANDSETS           164
+#define ATA_IDENT_MAX_LBA_EXT           200
+
+void ide_read_identify()
+{
+    unsigned char *buf = (unsigned char *) alloc_one_page(0);
+
+    // Select Drive
+    outb_p(0xA0,  REG_DEVSEL(0));
+
+    int d;
+    d = 10000000;
+    while(d--);
+
+    outb(0,   REG_NSECTOR(0));    // High
+    d = 10000000;
+    while(d--);
+    outb(1,   REG_NSECTOR(0));    // Low
+
+    d = 10000000;
+    while(d--);
+    outb(0,    REG_LBAL(0));
+    d = 10000000;
+    while(d--);
+    outb(1,    REG_LBAL(0));
+
+    d = 10000000;
+    while(d--);
+    outb(0,    REG_LBAM(0));
+    d = 10000000;
+    while(d--);
+    outb(0,    REG_LBAM(0));
+
+    d = 10000000;
+    while(d--);
+    outb(0,    REG_LBAH(0));
+    d = 10000000;
+    while(d--);
+    outb(0,    REG_LBAH(0));
+
+    d = 10000000;
+    while(d--);
+    outb_p(HD_CMD_IDENTIFY,   REG_CMD(0));
+
+    d = 10000000;
+    while(d--);
+
+    while(1) {
+        u8_t status = inb(REG_STATUS(0));
+        printk("status %02x\n", status);
+        if(status & HD_STATUS_ERR) {
+            printk("Hard Disk Error.\n");
+            break;
+        }
+        if(!(status & HD_STATUS_BSY) && (status & HD_STATUS_DRQ)) {
+            break;
+        }
+        int i = 1000000000;
+        while(i--);
+    }
+
+    insw(REG_DATA(0), buf, 256);
+
+    int i;
+    for(i=0; i<32; i+=2)
+    {
+        unsigned char *p;
+        unsigned char c;
+#if 1
+        p = buf+ATA_IDENT_SERIAL;
+        c = p[i + 1];
+        p[i+1] = p[i];
+        p[i] = c;
+#endif
+
+        p = buf + ATA_IDENT_MODEL;
+        c = p[i + 1];
+        p[i+1] = p[i];
+        p[i] = c;
+    }
+
+    buf[ATA_IDENT_SERIAL+32] = 0;
+    buf[ATA_IDENT_MODEL+32] = 0;
+
+    printk("Hard Disk SN: %s Model: %s\n", buf + ATA_IDENT_SERIAL, buf + ATA_IDENT_MODEL);
+
+    free_pages((unsigned long)buf);
+}
+
+int iobase;
+void ide_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);
+    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);
+
+    int i;
+    printk(" BARS: ");
+    for(i=0; i<5; ++i)
+        printk("%08x ", pci->bars[i]);
+    printk("\n");
+#if 0
+    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);
+#endif
+
+    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");
+        pci_write_config_byte(14, pci_cmd(pci, PCI_INTRLINE));
+        v = pci_read_config_byte(pci_cmd(pci, PCI_INTRLINE));
+        printk("---- %x\n", v);
+    } else {
+        if(progif == 0x8A || progif == 0x80) {
+            printk("This is a Parallel IDE Controller which use IRQ 14 and IRQ 15.\n");
+        }
+    }
+}
+
+void ide_init()
+{
+    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");
+
+    ide_pci_init(pci);
+    outb_p(0x02, REG_CTL(0));
+    ide_read_identify();
+
+}
index 80a802cd70f063d8410df8f5ea40ba9cbcbdea4f..f98e1f30f94e4651d2b04a23006de8ae3a6b6cc7 100644 (file)
@@ -42,6 +42,9 @@ void    kbd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
     unsigned char ScanCode;
     //printk("%s\n", dev_id);
     ScanCode = inb(0x60);
+
+    if(ScanCode == 0x01) // Esc
+        reboot();
     
     printk("%02x", ScanCode);
 
index e81046930103b44910c82b48de4a1739d39a1c30..0afecd17e05b902584e6131206b845210fb0b07f 100644 (file)
@@ -35,13 +35,13 @@ typedef struct partition
 
 /* 设备的主设备号. 占用两个字节. */
 #define DEV_MAJOR_UNUSED    0x0000
-#define DEV_MAJOR_MEM        0x0001
-#define DEV_MAJOR_TTY        0x0002
-#define DEV_MAJOR_IDE0        0x0003
+#define DEV_MAJOR_MEM       0x0001
+#define DEV_MAJOR_TTY       0x0002
+#define DEV_MAJOR_IDE0      0x0003
 #define DEV_MAJOR_HD        DEV_MAJOR_IDE0
-#define DEV_MAJOR_IDE1        0x0004
-#define DEV_MAJOR_SCSI0        0x0005
-#define DEV_MAJOR_SCSI2        0x0006
+#define DEV_MAJOR_IDE1      0x0004
+#define DEV_MAJOR_SCSI0     0x0005
+#define DEV_MAJOR_SCSI2     0x0006
 
 #define DEV_MAJOR_BITS        (16)
 #define DEV_MINOR_MASK        ((1UL << DEV_MAJOR_BITS) - 1)
index 648d4d02d8a48f0b77041af2f6f3423e4de94bd6..da35004497b426bbbebfb675ac6fac40b1b4bcf0 100644 (file)
@@ -126,34 +126,6 @@ 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)
-            {
-                cmd = PCI_CMD(bus, dev, devfn, PCI_PRIMARY_BUS_NUMBER);
-                pci->primary_bus_nr = pci_read_config_byte(cmd);
-
-                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);
         }
     }
index 8b6f184bcdc8b3c4175ba841f23f02f2ab44e99b..301d552e71e856ba04af9211ea1c8ad2ffb0be96 100644 (file)
@@ -1 +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
+qemu-system-i386 -device ahci,id=ahci -drive if=none,file=/root/kernel/HD.IMG,format=raw,id=sata -device ide-drive,drive=sata,bus=ahci.0
index a701670d3744fa12c2198257224b6d2c6c4e25a9..0ca82d4e3fb90f0a87da5971cc94e2f2b1a4d328 100644 (file)
@@ -29,7 +29,7 @@ extern void set_tss();
 extern void show_logo();
 extern void setup_tasks();
 extern void setup_root_dev();
-extern void setup_hd();
+extern void ide_init();
 extern void setup_fs();
 extern void setup_ext2();
 
@@ -79,26 +79,10 @@ void hd()
     outb((u8)((sect_nr>>40)&0xFF),    REG_LBAH(dev));
     outb((u8)((sect_nr>>16)&0xFF),    REG_LBAH(dev));
 
-    outb(0xE0,    REG_DEVICE(dev));
+    outb(0xE0,    REG_DEVSEL(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);
 }
 
 
@@ -121,16 +105,16 @@ void setup_kernel()
     set_tss();
 
     setup_sysc();
-    //setup_pci();
+    setup_pci();
 
     setup_tasks();
 
     setup_irqs();
 
-    asm("sti;");
-    hd();
+    //asm("sti;");
+    //hd();
 
-    setup_hd();
+    ide_init();
     printk("%s\n", version);
     //asm("cli;");
     //while(1);
index 1b9daeee772ff4f1b3b4bd349b5d974e06a7e470..fae026589c1961daa14137be37292d8bdf4328c8 100644 (file)
@@ -103,6 +103,7 @@ do{                            \
 }
 
 #include<hd.h>
+void dump();
 void    sata_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
 {
     printk("sata irq handler %d \n", irq);
@@ -110,6 +111,8 @@ void    sata_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
     char buf[1024];
     memset(buf, 0, 1024);
     hd_rd_data(0, buf, 512);
+    printk("SECTOR %04x\n", *(unsigned short *)(buf+510));
+    dump();
 }
 
 void    setup_irqs()