#include <io.h>
#include <hd.h>
#include <irq.h>
+#include <pci.h>
#include <system.h>
//void hd_handler(pt_regs_t * regs, unsigned int irq)
void hd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
if(!hd_controller_ready(dev))
{
+ printk("hd is not ready\n");
return ;
}
#endif
outb((u8)device, REG_DEVICE(dev));
outb((u8)cmd, REG_CMD(dev));
+
}
void _hd_read(Dev dev, u64 sect_nr, void *buf, u32 count, u32 cmd)
panic("Your hard disk ");
}
+void hd_pci_init(pci_device_t *pci)
+{
+ unsigned int v;
+ 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));
+ 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;
+
+ 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);
+}
+
void setup_hd()
{
+ pci_device_t *pci = pci_find_device(PCI_VENDORID_INTEL, 0x2850);
+ if(pci == 0)
+ pci = pci_find_device(PCI_VENDORID_INTEL, 0x7010); // qemu
+
+ if(pci == 0)
+ panic("can not find ide device");
+
+ printk("found ide pci device\n");
+
+ hd_pci_init(pci);
+
hd_controller_reset(ROOT_DEV);
char *buf;
*--------------------------------------------------------------------------
*/
-#ifndef _HD_H
+#ifndef _HD_H
#define _HD_H
#include <types.h>
#define HD_CHL0_CMD_BASE 0x1F0
#define HD_CHL1_CMD_BASE 0x170
-#define HD_DATA 0
-#define HD_ERR 1
+#define HD_DATA 0
+#define HD_ERR 1
#define HD_ERR_BB 0x80
-#define HD_ERR_ECC 0x40
+#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_DEVICE 6
-#define HD_STATUS 7 /* controller status */
+#define HD_NSECTOR 2
+#define HD_LBAL 3
+#define HD_LBAM 4
+#define HD_LBAH 5
+#define HD_DEVICE 6
+#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_CRD 0x04 /* correct data */
#define HD_STATUS_IDX 0x02 /* index pulse */
#define HD_STATUS_ERR 0x01 /* error */
-#define HD_FEATURES HD_ERR
-#define HD_CMD HD_STATUS
-#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_FEATURES HD_ERR
+#define HD_CMD HD_STATUS
+#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_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_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_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_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_CTL_DISABLE_INT 0x02 /* disable interrupts */
#define HD_GET_CHL(dev) (0) /* 暂时还是只支持通道0 */
#define HD_GET_DEV(dev) (0) /* 暂时还是只支持一个硬盘 */
#define hd_err(dev) ((inb(REG_STATUS(dev)) & HD_STATUS_ERR))
-#define USE_LBA_48 /* 使用LBA-48bit 模式操作硬盘 */
+#define USE_LBA_48 1 /* 使用LBA-48bit 模式操作硬盘 */
#endif //_HD_H
#include <syscall.h>
#include <stdio.h>
#include <io.h>
+#include <hd.h>
#define KBD_BUF_SIZE 256
static struct
ScanCode = inb(0x60);
printk("%02x", ScanCode);
- hd_out(0, 1, 1, 0x24);
- return; // debug
+
+ hd_out(0, 1, 1, HD_CMD_READ_EXT);
+
if(count < KBD_BUF_SIZE)
{
count++;
*--------------------------------------------------------------------------
*/
-#ifndef _IO_H
+#ifndef _IO_H
#define _IO_H
#include <types.h>
-#define outb_p(value,port)({ \
-__asm__("outb %%al,%%dx;nop;nop;nop;nop" \
-: \
-:"a" (value),"d" (port)); \
-})
-
-#define inb_p(port)({ \
-u8 _bt; \
-__asm__("inb %%dx,%%al;nop;nop;nop;nop" \
-:"=a" (_bt) \
-:"d" (port)); \
-_bt; \
-})
-
-
-#define outb(value,port)({ \
-__asm__("outb %%al,%%dx" \
-: \
-:"a" (value),"d" (port)); \
-})
-
-#define outw(value,port)({ \
-__asm__("outw %%ax,%%dx" \
-: \
-:"a" (value),"d" (port)); \
-})
-#define outl(value,port)({ \
-__asm__("outl %%eax,%%dx" \
-: \
-:"a" (value),"d" (port)); \
-})
-
#define inb(port)({ \
u8 _bt; \
-asm("inb %%dx,%%al" \
+asm("inb %%dx,%%al" \
:"=a" (_bt) \
:"d" (port)); \
_bt; \
#define inw(port)({ \
u16 _bt; \
-asm("inw %%dx,%%ax" \
+asm("inw %%dx,%%ax" \
:"=a" (_bt) \
:"d" (port)); \
_bt; \
#define inl(port)({ \
u32 _bt; \
-asm("inl %%dx,%%eax" \
+asm("inl %%dx,%%eax" \
:"=a" (_bt) \
:"d" (port)); \
_bt; \
})
+#define outb(value, port)({ \
+__asm__("outb %%al,%%dx" \
+: \
+:"a" (value),"d" (port)); \
+})
+
+#define outw(value, port)({ \
+__asm__("outw %%ax,%%dx" \
+: \
+:"a" (value),"d" (port)); \
+})
+#define outl(value, port)({ \
+__asm__("outl %%eax,%%dx" \
+: \
+:"a" (value),"d" (port)); \
+})
+
+#define outb_p(value, port)({ \
+__asm__("outb %%al,%%dx;nop;nop;nop;nop" \
+: \
+:"a" (value),"d" (port)); \
+})
+
+#define inb_p(port)({ \
+u8 _bt; \
+__asm__("inb %%dx,%%al;nop;nop;nop;nop" \
+:"=a" (_bt) \
+:"d" (port)); \
+_bt; \
+})
#define BUILDIO(bwl, type) \
static inline void ins##bwl(int port, void *buf, unsigned long count) \
{ \
- asm volatile( "cld;rep;ins" #bwl \
+ asm volatile("cld;rep;ins" #bwl \
: "+c"(count), "+D"(buf) : "d"(port)); \
}
extern list_head_t pci_devs;
+#define BARS_CNT 6
+
typedef struct pci_device
{
list_head_t list;
- unsigned long vendor;
- unsigned long device;
- unsigned long command;
- unsigned long status;
- unsigned long revision;
- unsigned long classcode;
- unsigned long hdr_type;
- unsigned long bar0, bar1, bar2, bar3, bar4, bar5;
- unsigned long sub_system_id;
- unsigned long system_id;
- unsigned long intr_line;
- unsigned long intr_pin;
-
- unsigned long primary_bus_nr; /* only for pci bridge */
+ unsigned int bus, dev, devfn;
+
+
+ unsigned int vendor;
+ unsigned int device;
+ unsigned int command;
+ unsigned int status;
+ unsigned int revision;
+ unsigned int classcode;
+ unsigned int hdr_type;
+ //unsigned int bar0, bar1, bar2, bar3, bar4, bar5;
+ unsigned int bars[BARS_CNT];
+ unsigned int sub_system_id;
+ unsigned int system_id;
+ unsigned int intr_line;
+ unsigned int intr_pin;
+
+ unsigned int primary_bus_nr; /* only for pci bridge */
+ unsigned int secondary_bus_nr;
} __attribute__((packed)) pci_device_t;
#define PCI_HDRTYPE_NORMAL 0x00
#define PCI_HDRTYPE_BRIDGE 0x01 /* PCI-to-PCI Bridge */
#define PCI_HDRTYPE_CARDBUS 0x02 /* CardBus Bridge */
+#define PCI_BAR0 0x10
+#define PCI_BAR1 0x14
+#define PCI_BAR2 0x18
+#define PCI_BAR3 0x1C
+#define PCI_BAR4 0x20
+#define PCI_BAR5 0x24
#define PCI_PRIMARY_BUS_NUMBER 0x18
#define PCI_SECONDARY_BUS_NUMBER 0x19
#define PCI_INTRLINE 0x3C
#define PCI_VENDORID_NVIDIA 0x10DE
#define PCI_VENDORID_REALTEK 0x10EC
+pci_device_t *pci_find_device(unsigned int vendor, unsigned int device);
+
+static inline u32 pci_cmd(pci_device_t *pci, unsigned int reg) {
+ return PCI_CMD(pci->bus, pci->dev, pci->devfn, reg);
+}
+
+int pci_read_config_byte(int cmd);
+int pci_read_config_word(int cmd);
+int pci_read_config_long(int cmd);
+void pci_write_config_byte(int value, int cmd);
+void pci_write_config_word(int value, int cmd);
+void pci_write_config_long(int value, int cmd);
+
+
+
// PCI Bridge
/*
*--------------------------------------------------------------------------
*/
-#ifndef _PRINTK_H
-#define _PRINTK_H
+#pragma once
int printk(char *fmtstr, ...);
-
-#endif //_PRINTK_H
free_virt_pages((void*)va2pa(p));
}
-extern inline void panic(char *msg);
+#define panic(msg) do { \
+ printk("PANIC:\"%s\" file:%s function:%s line:%d\n", \
+ msg, __FILE__, __FUNCTION__, __LINE__); \
+ while(1); \
+} while(0);
extern char etext, edata, end;
#include <system.h>
#include <task.h>
-#define IRQ_SYMBL(a,b) irq_0x##a##b_handler
-#define IRQ_LIST(x) \
-IRQ_SYMBL(x,0), \
-IRQ_SYMBL(x,1), \
-IRQ_SYMBL(x,2), \
-IRQ_SYMBL(x,3), \
-IRQ_SYMBL(x,4), \
-IRQ_SYMBL(x,5), \
-IRQ_SYMBL(x,6), \
-IRQ_SYMBL(x,7), \
-IRQ_SYMBL(x,8), \
-IRQ_SYMBL(x,9), \
-IRQ_SYMBL(x,A), \
-IRQ_SYMBL(x,B), \
-IRQ_SYMBL(x,C), \
-IRQ_SYMBL(x,D), \
-IRQ_SYMBL(x,E), \
-IRQ_SYMBL(x,F)
-
-#define DEF_IRQ(a,b) \
-.align 0x04,0x90; \
-.global irq_0x##a##b##_handler; \
-irq_0x##a##b##_handler: \
-pushl $0x##a##b; \
-jmp _irq_handler;
+#define DEF_IRQ(a,b) \
+.align 0x04,0x90; \
+.global irq_0x##a##b##_handler; \
+irq_0x##a##b##_handler: \
+pushl $0x##a##b; \
+jmp _irq_handler;
+
+.align 0x04,0x90
+.global no_irq_handler
+no_irq_handler:
+pushl $0xFFFFFFFF
+jmp _irq_handler
DEF_IRQ(0,0)
.global _irq_handler
.extern irq_handler
-.extern schedule
+.extern schedule
_irq_handler:
SAVE_REGS
{
unsigned int irq = regs->irq;
+ if(irq >= NR_IRQS)
+ {
+ printk("invalid irq %d\n", irq);
+ return ;
+ }
+
irq_desc_t *p = irq_desc + irq;
+
irq_action_t *action = p->action;
current->preempt_cnt++;
p->chip->ack(irq);
sti();
- while(action)
+ while(action && action->handler)
{
- //action->handler(regs, irq);
action->handler(irq, regs, action->dev_id);
action = action->next;
}
}
-void panic(char *msg)
-{
- printk("PANIC:\"%s\" file:%s function:%s line:%d\n",
- msg, __FILE__, __FUNCTION__, __LINE__);
- while(1);
-}
LIST_HEAD(pci_devs);
-static int pci_read_config_byte(int cmd)
+int pci_read_config_byte(int cmd)
{
outl(PCI_CONFIG_CMD(cmd), PCI_ADDR);
return inb(PCI_DATA + (PCI_GET_CMD_REG(cmd) & 3));
}
-static int pci_read_config_word(int cmd)
+int pci_read_config_word(int cmd)
{
outl(PCI_CONFIG_CMD(cmd), PCI_ADDR);
return inw(PCI_DATA + (PCI_GET_CMD_REG(cmd) & 2));
}
-static int pci_read_config_long(int cmd)
+int pci_read_config_long(int cmd)
{
outl(PCI_CONFIG_CMD(cmd), PCI_ADDR);
return inl(PCI_DATA);
}
+void pci_write_config_byte(int value, int cmd)
+{
+ outl(PCI_CONFIG_CMD(cmd), PCI_ADDR);
+ outb(value & 0xFF, PCI_DATA);
+}
+
+void pci_write_config_word(int value, int cmd)
+{
+ outl(PCI_CONFIG_CMD(cmd), PCI_ADDR);
+ outb(value & 0xFFFF, PCI_DATA);
+}
+
+void pci_write_config_long(int value, int cmd)
+{
+ outl(PCI_CONFIG_CMD(cmd), PCI_ADDR);
+ outl(value, PCI_DATA);
+}
void scan_pci_bus(int bus)
{
u8 dev, devfn;
u32 cmd;
u32 v;
+ int i;
printk("scanning PCI bus %d\n", bus);
for(dev=0; dev<32; dev++)
continue;
}
+ pci->bus = bus;
+ pci->dev = dev;
+ pci->devfn = devfn;
+
pci->vendor = v;
cmd = PCI_CMD(bus, dev, devfn, PCI_DEVICEID);
cmd = PCI_CMD(bus, dev, devfn, PCI_INTRPIN);
pci->intr_pin = pci_read_config_byte(cmd);
+
cmd = PCI_CMD(bus, dev, devfn, PCI_HDRTYPE);
pci->hdr_type = pci_read_config_byte(cmd);
pci->hdr_type &= PCI_HDRTYPE_MASK;
+ for(i=0; i<BARS_CNT; ++i)
+ {
+ cmd = PCI_CMD(bus, dev, devfn, PCI_BAR0 + i*4);
+ pci->bars[i] = pci_read_config_long(cmd);
+ }
+
+#if 0
if(pci->hdr_type == PCI_HDRTYPE_BRIDGE)
{
cmd = PCI_CMD(bus, dev, devfn, PCI_PRIMARY_BUS_NUMBER);
pci->primary_bus_nr = pci_read_config_byte(cmd);
- scan_pci_bus(pci->primary_bus_nr);
+
+ cmd = PCI_CMD(bus, dev, devfn, PCI_SECONDARY_BUS_NUMBER);
+ pci->secondary_bus_nr = pci_read_config_byte(cmd);
+
+ printk(" PCI BUS: %d %d\n", pci->primary_bus_nr, pci->secondary_bus_nr);
+
+ scan_pci_bus(pci->secondary_bus_nr);
}
+#endif
list_add(&pci->list, &pci_devs);
}
}
}
+
+pci_device_t *pci_find_device(unsigned int vendor, unsigned int device)
+{
+ int i;
+ list_head_t *p;
+ pci_device_t *pci = 0;
+
+ list_for_each(p, &pci_devs)
+ {
+ pci = list_entry(p, pci_device_t, list);
+
+ if(pci->vendor == vendor && pci->device == device)
+ return pci;
+ }
+
+
+ return 0;
+}
+
void dump_pci_dev()
{
list_head_t *p;
+ int i;
+
list_for_each(p, &pci_devs)
{
pci_device_t *pci = list_entry(p, pci_device_t, list);
- printk("Vendor %x Device %x Class %x Revision %x IntrLine %d ", pci->vendor, pci->device, pci->classcode, pci->revision, pci->intr_line);
+ 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:
printk("Normal Device\n");
break;
case PCI_HDRTYPE_BRIDGE:
- printk("Aha PCI-PCI Bridge\n");
+ printk("PCI-PCI Bridge\n");
break;
case PCI_HDRTYPE_CARDBUS:
- printk("Wow PCI-CardBus\n");
+ printk("PCI-CardBus\n");
break;
default:
printk("Not Support!\n");
break;
}
}
- while(1);
}
int probe_pci_bus()
setup_irqs();
- setup_hd();
+ setup_hd();
printk("%s\n", version);
-
+ asm("cli;");
+ while(1);
return;
while(1); // TODO MODIFY CODE BELOW
*((unsigned long *)(idtr+2)) = (unsigned long)idt;
lidt();
}
-void no_irq_handler()
-{
- printk("no_irq_handler");
- //while(1);
-}
void setup_gate()
{ int i;
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(0x2E, INTR_GATE, PL_KRNL, irq_0x0E_handler);
set_sys_int(0x2F, INTR_GATE, PL_KRNL, irq_0x0F_handler);
#endif
+#endif
}
void setup_irqs()
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");
+ //request_irq(0x0E, hd_handler, "IDE", "IDE");
+ for(i=2; i<16; i++)
+ {
+ request_irq(i, hd_handler, "IDE", "IDE");
+ }
+
enable_irq(0x00);
enable_irq(0x01);
enable_irq(0x02);