#include <printk.h>
#include <assert.h>
#include <io.h>
-#include <hd.h>
#include <irq.h>
#include <pci.h>
#include <system.h>
-/* ata command base register */
-#define HD_CHL0_CMD_BASE 0x1F0
-#define HD_CHL1_CMD_BASE 0x170
+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;
#define HD_DATA 0
#define HD_FEATURES 1
#define HD_CMD_SPECIFY 0x91
#define HD_CMD_IDENTIFY 0xEC
-/* hard disk control register */
-#define HD_CHL0_CTL_BASE 0x3F6
-#define HD_CHL1_CTL_BASE 0x376
-
-
#define HD_CTL 0
#define HD_CTL_NORETRY 0x80 /* disable access retry */
#define HD_CTL_NOECC 0x40 /* disable ecc retry */
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));
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);
+#endif
int i;
printk(" BARS: ");
- for(i=0; i<5; ++i)
+ for(i=0; i<6; ++i)
+ {
printk("%08x ", pci->bars[i]);
+ pci->bars[i] &= (~1UL);
+ }
printk("\n");
#if 0
prd_t *p = (prd_t *) va2pa(hd_prd_tbl);
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;
+
+ 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);
+
+
+#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);
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)
+{
+
+ {
+ unsigned long long sect_nr = 0;
+ unsigned int nsect = 1;
+ outb_p(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_DEVSEL(dev));
+ outb(0x24, REG_CMD(dev));
+ }
+}
+
+
+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;
+
+ do
+ {
+ ide_hd_out(0, nsect, sect_nr, HD_CMD_READ_EXT);
+
+ int drq_retires = 100000;
+ while(!hd_drq(dev) && --drq_retires)
+ /* do nothing */;
+
+ 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);
+ }
+
+}
+
+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);
+ ide_pci_init(pci);
+ }
}
void ide_init()
{
- pci_device_t *pci = pci_find_device(PCI_VENDORID_INTEL, 0x2850);
+ 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);
+ pci_device_t *pci = 0;
+#if 0
+ pci = pci_find_device(PCI_VENDORID_INTEL, 0x7010); // qemu
if(pci == 0)
- pci = pci_find_device(PCI_VENDORID_INTEL, 0x7010); // qemu
-
+ {
+ printk("qemu ide controller\n");
+ }
+#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
+
+#if 0
if(pci == 0)
panic("can not find ide device");
printk("found ide pci device\n");
-
ide_pci_init(pci);
+#endif
+ return;
outb_p(0x02, REG_CTL(0));
ide_read_identify();
void setup_idt()
{
- //init idt.
*((unsigned short *)idtr) = NIDT*sizeof(Gate);
*((unsigned long *)(idtr+2)) = (unsigned long)idt;
lidt();
}
+
+
void setup_gate()
{ int i;
-#define set_sys_int(vect, type, DPL, handler) \
-do{ \
- extern void handler (); \
- set_idt_gate(vect, (u32)handler, type, DPL); \
-}while(0)
-
-#define PL_KRNL PRIVILEGE_KRNL
-#define PL_USER PRIVILEGE_USER
-#if 1
- set_sys_int(0x00, TRAP_GATE, PL_KRNL, DivideError);
- set_sys_int(0x01, TRAP_GATE, PL_KRNL, Debug);
- set_sys_int(0x02, INTR_GATE, PL_KRNL, NMI);
- set_sys_int(0x03, TRAP_GATE, PL_USER, BreakPoint);
- set_sys_int(0x04, TRAP_GATE, PL_USER, OverFlow);
- set_sys_int(0x05, TRAP_GATE, PL_USER, BoundsCheck);
- set_sys_int(0x06, TRAP_GATE, PL_KRNL, InvalidOpcode);
- set_sys_int(0x07, TRAP_GATE, PL_KRNL, DeviceNotAvailable);
- set_sys_int(0x08, TRAP_GATE, PL_KRNL, DoubleFault);
- set_sys_int(0x09, TRAP_GATE, PL_KRNL, CoprocSegOverRun);
- set_sys_int(0x0A, TRAP_GATE, PL_KRNL, InvalidTss);
- set_sys_int(0x0B, TRAP_GATE, PL_KRNL, SegNotPresent);
- set_sys_int(0x0C, TRAP_GATE, PL_KRNL, StackFault);
- set_sys_int(0x0D, TRAP_GATE, PL_KRNL, GeneralProtection);
- set_sys_int(0x0E, TRAP_GATE, PL_KRNL, PageFault);
- set_sys_int(0x10, TRAP_GATE, PL_KRNL, CoprocError);
+ set_sys_int(0x00, TRAP_GATE, PRIVILEGE_KRNL, DivideError);
+ set_sys_int(0x01, TRAP_GATE, PRIVILEGE_KRNL, Debug);
+ set_sys_int(0x02, INTR_GATE, PRIVILEGE_KRNL, NMI);
+ set_sys_int(0x03, TRAP_GATE, PRIVILEGE_USER, BreakPoint);
+ set_sys_int(0x04, TRAP_GATE, PRIVILEGE_USER, OverFlow);
+ set_sys_int(0x05, TRAP_GATE, PRIVILEGE_USER, BoundsCheck);
+ set_sys_int(0x06, TRAP_GATE, PRIVILEGE_KRNL, InvalidOpcode);
+ set_sys_int(0x07, TRAP_GATE, PRIVILEGE_KRNL, DeviceNotAvailable);
+ set_sys_int(0x08, TRAP_GATE, PRIVILEGE_KRNL, DoubleFault);
+ set_sys_int(0x09, TRAP_GATE, PRIVILEGE_KRNL, CoprocSegOverRun);
+ set_sys_int(0x0A, TRAP_GATE, PRIVILEGE_KRNL, InvalidTss);
+ set_sys_int(0x0B, TRAP_GATE, PRIVILEGE_KRNL, SegNotPresent);
+ set_sys_int(0x0C, TRAP_GATE, PRIVILEGE_KRNL, StackFault);
+ set_sys_int(0x0D, TRAP_GATE, PRIVILEGE_KRNL, GeneralProtection);
+ set_sys_int(0x0E, TRAP_GATE, PRIVILEGE_KRNL, PageFault);
+ set_sys_int(0x10, TRAP_GATE, PRIVILEGE_KRNL, CoprocError);
for(i=0x20; i<256; i++)
- set_sys_int(i, INTR_GATE, PL_KRNL, no_irq_handler);
-
-#if 1
- set_sys_int(0x20, INTR_GATE, PL_KRNL, irq_0x00_handler);
- set_sys_int(0x21, INTR_GATE, PL_KRNL, irq_0x01_handler);
- set_sys_int(0x22, INTR_GATE, PL_KRNL, irq_0x02_handler);
- set_sys_int(0x23, INTR_GATE, PL_KRNL, irq_0x03_handler);
- set_sys_int(0x24, INTR_GATE, PL_KRNL, irq_0x04_handler);
- set_sys_int(0x25, INTR_GATE, PL_KRNL, irq_0x05_handler);
- set_sys_int(0x26, INTR_GATE, PL_KRNL, irq_0x06_handler);
- set_sys_int(0x27, INTR_GATE, PL_KRNL, irq_0x07_handler);
- set_sys_int(0x28, INTR_GATE, PL_KRNL, irq_0x08_handler);
- set_sys_int(0x29, INTR_GATE, PL_KRNL, irq_0x09_handler);
- set_sys_int(0x2A, INTR_GATE, PL_KRNL, irq_0x0A_handler);
- set_sys_int(0x2B, INTR_GATE, PL_KRNL, irq_0x0B_handler);
- set_sys_int(0x2C, INTR_GATE, PL_KRNL, irq_0x0C_handler);
- set_sys_int(0x2D, INTR_GATE, PL_KRNL, irq_0x0D_handler);
- set_sys_int(0x2E, INTR_GATE, PL_KRNL, irq_0x0E_handler);
- set_sys_int(0x2F, INTR_GATE, PL_KRNL, irq_0x0F_handler);
-#endif
-#endif
+ set_sys_int(i, INTR_GATE, PRIVILEGE_KRNL, no_irq_handler);
+
+ set_sys_int(0x20, INTR_GATE, PRIVILEGE_KRNL, irq_0x00_handler);
+ set_sys_int(0x21, INTR_GATE, PRIVILEGE_KRNL, irq_0x01_handler);
+ set_sys_int(0x22, INTR_GATE, PRIVILEGE_KRNL, irq_0x02_handler);
+ set_sys_int(0x23, INTR_GATE, PRIVILEGE_KRNL, irq_0x03_handler);
+ set_sys_int(0x24, INTR_GATE, PRIVILEGE_KRNL, irq_0x04_handler);
+ set_sys_int(0x25, INTR_GATE, PRIVILEGE_KRNL, irq_0x05_handler);
+ set_sys_int(0x26, INTR_GATE, PRIVILEGE_KRNL, irq_0x06_handler);
+ set_sys_int(0x27, INTR_GATE, PRIVILEGE_KRNL, irq_0x07_handler);
+ set_sys_int(0x28, INTR_GATE, PRIVILEGE_KRNL, irq_0x08_handler);
+ set_sys_int(0x29, INTR_GATE, PRIVILEGE_KRNL, irq_0x09_handler);
+ set_sys_int(0x2A, INTR_GATE, PRIVILEGE_KRNL, irq_0x0A_handler);
+ set_sys_int(0x2B, INTR_GATE, PRIVILEGE_KRNL, irq_0x0B_handler);
+ set_sys_int(0x2C, INTR_GATE, PRIVILEGE_KRNL, irq_0x0C_handler);
+ set_sys_int(0x2D, INTR_GATE, PRIVILEGE_KRNL, irq_0x0D_handler);
+ set_sys_int(0x2E, INTR_GATE, PRIVILEGE_KRNL, irq_0x0E_handler);
+ set_sys_int(0x2F, INTR_GATE, PRIVILEGE_KRNL, irq_0x0F_handler);
}
-#include<hd.h>
-void dump();
-void sata_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
+void default_irq_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);
- printk("SECTOR %04x\n", *(unsigned short *)(buf+510));
- dump();
+ printk("default irq handler %d \n", irq);
}
void setup_irqs()
irq_desc[i].chip = &i8259_chip;
}
- //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=3; i<256; i++)
+ for(i=3; i<16; i++)
{
- //request_irq(i, hd_handler, "IDE", "IDE");
- request_irq(i, sata_handler, "Intel 8086", "SATA");
+ request_irq(i, default_irq_handler, "default", "default");
}
- //request_irq(11, sata_handler, "Intel 8086", "SATA");
- //request_irq(0x11, sata_handler, "Intel 8086", "SATA");
-
- //enable_irq(0x00);
- enable_irq(0x01);
- for(i=2; i<16; i++)
+ for(i=1; i<16; i++)
enable_irq(i);
asm("sti");
- //asm("cli");
-
-/*
- pIRQAction pKbdAction, pClkAction;
-
-
- pKbdAction = (pIRQAction) kmalloc_old(sizeof(IRQAction));
- pClkAction = (pIRQAction) kmalloc_old(sizeof(IRQAction));
-
-
- assert(pKbdAction != NULL);
- assert(pClkAction != NULL);
-
- pClkAction->handler = clk_handler;
- pClkAction->next = NULL;
- pKbdAction->handler = kbd_handler;
- pKbdAction->next = NULL;
-
- printk("**********%08x %08x", pKbdAction, pClkAction);
-
- irq_desc[0x0].chip = &i8259_chip;
- irq_desc[0x0].chip->enable(0x0);
- irq_desc[0x0].action = pClkAction;
-
- irq_desc[0x1].chip = &i8259_chip;
- irq_desc[0x1].chip->enable(0x1);
- irq_desc[0x1].action = pKbdAction;
-*/
-
}
void set_tss()
p->eflags = 0x1200;
p->iomap_base = sizeof(TSS);
set_tss_gate(INDEX_TSS, (u32)p);
- //printk("TSS:%08x\n", p);
asm("ltr %%ax"::"a"((INDEX_TSS<<3)+3));
}
{
unsigned char dev;
dev = (unsigned char)(system.boot_device >> 24);
- //if(dev != 0x80)
- // panic("OS must boot from the first hard disk");
-
printk("root device: %08x\n", system.root_dev);
-#if 0
-
- /*
- * 硬盘的次设备号
- * 0: 整个硬盘
- * 1-4: 主分区
- * 5~N: 逻辑分区(N<2^16-5)
- * 目录只支持从第一个硬盘引导.
- */
- int minor = ((system.boot_device>>16) & 0xFF) + 1;
- system.root_dev = MAKE_DEV(DEV_MAJOR_HD, minor);
-#endif
}