]> Zhao Yanbai Git Server - kernel.git/commitdiff
on the way to pci ide dma
authorAceVest <zhaoyanbai@126.com>
Wed, 28 May 2014 16:50:01 +0000 (00:50 +0800)
committerAceVest <zhaoyanbai@126.com>
Wed, 28 May 2014 16:50:01 +0000 (00:50 +0800)
Makefile
drivers/ide.c
drivers/ide.h [new file with mode: 0644]
setup/system.c

index b68a63c1764a430037dd5c2cbab2013cccefb2f9..d660621d9479b627f4e7f03f53f6bb95a2301280 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,6 +16,7 @@ OBJS := $(patsubst %,%.o,$(SOURCE_FILES))
 
 ${KERNELBIN}: ${OBJS}
        ld -M -T$(LINKSCRIPT) $(OBJS) -o $@ > $(SYSTEMMAP)
+       rm setup/setup.c.o
 
 %.S.o: %.S ${HEADER_FILES}
        ${CC} ${CFLAGS} $< -o $@
@@ -31,7 +32,10 @@ clean:
        rm -f $(KERNELBIN) $(SYSTEMMAP)
 
 install:
-       cp KERNEL.BIN /boot/
+       cp -p KERNEL.BIN /boot/
+       sync
+       md5sum /boot/KERNEL.BIN
+       md5sum KERNEL.BIN
 
 copy:
        ./scripts/copy.sh
index 7b1fc44b5af0b3de9660eb368b56a1d74a2d52dd..3b87bde676fae0895b947b02f409678fde0ff799 100644 (file)
@@ -11,6 +11,7 @@
 #include <printk.h>
 #include <assert.h>
 #include <io.h>
+#include <ide.h>
 #include <irq.h>
 #include <pci.h>
 #include <system.h>
@@ -22,92 +23,13 @@ unsigned int HD_CHL1_CMD_BASE = 0x170;
 unsigned int HD_CHL0_CTL_BASE = 0x3F6;
 unsigned int HD_CHL1_CTL_BASE = 0x376;
 
-#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
-
-#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
+typedef struct _hd_drv
+{
+    pci_device_t *pci;
+} hd_drive_t;
+
+hd_drive_t hdrv;
+
 
 void ide_read_identify()
 {
@@ -116,43 +38,22 @@ void ide_read_identify()
     // Select Drive
     outb_p(0xA0,  REG_DEVSEL(0));
 
-    int d;
-    d = 10000000;
-    while(d--);
+    //outb_p(0x00, REG_CTL(0));
 
     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);
@@ -195,7 +96,18 @@ void ide_read_identify()
     free_pages((unsigned long)buf);
 }
 
-int iobase;
+unsigned int iobase;
+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)));
+unsigned long prdt_phys = 0;
 void ide_pci_init(pci_device_t *pci)
 {
     unsigned int v;
@@ -207,11 +119,9 @@ void ide_pci_init(pci_device_t *pci)
     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;
-
-#if 0
-    pci_write_config_word(2, pci_cmd(pci, PCI_COMMAND));
+    iobase = v & 0xFFFC;
 
+#if 1
     v = inw(iobase+0);
     printk(" ide bus master ide command register primary %04x\n", v);
     v = inw(iobase+2);
@@ -226,22 +136,19 @@ void ide_pci_init(pci_device_t *pci)
         pci->bars[i] &= (~1UL);
     }
     printk("\n");
-#if 0
+
+#if 1
+
     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));
+    printk("iobase %04x hd_prd_tbl %08x physical %08x sizeof prd %d\n", iobase, 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);
+    prdt_phys = (unsigned long) p;
     printk(" ide bus master ide status register primary %04x\n", v);
 #endif
 
-
     HD_CHL0_CMD_BASE = pci->bars[0] ? pci->bars[0] : HD_CHL0_CMD_BASE;
     HD_CHL0_CTL_BASE = pci->bars[1] ? pci->bars[1] : HD_CHL0_CTL_BASE;
 
@@ -249,32 +156,30 @@ void ide_pci_init(pci_device_t *pci)
     HD_CHL1_CTL_BASE = pci->bars[3] ? pci->bars[3] : HD_CHL1_CTL_BASE;
 
     printk("channel0: cmd %04x ctl %04x channel1: cmd %04x ctl %04x\n", HD_CHL0_CMD_BASE, HD_CHL0_CTL_BASE, HD_CHL1_CMD_BASE, HD_CHL1_CTL_BASE);
-
-
-#if 0
-    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");
-        }
-    }
-#endif
 }
 
 void ide_hd_out(Dev dev, u32 nsect, u64 sect_nr, u32 cmd)
 {
+#if 1
+    outb(0x00, iobase);
+
+    //outl(prdt_phys, iobase+4);
+#if 1
+    outb((prdt_phys)&0xFF, iobase+0);
+    outb((prdt_phys>>8)&0xFF, iobase+1);
+    outb((prdt_phys>>16)&0xFF, iobase+2);
+    outb((prdt_phys>>24)&0xFF, iobase+3);
+#endif
+
+    outb(0x09,    iobase);
+#endif
 
     {
     unsigned long long sect_nr = 0;
     unsigned int nsect = 1;
+
     outb_p(0x00, REG_CTL(dev));
+    outb(0xE0,    REG_DEVSEL(dev));
 
     outb(0,           REG_NSECTOR(dev));    // High
     outb((u8)nsect,   REG_NSECTOR(dev));    // Low
@@ -288,12 +193,14 @@ void ide_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_DEVSEL(dev));
-    outb(0x24,    REG_CMD(dev));
+    outb(0x25,    REG_CMD(dev));
+
+
     }
 }
 
 
