00001
00002
00003
00004
00005
00006
00007
00008 #include <mach/pc/pci.h>
00009
00010 __BEGIN_SYS
00011
00012 CPU::Reg32 PC_PCI::base_address[Region::N] = {
00013 BASE_ADDRESS_0, BASE_ADDRESS_1,
00014 BASE_ADDRESS_2, BASE_ADDRESS_3,
00015 BASE_ADDRESS_4, BASE_ADDRESS_5
00016 };
00017
00018 void PC_PCI::header(const PC_PCI::Locator & l, PC_PCI::Header * h)
00019 {
00020 IA32 cpu;
00021
00022 h->vendor_id = cfg16(l.bus, l.dev_fn, VENDOR_ID);
00023 if((h->vendor_id != 0) && (h->vendor_id != 0xffff)) {
00024 h->locator = l;
00025 h->device_id = cfg16(l.bus, l.dev_fn, DEVICE_ID);
00026 h->command = cfg16(l.bus, l.dev_fn, COMMAND);
00027 h->status = cfg16(l.bus, l.dev_fn, STATUS);
00028 h->revision_id = cfg8(l.bus, l.dev_fn, REVISION_ID);
00029 h->class_prog = cfg8(l.bus, l.dev_fn, CLASS_PROG);
00030 h->class_id = cfg16(l.bus, l.dev_fn, CLASS_ID);
00031 h->cache_line_size = cfg8(l.bus, l.dev_fn, CACHE_LINE_SIZE);
00032 h->latency_time = cfg8(l.bus, l.dev_fn, LATENCY_TIMER);
00033 h->type = cfg8(l.bus, l.dev_fn, HEADER_TYPE);
00034 h->bist = cfg8(l.bus, l.dev_fn, BIST);
00035 for(int i = 0; i < Region::N; i++) {
00036 cpu.int_disable();
00037 h->region[i].phy_addr = cfg32(l.bus, l.dev_fn, base_address[i]);
00038 cfg32(l.bus, l.dev_fn, base_address[i], ~0);
00039 h->region[i].size = cfg32(l.bus, l.dev_fn, base_address[i]);
00040 cfg32(l.bus, l.dev_fn, base_address[i], h->region[i].phy_addr);
00041 cpu.int_enable();
00042 if( (h->region[i].phy_addr & BASE_ADDRESS_SPACE_MASK) ||
00043 ( (h->type&0x7f) == HEADER_TYPE_BRIDGE || (h->type&0x7f) == HEADER_TYPE_CARDBUS) || h->class_id == 257) {
00044 h->region[i].memory = false;
00045 h->region[i].phy_addr &= BASE_ADDRESS_IO_MASK;
00046 h->region[i].size =
00047 ~(h->region[i].size & BASE_ADDRESS_IO_MASK) + 1;
00048 } else {
00049 h->region[i].memory = true;
00050 h->region[i].phy_addr &= BASE_ADDRESS_MEM_MASK;
00051 h->region[i].size =
00052 ~(h->region[i].size & BASE_ADDRESS_MEM_MASK) + 1;
00053 }
00054 h->cardbus_cis = cfg32(l.bus, l.dev_fn, CARDBUS_CIS);
00055 h->subsystem_vendor_id =
00056 cfg16(l.bus, l.dev_fn, SUBSYSTEM_VENDOR_ID);
00057 h->subsystem_device_id =
00058 cfg16(l.bus, l.dev_fn, SUBSYSTEM_DEVICE_ID);
00059 h->rom_address = cfg32(l.bus, l.dev_fn, ROM_ADDRESS);
00060 h->interrupt_line = cfg8(l.bus, l.dev_fn, INTERRUPT_LINE);
00061 h->interrupt_pin = cfg8(l.bus, l.dev_fn, INTERRUPT_PIN);
00062 h->min_gnt = cfg8(l.bus, l.dev_fn, MIN_GNT);
00063 h->max_lat = cfg8(l.bus, l.dev_fn, MAX_LAT);
00064 }
00065 } else
00066 h->locator = Locator(Locator::INVALID, Locator::INVALID);
00067 }
00068
00069 PC_PCI::Locator PC_PCI::scan(const PC_PCI::Class_Id & c, int order)
00070 {
00071 db<PC_PCI>(TRC) << "scan_class\n";
00072
00073 for(int bus = 0 ; bus <= MAX_BUS; bus++)
00074 for(int dfn = 0; dfn <= MAX_DEV_FN; dfn++)
00075 if(class_id(bus, dfn) == c)
00076 if(!order--)
00077 return Locator(bus, dfn);
00078
00079 return Locator(Locator::INVALID, Locator::INVALID);
00080 }
00081
00082 PC_PCI::Locator PC_PCI::scan(const PC_PCI::Vendor_Id & v,
00083 const PC_PCI::Device_Id & d, int order)
00084 {
00085 db<PC_PCI>(TRC) << "scan_vendor\n";
00086
00087 for(int bus = 0 ; bus <= MAX_BUS; bus++)
00088 for(int dfn = 0; dfn <= MAX_DEV_FN; dfn++)
00089 if((vendor_id(bus, dfn) == v) && (device_id(bus, dfn) == d))
00090 if(!order--)
00091 return Locator(bus, dfn);
00092
00093 return Locator(Locator::INVALID, Locator::INVALID);
00094 }
00095
00096 __END_SYS