Ejemplo n.º 1
0
errval_t start_networking(coreid_t core, struct module_info* driver,
                          char* record)
{
    assert(driver != NULL);
    errval_t err = SYS_ERR_OK;

    if (is_started(driver)) {
        return KALUGA_ERR_DRIVER_ALREADY_STARTED;
    }

    if (!is_auto_driver(driver)) {
        return KALUGA_ERR_DRIVER_NOT_AUTO;
    }

    struct module_info* netd = find_module("netd");
    if (netd == NULL || !is_auto_driver(netd)) {
        KALUGA_DEBUG("netd not found or not declared as auto.");
        return KALUGA_ERR_DRIVER_NOT_AUTO;
    }

    struct module_info* ngd_mng = find_module("NGD_mng");
    if (ngd_mng == NULL || !is_auto_driver(ngd_mng)) {
        KALUGA_DEBUG("NGD_mng not found or not declared as auto.");
        return KALUGA_ERR_DRIVER_NOT_AUTO;
    }

    err = spawn_program(core, driver->path, driver->argv + 1, environ, 0,
                        &driver->did);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "Spawning %s failed.", driver->path);
        return err;
    }

    // XXX: Manually add cardname (overwrite first (auto) argument)
    // +Weird convention, e1000n binary but cardname=e1000
    char* cardname =
        strcmp(driver->binary, "e1000n") == 0 ? "e1000" : driver->binary;

    size_t name_len = strlen("cardname=") + strlen(cardname) + 1;
    char* card_argument = malloc(name_len);
    sprintf(card_argument, "cardname=%s", cardname);
    printf("############# starting network with argiments %s\n", card_argument);

    // Spawn netd and ngd_mng
    netd->argv[0] = card_argument;
    err = spawn_program(core, netd->path, netd->argv, environ, 0, &netd->did);

    ngd_mng->argv[0] = card_argument;
    err = spawn_program(core, ngd_mng->path, ngd_mng->argv, environ, 0,
                        &ngd_mng->did);

    free(card_argument);
    return err;
}
Ejemplo n.º 2
0
errval_t wait_for_all_spawnds(void)
{
    // Note: The whole wait for all_spawnds_up thing is a hack.
    // Our overall design goal is a system where cores
    // come and go dynamically and we do not want / need
    // to wait for a stable state.
    // However, some of our code (for example domain spanning)
    // still assumes a fixed set of cores and will deadlock
    // otherwise. Therefore we need to fix those parts first.
    KALUGA_DEBUG("Waiting for acpi");
    char* record = NULL;
    errval_t err = oct_wait_for(&record, "acpi { iref: _ }");
    free(record);
    if (err_is_fail(err)) {
        return err_push(err, KALUGA_ERR_WAITING_FOR_ACPI);
    }

    // No we should be able to get core count
    // of all cores to estimate the amount of
    // spawnd's we have to expect (one per core)
    char** names;
    size_t count;
    err = oct_get_names(&names, &count, local_apics);
    if (err_is_fail(err)) {
        return err_push(err, KALUGA_ERR_QUERY_LOCAL_APIC);
    }
    oct_free_names(names, count);

    static char* spawnds = "r'spawn.[0-9]+' { iref: _ }";
    octopus_trigger_id_t tid;
    return oct_trigger_existing_and_watch(spawnds, spawnd_change_event, (void*)count, &tid);
}
Ejemplo n.º 3
0
static void spawnd_change_event(octopus_mode_t mode, char* record, void* state)
{
    size_t count = (size_t) state;
    static coreid_t spawnd_counter = 0;

    if (mode & OCT_ON_SET) {
        KALUGA_DEBUG("spawnd found: %s\n", record);
        spawnd_counter++;

        if (spawnd_counter == count) {
            KALUGA_DEBUG("Found enough spawnds, setting all_spawnds_up\n");
            errval_t err = oct_set("all_spawnds_up { iref: 0 }");
            assert(err_is_ok(err));
        }
    }
}
Ejemplo n.º 4
0
static void cpu_change_event(octopus_mode_t mode, char* record, void* state)
{
    if (mode & OCT_ON_SET) {
        KALUGA_DEBUG("CPU found: %s\n", record);
        assert(my_core_id == 0); // TODO(gz): why?

        uint64_t barrelfish_id, arch_id, enabled = 0;
        errval_t err = oct_read(record, "_ { barrelfish_id: %d, apic_id: %d, enabled: %d }",
                                &barrelfish_id, &arch_id, &enabled);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "Cannot read record.");
            assert(!"Illformed core record received");
            goto out;
        }

        struct module_info* mi = find_module("corectrl");
        if (mi != NULL) {
            err = mi->start_function(0, mi, record);
            if (err_is_fail(err)) {
                printf("Boot driver not found. Do not boot discovered CPU %"PRIu64".\n",
                       barrelfish_id);
                goto out;
            }
            assert(err_is_ok(err));
        }

    }
    if (mode & OCT_ON_DEL) {
        KALUGA_DEBUG("CPU removed: %s\n", record);
        assert(!"NYI");
    }

