1/**
2 * \file
3 * \brief ARMv8 arch specfic code
4 */
5
6/*
7 * Copyright (c) 2013, 2016 ETH Zurich.
8 * Copyright (c) 2015-2016, Hewlett Packard Enterprise Development LP.
9 * All rights reserved.
10 *
11 * This file is distributed under the terms in the attached LICENSE file.
12 * If you do not find this file, copies can be found by writing to:
13 * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
14 */
15
16#include <barrelfish/barrelfish.h>
17#include <skb/skb.h>
18#include <barrelfish_kpi/platform.h>
19#include <if/monitor_blocking_defs.h>
20#include "kaluga.h"
21
22
23static errval_t armv8_startup_common(void)
24{
25    errval_t err = SYS_ERR_OK;
26
27    // We need to run on core 0
28    // (we are responsible for booting all the other cores)
29    assert(my_core_id == BSP_CORE_ID);
30
31    err = skb_client_connect();
32    if (err_is_fail(err)) {
33        USER_PANIC_ERR(err, "Connect to SKB.");
34    }
35
36    // Make sure the driver db is loaded
37    err = skb_execute("[device_db].");
38    if (err_is_fail(err)) {
39        USER_PANIC_ERR(err, "Device DB not loaded.");
40    }
41
42    // The current boot protocol needs us to have
43    // knowledge about how many CPUs are available at boot
44    // time in order to start-up properly.
45    char* record = NULL;
46    err = oct_barrier_enter("barrier.acpi", &record, 2);
47
48    KALUGA_DEBUG("Kaluga: watch_for_cores\n");
49
50    err = watch_for_cores();
51    if (err_is_fail(err)) {
52        USER_PANIC_ERR(err, "Watching cores.");
53    }
54
55    KALUGA_DEBUG("Kaluga: pci_root_bridge\n");
56
57    err = watch_for_pci_root_bridge();
58    if (err_is_fail(err)) {
59        USER_PANIC_ERR(err, "Watching PCI root bridges.");
60    }
61
62    KALUGA_DEBUG("Kaluga: pci_devices\n");
63
64    err = watch_for_pci_devices();
65    if (err_is_fail(err)) {
66        USER_PANIC_ERR(err, "Watching PCI devices.");
67    }
68
69    KALUGA_DEBUG("Kaluga: wait_for_all_spawnds\n");
70
71    err = wait_for_all_spawnds();
72    if (err_is_fail(err)) {
73        USER_PANIC_ERR(err, "Unable to wait for spawnds failed.");
74    }
75
76    return SYS_ERR_OK;
77}
78
79static errval_t fvp_startup(void)
80{
81    errval_t err;
82
83    err = skb_execute_query("[plat_fvp].");
84    if(err_is_fail(err)){
85        USER_PANIC_SKB_ERR(err, "Additional device db file 'plat_fvp' not loaded.");
86    }
87
88    return armv8_startup_common();
89}
90
91static errval_t qemu_startup(void)
92{
93    errval_t err;
94
95    err = skb_execute_query("[plat_qemu].");
96    if(err_is_fail(err)){
97        USER_PANIC_SKB_ERR(err, "Additional device db file 'plat_qemu' not loaded.");
98    }
99
100    return armv8_startup_common();
101}
102
103static errval_t apm88xxxx_startup(void)
104{
105    errval_t err;
106
107    err = skb_execute_query("[plat_apm88xxxx].");
108    if(err_is_fail(err)){
109        USER_PANIC_SKB_ERR(err, "Additional device db file 'plat_apm88xxxx' not loaded.");
110    }
111
112    return armv8_startup_common();
113}
114
115static errval_t cn88xx_startup(void)
116{
117    errval_t err;
118
119    err = skb_execute_query("[plat_cn88xx].");
120    if(err_is_fail(err)){
121        USER_PANIC_SKB_ERR(err, "Additional device db file 'plat_cn88xx' not loaded.");
122    }
123
124    return armv8_startup_common();
125}
126
127errval_t arch_startup(char * add_device_db_file)
128{
129    errval_t err;
130
131    err = skb_client_connect();
132    if (err_is_fail(err)) {
133        USER_PANIC_ERR(err, "Connect to SKB.");
134    }
135
136    // Make sure the driver db is loaded
137    err = skb_execute("[device_db].");
138    if (err_is_fail(err)) {
139        USER_PANIC_SKB_ERR(err, "Device DB not loaded.");
140    }
141
142    if (add_device_db_file) {
143        err = skb_execute_query("[%s].", add_device_db_file);
144        if(err_is_fail(err)){
145            USER_PANIC_SKB_ERR(err, "Additional device db file '%s' not loaded.",
146                               add_device_db_file);
147        }
148    }
149
150    struct monitor_blocking_binding *m = get_monitor_blocking_binding();
151    assert(m != NULL);
152
153    uint32_t arch, platform;
154    err = m->rpc_tx_vtbl.get_platform(m, &arch, &platform);
155    assert(err_is_ok(err));
156    assert(arch == PI_ARCH_ARMV8A);
157
158    switch(platform) {
159    case PI_PLATFORM_FVP:
160        debug_printf("Kaluga running on FVP\n");
161        return fvp_startup();
162    case PI_PLATFORM_QEMU:
163        debug_printf("Kaluga running on QEMU\n");
164        return qemu_startup();
165    case PI_PLATFORM_APM88XXXX:
166        debug_printf("Kaluga running on APM88xxxx\n");
167        return apm88xxxx_startup();
168    case PI_PLATFORM_CN88XX:
169        debug_printf("Kaluga running on CN88xx\n");
170        return cn88xx_startup();
171    }
172
173    return KALUGA_ERR_UNKNOWN_PLATFORM;
174}
175