1/**
2 * \file
3 * \brief ARMv7 arch specfic code
4 */
5
6/*
7 * Copyright (c) 2013, 2016 ETH Zurich.
8 * Copyright (c) 2015, 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 <hw_records_arch.h>
17#include <barrelfish/barrelfish.h>
18#include <barrelfish_kpi/platform.h>
19#include <if/monitor_blocking_defs.h>
20
21#include <skb/skb.h>
22#include <octopus/getset.h>
23
24#include "kaluga.h"
25
26static void start_driverdomain(char* record) {
27    struct module_info* mi = find_module("driverdomain");
28    if (mi != NULL) {
29        errval_t err = mi->start_function(0, mi, record, NULL);
30        assert(err_is_ok(err));
31    }
32}
33
34static errval_t omap44xx_startup(void)
35{
36    errval_t err;
37
38    err = init_device_caps_manager();
39    assert(err_is_ok(err));
40
41    start_driverdomain("fdif {}");
42    start_driverdomain("sdma {}");
43    start_driverdomain("mmchs { dep1: 'cm2', dep2: 'twl6030' }");
44
45    struct module_info* mi = find_module("prcm");
46    if (mi != NULL) {
47        err = mi->start_function(0, mi, "hw.arm.omap44xx.prcm {}", NULL);
48        assert(err_is_ok(err));
49    }
50
51    mi = find_module("serial");
52    if (mi != NULL) {
53        err = mi->start_function(0, mi, "hw.arm.omap44xx.uart {}", NULL);
54        assert(err_is_ok(err));
55    }
56
57    mi = find_module("usb_manager");
58    if (mi != NULL) {
59#define USB_ARM_EHCI_IRQ 109
60        char *buf = malloc(255);
61        uint8_t offset = 0;
62        mi->cmdargs = buf;
63        mi->argc = 3;
64        mi->argv[0] = mi->cmdargs + 0;
65
66        snprintf(buf + offset, 255 - offset, "ehci\0");
67        offset += strlen(mi->argv[0]) + 1;
68        mi->argv[1] = mi->cmdargs + offset;
69        snprintf(buf + offset, 255 - offset, "%u\0", 0xC00);
70        offset += strlen(mi->argv[1]) + 1;
71        mi->argv[2] = mi->cmdargs + offset;
72        snprintf(buf+offset, 255-offset, "%u\0", USB_ARM_EHCI_IRQ);
73
74        // XXX Use customized start function or add to module info
75        err = mi->start_function(0, mi, "hw.arm.omap44xx.usb {}", NULL);
76        assert(err_is_ok(err));
77        free(buf);
78    }
79    return SYS_ERR_OK;
80}
81
82static errval_t vexpress_startup(void)
83{
84    errval_t err;
85    struct module_info* mi = find_module("serial_pl011");
86    if (mi != NULL) {
87        err = mi->start_function(0, mi, "hw.arm.vexpress.uart {}", NULL);
88        assert(err_is_ok(err));
89    }
90    return SYS_ERR_OK;
91}
92
93static errval_t zynq7_startup(void)
94{
95    errval_t err;
96
97    // Since we don't seem to be able to boot cores on the Zynq yet,
98    // we just set all_spawnds_up here. -SG,2016-11-10.
99    err = oct_set("all_spawnds_up { iref: 0 }");
100    assert(err_is_ok(err));
101
102    /* There's nothing special to do for Zynq (yet). */
103    return SYS_ERR_OK;
104}
105
106errval_t arch_startup(char * add_device_db_file)
107{
108    errval_t err = SYS_ERR_OK;
109
110    KALUGA_DEBUG("Kaluga running on ARMv7.\n");
111
112    err = skb_client_connect();
113    if (err_is_fail(err)) {
114        USER_PANIC_ERR(err, "Connect to SKB.");
115    }
116
117    // Make sure the driver db is loaded
118    err = skb_execute("[device_db].");
119    if (err_is_fail(err)) {
120        USER_PANIC_SKB_ERR(err, "Device DB not loaded.");
121    }
122    if(add_device_db_file != NULL){
123        err = skb_execute_query("[%s].", add_device_db_file);
124        if(err_is_fail(err)){
125            USER_PANIC_SKB_ERR(err, "Additional device db file %s not loaded.",
126                               add_device_db_file);
127        }
128    }
129
130    err = skb_execute_query("decoding_net(N),load_net(N).");
131    if(err_is_fail(err)){
132        DEBUG_SKB_ERR(err, "No decoding net loaded.");
133    }
134
135    err = skb_execute_query("decoding_net_meta(M),load_net(M).");
136    if(err_is_fail(err)){
137        DEBUG_SKB_ERR(err, "No decoding net metadata loaded.");
138    }
139
140    err = skb_execute_query("decoding_net_irq(N),load_net(N).");
141    if(err_is_fail(err)){
142        DEBUG_SKB_ERR(err, "No irq decoding net loaded.");
143    }
144    printf("Decoding net irq successfully loaded!\n");
145
146    err = skb_execute_query("decoding_net_irq_meta(M),load_net(M).");
147    if(err_is_fail(err)){
148        DEBUG_SKB_ERR(err, "No irq decoding net metadata loaded.");
149    }
150
151    struct monitor_blocking_binding *m = get_monitor_blocking_binding();
152    assert(m != NULL);
153
154    uint32_t arch, platform;
155    err = m->rpc_tx_vtbl.get_platform(m, &arch, &platform);
156    assert(err_is_ok(err));
157    assert(arch == PI_ARCH_ARMV7A);
158
159    uint8_t buf[PI_ARCH_INFO_SIZE];
160
161    struct arch_info_armv7 *arch_info= (struct arch_info_armv7 *)buf;
162    size_t buflen;
163    err = m->rpc_tx_vtbl.get_platform_arch(m, buf, &buflen);
164    assert(buflen == sizeof(struct arch_info_armv7));
165
166    /* Query the SKB for the available cores on this platform - we can't
167     * generally discover this on ARMv7. */
168    err= skb_execute_query("arm_mpids(L) ,write(L).");
169    if (err_is_fail(err)) {
170        USER_PANIC_SKB_ERR(err, "Finding cores.");
171    }
172
173    /* Create Octopus records for the known cores. */
174    debug_printf("CPU driver reports %u core(s).\n", arch_info->ncores);
175    int mpidr_raw;
176    struct list_parser_status skb_list;
177    skb_read_list_init(&skb_list);
178    uint32_t bf_core_id= 0;
179    while(skb_read_list(&skb_list, "mpid(%d)", &mpidr_raw)) {
180        oct_set(HW_PROCESSOR_ARM_RECORD_FORMAT,
181                bf_core_id, 1, bf_core_id, (uint32_t)mpidr_raw, CPU_ARM7);
182        bf_core_id++;
183    }
184
185    KALUGA_DEBUG("Kaluga: watch_for_cores\n");
186
187    err = watch_for_cores();
188    if (err_is_fail(err)) {
189        USER_PANIC_ERR(err, "Watching cores.");
190    }
191
192    KALUGA_DEBUG("Kaluga: wait_for_all_spawnds\n");
193
194    err = wait_for_all_spawnds();
195    if (err_is_fail(err)) {
196        USER_PANIC_ERR(err, "Unable to wait for spawnds failed.");
197    }
198
199    switch(platform) {
200        case PI_PLATFORM_OMAP44XX:
201            debug_printf("Kaluga running on Pandaboard\n");
202            return omap44xx_startup();
203        case PI_PLATFORM_VEXPRESS:
204            debug_printf("Kaluga running on VExpressEMM\n");
205            return vexpress_startup();
206        case PI_PLATFORM_ZYNQ7:
207            debug_printf("Kaluga running on a Zynq7000\n");
208            return zynq7_startup();
209    }
210
211    return KALUGA_ERR_UNKNOWN_PLATFORM;
212}
213