out:
    assert(!(mode & OCT_REMOVED));
    free(record);
}
Ejemplo n.º 5
0
int main(int argc, char** argv)
{
    vfs_init();
    init_environ();

    errval_t err;

    my_core_id = disp_get_core_id();
    parse_arguments(argc, argv);

    err = oct_init();
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "Initialize octopus service.");
    }

    KALUGA_DEBUG("Kaluga: parse boot modules...\n");

    err = init_boot_modules();
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "Parse boot modules.");
    }
    add_start_function_overrides();
#ifdef __x86__
    // We need to run on core 0
    // (we are responsible for booting all the other cores)
    assert(my_core_id == BSP_CORE_ID);
    KALUGA_DEBUG("Kaluga running on x86.\n");

    err = skb_client_connect();
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "Connect to SKB.");
    }

    // Make sure the driver db is loaded
    err = skb_execute("[device_db].");
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "Device DB not loaded.");
    }

    // The current boot protocol needs us to have
    // knowledge about how many CPUs are available at boot
    // time in order to start-up properly.
    char* record = NULL;
    err = oct_barrier_enter("barrier.acpi", &record, 2);

    KALUGA_DEBUG("Kaluga: watch_for_cores\n");

    err = watch_for_cores();
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "Watching cores.");
    }

    KALUGA_DEBUG("Kaluga: pci_root_bridge\n");

    err = watch_for_pci_root_bridge();
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "Watching PCI root bridges.");
    }

    KALUGA_DEBUG("Kaluga: pci_devices\n");

    err = watch_for_pci_devices();
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "Watching PCI devices.");
    }

    KALUGA_DEBUG("Kaluga: wait_for_all_spawnds\n");

    err = wait_for_all_spawnds();
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "Unable to wait for spawnds failed.");
    }

