From: AceVest Date: Wed, 28 May 2014 16:50:01 +0000 (+0800) Subject: on the way to pci ide dma X-Git-Tag: 0.3.0~58 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/zlib_tech.html?a=commitdiff_plain;h=67b4acb0b2dd3b5ab0913b25486ad7df187fbf53;p=kernel.git on the way to pci ide dma --- diff --git a/Makefile b/Makefile index b68a63c..d660621 100644 --- 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 diff --git a/drivers/ide.c b/drivers/ide.c index 7b1fc44..3b87bde 100644 --- a/drivers/ide.c +++ b/drivers/ide.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -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 index 0000000..7545571 --- /dev/null +++ b/drivers/ide.h @@ -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 diff --git a/setup/system.c b/setup/system.c index dd868de..f68902e 100644 --- a/setup/system.c +++ b/setup/system.c @@ -23,6 +23,7 @@ #include #include #include +#include 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()