1/** 2 * \file 3 * \brief PCI 4 */ 5 6/* 7 * Copyright (c) 2007, 2008, 2009, 2011, 2014, ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <stdio.h> 16#include <stdlib.h> 17#include <string.h> 18 19#include <barrelfish/barrelfish.h> 20#include <barrelfish/nameservice_client.h> 21 22#include <if/monitor_blocking_defs.h> 23 24#include <mm/mm.h> 25#include <octopus/init.h> 26#include <skb/skb.h> 27#include <acpi_client/acpi_client.h> 28#include <int_route/int_route_server.h> 29#include <int_route/int_route_debug.h> 30 31#include "pci.h" 32#include "pci_debug.h" 33#include "pci_int_ctrl.h" 34 35#if !defined(__ARM_ARCH_8A__) 36static errval_t init_io_ports(void) 37{ 38 errval_t err; 39 40 struct monitor_blocking_binding *cl = get_monitor_blocking_binding(); 41 assert(cl != NULL); 42 43 // Request I/O Cap 44 struct capref requested_caps; 45 errval_t error_code; 46 err = slot_alloc(&requested_caps); 47 assert(err_is_ok(err)); 48 err = cl->rpc_tx_vtbl.get_io_cap(cl, &requested_caps, &error_code); 49 assert(err_is_ok(err) && err_is_ok(error_code)); 50 51 // Copy into correct slot 52 struct capref caps_io = { 53 .cnode = cnode_task, 54 .slot = TASKCN_SLOT_IO 55 }; 56 err = cap_copy(caps_io, requested_caps); 57 58 return SYS_ERR_OK; 59} 60#endif 61 62int main(int argc, char *argv[]) 63{ 64 errval_t err; 65 66 // Parse commandline arguments 67 for(int i = 1; i < argc; i++) { 68 if(!strncmp(argv[i], "skb_bridge_program=", strlen("skb_bridge_program="))) { 69 skb_bridge_program = argv[i] + strlen("skb_bridge_program="); 70 } else if(!strncmp(argv[i], "numvfs=", strlen("numvfs="))) { 71 max_numvfs = atoi(argv[i] + strlen("numvfs=")); 72 enable_vfs = true; 73 } else { 74 printf("%s: Unknown commandline option \"%s\" -- skipping.\n", argv[0], argv[i]); 75 } 76 } 77 78 PCI_DEBUG("oct_init.\n"); 79 err = oct_init(); 80 if (err_is_fail(err)) { 81 USER_PANIC_ERR(err, "dist initialization failed."); 82 } 83 84 PCI_DEBUG("skb_client_connect.\n"); 85 err = skb_client_connect(); 86 if (err_is_fail(err)) { 87 USER_PANIC_ERR(err, "Connecting to SKB failed."); 88 } 89 90 PCI_DEBUG("int_route_service_init.\n"); 91 err = int_route_service_init(); 92 if (err_is_fail(err)) { 93 DEBUG_ERR(err, "int_route_service_init failed"); 94 abort(); 95 } 96 97 PCI_DEBUG("connect_to_acpi.\n"); 98 err = connect_to_acpi(); 99 if (err_is_fail(err)) { 100 USER_PANIC_ERR(err, "ACPI Connection failed."); 101 } 102 103#if !defined(__ARM_ARCH_8A__) 104 err = init_io_ports(); 105 if (err_is_fail(err)) { 106 USER_PANIC_ERR(err, "Init memory allocator failed."); 107 } 108#endif 109 110 err = pcie_setup_confspace(); 111 if (err_is_fail(err)) { 112 if (err_no(err) == ACPI_ERR_NO_MCFG_TABLE) { 113 PCI_DEBUG("No PCIe found, continue.\n"); 114 } 115 else { 116 USER_PANIC_ERR(err, "Setup PCIe confspace failed."); 117 } 118 } 119 120 err = pci_setup_root_complex(); 121 if (err_is_fail(err)) { 122 USER_PANIC_ERR(err, "Setup PCI root complex failed."); 123 } 124 125 err = pci_int_ctrl_init(); 126 if (err_is_fail(err)) { 127 USER_PANIC_ERR(err, "Initializing pci_int_ctrl failed"); 128 } 129 130 131 // Start configuring PCI 132 PCI_DEBUG("Programming PCI BARs and bridge windows\n"); 133 pci_program_bridges(); 134 PCI_DEBUG("PCI programming completed\n"); 135 pci_init_datastructures(); 136 pci_init(); 137 138 139#if 0 // defined(PCI_SERVICE_DEBUG) || defined(GLOBAL_DEBUG) 140//output all the facts stored in the SKB to produce a sample data file to use 141//for debugging on linux 142 skb_execute("listing."); 143 while (skb_read_error_code() == SKB_PROCESSING) messages_wait_and_handle_next(); 144 PCI_DEBUG("\nSKB returned: \n%s\n", skb_get_output()); 145 const char *errout = skb_get_error_output(); 146 if (errout != NULL && *errout != '\0') { 147 PCI_DEBUG("\nSKB error returned: \n%s\n", errout); 148 } 149#endif 150 151 skb_add_fact("pci_discovery_done."); 152 153 /* Using the name server as a lock server, 154 register a service with it so that other domains can do a blocking wait 155 on pci to finish enumeration */ 156 err = nameservice_register("pci_discovery_done", 0); 157 if (err_is_fail(err)) { 158 DEBUG_ERR(err, "nameservice_register failed"); 159 abort(); 160 } 161 162 err = vtd_add_devices(); 163 if (err_is_fail(err)) { 164 DEBUG_ERR(err, "vtd_add_devices failed"); 165 abort(); 166 } 167 168 messages_handler_loop(); 169} 170