1/**
2 * \file
3 * \brief Device manager for Barrelfish.
4 *
5 * Interacts with the SKB / PCI to start cores, drivers etc.
6 *
7 */
8
9/*
10 * Copyright (c) 2007-2010, ETH Zurich.
11 * Copyright (c) 2015, Hewlett Packard Enterprise Development LP.
12 * All rights reserved.
13 *
14 * This file is distributed under the terms in the attached LICENSE file.
15 * If you do not find this file, copies can be found by writing to:
16 * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
17 */
18
19#include <stdlib.h>
20#include <stdbool.h>
21#include <stdio.h>
22#include <assert.h>
23#include <string.h>
24#include <errors/errno.h>
25
26#include <barrelfish/barrelfish.h>
27#include <barrelfish/cpu_arch.h>
28#include <barrelfish/nameservice_client.h>
29
30#include <if/monitor_defs.h>
31
32#include <vfs/vfs.h>
33#include <pci/pci_types.h> // for pci_addr
34#include <octopus/octopus.h>
35#include <thc/thc.h>
36
37#include <trace/trace.h>
38
39#include "kaluga.h"
40
41
42coreid_t my_core_id = 0;  // Core ID
43uint32_t my_arch_id = 0;  // APIC ID
44struct pci_addr eth0 = {0xff, 0xff, 0xff};
45size_t cpu_count = 0;
46
47static void add_start_function_overrides(void)
48{
49
50    set_start_function("e10k", start_networking);
51    set_start_function("net_sockets_server", start_networking);
52    set_start_function("rtl8029", start_networking);
53    set_start_function("corectrl", start_boot_driver);
54
55#ifndef __ARM_ARCH_7A__
56    set_start_function("sfn5122f", start_networking_new);
57    set_start_function("e1000n", start_networking_new);
58    set_start_function("e1000n_irqtest", default_start_function_new);
59#endif
60
61#ifdef __ARM_ARCH_7A__
62    set_start_function("driverdomain", newstyle_start_function);
63#endif
64    //set_start_function("driverdomain", default_start_function_new);
65}
66
67static void parse_arguments(int argc, char** argv, char ** add_device_db_file, size_t *cpu_count)
68{
69    for (int i = 1; i < argc; i++) {
70        if (strncmp(argv[i], "apicid=", 7) == 0) {
71            my_arch_id = strtol(argv[i] + 7, NULL, 10);
72        } else if (strncmp(argv[i], "eth0=", 5) == 0) {
73            int parsed = sscanf(argv[i], "eth0=%" SCNu32 ":%" SCNu32 ":%" SCNu32,
74                                &eth0.bus, &eth0.device, &eth0.function);
75            printf("Kaluga using eth0=%u:%u:%u as network device\n", eth0.bus,
76                         eth0.device, eth0.function);
77            if (parsed != 3) {
78                eth0.bus = 0xff;
79                eth0.device = 0xff;
80                eth0.function = 0xff;
81            }
82        } else if (strcmp(argv[i], "boot") == 0) {
83            // ignored
84        } else if (strncmp(argv[i],"add_device_db=", strlen("add_device_db=")) == 0){
85           *add_device_db_file = argv[i] + strlen("add_device_db=");
86           printf("Kaluga using additional device_db file: %s.\n", *add_device_db_file);
87        } else if (strncmp(argv[i], "cpu_count=", strlen("cpu_count=")) == 0) {
88            sscanf(argv[i], "cpu_count=%zu", cpu_count);
89        }
90    }
91}
92
93static inline errval_t wait_for_pci(void)
94{
95    iref_t iref;
96    return nameservice_blocking_lookup("pci_discovery_done", &iref);
97}
98
99int main(int argc, char** argv)
100{
101    vfs_init();
102    init_environ();
103
104    errval_t err;
105
106    my_core_id = disp_get_core_id();
107    char * add_device_db_file = NULL;
108    parse_arguments(argc, argv, &add_device_db_file, &cpu_count);
109
110    err = oct_init();
111    if (err_is_fail(err)) {
112        USER_PANIC_ERR(err, "Initialize octopus service.");
113    }
114
115    KALUGA_DEBUG("Kaluga: parse boot modules...\n");
116
117    ddomain_controller_init();
118
119    err = init_boot_modules();
120    if (err_is_fail(err)) {
121        USER_PANIC_ERR(err, "Parse boot modules.");
122    }
123
124    add_start_function_overrides();
125
126    // TODO: Check if this is supported by all plattforms
127    // TODO: Get cap from somewhere else.
128    struct capref all_irq_cap;
129    err = slot_alloc(&all_irq_cap);
130    if (err_is_fail(err)) {
131        USER_PANIC_ERR(err, "slot alloc");
132    }
133    err = sys_debug_create_irq_src_cap(all_irq_cap, 0, 65536);
134    if (err_is_fail(err)) {
135        USER_PANIC_ERR(err, "create all_irq_cap");
136    }
137    err = init_int_caps_manager(all_irq_cap);
138    if (err_is_fail(err)) {
139        USER_PANIC_ERR(err, "init device caps manager");
140    }
141
142    err = arch_startup(add_device_db_file);
143    if (err_is_fail(err)) {
144        USER_PANIC_ERR(err, "arch startup");
145    }
146
147    THCFinish();
148    return EXIT_SUCCESS;
149}
150