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, 2017-2018 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, Universitaetstrasse 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;
46struct queue_service_state* qs;
47
48static void add_start_function_overrides(void)
49{
50
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
56#ifdef __x86_64__
57    set_start_function("iommu", start_iommu_driver);
58    set_start_function("serial_pc16550d", default_start_function_pure);
59#endif
60#ifndef __ARM_ARCH_7A__
61    //X86 and ARMv8
62    set_start_function("sfn5122f", start_networking_new);
63    set_start_function("e10k", start_networking_new);
64    set_start_function("e1000n", start_networking_new);
65    set_start_function("mlx4", start_networking_new);
66    set_start_function("e1000n_irqtest", default_start_function_new);
67    set_start_function("ioat_dma", default_start_function_new);
68    set_start_function("xeon_phi", default_start_function_new);
69#else
70    set_start_function("driverdomain", default_start_function_new);
71    set_start_function("serial_kernel", default_start_function_pure);
72    set_start_function("serial_pl011", default_start_function_pure);
73    set_start_function("serial_omap44xx", default_start_function_pure);
74    set_start_function("driverdomain_pl390", default_start_function_pure);
75#endif
76
77
78}
79
80static void parse_arguments(int argc, char** argv, char ** add_device_db_file,
81        size_t *cpu_count)
82{
83    for (int i = 1; i < argc; i++) {
84        if (strncmp(argv[i], "apicid=", 7) == 0) {
85            my_arch_id = strtol(argv[i] + 7, NULL, 10);
86        } else if (strncmp(argv[i], "eth0=", 5) == 0) {
87            int parsed = sscanf(argv[i], "eth0=%" SCNu32 ":%" SCNu32 ":%" SCNu32,
88                                &eth0.bus, &eth0.device, &eth0.function);
89            printf("Kaluga using eth0=%u:%u:%u as network device\n", eth0.bus,
90                         eth0.device, eth0.function);
91            if (parsed != 3) {
92                eth0.bus = 0xff;
93                eth0.device = 0xff;
94                eth0.function = 0xff;
95            }
96        } else if (strcmp(argv[i], "boot") == 0) {
97            // ignored
98        } else if (strncmp(argv[i],"add_device_db=", strlen("add_device_db=")) == 0){
99           *add_device_db_file = argv[i] + strlen("add_device_db=");
100           printf("Kaluga using additional device_db file: %s.\n", *add_device_db_file);
101        } else if (strncmp(argv[i], "cpu_count=", strlen("cpu_count=")) == 0) {
102            sscanf(argv[i], "cpu_count=%zu", cpu_count);
103        }
104    }
105}
106
107int main(int argc, char** argv)
108{
109    vfs_init();
110    init_environ();
111
112    errval_t err;
113
114    my_core_id = disp_get_core_id();
115    char * add_device_db_file = NULL;
116    parse_arguments(argc, argv, &add_device_db_file, &cpu_count);
117
118    err = oct_init();
119    if (err_is_fail(err)) {
120        USER_PANIC_ERR(err, "Initialize octopus service.");
121    }
122
123    KALUGA_DEBUG("Kaluga: parse boot modules...\n");
124
125    ddomain_controller_init();
126
127    err = init_boot_modules();
128    if (err_is_fail(err)) {
129        USER_PANIC_ERR(err, "Parse boot modules.");
130    }
131
132    add_start_function_overrides();
133
134    // TODO: Check if this is supported by all plattforms
135    // TODO: Get cap from somewhere else.
136    struct capref all_irq_cap;
137    err = slot_alloc(&all_irq_cap);
138    if (err_is_fail(err)) {
139        USER_PANIC_ERR(err, "slot alloc");
140    }
141    err = sys_debug_create_irq_src_cap(all_irq_cap, 0, 65536);
142    if (err_is_fail(err)) {
143        USER_PANIC_ERR(err, "create all_irq_cap");
144    }
145    err = init_int_caps_manager(all_irq_cap);
146    if (err_is_fail(err)) {
147        USER_PANIC_ERR(err, "init device caps manager");
148    }
149
150    KALUGA_DEBUG("Kaluga: initializing queue endpoint service\n");
151    // startup queue service so endpoints to drivers can be requested
152    err = queue_service_init(&qs, NULL);
153    if (err_is_fail(err)) {
154        USER_PANIC_ERR(err, "init queue service");
155    }
156
157    err = arch_startup(add_device_db_file);
158    if (err_is_fail(err)) {
159        USER_PANIC_ERR(err, "arch startup");
160    }
161
162    THCFinish();
163    return EXIT_SUCCESS;
164}
165