1/** 2 * \file 3 * \brief Device manager for Barrelfish. 4 * 5 * Interacts with the SKB / PCI to start cores, drivers etc. 6 * 7 * x86 specific startup code 8 * 9 */ 10 11/* 12 * Copyright (c) 2007-2010, 2016 ETH Zurich. 13 * Copyright (c) 2015, Hewlett Packard Enterprise Development LP. 14 * All rights reserved. 15 * 16 * This file is distributed under the terms in the attached LICENSE file. 17 * If you do not find this file, copies can be found by writing to: 18 * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group. 19 */ 20 21#include <barrelfish/barrelfish.h> 22#include <skb/skb.h> 23#include <pci/pci.h> 24#include <acpi_client/acpi_client.h> 25#include "kaluga.h" 26 27#define SERIAL_IRQ 4 28#define SERIAL_BINARY "serial_pc16550d" 29 30#define LPC_TIMER_IRQ 0 31#define LPC_TIMER_BINARY "lpc_timer" 32 33static errval_t start_serial(void){ 34 errval_t err; 35 struct module_info * mi = find_module(SERIAL_BINARY); 36 if (mi != NULL) { 37 // Get internal int number. COM1 uses ISA nr. 4 38 struct driver_argument arg; 39 err = init_driver_argument(&arg); 40 if(err_is_fail(err)){ 41 DEBUG_ERR(err, "init_driver_argument failed\n"); 42 return err; 43 } 44 err = skb_execute_query("isa_irq_to_int(%d,N), writeln(N).", SERIAL_IRQ); 45 if(err_is_fail(err)){ 46 DEBUG_SKB_ERR(err, "skb_execute_query"); 47 return err; 48 } 49 int int_nr; 50 err = skb_read_output("%d", &int_nr); 51 if(err_is_fail(err)){ 52 DEBUG_ERR(err, "skb_read_output"); 53 return err; 54 } 55 KALUGA_DEBUG("Found internal int number (%d) for serial.\n", int_nr); 56 arg.int_arg.int_range_start = int_nr; 57 arg.int_arg.int_range_end = int_nr; 58 arg.int_arg.model = INT_MODEL_LEGACY; 59 60 err = store_int_cap(int_nr, int_nr, &arg); 61 if(err_is_fail(err)){ 62 DEBUG_ERR(err, "int_src_cap"); 63 return err; 64 } 65 err = mi->start_function(0, mi, "hw.legacy.uart.1 {}", &arg); 66 if(err_is_fail(err)){ 67 USER_PANIC_ERR(err, "serial->start_function"); 68 } 69 } else { 70 printf("Kaluga: Not starting \"%s\", binary not found\n", SERIAL_BINARY); 71 return KALUGA_ERR_MODULE_NOT_FOUND; 72 } 73 return SYS_ERR_OK; 74} 75 76static errval_t start_lpc_timer(void){ 77 errval_t err; 78 struct module_info * mi = find_module(LPC_TIMER_BINARY); 79 if (mi != NULL) { 80 // Get internal int number. 81 struct driver_argument arg; 82 init_driver_argument(&arg); 83 84 err = skb_execute_query("isa_irq_to_int(%d,N), writeln(N).", LPC_TIMER_IRQ); 85 if(err_is_fail(err)){ 86 DEBUG_SKB_ERR(err, "skb_execute"); 87 return err; 88 } 89 int int_nr; 90 err = skb_read_output("%d", &int_nr); 91 if(err_is_fail(err)){ 92 DEBUG_ERR(err, "skb_read_output"); 93 return err; 94 } 95 KALUGA_DEBUG("Found internal int number (%d) for lpc_timer.\n", int_nr); 96 arg.int_arg.int_range_start = int_nr; 97 arg.int_arg.int_range_end = int_nr; 98 arg.int_arg.model = INT_MODEL_LEGACY; 99 100 err = store_int_cap(int_nr, int_nr, &arg); 101 if(err_is_fail(err)){ 102 DEBUG_ERR(err, "store_int_cap"); 103 return err; 104 } 105 106 err = mi->start_function(0, mi, "hw.legacy.timer.1 {}", &arg); 107 if(err_is_fail(err)){ 108 USER_PANIC_ERR(err, "serial->start_function"); 109 } 110 } else { 111 printf("Kaluga: Not starting \"%s\", binary not found\n", LPC_TIMER_BINARY); 112 return KALUGA_ERR_MODULE_NOT_FOUND; 113 } 114 return SYS_ERR_OK; 115} 116 117errval_t arch_startup(char * add_device_db_file) 118{ 119 errval_t err = SYS_ERR_OK; 120 // We need to run on core 0 121 // (we are responsible for booting all the other cores) 122 assert(my_core_id == BSP_CORE_ID); 123 KALUGA_DEBUG("Kaluga running on x86.\n"); 124 125 126 err = skb_client_connect(); 127 if (err_is_fail(err)) { 128 USER_PANIC_ERR(err, "Connect to SKB."); 129 } 130 131 // Make sure the driver db is loaded 132 err = skb_execute("[device_db]."); 133 if (err_is_fail(err)) { 134 USER_PANIC_SKB_ERR(err, "Device DB not loaded."); 135 } 136 if(add_device_db_file != NULL){ 137 err = skb_execute_query("[%s].", add_device_db_file); 138 if(err_is_fail(err)){ 139 USER_PANIC_SKB_ERR(err,"Additional device db file %s not loaded.", add_device_db_file); 140 } 141 } 142 143 // The current boot protocol needs us to have 144 // knowledge about how many CPUs are available at boot 145 // time in order to start-up properly. 146 char* record = NULL; 147 err = oct_barrier_enter("barrier.acpi", &record, 2); 148 149 KALUGA_DEBUG("Kaluga: watch_for_cores\n"); 150 151 err = watch_for_cores(); 152 if (err_is_fail(err)) { 153 USER_PANIC_ERR(err, "Watching cores."); 154 } 155 156 KALUGA_DEBUG("Kaluga: pci_root_bridge\n"); 157 158 err = watch_for_pci_root_bridge(); 159 if (err_is_fail(err)) { 160 USER_PANIC_ERR(err, "Watching PCI root bridges."); 161 } 162 163 KALUGA_DEBUG("Kaluga: int_controller_devices\n"); 164 165 err = watch_for_int_controller(); 166 if (err_is_fail(err)) { 167 USER_PANIC_ERR(err, "Watching interrupt controllers."); 168 } 169 170 KALUGA_DEBUG("Kaluga: wait_for_all_spawnds\n"); 171 172 err = wait_for_all_spawnds(); 173 if (err_is_fail(err)) { 174 USER_PANIC_ERR(err, "Unable to wait for spawnds failed."); 175 } 176 177 KALUGA_DEBUG("Kaluga: ACPI connect...\n"); 178 err = connect_to_acpi(); 179 if (err_is_fail(err) && err != KALUGA_ERR_MODULE_NOT_FOUND) { 180 USER_PANIC_ERR(err, "start_lpc_timer"); 181 } 182 183 KALUGA_DEBUG("Kaluga: pci_devices\n"); 184 185 err = watch_for_pci_devices(); 186 if (err_is_fail(err)) { 187 USER_PANIC_ERR(err, "Watching PCI devices."); 188 } 189 190 KALUGA_DEBUG("Kaluga: Starting serial...\n"); 191 err = start_serial(); 192 if (err_is_fail(err) && err != KALUGA_ERR_MODULE_NOT_FOUND) { 193 USER_PANIC_ERR(err, "start_serial"); 194 } 195 196 KALUGA_DEBUG("Kaluga: Starting lpc timer...\n"); 197 err = start_lpc_timer(); 198 if (err_is_fail(err) && err != KALUGA_ERR_MODULE_NOT_FOUND) { 199 USER_PANIC_ERR(err, "start_lpc_timer"); 200 } 201 202 return SYS_ERR_OK; 203} 204