Beispiel #1
0
int main(int argc, char **argv)
{
 //this is the bootstrap copy of the domain
     if (strcmp(argv[argc - 1], "SpAwNeD") != 0) {
        bsp_datagatherer = true;
    } else {
        bsp_datagatherer = false;
    }

    core_id = disp_get_core_id();
    skb_client_connect();

#ifdef SPAWN_YOUR_SELF
    if (bsp_datagatherer) {
        spawnmyself();
    }
#endif

//gather different types of data

//run cpuid
    gather_cpuid_data(core_id);

//get the number of running cores and their APIC IDs from the monitor
    if (bsp_datagatherer) {
        gather_nr_running_cores(get_monitor_binding());
    } else {
        nr_cores_done = true;
    }

//adding the numer of cores is the last operation performed by the datagatherer.
//therefore the domain can exit after this. process events as long as the number
//of cores has not yet been added to the SKB.
    struct waitset *ws = get_default_waitset();
    while (!nr_cores_done) {
        errval_t err = event_dispatch(ws);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in event_dispatch");
            break;
        }
    }

    skb_add_fact("datagatherer_done.");

    if (bsp_datagatherer) {
        int length = nr_of_running_cores + 1;
        while (length != nr_of_running_cores) {
            skb_execute_query("findall(X, datagatherer_done, L),length(L,Len),write(Len).");
            skb_read_output("%d", &length);
            thread_yield();
        }


        errval_t err = nameservice_register("datagatherer_done", 0);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "nameservice_register failed");
        }
    }
    return 0;
}
Beispiel #2
0
static errval_t setup_skb_info(void)
{
    skb_execute("[pci_queries].");
    errval_t err = skb_read_error_code();
    if (err_is_fail(err)) {
        ACPI_DEBUG("\npcimain.c: Could not load pci_queries.pl.\n"
               "SKB returned: %s\nSKB error: %s\n",
                skb_get_output(), skb_get_error_output());
        return err;
    }

    skb_add_fact("mem_region_type(%d,ram).", RegionType_Empty);
    skb_add_fact("mem_region_type(%d,roottask).", RegionType_RootTask);
    skb_add_fact("mem_region_type(%d,phyaddr).", RegionType_PhyAddr);
    skb_add_fact("mem_region_type(%d,multiboot_module).", RegionType_Module);
    skb_add_fact("mem_region_type(%d,platform_data).", RegionType_PlatformData);
    skb_add_fact("mem_region_type(%d,apic).", RegionType_LocalAPIC);
    skb_add_fact("mem_region_type(%d,ioapic).", RegionType_IOAPIC);

    return err;
}
Beispiel #3
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;
}
Beispiel #4
0
static errval_t init_allocators(void)
{
    errval_t err, msgerr;

    struct monitor_blocking_rpc_client *cl = get_monitor_blocking_rpc_client();
    assert(cl != NULL);

    // Get the bootinfo and map it in.
    struct capref bootinfo_frame;
    size_t bootinfo_size;
    struct bootinfo *bootinfo;

    msgerr = cl->vtbl.get_bootinfo(cl, &err, &bootinfo_frame, &bootinfo_size);
    if (err_is_fail(msgerr) || err_is_fail(err)) {
        USER_PANIC_ERR(err_is_fail(msgerr) ? msgerr : err, "failed in get_bootinfo");
    }

    err = vspace_map_one_frame((void**)&bootinfo, bootinfo_size, bootinfo_frame,
                               NULL, NULL);
    assert(err_is_ok(err));

    /* Initialize the memory allocator to handle PhysAddr caps */
    static struct range_slot_allocator devframes_allocator;
    err = range_slot_alloc_init(&devframes_allocator, PCI_CNODE_SLOTS, NULL);
    if (err_is_fail(err)) {
        return err_push(err, LIB_ERR_SLOT_ALLOC_INIT);
    }

    err = mm_init(&pci_mm_physaddr, ObjType_DevFrame, 0, 48,
                  /* This next parameter is important. It specifies the maximum
                   * amount that a cap may be "chunked" (i.e. broken up) at each
                   * level in the allocator. Setting it higher than 1 reduces the
                   * memory overhead of keeping all the intermediate caps around,
                   * but leads to problems if you chunk up a cap too small to be
                   * able to allocate a large subregion. This caused problems
                   * for me with a large framebuffer... -AB 20110810 */
                  1, /*was DEFAULT_CNODE_BITS,*/
                  slab_default_refill, slot_alloc_dynamic, &devframes_allocator, false);
    if (err_is_fail(err)) {
        return err_push(err, MM_ERR_MM_INIT);
    }

    // Request I/O Cap
    struct capref requested_caps;
    errval_t error_code;
    err = cl->vtbl.get_io_cap(cl, &requested_caps, &error_code);
    assert(err_is_ok(err) && err_is_ok(error_code));
    // Copy into correct slot
    struct capref caps_io = {
        .cnode = cnode_task,
        .slot  = TASKCN_SLOT_IO
    };
    err = cap_copy(caps_io, requested_caps);

    // XXX: The code below is confused about gen/l/paddrs.
    // Caps should be managed in genpaddr, while the bus mgmt must be in lpaddr.
    err = cl->vtbl.get_phyaddr_cap(cl, &requested_caps, &error_code);
    assert(err_is_ok(err) && err_is_ok(error_code));
    physical_caps = requested_caps;

    // Build the capref for the first physical address capability
    struct capref phys_cap;
    phys_cap.cnode = build_cnoderef(requested_caps, PHYSADDRCN_BITS);
    phys_cap.slot = 0;

    struct cnoderef devcnode;
    err = slot_alloc(&my_devframes_cnode);
    assert(err_is_ok(err));
    cslot_t slots;
    err = cnode_create(&my_devframes_cnode, &devcnode, 255, &slots);
    if (err_is_fail(err)) { USER_PANIC_ERR(err, "cnode create"); }
    struct capref devframe;
    devframe.cnode = devcnode;
    devframe.slot = 0;

    for (int i = 0; i < bootinfo->regions_length; i++) {
		struct mem_region *mrp = &bootinfo->regions[i];
		if (mrp->mr_type == RegionType_Module) {
			skb_add_fact("memory_region(16'%" PRIxGENPADDR ",%u,%zu,%u,%tu).",
						mrp->mr_base,
						0,
						mrp->mrmod_size,
						mrp->mr_type,
						mrp->mrmod_data);
		}
		else {
			skb_add_fact("memory_region(16'%" PRIxGENPADDR ",%u,%zu,%u,%tu).",
						mrp->mr_base,
						mrp->mr_bits,
						((size_t)1) << mrp->mr_bits,
						mrp->mr_type,
						mrp->mrmod_data);
		}

        if (mrp->mr_type == RegionType_PhyAddr ||
            mrp->mr_type == RegionType_PlatformData) {
            ACPI_DEBUG("Region %d: %"PRIxGENPADDR" - %"PRIxGENPADDR" %s\n",
                       i, mrp->mr_base,
                       mrp->mr_base + (((size_t)1)<<mrp->mr_bits),
                       mrp->mr_type == RegionType_PhyAddr ?
                       "physical address" : "platform data");

            err = cap_retype(devframe, phys_cap, ObjType_DevFrame, mrp->mr_bits);
            if (err_no(err) == SYS_ERR_REVOKE_FIRST) {
                printf("cannot retype region %d: need to revoke first; ignoring it\n", i);
            } else {
                assert(err_is_ok(err));

                err = mm_add(&pci_mm_physaddr, devframe,
                             mrp->mr_bits, mrp->mr_base);
                if (err_is_fail(err)) {
                    USER_PANIC_ERR(err, "adding region %d FAILED\n", i);
                }
            }

            phys_cap.slot++;
            devframe.slot++;
        }
    }

    return SYS_ERR_OK;
}