]> Zhao Yanbai Git Server - kernel.git/commitdiff
support ide dma on my laptop. but not on qemu
authorAceVest <zhaoyanbai@126.com>
Mon, 30 Jun 2014 16:02:24 +0000 (00:02 +0800)
committerAceVest <zhaoyanbai@126.com>
Mon, 30 Jun 2014 16:02:24 +0000 (00:02 +0800)
drivers/ide.c
drivers/ide.h
drivers/keyboard.c
drivers/vga.c
include/task.h
kernel/cpuid.c
kernel/init.c
kernel/sched.c
kernel/setup.c
kernel/system.c

index 35f7f6f96e0d5ba61419f500ad31e33d3756fb1d..b608564540196eae2433ed89e8a2c21f5800b78f 100644 (file)
@@ -26,9 +26,14 @@ unsigned int HD_CHL1_CTL_BASE = 0x376;
 typedef struct _ide_drv
 {
     pci_device_t *pci;
-    u32_t iobase;
-    unsigned long cmd_out_cnt;
+    unsigned long cmd_cnt;
     unsigned long irq_cnt;
+
+    unsigned int iobase;
+
+    unsigned int bus_cmd;
+    unsigned int bus_status;
+    unsigned int bus_prdt;
 } ide_drive_t;
 
 ide_drive_t drv;
@@ -41,6 +46,8 @@ typedef struct prd
     unsigned int eot : 1;
 } prd_t;
 
+unsigned char *data = 0;
+
 void ide_pci_init(pci_device_t *pci)
 {
     unsigned int v;
@@ -54,9 +61,11 @@ void ide_pci_init(pci_device_t *pci)
     unsigned int iobase = pci_read_config_long(pci_cmd(pci, PCI_BAR4));
     printk(" ide pci Base IO Address Register %08x\n", iobase);
     iobase &= 0xFFFC;
-    drv.iobase = iobase;
+    drv.iobase      = iobase;
+    drv.bus_cmd     = iobase + PCI_IDE_CMD;
+    drv.bus_status  = iobase + PCI_IDE_STATUS;
+    drv.bus_prdt    = iobase + PCI_IDE_PRDT;
 
-    outb(0x20, drv.iobase+2);
 
     int i;
     printk(" BARS: ");
@@ -74,16 +83,17 @@ 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);
+    printd(18, "channel0: cmd %04x ctl %04x channel1: cmd %04x ctl %04x", HD_CHL0_CMD_BASE, HD_CHL0_CTL_BASE, HD_CHL1_CMD_BASE, HD_CHL1_CTL_BASE);
 }
 
 
 void ide_printd()
 {
-    printd(MPL_IDE, "ide cmd cnt %d irq cnt %d", drv.cmd_out_cnt,  drv.irq_cnt);
+    printd(MPL_IDE, "ide cmd cnt %d irq cnt %d", drv.cmd_cnt,  drv.irq_cnt);
 }
 void ide_cmd_out(Dev dev, u32 nsect, u64 sect_nr, u32 cmd)
 {
-    drv.cmd_out_cnt++;
+    drv.cmd_cnt++;
 
     outb(0x00,                      REG_CTL(dev));
     outb(0x40,                      REG_DEVSEL(dev));
@@ -109,7 +119,7 @@ void dump_pci_ide();
 void ide_status()
 {
     u8_t idest = inb(REG_STATUS(0));
-    u8_t pcist = inb(drv.iobase+PCI_IDE_STATUS);
+    u8_t pcist = inb(drv.bus_status);
     printk(" ide status %02x pci status %02x\n", idest, pcist);
 }
 
@@ -135,6 +145,7 @@ void init_pci_controller(unsigned int vendor, unsigned int device)
     if(pci != 0)
     {
         printk("Found PCI Vendor %04x Device %04x Class %04x IntrLine %d\n", vendor, device, pci->classcode, pci->intr_line);
+        printd(17, "Found PCI Vendor %04x Device %04x Class %04x IntrLine %d", vendor, device, pci->classcode, pci->intr_line);
         ide_pci_init(pci);
         drv.pci = pci;
     }
@@ -147,19 +158,21 @@ void ide_irq()
 
     drv.irq_cnt++;
 
-    status = inb(drv.iobase+PCI_IDE_STATUS);
+    status = inb(drv.bus_status);
     if(0 == (status & PCI_IDE_STATUS_INTR))
     {
         return ;
     }
 
     status |= PCI_IDE_STATUS_INTR;
-    outb(status, drv.iobase+PCI_IDE_STATUS);
-    outb(0x00,   drv.iobase+PCI_IDE_CMD);
+    outb(status, drv.bus_status);
+    outb(0x00,   drv.bus_cmd);
 
     insl(REG_DATA(0), buf, (512>>2));
     u16_t sig = *((u16_t *) (buf+510));
     printk("hard disk data %04x\n", sig);
+    sig = *((u16_t *) (data+510));
+    printk("hard disk data %04x\n", sig);
     ide_printd();
 
     up(&mutex);
@@ -230,12 +243,118 @@ void ide_read_identify()
     print_ide_identify(buf);
 }
 
