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; }
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; }
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; }
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; }