#elif __pandaboard__
    debug_printf("Kaluga running on Pandaboard.\n");

    err = init_cap_manager();
    assert(err_is_ok(err));

    err = oct_set("all_spawnds_up { iref: 0 }");
    assert(err_is_ok(err));

    struct module_info* mi = find_module("fdif");
    if (mi != NULL) {
        err = mi->start_function(0, mi, "hw.arm.omap44xx.fdif {}");
        assert(err_is_ok(err));
    }
    mi = find_module("mmchs");
    if (mi != NULL) {
        err = mi->start_function(0, mi, "hw.arm.omap44xx.mmchs {}");
        assert(err_is_ok(err));
    }
    mi = find_module("mmchs2");
    if (mi != NULL) {
        err = mi->start_function(0, mi, "hw.arm.omap44xx.mmchs {}");
        assert(err_is_ok(err));
    }
    mi = find_module("prcm");
    if (mi != NULL) {
        err = mi->start_function(0, mi, "hw.arm.omap44xx.prcm {}");
        assert(err_is_ok(err));
    }
    mi = find_module("serial");
    if (mi != NULL) {
        err = mi->start_function(0, mi, "hw.arm.omap44xx.uart {}");
        assert(err_is_ok(err));
    }
    mi = find_module("sdma");
    if (mi != NULL) {
        err = mi->start_function(0, mi, "hw.arm.omap44xx.sdma {}");
        assert(err_is_ok(err));
    }

    mi = find_module("usb_manager");
    if (mi != NULL) {
#define USB_ARM_EHCI_IRQ 109
        char *buf = malloc(255);
        uint8_t offset = 0;
        mi->cmdargs = buf;
        mi->argc = 3;
        mi->argv[0] = mi->cmdargs + 0;

        snprintf(buf + offset, 255 - offset, "ehci\0");
        offset += strlen(mi->argv[0]) + 1;
        mi->argv[1] = mi->cmdargs + offset;
        snprintf(buf + offset, 255 - offset, "%u\0", 0xC00);
        offset += strlen(mi->argv[1]) + 1;
        mi->argv[2] = mi->cmdargs + offset;
        snprintf(buf+offset, 255-offset, "%u\0", USB_ARM_EHCI_IRQ);

        // XXX Use customized start function or add to module info
        err = mi->start_function(0, mi, "hw.arm.omap44xx.usb {}");
        assert(err_is_ok(err));
    }
#elif __gem5__
    printf("Kaluga running on GEM5 armv8.\n");

    err = init_cap_manager();
    assert(err_is_ok(err));

    err = oct_set("all_spawnds_up { iref: 0 }");
    assert(err_is_ok(err));

    struct module_info* mi = find_module("serial");
    if (mi != NULL) {
        err = mi->start_function(0, mi, "hw.arm.gem5.uart {}");
        assert(err_is_ok(err));
    }	
