POK(kernelpart)
|
00001 /* 00002 * POK header 00003 * 00004 * The following file is a part of the POK project. Any modification should 00005 * made according to the POK licence. You CANNOT use this file or a part of 00006 * this file is this part of a file for your own project 00007 * 00008 * For more information on the POK licence, please see our LICENCE FILE 00009 * 00010 * Please follow the coding guidelines described in doc/CODING_GUIDELINES 00011 * 00012 * Copyright (c) 2007-2009 POK team 00013 * 00014 * Created by laurent on Mon Jun 08 11:01:12 2009 00015 */ 00016 00017 #ifdef POK_NEEDS_PCI 00018 00019 # include <libc.h> 00020 # include <arch/x86/pci.h> 00021 00022 # include "gdt.h" 00023 # include "event.h" 00024 00025 static inline 00026 unsigned int pci_read(unsigned int bus, 00027 unsigned int dev, 00028 unsigned int fun, 00029 unsigned int reg) 00030 { 00031 unsigned int addr = (1 << 31) | (bus << 16) | (dev << 11) | (fun << 8) | (reg & 0xfc); 00032 unsigned int val = -1; 00033 00034 outl(PCI_CONFIG_ADDRESS, addr); 00035 val = inl(PCI_CONFIG_DATA); 00036 00037 return (val >> ((reg & 3) << 3)); 00038 } 00039 00040 static inline 00041 unsigned int pci_read_reg(s_pci_device* d, 00042 unsigned int reg) 00043 { 00044 return (pci_read(d->bus, d->dev, d->fun, reg)); 00045 } 00046 00047 static inline 00048 int pci_open(s_pci_device* d) 00049 { 00050 unsigned int bus = 0; 00051 unsigned int dev = 0; 00052 unsigned int fun = 0; 00053 00054 for (bus = 0; bus < PCI_BUS_MAX; bus++) 00055 for (dev = 0; dev < PCI_DEV_MAX; dev++) 00056 for (fun = 0; fun < PCI_FUN_MAX; fun++) 00057 if (((unsigned short) pci_read(bus, dev, fun, PCI_REG_VENDORID)) == d->vendorid && 00058 ((unsigned short) pci_read(bus, dev, fun, PCI_REG_DEVICEID)) == d->deviceid) 00059 { 00060 // we do not handle type 1 or 2 PCI configuration spaces 00061 if (pci_read(bus, dev, fun, PCI_REG_HEADERTYPE) != 0) 00062 continue; 00063 00064 d->bus = bus; 00065 d->dev = dev; 00066 d->fun = fun; 00067 d->bar[0] = pci_read(bus, dev, fun, PCI_REG_BAR0); 00068 d->irq_line = (unsigned char) pci_read_reg(d, PCI_REG_IRQLINE); 00069 00070 return (0); 00071 } 00072 00073 return (-1); 00074 } 00075 00076 void pci_handler(void); 00077 00078 void dummy_pci_handler(void) 00079 { 00080 __asm__ volatile 00081 ( 00082 ".globl pci_handler\n" 00083 "pci_handler:\n" 00084 "push %eax\n" // save restricted context 00085 "push %edx\n" 00086 "mov $0x20, %al\n" 00087 "mov $0xA0, %dx\n" // ack slave pic 00088 "outb %al, %dx\n" 00089 "mov $0x20, %dx\n" // ack master pic 00090 "outb %al, %dx\n" 00091 "pop %edx\n" // restore retricted context 00092 "pop %eax\n" 00093 "iret\n" // return 00094 ); 00095 } 00096 00097 void* ne2000_dev = NULL; 00098 00099 pok_ret_t pci_register(s_pci_device* dev, 00100 uint8_t part_id) 00101 { 00102 if (pci_open(dev) != 0) 00103 return (-1); 00104 00105 pok_partitions[part_id].io_min = (dev->bar[0] & (~0x1F)); 00106 pok_partitions[part_id].io_max = (dev->bar[0] & (~0x1F)) + dev->io_range; 00107 00108 pok_idt_set_gate(32 + dev->irq_line, 00109 GDT_CORE_CODE_SEGMENT, 00110 (uint32_t) pci_handler, 00111 IDTE_INTERRUPT, 00112 0); 00113 00114 ne2000_dev = dev; 00115 00116 return (0); 00117 } 00118 00119 #endif /* POK_NEEDS_PCI */