+void dump_pci_ide();
 void ide_debug()
 {
     u32    device;
@@ -304,44 +211,11 @@ void ide_debug()
 
     nsect    = (count + SECT_SIZE -1)/SECT_SIZE;
 
-    do
-    {
-        ide_hd_out(0, nsect,  sect_nr, HD_CMD_READ_EXT);
-
-        int drq_retires = 100000;
-        while(!hd_drq(dev) && --drq_retires)
-            /* do nothing */;
+    dump_pci_ide();
 
-        if(drq_retires != 0)
-            break;
-    }while(--retires);
-
-    if(retires == 0)
-        panic("hard disk is not ready");
-
-    char buf[1024];
-    memset(buf, 0xDD, 512);
-    insw(REG_DATA(0), buf, count>>1);
-    unsigned short *p = (unsigned short *) (buf+510);
-    printk("ide_debug %04x\n", *p);
-    //hd_rd_data(dev, buf, count);
-}
-
-void dbg()
-{
-    pci_device_t *pci;
-    pci = pci_find_device(PCI_VENDORID_INTEL, 0x2829);
-    if(pci != 0)
-    {
-        printk("0x2829    command %08x\n", pci->command);
-    }
-
-    pci = pci_find_device(PCI_VENDORID_INTEL, 0x2850);
-    if(pci != 0)
-    {
-        printk("0x2850    command %08x\n", pci->command);
-    }
+    ide_hd_out(0, nsect,  sect_nr, HD_CMD_READ_DMA);
 
+    printk("ide_debug\n");
 }
 
 void dump_pci_controller(unsigned int vendor, unsigned int device)
@@ -349,18 +223,53 @@ void dump_pci_controller(unsigned int vendor, unsigned int device)
     pci_device_t *pci = pci_find_device(vendor, device);
     if(pci != 0)
     {
-        printk("Found PCI Vendor %04x Device %04x Class %04x\n", vendor, device, pci->classcode);
+        printk("Found PCI Vendor %04x Device %04x Class %04x IntrLine %d\n", vendor, device, pci->classcode, pci->intr_line);
         ide_pci_init(pci);
+        hdrv.pci = pci;
     }
 }
 
-void ide_init()
+void dump_pci_ide()
 {
-    dump_pci_controller(PCI_VENDORID_INTEL, 0x7010);
+    //dump_pci_controller(PCI_VENDORID_INTEL, 0x7010);
     dump_pci_controller(PCI_VENDORID_INTEL, 0x2922);
     dump_pci_controller(PCI_VENDORID_INTEL, 0x2829);
-    dump_pci_controller(PCI_VENDORID_INTEL, 0x2850);
+}
+
+void ide_irq()
+{
+    u8_t sa = inb(REG_STATUS(0));
+#if 1
+    unsigned short *p = (unsigned short *) (0+510);
+    printk("||----------------- %s:%d  status %04x SIG: %04x\n", __func__, __LINE__, sa, *p);
+    outb(0x00, iobase);
+    unsigned short v = inw(iobase+2);
+    printk(" irq ide status register primary %04x\n", v);
+#else
+    char buf[1024];
+    memset(buf, 0xEE, 1024);
+    //hd_rd_data(0, buf, 512);
+    insw(REG_DATA(0), buf, 512>>1);
+    unsigned short *p = (unsigned short *) (buf+510);
+    unsigned short *s = (unsigned short *) (buf+512);
+    u8_t sb = inb(REG_STATUS(0));
+    printk("sata %04x sa %02x sb %02x REG_STATUS %x REG_DATA %x SIG %02x\n", *p, sa, sb, REG_STATUS(0), REG_DATA(0), *s);
+    dump_pci_ide();
+
+    unsigned short ctl = inw(iobase+0);
+    printk(" ide bus master ide command register primary %04x\n", ctl);
+    unsigned short sts = inw(iobase+2);
+    printk(" ide bus master ide status register primary %04x\n", sts);
+    outw(0x04, iobase+0);
+    outw(0x00, iobase);
+    outw(0x00, iobase+2);
+#endif
+}
+
+void ide_init()
+{
     pci_device_t *pci = 0;
+    dump_pci_ide();
 #if 0
     pci = pci_find_device(PCI_VENDORID_INTEL, 0x7010); // qemu
     if(pci == 0)
@@ -391,8 +300,10 @@ void ide_init()
     printk("found ide pci device\n");
     ide_pci_init(pci);
 #endif
-    return;
+
+#if 0
     outb_p(0x02, REG_CTL(0));
     ide_read_identify();
+#endif
 
 }
diff --git a/drivers/ide.h b/drivers/ide.h
new file mode 100644 (file)
index 0000000..7545571
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: ide.h
+ *      Author: Zhao Yanbai
+ *              Tue May 27 22:51:50 2014
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
+
+extern unsigned int HD_CHL0_CMD_BASE;
+extern unsigned int HD_CHL1_CMD_BASE;
+extern unsigned int HD_CHL0_CTL_BASE;
+extern unsigned int HD_CHL1_CTL_BASE;
+
+#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
+
+#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
index dd868de6ba351a7b083fdc86b5dece02e79a2f8b..f68902e58602eaab524ac435b44d3aa3f452932d 100644 (file)
@@ -23,6 +23,7 @@
 #include <assert.h>
 #include <i8259.h>
 #include <fs.h>
+#include <ide.h>
 
 void    setup_gdt()
 {
@@ -91,9 +92,11 @@ void    setup_gate()
     set_sys_int(0x2F, INTR_GATE, PRIVILEGE_KRNL, irq_0x0F_handler);    
 }
 
+void ide_irq();
 void default_irq_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
 {
     printk("default irq handler %d \n", irq);
+    ide_irq();
 }
 
 void    setup_irqs()