#endif

    THCFinish();
    return EXIT_SUCCESS;
}
Ejemplo n.º 6
0
errval_t start_networking(coreid_t core,
                          struct module_info* driver,
                          char* record)
{
    assert(driver != NULL);
    errval_t err = SYS_ERR_OK;

    uint64_t vendor_id, device_id, bus, dev, fun;

    /* check if we are using the supplied pci address of eth0 */
    if (eth0.bus != 0xff || eth0.device != 0xff || eth0.function != 0xff) {
        err = oct_read(record, "_ { bus: %d, device: %d, function: %d, vendor: %d, device_id: %d }",
                            &bus, &dev, &fun, &vendor_id, &device_id);
        assert(err_is_ok(err));

        if ((eth0.bus != (uint8_t)bus)
             | (eth0.device != (uint8_t)dev)
             | (eth0.function != (uint8_t)fun)) {
            KALUGA_DEBUG("start_networking: skipping card %" PRIu64 ":% "PRIu64 ":% "
                         PRIu64"\n", bus, dev, fun);
            return KALUGA_ERR_DRIVER_NOT_AUTO;
        }
    }

    if (is_started(driver)) {
        return KALUGA_ERR_DRIVER_ALREADY_STARTED;
    }

    if (!is_auto_driver(driver)) {
        return KALUGA_ERR_DRIVER_NOT_AUTO;
    }

    struct module_info* netd = find_module("netd");
    if (netd == NULL || !is_auto_driver(netd)) {
        KALUGA_DEBUG("netd not found or not declared as auto.");
        return KALUGA_ERR_DRIVER_NOT_AUTO;
    }

    struct module_info* ngd_mng = find_module("NGD_mng");
    if (ngd_mng == NULL || !is_auto_driver(ngd_mng)) {
        KALUGA_DEBUG("NGD_mng not found or not declared as auto.");
        return KALUGA_ERR_DRIVER_NOT_AUTO;
    }

    err = default_start_function(core, driver, record);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "Spawning %s failed.", driver->path);
        return err;
    }

    // XXX: Manually add cardname (overwrite first (auto) argument)
    // +Weird convention, e1000n binary but cardname=e1000
    char* cardname = strcmp(driver->binary, "e1000n") == 0 ? "e1000" : driver->binary;

    size_t name_len = strlen("cardname=") + strlen(cardname) + 1;
    char* card_argument = malloc(name_len);
    sprintf(card_argument, "cardname=%s", cardname);
    printf("############# starting network with arguments %s\n", card_argument);

    // Spawn netd and ngd_mng
    netd->argv[0] = card_argument;
    err = spawn_program(core, netd->path, netd->argv, environ, 0, get_did_ptr(netd));

    ngd_mng->argv[0] = card_argument;
    err = spawn_program(core, ngd_mng->path, ngd_mng->argv, environ, 0,
                        get_did_ptr(ngd_mng));

    free(card_argument);
    return err;
}
Ejemplo n.º 7
0
errval_t start_boot_driver(coreid_t where, struct module_info* mi,
                           char* record)
{
    assert(mi != NULL);
    errval_t err = SYS_ERR_OK;

    if (!is_auto_driver(mi)) {
        return KALUGA_ERR_DRIVER_NOT_AUTO;
    }

    // Construct additional command line arguments containing pci-id.
    // We need one extra entry for the new argument.
    uint64_t barrelfish_id, apic_id, cpu_type;
    char **argv = mi->argv;
    bool cleanup = false;
    char barrelfish_id_s[10];
    size_t argc = mi->argc;

    KALUGA_DEBUG("Starting corectrl for %s\n", record);
    err = oct_read(record, "_ { apic_id: %d, barrelfish_id: %d, type: %d }",
                   &apic_id, &barrelfish_id, &cpu_type);
    if (err_is_ok(err)) {
        skb_add_fact("corename(%"PRIu64", %s, apic(%"PRIu64")).",
                     barrelfish_id, cpu_type_to_archstr(cpu_type), apic_id);
        if (barrelfish_id == my_core_id) {
            return SYS_ERR_OK;
        }

        argv = malloc((argc+5) * sizeof(char *));
        memcpy(argv, mi->argv, argc * sizeof(char *));
        snprintf(barrelfish_id_s, 10, "%"PRIu64"", barrelfish_id);

        argv[argc] = "boot";
        argc += 1;
        argv[argc] = barrelfish_id_s;
        argc += 1;
        // Copy kernel args over to new core
        struct module_info* cpu_module = find_module("cpu");
        if (cpu_module != NULL && strlen(cpu_module->args) > 1) {
            KALUGA_DEBUG("%s:%s:%d: Boot with cpu arg %s and barrelfish_id_s=%s\n",
                         __FILE__, __FUNCTION__, __LINE__, cpu_module->args, barrelfish_id_s);
            argv[argc] = "-a";
            argc += 1;
            argv[argc] = cpu_module->args;
            argc += 1;
        }
        argv[argc] = NULL;

        cleanup = true;
    }
    else {
        DEBUG_ERR(err, "Malformed CPU record?");
        return err;
    }

    struct capref task_cap_kernel;
    task_cap_kernel.cnode = cnode_task;
    task_cap_kernel.slot = TASKCN_SLOT_KERNELCAP;

#ifdef KALUGA_SERVICE_DEBUG
    struct capability info;
    err = debug_cap_identify(task_cap_kernel, &info);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "Can not identify the capability.");
    }
    char buffer[1024];
    debug_print_cap(buffer, 1024, &info);
    KALUGA_DEBUG("%s:%d: capability=%s\n", __FILE__, __LINE__, buffer);
#endif

    struct capref inheritcn_cap;
    err = alloc_inheritcn_with_caps(&inheritcn_cap,
                                    NULL_CAP, NULL_CAP, task_cap_kernel);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "alloc_inheritcn_with_caps failed.");
    }

    err = spawn_program_with_caps(where, mi->path, argv,
                                  environ, inheritcn_cap,
                                  NULL_CAP, SPAWN_FLAGS_NEW_DOMAIN,
                                  &mi->did[0]);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "Spawning %s failed.", mi->path);
    }

    if (cleanup) {
        free(argv);
    }

    return err;
}