From b2ca84ea96e38a5cef4d0b41372b8b2c51673263 Mon Sep 17 00:00:00 2001 From: AceVest Date: Sun, 1 Jun 2014 20:47:23 +0800 Subject: [PATCH] remove dma --- drivers/ide.c | 250 ++++++++++++++++++++-------------------------- drivers/ide.c.bak | 217 ++++++++++++++++++++++++++++++++++++++++ drivers/ide.h | 7 ++ 3 files changed, 332 insertions(+), 142 deletions(-) create mode 100644 drivers/ide.c.bak diff --git a/drivers/ide.c b/drivers/ide.c index 05a60eb..edaa0bc 100644 --- a/drivers/ide.c +++ b/drivers/ide.c @@ -19,18 +19,17 @@ unsigned int HD_CHL0_CMD_BASE = 0x1F0; unsigned int HD_CHL1_CMD_BASE = 0x170; - unsigned int HD_CHL0_CTL_BASE = 0x3F6; unsigned int HD_CHL1_CTL_BASE = 0x376; -typedef struct _hd_drv +typedef struct _ide_drv { pci_device_t *pci; -} hd_drive_t; + u32_t iobase; +} ide_drive_t; -hd_drive_t hdrv; +ide_drive_t drv; -unsigned int iobase; typedef struct prd { unsigned int addr; @@ -39,29 +38,22 @@ typedef struct prd unsigned int eot : 1; } prd_t; -#define PRD_CNT 1 -#define USE_DMA 0 -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; - 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 & 0xFFFC; -#if USE_DMA - v = inb(iobase+0); - printk(" ide bus master ide command register primary %04x\n", v); - v = inb(iobase+2); - printk(" ide bus master ide status register primary %04x\n", v); -#endif + 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; + + outb(0x20, drv.iobase+2); int i; printk(" BARS: "); @@ -72,17 +64,6 @@ void ide_pci_init(pci_device_t *pci) } printk("\n"); -#if USE_DMA - prd_t *p = (prd_t *) va2pa(hd_prd_tbl); - 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; - 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; @@ -92,41 +73,22 @@ void ide_pci_init(pci_device_t *pci) 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); } -void ide_hd_out(Dev dev, u32 nsect, u64 sect_nr, u32 cmd) +void ide_cmd_out(Dev dev, u32 nsect, u64 sect_nr, u32 cmd) { -#if USE_DMA - 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(0x00, REG_CTL(dev)); + outb(0x40, REG_DEVSEL(dev)); - outb(0x09, iobase); -#endif + outb(0, REG_NSECTOR(dev)); // High + outb((u8)((sect_nr>>24)&0xFF), REG_LBAL(dev)); + outb((u8)((sect_nr>>32)&0xFF), REG_LBAM(dev)); + outb((u8)((sect_nr>>40)&0xFF), REG_LBAH(dev)); - { - unsigned long long sect_nr = 0; - unsigned int nsect = 1; + outb((u8)nsect, REG_NSECTOR(dev)); // Low + outb((u8)((sect_nr>> 0)&0xFF), REG_LBAL(dev)); + outb((u8)((sect_nr>> 8)&0xFF), REG_LBAM(dev)); + outb((u8)((sect_nr>>16)&0xFF), REG_LBAH(dev)); - outb(0x00, REG_CTL(dev)); - outb(0x40, REG_DEVSEL(dev)); - - outb(0, REG_NSECTOR(dev)); // High - outb((u8)((sect_nr>>24)&0xFF), REG_LBAL(dev)); - outb((u8)((sect_nr>>32)&0xFF), REG_LBAM(dev)); - outb((u8)((sect_nr>>40)&0xFF), REG_LBAH(dev)); - - outb((u8)nsect, REG_NSECTOR(dev)); // Low - outb((u8)((sect_nr>> 0)&0xFF), REG_LBAL(dev)); - outb((u8)((sect_nr>> 8)&0xFF), REG_LBAM(dev)); - outb((u8)((sect_nr>>16)&0xFF), REG_LBAH(dev)); - - outb(0x24, REG_CMD(dev)); - } + outb(cmd, REG_CMD(dev)); } @@ -135,7 +97,7 @@ void dump_pci_ide(); void ide_status() { u8_t idest = inb(REG_STATUS(0)); - u8_t pcist = inb(iobase+2); + u8_t pcist = inb(drv.iobase+PCI_IDE_STATUS); printk(" ide status %02x pci status %02x\n", idest, pcist); } @@ -144,115 +106,119 @@ void ide_debug() u32 device; u32 nsect = 1; u32 retires = 100; - u32 sect_nr = 1; + u32 sect_nr = 0; int count=SECT_SIZE; nsect = (count + SECT_SIZE -1)/SECT_SIZE; - dump_pci_ide(); - - ide_hd_out(0, nsect, sect_nr, HD_CMD_READ_DMA); + ide_cmd_out(0, nsect, sect_nr, HD_CMD_READ_EXT); printk("ide_debug\n"); } -void dump_pci_controller(unsigned int vendor, unsigned int device) +void init_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 IntrLine %d\n", vendor, device, pci->classcode, pci->intr_line); ide_pci_init(pci); - hdrv.pci = pci; + drv.pci = pci; } } -void dump_pci_ide() -{ - dump_pci_controller(PCI_VENDORID_INTEL, 0x2922); - dump_pci_controller(PCI_VENDORID_INTEL, 0x2829); - //dump_pci_controller(PCI_VENDORID_INTEL, 0x7000); -} - 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); - u8_t v = inb(iobase+2); - printk(" irq pci ide status register primary %02x\n", v); - v |= 0x04; - printk(" irq pci ide status before write %02x\n", v); - //outb(v, iobase+2); - v = inb(iobase+2); - printk(" irq pci ide status after write %02x\n", v); - outb(0x00, iobase); + u8_t status = inb(REG_STATUS(0)); char buf[1024]; memset(buf, 0xEE, 1024); - insw(REG_DATA(0), buf, 512>>1); - unsigned short *s = (unsigned short *) (buf+510); + + status = inb(drv.iobase+PCI_IDE_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); + + insl(REG_DATA(0), buf, 512>>2); + u16_t *s = (u16_t *) (buf+510); printk("insw %04x\n", *s); -#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() + +void print_ide_identify(const char *buf) { - pci_device_t *pci = 0; - //dump_pci_ide(); -#if 0 - pci = pci_find_device(PCI_VENDORID_INTEL, 0x7010); // qemu - if(pci == 0) + char *p; + short *ident; + int i; + + ident = (short *) buf; + + char hd_sn[32]; /* 20 bytes */ + char hd_model[64]; /* 40 bytes */ + short hd_capabilites = ident[49]; + short hd_supt_inst_set = ident[83]; + + p = (char *) (ident+10); + for(i=0; i<20; i++) { - printk("qemu ide controller\n"); + hd_sn[i] = p[i]; } -#endif -#if 0 - pci_device_t *pci = pci_find_device(PCI_VENDORID_INTEL, 0x2922); - if(pci != 0) - printk("laptop ide....\n"); -#endif -#if 0 - pci_device_t *pci = pci_find_device(PCI_VENDORID_INTEL, 0x2829); - if(pci != 0) - printk("laptop achi....\n"); -#endif -#if 0 - pci_device_t *pci = pci_find_device(PCI_VENDORID_INTEL, 0x2850); - if(pci != 0) - printk("laptop ide....\n"); -#endif + hd_sn[i] = 0; + + p = (char *) (ident+27); + for(i=0; i<40; i++) + { + hd_model[i] = p[i]; + } + hd_model[i] = 0; + + + printk("Hard Disk Vendor: %s\n", hd_sn); + printk("Hard Disk Model: %s\n", hd_model); + printk("Hard Disk Support LBA: %s\n", + (hd_capabilites & 0x0200) ? "Yes" : "No"); + printk("Hard Disk Support LBA-48bit: %s\n", + (hd_supt_inst_set & 0x0400) ? "Yes" : "No"); + + if(!(hd_supt_inst_set & 0x0400)) + panic("Your hard disk "); +} + +void ide_read_identify() +{ + outb(0x02, REG_CTL(0)); + outb(0x40, REG_DEVSEL(dev)); + outb(HD_CMD_IDENTIFY, REG_CMD(dev)); + + u32 retires = 100; -#if 0 - if(pci == 0) - panic("can not find ide device"); + do + { + int drq_retires = 100000; + while(!hd_drq(dev) && --drq_retires) + /* do nothing */; - printk("found ide pci device\n"); - ide_pci_init(pci); -#endif + if(drq_retires != 0) + break; + }while(--retires); + + if(retires == 0) + panic("hard disk is not ready"); + + char buf[1024]; + insl(REG_DATA(0), buf, 512>>2); + print_ide_identify(buf); +} -#if 0 - outb_p(0x02, REG_CTL(0)); - ide_read_identify(); -#endif +void ide_init() +{ + ide_read_identify(); + init_pci_controller(PCI_VENDORID_INTEL, 0x2829); + init_pci_controller(PCI_VENDORID_INTEL, 0x7010); } diff --git a/drivers/ide.c.bak b/drivers/ide.c.bak new file mode 100644 index 0000000..7857ad1 --- /dev/null +++ b/drivers/ide.c.bak @@ -0,0 +1,217 @@ +/* + * ------------------------------------------------------------------------ + * File Name: ide.c + * Author: Zhao Yanbai + * Sat May 24 16:30:38 2014 + * Description: none + * ------------------------------------------------------------------------ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +unsigned int HD_CHL0_CMD_BASE = 0x1F0; +unsigned int HD_CHL1_CMD_BASE = 0x170; + + +unsigned int HD_CHL0_CTL_BASE = 0x3F6; +unsigned int HD_CHL1_CTL_BASE = 0x376; + +typedef struct _hd_drv +{ + pci_device_t *pci; + u32_t iobase; +} hd_drive_t; + +hd_drive_t hdrv; + +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 +#define USE_DMA 0 +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; + 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 & 0xFFFC; + + outb(0x20, iobase+2); + +#if 1 //USE_DMA + v = inb(iobase+0); + printk(" ide bus master ide command register primary %04x\n", v); + v = inb(iobase+2); + printk(" ide bus master ide status register primary %04x\n", v); +#endif + + int i; + printk(" BARS: "); + for(i=0; i<6; ++i) + { + printk("%08x ", pci->bars[i]); + pci->bars[i] &= (~1UL); + } + printk("\n"); + +#if 1 // USE_DMA + prd_t *p = (prd_t *) hd_prd_tbl; + printk("iobase %04x hd_prd_tbl %08x physical %08x sizeof prd %d\n", iobase, hd_prd_tbl, p, sizeof(prd_t)); + unsigned long addr = alloc_one_page(0); + p->addr = va2pa(addr); + printk("ADDR %08x %08x %08x\n", addr, p->addr, va2pa(addr)); + p->cnt = 512; + p->reserved = 0; + p->eot = 1; + prdt_phys = (unsigned long) va2pa(p); + printk(" ide bus master ide status register primary %04x\n", v); + + printk("prdt_phys %08x p->addr %08x hd_prd_tbl[0].addr %08x\n", prdt_phys, p->addr, hd_prd_tbl[0].addr); +#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; + + HD_CHL1_CMD_BASE = pci->bars[2] ? pci->bars[2] : HD_CHL1_CMD_BASE; + 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); +} + +void ide_hd_out(Dev dev, u32 nsect, u64 sect_nr, u32 cmd) +{ +#if USE_DMA + outb(0x00, iobase); + outb(0x06, iobase+2); + outl(prdt_phys, iobase+4); +#endif + + { + unsigned long long sect_nr = 0; + unsigned int nsect = 1; + + outb(0x00, REG_CTL(dev)); + outb(0x40, REG_DEVSEL(dev)); + + outb(0, REG_NSECTOR(dev)); // High + outb((u8)((sect_nr>>24)&0xFF), REG_LBAL(dev)); + outb((u8)((sect_nr>>32)&0xFF), REG_LBAM(dev)); + outb((u8)((sect_nr>>40)&0xFF), REG_LBAH(dev)); + + outb((u8)nsect, REG_NSECTOR(dev)); // Low + outb((u8)((sect_nr>> 0)&0xFF), REG_LBAL(dev)); + outb((u8)((sect_nr>> 8)&0xFF), REG_LBAM(dev)); + outb((u8)((sect_nr>>16)&0xFF), REG_LBAH(dev)); + +#if USE_DMA + outb(0x25, REG_CMD(dev)); +#else + outb(0x24, REG_CMD(dev)); +#endif + } + +#if USE_DMA + outb(0x09, iobase); +#endif +} + + +void dump_pci_ide(); + +void ide_status() +{ + u8_t idest = inb(REG_STATUS(0)); + u8_t pcist = inb(iobase+2); + printk(" ide status %02x pci status %02x\n", idest, pcist); + +} +void ide_debug() +{ + u32 device; + u32 nsect = 1; + u32 retires = 100; + u32 sect_nr = 1; + int count=SECT_SIZE; + + nsect = (count + SECT_SIZE -1)/SECT_SIZE; + + dump_pci_ide(); + + 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) +{ + pci_device_t *pci = pci_find_device(vendor, device); + if(pci != 0) + { + 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 dump_pci_ide() +{ + dump_pci_controller(PCI_VENDORID_INTEL, 0x2829); + dump_pci_controller(PCI_VENDORID_INTEL, 0x7010); +} + +void ide_irq() +{ + u8_t sa = inb(REG_STATUS(0)); + + char buf[1024]; + memset(buf, 0xEE, 1024); + + u8_t v = inb(iobase+2); + printk(" irq pci ide status register primary %02x\n", v); + v |= 0x04; + printk(" irq pci ide status before write %02x\n", v); + outb(v, iobase+2); + v = inb(iobase+2); + printk(" irq pci ide status after write %02x\n", v); + outb(0x00, iobase); + + unsigned int *p = (unsigned int *) pa2va((0+510)); + printk("||----------------- %s:%d status %04x SIG: %08x\n", __func__, __LINE__, sa, *p); + + insw(REG_DATA(0), buf, 512>>1); + unsigned int *s = (unsigned int *) (buf+510); + printk("insw %08x\n", *s); +} + +void ide_init() +{ + pci_device_t *pci = 0; + dump_pci_ide(); + +#if 0 + outb_p(0x02, REG_CTL(0)); + ide_read_identify(); +#endif + +} diff --git a/drivers/ide.h b/drivers/ide.h index 7545571..59edb92 100644 --- a/drivers/ide.h +++ b/drivers/ide.h @@ -100,3 +100,10 @@ extern unsigned int HD_CHL1_CTL_BASE; #define ATA_IDENT_MAX_LBA 120 #define ATA_IDENT_COMMANDSETS 164 #define ATA_IDENT_MAX_LBA_EXT 200 + + + +#define PCI_IDE_CMD 0 +#define PCI_IDE_STATUS 2 + #define PCI_IDE_STATUS_INTR 0x04 +#define PCI_IDE_PRDT 4 -- 2.44.0