void get_parameters(u32_t ebx, kinfo_t *cbi) { multiboot_memory_map_t *mmap; multiboot_info_t *mbi = &cbi->mbi; int var_i,value_i, m, k; char *p; extern char _kern_phys_base, _kern_vir_base, _kern_size, _kern_unpaged_start, _kern_unpaged_end; phys_bytes kernbase = (phys_bytes) &_kern_phys_base, kernsize = (phys_bytes) &_kern_size; #define BUF 1024 static char cmdline[BUF]; /* get our own copy of the multiboot info struct and module list */ memcpy((void *) mbi, (void *) ebx, sizeof(*mbi)); /* Set various bits of info for the higher-level kernel. */ cbi->mem_high_phys = 0; cbi->user_sp = (vir_bytes) &_kern_vir_base; cbi->vir_kern_start = (vir_bytes) &_kern_vir_base; cbi->bootstrap_start = (vir_bytes) &_kern_unpaged_start; cbi->bootstrap_len = (vir_bytes) &_kern_unpaged_end - cbi->bootstrap_start; cbi->kmess = &kmess; /* set some configurable defaults */ cbi->do_serial_debug = 0; cbi->serial_debug_baud = 115200; /* parse boot command line */ if (mbi->mi_flags & MULTIBOOT_INFO_HAS_CMDLINE) { static char var[BUF]; static char value[BUF]; /* Override values with cmdline argument */ memcpy(cmdline, (void *) mbi->mi_cmdline, BUF); p = cmdline; while (*p) { var_i = 0; value_i = 0; while (*p == ' ') p++; if (!*p) break; while (*p && *p != '=' && *p != ' ' && var_i < BUF - 1) var[var_i++] = *p++ ; var[var_i] = 0; if (*p++ != '=') continue; /* skip if not name=value */ while (*p && *p != ' ' && value_i < BUF - 1) value[value_i++] = *p++ ; value[value_i] = 0; mb_set_param(cbi->param_buf, var, value, cbi); } } /* let higher levels know what we are booting on */ mb_set_param(cbi->param_buf, ARCHVARNAME, (char *)get_board_arch_name(BOARD_ID_INTEL), cbi); mb_set_param(cbi->param_buf, BOARDVARNAME,(char *)get_board_name(BOARD_ID_INTEL) , cbi); /* move user stack/data down to leave a gap to catch kernel * stack overflow; and to distinguish kernel and user addresses * at a glance (0xf.. vs 0xe..) */ cbi->user_sp = USR_STACKTOP; cbi->user_end = USR_DATATOP; /* kernel bytes without bootstrap code/data that is currently * still needed but will be freed after bootstrapping. */ kinfo.kernel_allocated_bytes = (phys_bytes) &_kern_size; kinfo.kernel_allocated_bytes -= cbi->bootstrap_len; assert(!(cbi->bootstrap_start % I386_PAGE_SIZE)); cbi->bootstrap_len = rounddown(cbi->bootstrap_len, I386_PAGE_SIZE); assert(mbi->mi_flags & MULTIBOOT_INFO_HAS_MODS); assert(mbi->mi_mods_count < MULTIBOOT_MAX_MODS); assert(mbi->mi_mods_count > 0); memcpy(&cbi->module_list, (void *) mbi->mi_mods_addr, mbi->mi_mods_count * sizeof(multiboot_module_t)); memset(cbi->memmap, 0, sizeof(cbi->memmap)); /* mem_map has a variable layout */ if(mbi->mi_flags & MULTIBOOT_INFO_HAS_MMAP) { cbi->mmap_size = 0; for (mmap = (multiboot_memory_map_t *) mbi->mmap_addr; (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->mm_size + sizeof(mmap->mm_size))) { if(mmap->mm_type != MULTIBOOT_MEMORY_AVAILABLE) continue; add_memmap(cbi, mmap->mm_base_addr, mmap->mm_length); } } else { assert(mbi->mi_flags & MULTIBOOT_INFO_HAS_MEMORY); add_memmap(cbi, 0, mbi->mi_mem_lower*1024); add_memmap(cbi, 0x100000, mbi->mi_mem_upper*1024); } /* Sanity check: the kernel nor any of the modules may overlap * with each other. Pretend the kernel is an extra module for a * second. */ k = mbi->mi_mods_count; assert(k < MULTIBOOT_MAX_MODS); cbi->module_list[k].mod_start = kernbase; cbi->module_list[k].mod_end = kernbase + kernsize; cbi->mods_with_kernel = mbi->mi_mods_count+1; cbi->kern_mod = k; for(m = 0; m < cbi->mods_with_kernel; m++) { #if 0 printf("checking overlap of module %08lx-%08lx\n", cbi->module_list[m].mod_start, cbi->module_list[m].mod_end); #endif if(overlaps(cbi->module_list, cbi->mods_with_kernel, m)) panic("overlapping boot modules/kernel"); /* We cut out the bits of memory that we know are * occupied by the kernel and boot modules. */ cut_memmap(cbi, cbi->module_list[m].mod_start, cbi->module_list[m].mod_end); } }
void io_xswitch_widget_init(devfs_handle_t xswitchv, devfs_handle_t hubv, xwidgetnum_t widgetnum, async_attach_t aa) { xswitch_info_t xswitch_info; xwidgetnum_t hub_widgetid; devfs_handle_t widgetv; cnodeid_t cnode; widgetreg_t widget_id; nasid_t nasid, peer_nasid; struct xwidget_hwid_s hwid; hubinfo_t hubinfo; /*REFERENCED*/ int rc; char pathname[128]; char new_name[64]; moduleid_t module; slotid_t slot; lboard_t *board = NULL; char buffer[16]; slotid_t get_widget_slotnum(int xbow, int widget); DBG("\nio_xswitch_widget_init: hubv 0x%p, xswitchv 0x%p, widgetnum 0x%x\n", hubv, xswitchv, widgetnum); /* * Verify that xswitchv is indeed an attached xswitch. */ xswitch_info = xswitch_info_get(xswitchv); ASSERT(xswitch_info != NULL); hubinfo_get(hubv, &hubinfo); nasid = hubinfo->h_nasid; cnode = NASID_TO_COMPACT_NODEID(nasid); hub_widgetid = hubinfo->h_widgetid; /* * Check that the widget is an io widget and is enabled * on this nasid or the `peer' nasid. The peer nasid * is the other hub/bedrock connected to the xbow. */ peer_nasid = NODEPDA(cnode)->xbow_peer; if (peer_nasid == INVALID_NASID) /* If I don't have a peer, use myself. */ peer_nasid = nasid; if (!xbow_port_io_enabled(nasid, widgetnum) && !xbow_port_io_enabled(peer_nasid, widgetnum)) { return; } if (xswitch_info_link_ok(xswitch_info, widgetnum)) { char name[4]; /* * If the current hub is not supposed to be the master * for this widgetnum, then skip this widget. */ if (xswitch_info_master_assignment_get(xswitch_info, widgetnum) != hubv) { return; } module = NODEPDA(cnode)->module_id; #ifdef XBRIDGE_REGS_SIM /* hardwire for now...could do this with something like: * xbow_soft_t soft = hwgraph_fastinfo_get(vhdl); * xbow_t xbow = soft->base; * xbowreg_t xwidget_id = xbow->xb_wid_id; * but I don't feel like figuring out vhdl right now.. * and I know for a fact the answer is 0x2d000049 */ DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n"); DBG("XWIDGET_PART_NUM(0x2d000049)= 0x%x\n", XWIDGET_PART_NUM(0x2d000049)); if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM) #else if (nasid_has_xbridge(nasid)) #endif /* XBRIDGE_REGS_SIM */ { board = find_lboard_module_class( (lboard_t *)KL_CONFIG_INFO(nasid), module, KLTYPE_IOBRICK); DBG("io_xswitch_widget_init: Board 0x%p\n", board); { lboard_t dummy; if (board) { DBG("io_xswitch_widget_init: Found KLTYPE_IOBRICK Board 0x%p brd_type 0x%x\n", board, board->brd_type); } else { DBG("io_xswitch_widget_init: FIXME did not find IOBOARD\n"); board = &dummy; } } /* * Make sure we really want to say xbrick, pbrick, * etc. rather than XIO, graphics, etc. */ #ifdef SUPPORT_PRINTING_M_FORMAT sprintf(pathname, EDGE_LBL_MODULE "/%M/" "%cbrick" "/%s/%d", NODEPDA(cnode)->module_id, #else memset(buffer, 0, 16); format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF); sprintf(pathname, EDGE_LBL_MODULE "/%s/" "%cbrick" "/%s/%d", buffer, #endif (board->brd_type == KLTYPE_IBRICK) ? 'I' : (board->brd_type == KLTYPE_PBRICK) ? 'P' : (board->brd_type == KLTYPE_XBRICK) ? 'X' : '?', EDGE_LBL_XTALK, widgetnum); } DBG("io_xswitch_widget_init: path= %s\n", pathname); rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv); ASSERT(rc == GRAPH_SUCCESS); /* This is needed to let the user programs to map the * module,slot numbers to the corresponding widget numbers * on the crossbow. */ rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv); /* If we are looking at the global master io6 * then add information about the version of * the io6prom as a part of "detailed inventory" * information. */ if (is_master_baseio(nasid, NODEPDA(cnode)->module_id, get_widget_slotnum(0,widgetnum))) { extern void klhwg_baseio_inventory_add(devfs_handle_t, cnodeid_t); module = NODEPDA(cnode)->module_id; #ifdef XBRIDGE_REGS_SIM DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n"); if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM) #else if (nasid_has_xbridge(nasid)) #endif /* XBRIDGE_REGS_SIM */ { board = find_lboard_module( (lboard_t *)KL_CONFIG_INFO(nasid), module); /* * Change iobrick to correct i/o brick */ #ifdef SUPPORT_PRINTING_M_FORMAT sprintf(pathname, EDGE_LBL_MODULE "/%M/" #else sprintf(pathname, EDGE_LBL_MODULE "/%x/" #endif "iobrick" "/%s/%d", NODEPDA(cnode)->module_id, EDGE_LBL_XTALK, widgetnum); } else { slot = get_widget_slotnum(0, widgetnum); board = get_board_name(nasid, module, slot, new_name); /* * Create the vertex for the widget, * using the decimal * widgetnum as the name of the primary edge. */ #ifdef SUPPORT_PRINTING_M_FORMAT sprintf(pathname, EDGE_LBL_MODULE "/%M/" EDGE_LBL_SLOT "/%s", NODEPDA(cnode)->module_id, new_name); #else memset(buffer, 0, 16); format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF); sprintf(pathname, EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLOT "/%s", buffer, new_name); #endif } rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv); DBG("io_xswitch_widget_init: (2) path= %s\n", pathname); /* * This is a weird ass code needed for error injection * purposes. */ rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv); klhwg_baseio_inventory_add(widgetv,cnode); } sprintf(name, "%d", widgetnum); DBG("io_xswitch_widget_init: FIXME hwgraph_edge_add %s xswitchv 0x%p, widgetv 0x%p\n", name, xswitchv, widgetv); rc = hwgraph_edge_add(xswitchv, widgetv, name); /* * crosstalk switch code tracks which * widget is attached to each link. */ xswitch_info_vhdl_set(xswitch_info, widgetnum, widgetv); /* * Peek at the widget to get its crosstalk part and * mfgr numbers, then present it to the generic xtalk * bus provider to have its driver attach routine * called (or not). */ #ifdef XBRIDGE_REGS_SIM widget_id = 0x2d000049; DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: id hardwired to widget_id\n"); #else widget_id = XWIDGET_ID_READ(nasid, widgetnum); #endif /* XBRIDGE_REGS_SIM */ hwid.part_num = XWIDGET_PART_NUM(widget_id); hwid.rev_num = XWIDGET_REV_NUM(widget_id); hwid.mfg_num = XWIDGET_MFG_NUM(widget_id); /* Store some inventory information about * the xwidget in the hardware graph. */ xwidget_inventory_add(widgetv,board,hwid); (void)xwidget_register(&hwid, widgetv, widgetnum, hubv, hub_widgetid, aa); #ifdef SN0_USE_BTE bte_bpush_war(cnode, (void *)board); #endif }