1/** 2 * \file 3 * \brief Code responsible for booting application cores 4 */ 5 6/* 7 * Copyright (c) 2007, 2008, 2009, 2010, 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 <stdlib.h> 16#include <stdio.h> 17#include <string.h> 18#include <assert.h> 19 20#include <barrelfish/barrelfish.h> 21#include <barrelfish/spawn_client.h> 22 23#include <if/octopus_defs.h> 24#include <if/octopus_thc.h> 25 26#include <octopus/octopus.h> 27#include <octopus/trigger.h> 28 29#include <skb/skb.h> 30#include <thc/thc.h> 31 32#include "kaluga.h" 33 34 35/** Turn a line of comma seperated values into a a number of arguments 36 * and a pointer array of values (a la argc/argv). 37 * string pointed to by in _will be modified_ 38 * argv will be null terminated 39 */ 40 41static void csv_to_argv(char * in, int * argc, char *** argv) { 42 // Determine argc 43 *argc = 0; 44 for(char * pos = in; *pos; pos++) *argc += *pos == ',' ? 1 : 0; 45 46 char ** argv_out = (char **)malloc(sizeof(char *) * (*argc) + 1); 47 *argv = argv_out; 48 assert(argv_out != NULL); 49 50 //Replace , with \0 and generate argv 51 int argv_idx = 0; 52 argv_out[argv_idx] = in; 53 argv_idx++; 54 for(char * pos = in; *pos; pos++) { 55 if(*pos == ',') { 56 argv_out[argv_idx] = pos+1; 57 argv_idx++; 58 *pos = '\0'; 59 } 60 } 61 argv_out[argv_idx] = NULL; 62} 63 64static void int_controller_change_event(octopus_mode_t mode, 65 const char* device_record, void* st) 66{ 67 KALUGA_DEBUG("int_controller_change_event!\n"); 68 69 errval_t err; 70 char ** argv = NULL; 71 72 if (mode & OCT_ON_SET) { 73 char * label; 74 char * class; 75 KALUGA_DEBUG("Device record: %s\n", device_record); 76 err = oct_read(device_record, "_ { label: %s, class: %s }", 77 &label, &class); 78 if (err_is_fail(err)) { 79 USER_PANIC_ERR(err, "Got malformed int controller device record?"); 80 goto out; 81 } 82 83 KALUGA_DEBUG("Int Controller appeared, Label: %s\n", label); 84 // Ask the SKB which binary and where to start it... 85 static char* query = "find_int_controller_driver(%s)."; 86 err = skb_execute_query(query, label); 87 if (err_no(err) == SKB_ERR_EXECUTION) { 88 KALUGA_DEBUG("No int controller driver found for: label=%s,class=%s\n", 89 label, class); 90 goto out; 91 } 92 else if (err_is_fail(err)) { 93 DEBUG_ERR(err, "Failed to query SKB.\n"); 94 goto out; 95 } 96 97 char * out = skb_get_output(); 98 int argc; 99 csv_to_argv(out, &argc, &argv); 100 101 // TODO: specify core somehow. If core != my_core_id 102 // We must make sure that spawnd is up (see start_pci.c) 103 coreid_t core = get_my_core_id(); 104 KALUGA_DEBUG("Starting int controller binary: %s\n", argv[0]); 105 106 err = spawn_program(core, argv[0], argv+1, 107 environ, 0, NULL); 108 if (err_is_fail(err)) { 109 DEBUG_ERR(err, "Spawning %s failed.", argv[0]); 110 } 111 } 112 113out: 114 free(argv); 115} 116 117errval_t watch_for_int_controller(void) { 118 KALUGA_DEBUG("watch_for_int_controller\n"); 119 static char* int_controller_device = "r'hw\\.int\\.controller\\.[0-9]+' { " 120 " label: _, class: _ }"; 121 octopus_trigger_id_t tid; 122 return oct_trigger_existing_and_watch(int_controller_device, int_controller_change_event, NULL, &tid); 123} 124