+prd_t prd __attribute__((aligned(64*1024)));
+unsigned long gprdt = 0;
+
+#define DELAY400NS {        \
+    inb(HD_CHL0_CTL_BASE);  \
+    inb(HD_CHL0_CTL_BASE);  \
+    inb(HD_CHL0_CTL_BASE);  \
+    inb(HD_CHL0_CTL_BASE);  \
+}
+
+
+void ide_dma_pci_lba48()
+{
+#if 1
+    memset((void *)&prd, 0, sizeof(prd));
+    unsigned long addr = alloc_one_page(0);
+    data = (char *) addr;
+    memset(data, 0xBB, 512);
+    prd.addr = va2pa(addr);
+    prd.cnt  = 512;
+    prd.eot  = 1;
+    gprdt = va2pa(&prd);
+
+    printd(16, "gprdt %08x &prdt %08x prd.addr %08x addr %08x",
+            gprdt, &prd, prd.addr, addr);
+
+#if 0
+    pci_write_config_word(PCI_IDE_CMD_STOP, drv.bus_cmd);
+    unsigned char status;
+    status = pci_read_config_long(drv.bus_status);
+    pci_write_config_word(status | PCI_IDE_STATUS_INTR | PCI_IDE_STATUS_ERR, drv.bus_status);
+    pci_write_config_long(gprdt, drv.bus_prdt);
+    pci_write_config_word(PCI_IDE_CMD_WRITE, drv.bus_cmd);
+#else
+    outb(PCI_IDE_CMD_STOP, drv.bus_cmd);
+    unsigned short status = inb(drv.bus_status);
+    outb(status | PCI_IDE_STATUS_INTR | PCI_IDE_STATUS_ERR, drv.bus_status);
+    outl(gprdt, drv.bus_prdt);
+    outb(PCI_IDE_CMD_WRITE, drv.bus_cmd);
+#endif
+#endif
+
+#if 1
+    while ( 1 )
+    {
+        status = inb(HD_CHL0_CMD_BASE+HD_STATUS);
+        printk(" <%02x> ", status);
+        if((status & (HD_STATUS_BSY | HD_STATUS_DRQ)) == 0)
+        {
+            break;
+        }
+    }
+
+#endif
+    outb(0x00, HD_CHL0_CMD_BASE+HD_DEVSEL);
+    DELAY400NS;
+
+#if 1
+    while ( 1 )
+    {
+        status = inb(HD_CHL0_CMD_BASE+HD_STATUS);
+        printk(" <%02x> ", status);
+        if((status & (HD_STATUS_BSY | HD_STATUS_DRQ)) == 0)
+        {
+            break;
+        }
+    }
+#endif
+
+    printd(16, "---------------------------------------");
+
+    outb(0x00,  HD_CHL0_CTL_BASE);  // Device Control
+
+    outb(0x00,  HD_CHL0_CMD_BASE+HD_FEATURES);
+    outb(0x00,  HD_CHL0_CMD_BASE+HD_NSECTOR);
+    outb(0x00,  HD_CHL0_CMD_BASE+HD_LBAL);
+    outb(0x00,  HD_CHL0_CMD_BASE+HD_LBAM);
+    outb(0x00,  HD_CHL0_CMD_BASE+HD_LBAH);
+
+    outb(0x00,  HD_CHL0_CMD_BASE+HD_FEATURES);
+    outb(0x01,  HD_CHL0_CMD_BASE+HD_NSECTOR);
+    outb(0x00,  HD_CHL0_CMD_BASE+HD_LBAL);
+    outb(0x00,  HD_CHL0_CMD_BASE+HD_LBAM);
+    outb(0x00,  HD_CHL0_CMD_BASE+HD_LBAH);
+
+    outb(0x40,  HD_CHL0_CMD_BASE+HD_DEVSEL);
+
+    outb(0x25, HD_CHL0_CMD_BASE+HD_CMD);
+
+#if 0
+    pci_read_config_word(drv.bus_cmd);
+    pci_read_config_word(drv.bus_status);
+    pci_write_config_word(PCI_IDE_CMD_WRITE|PCI_IDE_CMD_START, drv.bus_cmd);
+    pci_read_config_word(drv.bus_cmd);
+    pci_read_config_word(drv.bus_status);
+#else
+    inb(drv.bus_cmd);
+    inb(drv.bus_status);
+    unsigned short w = inb(drv.bus_cmd);
+    outb(w|PCI_IDE_CMD_WRITE|PCI_IDE_CMD_START, drv.bus_cmd);
+    inb(drv.bus_cmd);
+    inb(drv.bus_status);
+#endif
+}
 
 void ide_init()
 {
     memset((void *)&drv, 0, sizeof(drv));
     init_pci_controller(PCI_VENDORID_INTEL, 0x2829);
     init_pci_controller(PCI_VENDORID_INTEL, 0x7010);
+#if 0
     ide_read_identify();
     ide_printd();
+#endif
 }
