github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/vmm/host/hw/host_pci_configuration.c (about) 1 /* 2 * Copyright (c) 2013 Intel Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * Unless required by applicable law or agreed to in writing, software 9 * distributed under the License is distributed on an "AS IS" BASIS, 10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 * See the License for the specific language governing permissions and 12 * limitations under the License. 13 */ 14 15 #include "host_pci_configuration.h" 16 #include "hw_utils.h" 17 #include "vmm_dbg.h" 18 #include "libc.h" 19 #include "file_codes.h" 20 #define VMM_DEADLOOP() VMM_DEADLOOP_LOG(HOST_PCI_CONFIGURATION_C) 21 #define VMM_ASSERT(__condition) VMM_ASSERT_LOG(HOST_PCI_CONFIGURATION_C, __condition) 22 #ifdef JLMDEBUG 23 #include "jlmdebug.h" 24 #endif 25 26 27 #define PCI_DEV_INDEX_INVALID 0 // index 0 is not in use. used to specify "invalid" in lookup table 28 29 // bit 7: =0 single function, =1 multi-function 30 #define PCI_IS_MULTIFUNCTION_DEVICE(header_type) (((header_type) & 0x80) != 0) 31 #define PCI_IS_PCI_2_PCI_BRIDGE(base_class, sub_class) ((base_class) == PCI_BASE_CLASS_BRIDGE && (sub_class) == 0x04) 32 #ifdef PCI_SCAN 33 static HOST_PCI_DEVICE pci_devices[PCI_MAX_NUM_SUPPORTED_DEVICES + 1]; 34 static PCI_DEV_INDEX avail_pci_device_index = 1; // index 0 is not in use. used to specify "invalid" in lookup table 35 static PCI_DEV_INDEX pci_devices_lookup_table[PCI_MAX_NUM_FUNCTIONS]; 36 static UINT32 num_pci_devices = 0; 37 38 UINT8 pci_read8(UINT8 bus, UINT8 device, UINT8 function, UINT8 reg) 39 { 40 PCI_CONFIG_ADDRESS addr; 41 42 addr.Uint32 = 0; 43 addr.Bits.Bus = bus; 44 addr.Bits.Device = device; 45 addr.Bits.Function = function; 46 addr.Bits.Register = reg; 47 addr.Bits.Enable = 1; 48 49 hw_write_port_32(PCI_CONFIG_ADDRESS_REGISTER, addr.Uint32 & ~0x3); 50 return hw_read_port_8(PCI_CONFIG_DATA_REGISTER | (addr.Uint32 & 0x3)); 51 } 52 53 void pci_write8(UINT8 bus, UINT8 device, UINT8 function, UINT8 reg, UINT8 value) 54 { 55 PCI_CONFIG_ADDRESS addr; 56 57 addr.Uint32 = 0; 58 addr.Bits.Bus = bus; 59 addr.Bits.Device = device; 60 addr.Bits.Function = function; 61 addr.Bits.Register = reg; 62 addr.Bits.Enable = 1; 63 64 hw_write_port_32(PCI_CONFIG_ADDRESS_REGISTER, addr.Uint32 & ~0x3); 65 hw_write_port_8(PCI_CONFIG_DATA_REGISTER | (addr.Uint32 & 0x3), value); 66 } 67 68 UINT16 pci_read16(UINT8 bus, UINT8 device, UINT8 function, UINT8 reg) 69 { 70 PCI_CONFIG_ADDRESS addr; 71 72 addr.Uint32 = 0; 73 addr.Bits.Bus = bus; 74 addr.Bits.Device = device; 75 addr.Bits.Function = function; 76 addr.Bits.Register = reg; 77 addr.Bits.Enable = 1; 78 79 hw_write_port_32(PCI_CONFIG_ADDRESS_REGISTER, addr.Uint32 & ~0x3); 80 return hw_read_port_16(PCI_CONFIG_DATA_REGISTER | (addr.Uint32 & 0x3)); 81 } 82 83 void pci_write16(UINT8 bus, UINT8 device, UINT8 function, UINT8 reg, UINT16 value) 84 { 85 PCI_CONFIG_ADDRESS addr; 86 87 addr.Uint32 = 0; 88 addr.Bits.Bus = bus; 89 addr.Bits.Device = device; 90 addr.Bits.Function = function; 91 addr.Bits.Register = reg; 92 addr.Bits.Enable = 1; 93 94 hw_write_port_32(PCI_CONFIG_ADDRESS_REGISTER, addr.Uint32 & ~0x3); 95 hw_write_port_16(PCI_CONFIG_DATA_REGISTER | (addr.Uint32 & 0x2), value); 96 } 97 98 UINT32 pci_read32(UINT8 bus, UINT8 device, UINT8 function, UINT8 reg) 99 { 100 PCI_CONFIG_ADDRESS addr; 101 102 addr.Uint32 = 0; 103 addr.Bits.Bus = bus; 104 addr.Bits.Device = device; 105 addr.Bits.Function = function; 106 addr.Bits.Register = reg; 107 addr.Bits.Enable = 1; 108 109 hw_write_port_32(PCI_CONFIG_ADDRESS_REGISTER, addr.Uint32 & ~0x3); 110 return hw_read_port_32(PCI_CONFIG_DATA_REGISTER); 111 } 112 113 void pci_write32(UINT8 bus, UINT8 device, UINT8 function, UINT8 reg, UINT32 value) 114 { 115 PCI_CONFIG_ADDRESS addr; 116 117 addr.Uint32 = 0; 118 addr.Bits.Bus = bus; 119 addr.Bits.Device = device; 120 addr.Bits.Function = function; 121 addr.Bits.Register = reg; 122 addr.Bits.Enable = 1; 123 124 hw_write_port_32(PCI_CONFIG_ADDRESS_REGISTER, addr.Uint32 & ~0x3); 125 hw_write_port_32(PCI_CONFIG_DATA_REGISTER, value); 126 } 127 128 HOST_PCI_DEVICE *get_host_pci_device(UINT8 bus, UINT8 device, UINT8 function) 129 { 130 HOST_PCI_DEVICE *pci_dev; 131 PCI_DEVICE_ADDRESS lookup_table_index = 0; 132 PCI_DEV_INDEX pci_dev_index = 0; 133 134 if(FALSE == PCI_IS_ADDRESS_VALID(bus, device, function)) 135 { 136 return NULL; 137 } 138 SET_PCI_BUS(lookup_table_index, bus); 139 SET_PCI_DEVICE(lookup_table_index, device); 140 SET_PCI_FUNCTION(lookup_table_index, function); 141 pci_dev_index = pci_devices_lookup_table[lookup_table_index]; 142 143 if(PCI_DEV_INDEX_INVALID == pci_dev_index) { 144 pci_dev = NULL; 145 } 146 else { 147 pci_dev = &pci_devices[pci_dev_index]; 148 } 149 return pci_dev; 150 } 151 152 BOOLEAN pci_read_secondary_bus_reg(UINT8 bus, UINT8 device, UINT8 func, OUT UINT8 *secondary_bus) 153 { 154 HOST_PCI_DEVICE *pci_bridge = get_host_pci_device(bus, device, func); 155 156 *secondary_bus = 0; 157 if(NULL == pci_bridge || FALSE == pci_bridge->is_pci_2_pci_bridge 158 || PCI_CONFIG_HEADER_TYPE_PCI2PCI_BRIDGE != pci_bridge->header_type) { 159 return FALSE; 160 } 161 162 *secondary_bus = pci_read8(bus, device, func, PCI_CONFIG_SECONDARY_BUS_OFFSET); 163 return TRUE; 164 } 165 166 static UINT8 167 host_pci_decode_bar( 168 UINT8 bus, 169 UINT8 device, 170 UINT8 function, 171 UINT8 bar_offset, 172 PCI_BASE_ADDRESS_REGISTER *bar) 173 { 174 UINT32 bar_value_low = pci_read32(bus, device, function, bar_offset); 175 UINT32 bar_value_high = 0; 176 UINT64 bar_value = 0; 177 UINT32 encoded_size_low = 0; 178 UINT32 encoded_size_high = 0; 179 UINT64 encoded_size = 0; 180 UINT64 mask; 181 UINT32 address_type = PCI_CONFIG_HEADER_BAR_ADDRESS_32; 182 183 VMM_LOG(mask_anonymous, level_trace,"%s %d:%d:%d:%d, bar_value_low=0x%x\r\n", 184 __FUNCTION__, bus, device, function, bar_offset, bar_value_low); 185 186 if (bar_value_low > 1) // 0: not used mmio space; 1: not used io space 187 { 188 // issue size determination command 189 pci_write32(bus, device, function, bar_offset, PCI_CONFIG_HEADER_BAR_SIZING_COMMAND); 190 encoded_size_low = pci_read32(bus, device, function, bar_offset); 191 192 bar->type = bar_value_low & PCI_CONFIG_HEADER_BAR_MEMORY_TYPE_MASK; 193 194 mask = (PCI_BAR_IO_REGION == bar->type) ? 195 PCI_CONFIG_HEADER_BAR_ADDRESS_MASK_TYPE_IO : 196 PCI_CONFIG_HEADER_BAR_ADDRESS_MASK_TYPE_MMIO; 197 198 // valid only for mmio 199 address_type = (UINT32)(bar_value_low & PCI_CONFIG_HEADER_BAR_ADDRESS_TYPE_MASK) >> 1; 200 201 if(bar->type == PCI_BAR_MMIO_REGION && address_type == PCI_CONFIG_HEADER_BAR_ADDRESS_64) { 202 // issue size determination command 203 bar_value_high = pci_read32(bus, device, function, bar_offset + 4); 204 pci_write32(bus, device, function, bar_offset + 4, PCI_CONFIG_HEADER_BAR_SIZING_COMMAND); 205 encoded_size_high = pci_read32(bus, device, function, bar_offset + 4); 206 bar_value = (UINT64) bar_value_high << 32 | ((UINT64)bar_value_low & 0x00000000FFFFFFFF); 207 bar->addr = bar_value & mask; 208 encoded_size = (UINT64) encoded_size_high << 32 | ((UINT64)encoded_size_low & 0x00000000FFFFFFFF); 209 encoded_size &= mask; 210 bar->length = (~encoded_size) + 1; 211 pci_write32(bus, device, function, bar_offset, bar_value_low); // restore original value 212 pci_write32(bus, device, function, bar_offset + 4, bar_value_high); // restore original value 213 } 214 else { 215 bar->addr = ((UINT64)bar_value_low & 0x00000000FFFFFFFF) & mask; 216 encoded_size = 0xFFFFFFFF00000000 | ((UINT64)encoded_size_low & 0x00000000FFFFFFFF); 217 encoded_size &= mask; 218 bar->length = (~encoded_size) + 1; 219 pci_write32(bus, device, function, bar_offset, bar_value_low); // restore original value 220 } 221 222 if (PCI_BAR_IO_REGION == bar->type) { 223 bar->length &= 0xFFFF; // IO space in Intel arch can't exceed 64K bytes 224 } 225 } 226 else { 227 bar->type = PCI_BAR_UNUSED; 228 } 229 return (address_type == PCI_CONFIG_HEADER_BAR_ADDRESS_64) ? 8 : 4; 230 } 231 232 static void host_pci_decode_pci_bridge( 233 UINT8 bus, 234 UINT8 device, 235 UINT8 function, 236 PCI_BASE_ADDRESS_REGISTER *bar_mmio, 237 PCI_BASE_ADDRESS_REGISTER *bar_io) 238 { 239 UINT32 memory_base = ((UINT32)pci_read16(bus, device, function, PCI_CONFIG_BRIDGE_MEMORY_BASE) << 16) & 0xFFF00000; 240 UINT32 memory_limit = ((UINT32)pci_read16(bus, device, function, PCI_CONFIG_BRIDGE_MEMORY_LIMIT) << 16) | 0x000FFFFF; 241 UINT8 io_base_low = pci_read8(bus, device, function, PCI_CONFIG_BRIDGE_IO_BASE_LOW); 242 UINT8 io_limit_low = pci_read8(bus, device, function, PCI_CONFIG_BRIDGE_IO_LIMIT_LOW); 243 UINT16 io_base_high = 0; 244 UINT16 io_limit_high = 0; 245 UINT64 io_base; 246 UINT64 io_limit; 247 248 // mmio 249 if (memory_limit < memory_base) { 250 bar_mmio->type = PCI_BAR_UNUSED; 251 } 252 else { 253 bar_mmio->type = PCI_BAR_MMIO_REGION; 254 bar_mmio->addr = (UINT64)memory_base & 0x00000000FFFFFFFF; 255 bar_mmio->length = (UINT64)(memory_limit - memory_base +1) & 0x00000000FFFFFFFF; 256 } 257 258 // io 259 if (io_base_low == 0 || io_limit_low == 0 || io_limit_low < io_base_low) { 260 bar_io->type = PCI_BAR_UNUSED; 261 } 262 else if ((io_base_low & 0xF) > 1) { 263 bar_io->type = PCI_BAR_UNUSED; 264 VMM_LOG(mask_anonymous, level_print_always,"%s Warning: reserved IO address capability in bridge (%d:%d:%d) detected, io_base_low=0x%x\r\n", 265 __FUNCTION__, bus, device, function, io_base_low); 266 } 267 else { 268 if ((io_base_low & 0xF) == 1) // 32 bit IO address { 269 // update the high 16 bits 270 io_base_high = pci_read16(bus, device, function, PCI_CONFIG_BRIDGE_IO_BASE_HIGH); 271 io_limit_high = pci_read16(bus, device, function, PCI_CONFIG_BRIDGE_IO_LIMIT_HIGH); 272 } 273 io_base = (((UINT64) io_base_high << 16) & 0x00000000FFFF0000) | 274 (((UINT64) io_base_low << 8) & 0x000000000000F000); 275 io_limit = (((UINT64) io_limit_high << 16) & 0x00000000FFFF0000) | 276 (((UINT64) io_limit_low << 8) & 0x000000000000F000) | 277 0x0000000000000FFF; 278 bar_io->type = PCI_BAR_IO_REGION; 279 bar_io->addr = io_base; 280 bar_io->length = io_limit-io_base+1; 281 } 282 } 283 284 static void pci_init_device(PCI_DEVICE_ADDRESS device_addr, 285 PCI_DEVICE_ADDRESS parent_addr, 286 BOOLEAN parent_addr_valid, 287 BOOLEAN is_bridge) 288 { 289 HOST_PCI_DEVICE *pci_dev; 290 PCI_DEV_INDEX pci_dev_index = 0; 291 UINT32 i; 292 UINT8 bus, device, function; 293 UINT8 bar_offset; 294 295 // BEFORE_VMLAUNCH 296 VMM_ASSERT(avail_pci_device_index <= PCI_MAX_NUM_SUPPORTED_DEVICES); 297 298 pci_dev_index = pci_devices_lookup_table[device_addr]; 299 300 if(PCI_DEV_INDEX_INVALID != pci_dev_index) {// already initialized 301 return; 302 } 303 304 num_pci_devices++; 305 pci_dev_index = avail_pci_device_index++; 306 pci_devices_lookup_table[device_addr] = pci_dev_index; 307 308 pci_dev = &pci_devices[pci_dev_index]; 309 pci_dev->address = device_addr; 310 bus = GET_PCI_BUS(device_addr); 311 device = GET_PCI_DEVICE(device_addr); 312 function = GET_PCI_FUNCTION(device_addr); 313 pci_dev->vendor_id = pci_read16(bus, device, function, PCI_CONFIG_VENDOR_ID_OFFSET); 314 pci_dev->device_id = pci_read16(bus, device, function, PCI_CONFIG_DEVICE_ID_OFFSET); 315 pci_dev->revision_id = pci_read8(bus, device, function, PCI_CONFIG_REVISION_ID_OFFSET); 316 pci_dev->base_class = pci_read8(bus, device, function, PCI_CONFIG_BASE_CLASS_CODE_OFFSET); 317 pci_dev->sub_class = pci_read8(bus, device, function, PCI_CONFIG_SUB_CLASS_CODE_OFFSET); 318 pci_dev->programming_interface = pci_read8(bus, device, function, PCI_CONFIG_PROGRAMMING_INTERFACE_OFFSET); 319 pci_dev->header_type = pci_read8(bus, device, 0, PCI_CONFIG_HEADER_TYPE_OFFSET); 320 pci_dev->is_multifunction = PCI_IS_MULTIFUNCTION_DEVICE(pci_dev->header_type); 321 pci_dev->header_type = pci_dev->header_type & ~0x80; // clear multifunction bit 322 pci_dev->is_pci_2_pci_bridge = PCI_IS_PCI_2_PCI_BRIDGE(pci_dev->base_class, pci_dev->sub_class); 323 pci_dev->interrupt_pin = pci_read8(bus, device, function, PCI_CONFIG_INTERRUPT_PIN_OFFSET); 324 pci_dev->interrupt_line = pci_read8(bus, device, function, PCI_CONFIG_INTERRUPT_LINE_OFFSET); 325 if(parent_addr_valid) { 326 pci_dev->parent = get_host_pci_device(GET_PCI_BUS(parent_addr), GET_PCI_DEVICE(parent_addr), GET_PCI_FUNCTION(parent_addr)); 327 } 328 else { 329 pci_dev->parent = NULL; 330 } 331 332 if(pci_dev->parent == NULL) { 333 pci_dev->depth = 1; 334 pci_dev->path.start_bus = bus; 335 } 336 else { 337 pci_dev->depth = pci_dev->parent->depth + 1; 338 pci_dev->path.start_bus = pci_dev->parent->path.start_bus; 339 for(i = 0; i < pci_dev->parent->depth; i++) 340 { 341 pci_dev->path.path[i] = pci_dev->parent->path.path[i]; 342 } 343 } 344 VMM_ASSERT(pci_dev->depth <= PCI_MAX_PATH); 345 pci_dev->path.path[pci_dev->depth - 1].device = device; 346 pci_dev->path.path[pci_dev->depth - 1].function = function; 347 348 bar_offset = PCI_CONFIG_BAR_OFFSET; 349 if (is_bridge) { 350 for(i = 0; i < PCI_MAX_BAR_NUMBER_IN_BRIDGE; i++) { 351 // Assumption: according to PCI bridge spec 1.2, host_pci_decode_bar() will only return 4 (as 32 bit) for bridge 352 // 64 bit mapping is not supported in bridge 353 bar_offset = bar_offset + host_pci_decode_bar(bus, device, function, bar_offset, &pci_dev->bars[i]); 354 } 355 host_pci_decode_pci_bridge(bus, device, function, &pci_dev->bars[i], &pci_dev->bars[i+1]); // set io range and mmio range 356 i+=2; // for the io bar and mmio bar set by host_pci_decode_pci_bridge() above 357 // set rest bars as unused 358 for (; i < PCI_MAX_BAR_NUMBER; i++) 359 pci_dev->bars[i].type = PCI_BAR_UNUSED; 360 } 361 else { 362 for(i = 0; i < PCI_MAX_BAR_NUMBER; i++) { 363 if (bar_offset > PCI_CONFIG_BAR_LAST_OFFSET) // total bar size is 0x10~0x24 364 pci_dev->bars[i].type = PCI_BAR_UNUSED; 365 else 366 bar_offset = bar_offset + host_pci_decode_bar(bus, device, function, bar_offset, &pci_dev->bars[i]); 367 } 368 } 369 } 370 371 372 static void pci_scan_bus(UINT8 bus, PCI_DEVICE_ADDRESS parent_addr, BOOLEAN parent_addr_valid) 373 { 374 UINT8 device = 0; 375 UINT8 function = 0; 376 UINT8 header_type = 0; 377 UINT8 max_functions = 0; 378 UINT16 vendor_id = 0; 379 UINT16 device_id = 0; 380 BOOLEAN is_multifunction = 0; 381 UINT8 base_class = 0; 382 UINT8 sub_class = 0; 383 UINT8 secondary_bus = 0; 384 PCI_DEVICE_ADDRESS this_device_address = 0; 385 BOOLEAN is_bridge; 386 387 for(device = 0; device < PCI_MAX_NUM_DEVICES_ON_BUS; device++) { 388 header_type = pci_read8(bus, device, 0, PCI_CONFIG_HEADER_TYPE_OFFSET); 389 is_multifunction = PCI_IS_MULTIFUNCTION_DEVICE(header_type); // bit 7: =0 single function, =1 multi-function 390 max_functions = is_multifunction ? PCI_MAX_NUM_FUNCTIONS_ON_DEVICE: 1; 391 header_type = header_type & ~0x80; // clear multifunction bit 392 393 for(function = 0; function < max_functions; function++) { 394 vendor_id = pci_read16(bus, device, function, PCI_CONFIG_VENDOR_ID_OFFSET); 395 device_id = pci_read16(bus, device, function, PCI_CONFIG_DEVICE_ID_OFFSET); 396 397 if(PCI_INVALID_VENDOR_ID == vendor_id || PCI_INVALID_DEVICE_ID == device_id) { 398 continue; 399 } 400 401 SET_PCI_BUS(this_device_address, bus); 402 SET_PCI_DEVICE(this_device_address, device); 403 SET_PCI_FUNCTION(this_device_address, function); 404 405 base_class = pci_read8(bus, device, function, PCI_CONFIG_BASE_CLASS_CODE_OFFSET); 406 sub_class = pci_read8(bus, device, function, PCI_CONFIG_SUB_CLASS_CODE_OFFSET); 407 408 is_bridge = PCI_IS_PCI_2_PCI_BRIDGE(base_class, sub_class); 409 410 // call device handler 411 pci_init_device(this_device_address, parent_addr, parent_addr_valid, is_bridge); 412 413 // check if it is needed to go downstream the bridge 414 if(is_bridge) { 415 if (header_type == 1) // PCI Bridge header type. it should be 1. Skip misconfigured devices { 416 secondary_bus = pci_read8(bus, device, function, PCI_CONFIG_SECONDARY_BUS_OFFSET); 417 pci_scan_bus(secondary_bus, this_device_address, TRUE); 418 } 419 } 420 } 421 } 422 } 423 424 UINT32 host_pci_get_num_devices(void) 425 { 426 return num_pci_devices; 427 } 428 429 static void host_pci_print_bar(PCI_BASE_ADDRESS_REGISTER *bar) 430 { 431 static char* bar_type_string = NULL; 432 433 if(PCI_BAR_UNUSED == bar->type) { 434 //bar_type_string = "unused"; 435 return; 436 } 437 else if(PCI_BAR_IO_REGION == bar->type) { 438 bar_type_string = "io"; 439 } 440 else if(PCI_BAR_MMIO_REGION == bar->type) { 441 bar_type_string = "mmio"; 442 } 443 444 VMM_LOG(mask_anonymous, level_trace,"%s addr=%p size=%p; ", bar_type_string, bar->addr, bar->length); 445 } 446 447 #ifdef VMM_DEBUG_SCREEN 448 static void host_pci_print_bar_screen(PCI_BASE_ADDRESS_REGISTER *bar) 449 { 450 static char* bar_type_string = NULL; 451 452 if(PCI_BAR_UNUSED == bar->type) { 453 //bar_type_string = "unused"; 454 return; 455 } 456 else if(PCI_BAR_IO_REGION == bar->type) { 457 bar_type_string = "io"; 458 } 459 else if(PCI_BAR_MMIO_REGION == bar->type) { 460 bar_type_string = "mmio"; 461 } 462 463 VMM_LOG_SCREEN("%s addr=%p size=%p; ", bar_type_string, bar->addr, bar->length); 464 } 465 #endif 466 467 static void host_pci_print(void) 468 { 469 UINT32 i = 0, j; 470 PCI_DEVICE_ADDRESS device_addr; 471 PCI_DEV_INDEX pci_dev_index = 0; 472 HOST_PCI_DEVICE *pci_dev; 473 474 VMM_LOG(mask_anonymous, level_trace,"[Bus] [Dev] [Func] [Vendor ID] [Dev ID] [PCI-PCI Bridge]\r\n"); 475 //vmm_clear_screen(); 476 for(i = 0; i < PCI_MAX_NUM_FUNCTIONS; i++) { 477 if(PCI_DEV_INDEX_INVALID == pci_devices_lookup_table[i]) { 478 continue; 479 } 480 481 device_addr = (UINT16) i; 482 pci_dev_index = pci_devices_lookup_table[i]; 483 pci_dev = &pci_devices[pci_dev_index]; 484 485 VMM_LOG(mask_anonymous, level_trace,"%5d %5d %6d %#11x %#8x ", 486 GET_PCI_BUS(device_addr), GET_PCI_DEVICE(device_addr), GET_PCI_FUNCTION(device_addr), pci_dev->vendor_id, pci_dev->device_id); 487 488 if(pci_dev->is_pci_2_pci_bridge) { 489 VMM_LOG(mask_anonymous, level_trace,"%16c ", 'X'); 490 } 491 VMM_LOG(mask_anonymous, level_trace,"\r\n BARs: "); 492 for(j = 0; j < PCI_MAX_BAR_NUMBER; j++) { 493 host_pci_print_bar(&(pci_dev->bars[j])); 494 } 495 VMM_LOG(mask_anonymous, level_trace,"\r\n"); 496 } 497 } 498 499 void host_pci_initialize(void) 500 { 501 UINT16 bus; // use 16 bits instead of 8 to avoid wrap around on bus==256 502 PCI_DEVICE_ADDRESS addr = {0}; 503 504 vmm_zeromem(pci_devices, sizeof(pci_devices)); 505 vmm_zeromem(pci_devices_lookup_table, sizeof(pci_devices_lookup_table)); 506 507 VMM_LOG(mask_anonymous, level_trace,"\r\nSTART Host PCI scan\r\n"); 508 for(bus = 0; bus < PCI_MAX_NUM_BUSES; bus++) { 509 pci_scan_bus((UINT8) bus, addr, FALSE); 510 } 511 512 host_pci_print(); 513 VMM_LOG(mask_anonymous, level_trace,"\r\nEND Host PCI scan\r\n"); 514 } 515 #endif //PCI_SCAN