#include <irq.h>
#include <pci.h>
#include <system.h>
+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)
{
- printk("\nhd_handler:%d\n", irq);
+ //printk("\nhd_handler:%d\n", irq);
+ unsigned int v = inw(iobase+2);
+ printk("[%04x]", v);
}
int hd_controller_ready(Dev dev)
void hd_out(Dev dev, u32 nsect, u64 sect_nr, u32 cmd)
{
+
+ {
+ unsigned long long sect_nr = 0;
+ unsigned int nsect = 1;
+
+ cli();
+ outb(0x00, REG_CTL(dev));
+
+ outb(0, REG_NSECTOR(dev)); // High
+ outb((u8)nsect, REG_NSECTOR(dev)); // Low
+
+ 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(0xE0, REG_DEVICE(dev));
+ outb(0x24, REG_CMD(dev));
+ sti();
+ return ;
+ }
+
+
+
+
+
+
assert(nsect > 0);
assert(HD_GET_DEV(dev) < 2); // 0: ata-master 1:ata-slave
- unsigned char device = 0xE0;
+ 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(system.debug)
+#if 0
{
- hd_controller_reset(dev);
+ 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_FEATURES(dev));
- outb((u8)nsect, REG_NSECTOR(dev));
-#ifdef USE_LBA_48
- /*
- * LBA-48 bit
- * 先写高位.再写低位.
- */
- outb((u8)((sect_nr>>0x18)&0xFF), REG_LBAL(dev));
- outb((u8)((sect_nr>>0x20)&0xFF), REG_LBAM(dev));
- outb((u8)((sect_nr>>0x28)&0xFF), REG_LBAH(dev));
-
- outb((u8)((sect_nr>>0x00)&0xFF), REG_LBAL(dev));
- outb((u8)((sect_nr>>0x08)&0xFF), REG_LBAM(dev));
- outb((u8)((sect_nr>>0x10)&0xFF), REG_LBAH(dev));
-#else
- outb((u8)((sect_nr>>0x00)&0xFF), REG_LBAL(dev));
- outb((u8)((sect_nr>>0x08)&0xFF), REG_LBAM(dev));
- outb((u8)((sect_nr>>0x10)&0xFF), REG_LBAH(dev));
-#endif
- outb((u8)device, REG_DEVICE(dev));
- outb((u8)cmd, REG_CMD(dev));
+ //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)
panic("Your hard disk ");
}
+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)));
+
void hd_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);
- unsigned long iobase = v & 0xFFF0;
+ 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);
+
+
+
+
+ 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);
+
+
+ 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");
+ } else {
+ if(progif == 0x8A || progif == 0x80) {
+ printk("This is a Parallel IDE Controller which use IRQ 14 and IRQ 15.\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);
}
+/*
+ * Bus Master IDE Status Register
+ * Bit2 Bit0
+ * 0 0 Error Condition
+ * 0 1 DMA transfer is in progress
+ * 1 0 The IDE device generated an interrupt and the Physical Region Descriptors exhausted
+ * 1 1 The IDE device generated an interrupt
+ */
+
void setup_hd()
{
+#if 1
pci_device_t *pci = pci_find_device(PCI_VENDORID_INTEL, 0x2850);
if(pci == 0)
pci = pci_find_device(PCI_VENDORID_INTEL, 0x7010); // qemu
+#else
+ pci_device_t *pci = pci_find_device(PCI_VENDORID_INTEL, 0x2922);
+#endif
+
if(pci == 0)
panic("can not find ide device");
hd_pci_init(pci);
- hd_controller_reset(ROOT_DEV);
+ //hd_controller_reset(ROOT_DEV);
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);
}
#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 PIC_CASCADE_IR 0x2 //The IR2 on Master Connect to Slave.
+#define PIC_AEOI 1
+
extern void init_i8259();
extern void mask_i8259();
_bt; \
})
+
#define outb(value, port)({ \
__asm__("outb %%al,%%dx" \
: \
//mask all of 8259
outb_p(0xFF, PIC_MASTER_IMR);
outb_p(0xFF, PIC_SLAVE_IMR);
+ //outb_p(0x0, PIC_MASTER_IMR);
+ //outb_p(0x0, PIC_SLAVE_IMR);
}
void init_i8259()
//Master...
outb_p(0x11, PIC_MASTER_CMD); // ICW1
outb_p(0x20, PIC_MASTER_IMR); // ICW2: IR0-7 mapped to 0x20-0x27
- outb_p(1U<<PIC_CASCADE_IR, PIC_MASTER_IMR); //IR2 Connect Slave.
+ outb_p((1U<<PIC_CASCADE_IR), PIC_MASTER_IMR); //IR2 Connect Slave.
+#if PIC_AEOI
+ outb_p(0x03, PIC_MASTER_IMR);
+#else
outb_p(0x01, PIC_MASTER_IMR); // Normal EOI
- //Auto EOI:outb_p(0x03, PIC_MASTER_CMDB);
+#endif
//Slave...
outb_p(0x11, PIC_SLAVE_CMD);
outb_p(0x28, PIC_SLAVE_IMR); // IR0-7 mapped to 0x28-0x2F
outb_p(PIC_CASCADE_IR, PIC_SLAVE_IMR);
+#if PIC_AEOI
+ outb_p(0x03, PIC_SLAVE_IMR);
+#else
outb_p(0x01, PIC_SLAVE_IMR);
- //Auto EOI:outb_p(0x01, PIC_SLAVE_CMDB);
+#endif
mask_i8259();
}
int enable_i8259_irq(unsigned int irq)
{
- unsigned char mask = ~(1 << irq);
+ unsigned char mask = 0;
if(irq & 8)
{
+ mask = ~(1 << (irq-8));
mask &= inb(PIC_SLAVE_IMR);
outb( mask, PIC_SLAVE_IMR);
}
else
{
+ mask = ~(1 << irq);
mask &= inb(PIC_MASTER_IMR);
outb_p( mask, PIC_MASTER_IMR);
}
int disable_i8259_irq(unsigned int irq)
{
- unsigned char mask = 1 << irq;
+ unsigned char mask = 0;
if(irq & 8)
{
+ mask |= (1 << (irq-8));
mask |= inb(PIC_SLAVE_IMR);
outb( mask, PIC_SLAVE_IMR);
}
else
{
+ mask |= (1 << irq);
mask |= inb(PIC_MASTER_IMR);
outb( mask, PIC_MASTER_IMR);
}
void mask_ack_i8259_irq(unsigned int irq)
{
- unsigned int mask = 1 << irq;
+ unsigned char mask = 0;
if(irq & 8) // Slave
{
+ mask |= (1 << (irq-8));
mask |= inb(PIC_SLAVE_IMR);
// Mask
outb(mask, PIC_SLAVE_IMR);
+#if PIC_AEOI
+ // ...
+#else
// Specific EOI to slave
outb(0x60 + (irq & 0x07), PIC_SLAVE_CMD);
// Specific EOI to master
outb(0x60 + (PIC_CASCADE_IR & 0x07), PIC_MASTER_CMD);
+#endif
}
else // Master
{
+ mask |= (1 << irq);
mask |= inb(PIC_MASTER_IMR);
// Mask
outb(mask, PIC_MASTER_IMR);
+#if PIC_AEOI
+ // ...
+#else
// Specific EOI to master
outb(0x60 + irq, PIC_MASTER_CMD);
+#endif
}
}
{
unsigned int irq = regs->irq;
+
if(irq >= NR_IRQS)
{
printk("invalid irq %d\n", irq);
p->chip->ack(irq);
sti();
-
while(action && action->handler)
{
action->handler(irq, regs, action->dev_id);
void pci_write_config_word(int value, int cmd)
{
outl(PCI_CONFIG_CMD(cmd), PCI_ADDR);
- outb(value & 0xFFFF, PCI_DATA);
+ outw(value & 0xFFFF, PCI_DATA);
}
void pci_write_config_long(int value, int cmd)
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)
{
{
pci_device_t *pci = list_entry(p, pci_device_t, list);
printk("Vendor %x Device %x Class %x Revision %x IntrLine %d Pin %d ", pci->vendor, pci->device, pci->classcode, pci->revision, pci->intr_line, pci->intr_pin);
+
switch(pci->hdr_type)
{
case PCI_HDRTYPE_NORMAL:
--- /dev/null
+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
#include <printk.h>
#include <system.h>
#include <io.h>
+#include <hd.h>
extern void setup_gdt();
extern void setup_idt();
BUIDER;
+extern void hd_out(Dev dev, u32 nsect, u64 sect_nr, u32 cmd);
+
+#include "hd.h"
+void hd()
+{
+ unsigned long long sect_nr = 0;
+ unsigned int nsect = 1;
+
+ cli();
+ outb(0x00, REG_CTL(dev));
+
+ outb(0, REG_NSECTOR(dev)); // High
+ outb((u8)nsect, REG_NSECTOR(dev)); // Low
+
+ 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(0xE0, REG_DEVICE(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);
+}
+
+
void setup_kernel()
{
extern char kernel_begin, kernel_end;
setup_idt();
setup_gate();
- //setup_i8253();
+ setup_i8253();
detect_cpu();
set_tss();
setup_sysc();
- setup_pci();
+ //setup_pci();
setup_tasks();
setup_irqs();
+ asm("sti;");
+ hd();
setup_hd();
printk("%s\n", version);
- asm("cli;");
- while(1);
+ //asm("cli;");
+ //while(1);
return;
+ hd_out(0, 1, 1, HD_CMD_READ_EXT);
while(1); // TODO MODIFY CODE BELOW
#endif
}
+#include<hd.h>
+void sata_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
+{
+ printk("sata irq handler %d \n", irq);
+ inb(REG_STATUS(0));
+ char buf[1024];
+ memset(buf, 0, 1024);
+ hd_rd_data(0, buf, 512);
+}
+
void setup_irqs()
{
extern void init_i8259();
//extern void kbd_handler(pt_regs_t *, unsigned int); //extern void clk_handler(pt_regs_t *, unsigned int);
//extern void hd_handler(pt_regs_t *, unsigned int);
+ extern void hd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id);
void kbd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id);
void clk_handler(unsigned int irq, pt_regs_t * regs, void *dev_id);
void hd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id);
request_irq(0x00, clk_handler, "Intel 8254", "Clock Chip");
request_irq(0x01, kbd_handler, "Intel 8042", "PS/2 Keyboard");
//request_irq(0x0E, hd_handler, "IDE", "IDE");
- for(i=2; i<16; i++)
+ for(i=3; i<256; i++)
{
- request_irq(i, hd_handler, "IDE", "IDE");
+ //request_irq(i, hd_handler, "IDE", "IDE");
+ request_irq(i, sata_handler, "Intel 8086", "SATA");
}
- enable_irq(0x00);
+ //request_irq(11, sata_handler, "Intel 8086", "SATA");
+ //request_irq(0x11, sata_handler, "Intel 8086", "SATA");
+
+ //enable_irq(0x00);
enable_irq(0x01);
- enable_irq(0x02);
- enable_irq(0x03);
- enable_irq(0x04);
- enable_irq(0x05);
- enable_irq(0x06);
- enable_irq(0x07);
- enable_irq(0x08);
- enable_irq(0x09);
- enable_irq(0x0A);
- enable_irq(0x0B);
- enable_irq(0x0C);
- enable_irq(0x0D);
- enable_irq(0x0F);
- enable_irq(0x0E);
+ for(i=2; i<16; i++)
+ enable_irq(i);
asm("sti");
//asm("cli");