index 59edb92b38b28e0a60c28570c7e6e78148eb0a63..99a825288d74bcfa8c2aef6505d7ae44dbe7ddb1 100644 (file)
@@ -104,6 +104,15 @@ extern unsigned int HD_CHL1_CTL_BASE;
 
 
 #define PCI_IDE_CMD     0
+    #define PCI_IDE_CMD_STOP    0x00
+    #define PCI_IDE_CMD_READ    0x00
+    #define PCI_IDE_CMD_START   0x01
+    #define PCI_IDE_CMD_WRITE   0x08
 #define PCI_IDE_STATUS  2
-    #define PCI_IDE_STATUS_INTR 0x04
+    #define PCI_IDE_STATUS_ACT      0x01
+    #define PCI_IDE_STATUS_ERR      0x02
+    #define PCI_IDE_STATUS_INTR     0x04
+    #define PCI_IDE_STATUS_DRV0     0x20
+    #define PCI_IDE_STATUS_DRV1     0x40
+    #define PCI_IDE_STATUS_SIMPLEX  0x80
 #define PCI_IDE_PRDT    4
index 01d465a1d4207fa62a7b1ec6dccd14e229a844b0..d9d5e967a3415bfcc07a9d68106fc50f604365c7 100644 (file)
@@ -27,6 +27,7 @@ void ide_status();
 void debug_sched();
 void vga_dbg_toggle();
 int debug_wait_queue_put(unsigned int v);
+void ide_dma_pci_lba48();
 
 unsigned long kbd_cnt = 0;
 void kbd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
@@ -41,6 +42,15 @@ void kbd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
     
     printk("[%02x]", scan_code);
 
+    if(scan_code == 0x09)   // 8
+        ide_dma_pci_lba48();
+
+    if(scan_code == 0x0B)   // 0
+    {
+        asm("cli;");
+        while(1);
+    }
+
     if(scan_code == 0x13)   // r
         ide_debug();
 
@@ -70,7 +80,8 @@ void kbd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
 
     if(scan_code == 0x43);  // F9
     if(scan_code == 0x44);  // F10
-    if(scan_code == 0x57);  // F11
+    if(scan_code == 0x57)   // F11
+        poweroff();
     if(scan_code == 0x58)   // F12
         vga_dbg_toggle();
 
index db2e656cd4491bf576200ea741c9a37180e9334c..d2dd4359c1bf311981be1ae7ae57a615b0f2ddd9 100644 (file)
@@ -34,6 +34,7 @@ typedef struct {
 
 #define TAB_ALIGN               4
 #define TAB_MASK                (TAB_ALIGN-1)
+
 typedef struct {
     unsigned int id;
     vga_char_t *base;
@@ -110,7 +111,7 @@ void vga_scroll_up(vga_screen_t *s)
     if(delta <= 0)
         return;
 
-    vga_char_t *base = s->base; //(vga_char_t *) VIDEO_ADDR;
+    vga_char_t *base = s->base;
     vga_char_t *head = base + delta*CHARS_PER_LINE;
     vga_char_t *empt = base + (LINES_PER_SCREEN-delta)*CHARS_PER_LINE;
 
@@ -198,8 +199,6 @@ void vga_init()
     bvga = 1;
 }
 
-
-
 void vga_switch(unsigned int nr)
 {
     if(nr >= VGA_MAX_SCREEN_CNT)
index 0215fd71ca184e6a884036260774ff067edb085c..3873c0ed98a9e33d40ff3a253c0f30ba8675a7a4 100644 (file)
@@ -30,32 +30,34 @@ enum
     TASK_UNUSED,
     TASK_RUNNING,
     TASK_WAIT,
-    //TASK_UNINTERRUPTIBLE,
-    //TASK_INTERRUPTIBLE,
     TASK_EXITING
 };
 
+#define TASK_NAME_SIZE  32
+
 typedef union task_union
 {
     struct
     {
-        unsigned long   preempt_cnt;
+        unsigned long preempt_cnt;
 
-        unsigned long    esp0;    /* kernel stack */
+        unsigned long esp0;    /* kernel stack */
 
         /* for context switch */
-        unsigned long    esp;
-        unsigned long    eip;
+        unsigned long esp;
+        unsigned long eip;
 
-        long   weight;
+        long weight;
 
-        pid_t        pid;
-        pid_t        ppid;
+        pid_t pid;
+        pid_t ppid;
         unsigned int state;
-        long        exit_code;
+        long exit_code;
         unsigned long cr3;
 
-        long        tty;
+        long tty;
+
+        char name[TASK_NAME_SIZE];
 
         list_head_t list;
 
index 4972dc57bc6ad311c26e8e2ff4b583731bf9efee..13660ff20542ff1031dc8d72bb5426d000324c4a 100644 (file)
@@ -18,7 +18,7 @@
 #define TEST_FEATURE(val,bit,fea)\
 do{\
     if( ISSET_BIT(val,bit) )\
-        /*printk(" %s",fea)*/;\
+        printk(" %s",fea);\
 }while(0);
 
 typedef struct reg{ unsigned long eax,ebx,ecx,edx; }Reg,*pReg;
@@ -72,7 +72,7 @@ void    detect_cpu()
     memcpy(pbs + 36 , &r.ebx, 4);
     memcpy(pbs + 40 , &r.ecx, 4);
     memcpy(pbs + 44 , &r.edx, 4);
-    //printk("Model Name: %s\n",pbs);
+    printk("Model Name: %s\n",pbs);
     printk("%s", pbs);
 
      /**********************Get Number of Processors********************/
@@ -91,8 +91,8 @@ void    detect_cpu()
     TEST_FEATURE(fv, 7, "mce")
     TEST_FEATURE(fv, 8, "cxs")
     TEST_FEATURE(fv, 9, "apic")
-    //TEST_FEATURE(fv, 10, "Reserved")
-    //TEST_FEATURE(fv, 11, "SYSENTER/SYSEXIT")
+    TEST_FEATURE(fv, 10, "Reserved")
+    TEST_FEATURE(fv, 11, "SYSENTER/SYSEXIT")
     TEST_FEATURE(fv, 12, "mttr")
     TEST_FEATURE(fv, 13, "pge")    
     TEST_FEATURE(fv, 14, "mca")
index 737d80e338ecc02d31cda3c1220f84ac6d23579b..b03b442e9e41ab2e6ac4dbbf653a1ffb526e3824 100644 (file)
@@ -35,26 +35,19 @@ void init_task_entry()
     }
 }
 
+void kernel_task(void *entry)
+{
+    pt_regs_t regs;
+    memset((void*)&regs, 0, sizeof(regs));
+    regs.edx = (unsigned long) entry;
+    int pid = do_fork(&regs, FORK_KRNL);
+    printk("kernel task pid is %d\n", pid);
+}
 
 void root_task_entry()
 {
-    {
-        pt_regs_t regs;
-        memset((void*)&regs, 0, sizeof(regs));
-        regs.edx = (unsigned long) init_task_entry;
-        int pid = do_fork(&regs, FORK_KRNL);
-        printk("a pid is %d\n", pid);
-    }
-
-
-    {
-        pt_regs_t regs;
-        memset((void*)&regs, 0, sizeof(regs));
-        regs.edx = (unsigned long) init_task_entry;
-        int pid = do_fork(&regs, FORK_KRNL);
-        printk("b pid is %d\n", pid);
-    }
-
+    kernel_task(init_task_entry);
+    kernel_task(init_task_entry);
 
     int cnt = 0;
     while(1)
index 59d8f11bdb2b50e0d0b4216ae8fb65ea56d08b14..fd9d475293b0ddbe6db718d813cabbc30c05c11c 100644 (file)
@@ -61,6 +61,7 @@ void init_root_tsk()
     root_task.ppid   = 0;
     root_task.state  = TASK_RUNNING;
     root_task.weight = TASK_INIT_WEIGHT;
+    strcpy(root_task.name, "root_task");
     INIT_LIST_HEAD(&root_task.list);
 
     for(i=0; i<NR_OPENS; i++)
index 6d316cefd9e71f4165f6d796f51b7fcc716f793a..58c64d562a9aedd45b1fe4abb1db4dd4af208547 100644 (file)
@@ -73,7 +73,6 @@ void setup_kernel()
 
     setup_i8253();
 
-    detect_cpu();
 
     set_tss();
 
@@ -89,8 +88,10 @@ void setup_kernel()
     
     void ide_init();
     ide_init();
-    printk("%s\n", version);
 
+    detect_cpu();
+
+    printk("%s\n", version);
 
     return;
     while(1); // TODO MODIFY CODE BELOW
index 94749a303cdf96606c64eb7be6d484f256ff1f77..f6f4e29375020e6bbc0c3009a1fda0ddcd6e6393 100644 (file)
@@ -94,12 +94,17 @@ void setup_gate()
 }
 
 void ide_irq();
-void default_irq_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
+void default_ide_irq_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
 {
     printk("default irq handler %d \n", irq);
     ide_irq();
 }
 
+void default_irq_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
+{
+    printk("default irq handler %d \n", irq);
+}
+
 void setup_irqs()
 {
     extern void init_i8259();
@@ -119,17 +124,19 @@ void setup_irqs()
 
     request_irq(0x00, clk_handler,    "Intel 8254",    "Clock Chip");
     request_irq(0x01, kbd_handler,    "Intel 8042",    "PS/2 Keyboard");
-    for(i=3; i<16; i++)
+    request_irq(0x0A, default_ide_irq_handler,    "hard",    "IDE");
+    request_irq(0x0E, default_ide_irq_handler,    "hard",    "IDE");
+    for(i=0; i<16; i++)
     {
-        request_irq(i, default_irq_handler,   "default",    "default");
+        if(i != 0 && i != 1 && i != 10 && i != 14)
+            request_irq(i, default_irq_handler,   "default",    "default");
     }
 
     for(i=0; i<16; i++)
         open_irq(i);
 
     enable_irq();
-}
-
+} 
 void set_tss()
 {
     pTSS p = &tss;