int __init arch_defterm_init(void) { int rc; const char *attr; struct vmm_devtree_node *node; const struct vmm_devtree_nodeid *nodeid; /* Find choosen console node */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_CHOSEN_NODE_NAME); if (!node) { return VMM_ENODEV; } rc = vmm_devtree_read_string(node, VMM_DEVTREE_CONSOLE_ATTR_NAME, &attr); if (rc) { return rc; } node = vmm_devtree_getnode(attr); if (!node) { return VMM_ENODEV; } /* Find appropriate defterm ops */ nodeid = vmm_devtree_match_node(defterm_devid_table, node); if (nodeid) { ops = nodeid->data; } return ops->init(node); }
int __init arch_board_final_init(void) { int rc; struct vmm_devtree_node *node; /* All VMM API's are available here */ /* We can register a Board specific resource here */ /* Do Probing using device driver framework */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_HOSTINFO_NODE_NAME VMM_DEVTREE_PATH_SEPARATOR_STRING "plb"); if(!node) { return VMM_ENOTAVAIL; } rc = vmm_devdrv_probe(node, NULL); if(rc) { return rc; } return VMM_OK; }
int __init arch_clocksource_init(void) { int rc; struct vmm_devtree_node *node; /* Map timer0 registers */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING "mct"); if (!node) { rc = VMM_EFAIL; goto skip_mct_timer_init; } rc = vmm_devtree_clock_frequency(node, &mct_clk_rate); if (rc) { goto skip_mct_timer_init; } if (!mct_timer_base) { rc = vmm_devtree_regmap(node, &mct_timer_base, 0); if (rc) { return rc; } } /* Initialize mct as clocksource */ rc = exynos4_clocksource_init(mct_timer_base, node->name, 300, mct_clk_rate); if (rc) { return rc; } skip_mct_timer_init: return rc; }
static void cmd_host_info(struct vmm_chardev *cdev) { const char *attr; struct vmm_devtree_node *node; u32 total = vmm_host_ram_total_frame_count(); attr = NULL; node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING); if (node) { vmm_devtree_read_string(node, VMM_DEVTREE_MODEL_ATTR_NAME, &attr); } if (attr) { vmm_cprintf(cdev, "%-20s: %s\n", "Host Name", attr); } else { vmm_cprintf(cdev, "%-20s: %s\n", "Host Name", CONFIG_BOARD); } vmm_cprintf(cdev, "%-20s: %u\n", "Boot CPU", vmm_smp_bootcpu_id()); vmm_cprintf(cdev, "%-20s: %u\n", "Total Online CPUs", vmm_num_online_cpus()); vmm_cprintf(cdev, "%-20s: %u MB\n", "Total VAPOOL", CONFIG_VAPOOL_SIZE_MB); vmm_cprintf(cdev, "%-20s: %u MB\n", "Total RAM", ((total *VMM_PAGE_SIZE) >> 20)); arch_board_print_info(cdev); }
int __init arch_defterm_init(void) { int rc; u32 *val; struct vmm_devtree_node *node; node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_HOSTINFO_NODE_NAME VMM_DEVTREE_PATH_SEPARATOR_STRING "motherboard" VMM_DEVTREE_PATH_SEPARATOR_STRING "iofpga" VMM_DEVTREE_PATH_SEPARATOR_STRING "uart0"); if (!node) { return VMM_ENODEV; } rc = vmm_devtree_regmap(node, &v2m_defterm_base, 0); if (rc) { return rc; } val = vmm_devtree_attrval(node, VMM_DEVTREE_CLOCK_RATE_ATTR_NAME); v2m_defterm_inclk = (val) ? *val : 24000000; val = vmm_devtree_attrval(node, "baudrate"); v2m_defterm_baud = (val) ? *val : 115200; pl011_lowlevel_init(v2m_defterm_base, v2m_defterm_baud, v2m_defterm_inclk); return VMM_OK; }
int __init arch_cpu_early_init(void) { const char *options; struct vmm_devtree_node *node; /* * Host virtual memory, device tree, heap is up. * Do necessary early stuff like iomapping devices * memory or boot time memory reservation here. */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_CHOSEN_NODE_NAME); if (!node) { return VMM_ENODEV; } if (vmm_devtree_read_string(node, VMM_DEVTREE_BOOTARGS_ATTR_NAME, &options) == VMM_OK) { vmm_parse_early_options(options); } vmm_devtree_dref_node(node); return VMM_OK; }
static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name) { unsigned int len = 0; struct vmm_devtree_phandle_args phandle; struct clk *clk = ERR_PTR(-ENODEV); char *path; len = strlen(name) + strlen("/clocks/") + 1; if (NULL == (path = kmalloc(GFP_KERNEL, len))) { vmm_printf("Failed to allocate fixed clock \"%s\" path " "string\n", name); return NULL; } sprintf(path, "/clocks/%s", name); phandle.np = vmm_devtree_getnode(path); kfree(path); if (phandle.np) { clk = of_clk_get_from_provider(&phandle); of_node_put(phandle.np); } return clk; }
int __init arch_smp_init_cpus(void) { int rc; const char *str; physical_addr_t hwid; unsigned int i, cpus_count = 0, cpu = 1; bool bootcpu_valid = false; struct vmm_devtree_node *dn, *cpus; smp_init_ops(); cpus = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING "cpus"); if (!cpus) { vmm_printf("%s: Failed to find cpus node\n", __func__); return VMM_ENOTAVAIL; } dn = NULL; vmm_devtree_for_each_child(dn, cpus) { str = NULL; rc = vmm_devtree_read_string(dn, VMM_DEVTREE_DEVICE_TYPE_ATTR_NAME, &str); if (rc || !str) { continue; } if (strcmp(str, VMM_DEVTREE_DEVICE_TYPE_VAL_CPU)) { continue; } cpus_count++; }
int __init arch_board_final_init(void) { int rc; struct vmm_devtree_node *node; struct vmm_chardev * cdev; /* All VMM API's are available here */ /* We can register a Board specific resource here */ /* Do Probing using device driver framework */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_HOSTINFO_NODE_NAME VMM_DEVTREE_PATH_SEPARATOR_STRING "l3"); if (!node) { return VMM_ENOTAVAIL; } rc = vmm_devdrv_probe(node, NULL); if (rc) { return rc; } /* Find uart0 character device and * set it as vmm_stdio character device */ if ((cdev = vmm_chardev_find("uart0"))) { vmm_stdio_change_indevice(cdev); vmm_stdio_change_outdevice(cdev); } return VMM_OK; }
int __init arch_defterm_init(void) { int rc; u32 *val; struct vmm_devtree_node *node; node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_HOSTINFO_NODE_NAME VMM_DEVTREE_PATH_SEPARATOR_STRING "soc" VMM_DEVTREE_PATH_SEPARATOR_STRING "uart0"); if (!node) { return VMM_ENODEV; } rc = vmm_devtree_regmap(node, &sun4i_uart_port.base, 0); if (rc) { return rc; } val = vmm_devtree_attrval(node, VMM_DEVTREE_CLOCK_RATE_ATTR_NAME); sun4i_uart_port.input_clock = (val) ? *val : 24000000; val = vmm_devtree_attrval(node, "baudrate"); sun4i_uart_port.baudrate = (val) ? *val : 115200; val = vmm_devtree_attrval(node, "reg_align"); sun4i_uart_port.reg_align = (val) ? *val : 4; uart_8250_lowlevel_init(&sun4i_uart_port); return VMM_OK; }
static int __init process_acpi_sdt_table(char *tab_sign, u32 *tab_data) { struct vmm_devtree_node *node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_MOTHERBOARD_NODE_NAME); /* FIXME: First find if tab_size already exists. */ struct vmm_devtree_node *cnode = vmm_devtree_addnode(node, tab_sign); vmm_devtree_dref_node(node); if (!strncmp(tab_sign, APIC_SIGNATURE, strlen(APIC_SIGNATURE))) { struct acpi_madt_hdr *madt_hdr; madt_hdr = (struct acpi_madt_hdr *)tab_data; if (acpi_populate_ioapic_devtree(madt_hdr, cnode) != VMM_OK) return VMM_EFAIL; if (acpi_populate_lapic_devtree(madt_hdr, cnode) != VMM_OK) return VMM_EFAIL; } else if (!strncmp(tab_sign, HPET_SIGNATURE, strlen(HPET_SIGNATURE))) { struct acpi_hpet hpet_chip, *hpet; int nr_hpet_blks, i; char hpet_nm[256]; if (acpi_read_sdt_at(tab_data, (struct acpi_sdt_hdr *)&hpet_chip, sizeof(struct acpi_hpet), HPET_SIGNATURE) < 0) { return VMM_EFAIL; } hpet = (struct acpi_hpet *)tab_data; nr_hpet_blks = (hpet->hdr.len - sizeof(struct acpi_sdt_hdr)) /sizeof(struct acpi_timer_blocks); vmm_devtree_setattr(cnode, VMM_DEVTREE_NR_HPET_ATTR_NAME, &nr_hpet_blks, VMM_DEVTREE_ATTRTYPE_UINT32, sizeof(nr_hpet_blks), FALSE); for (i = 0; i < nr_hpet_blks; i++) { memset(hpet_nm, 0, sizeof(hpet_nm)); vmm_sprintf(hpet_nm, VMM_DEVTREE_HPET_NODE_FMT, i); struct vmm_devtree_node *nnode = vmm_devtree_addnode(cnode, hpet_nm); BUG_ON(nnode == NULL); if (vmm_devtree_setattr(nnode, VMM_DEVTREE_HPET_ID_ATTR_NAME, &hpet->tmr_blks[i].asid, VMM_DEVTREE_ATTRTYPE_UINT32, sizeof(hpet->tmr_blks[i].asid), FALSE) != VMM_OK) { return VMM_EFAIL; } if (vmm_devtree_setattr(nnode, VMM_DEVTREE_HPET_PADDR_ATTR_NAME, &hpet->tmr_blks[i].base, VMM_DEVTREE_ATTRTYPE_PHYSADDR, sizeof(physical_addr_t), FALSE) != VMM_OK) { return VMM_EFAIL; } } } return VMM_OK; }
static int __init vmm_net_init(void) { int rc = VMM_OK; struct vmm_devtree_node *node; rc = vmm_mbufpool_init(); if (rc) { vmm_printf("%s: Failed to init mbuf pool\n", __func__); goto mbufpool_init_failed; } rc = vmm_netswitch_init(); if (rc) { vmm_printf("%s: Failed to init netswitch\n", __func__); goto netswitch_init_failed; } rc = vmm_netport_init(); if (rc) { vmm_printf("%s: Failed to init netport\n", __func__); goto netport_init_failed; } rc = vmm_bridge_init(); if (rc) { vmm_printf("%s: Failed to init bridge\n", __func__); goto bridge_init_failed; } node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_VMMINFO_NODE_NAME VMM_DEVTREE_PATH_SEPARATOR_STRING "net"); if (!node) { vmm_printf("%s: devtree node not found\n", __func__); goto net_devtree_probe_failed; } rc = vmm_devdrv_probe(node); if (rc) { vmm_printf("%s: devtree node probe failed\n", __func__); goto net_devtree_probe_failed; } goto net_init_done; net_devtree_probe_failed: vmm_bridge_exit(); bridge_init_failed: vmm_netport_exit(); netport_init_failed: vmm_netswitch_exit(); netswitch_init_failed: vmm_mbufpool_exit(); mbufpool_init_failed: net_init_done: return rc; }
int __init arch_defterm_init(void) { int rc; u32 *val; const char *attr; struct vmm_devtree_node *node; u32 imx_defterm_inclk; u32 imx_defterm_baud; node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_CHOSEN_NODE_NAME); if (!node) { return VMM_ENODEV; } attr = vmm_devtree_attrval(node, VMM_DEVTREE_CONSOLE_ATTR_NAME); if (!attr) { return VMM_ENODEV; } node = vmm_devtree_getnode(attr); if (!node) { return VMM_ENODEV; } rc = vmm_devtree_regmap(node, &imx_defterm_base, 0); if (rc) { return rc; } rc = vmm_devtree_clock_frequency(node, &imx_defterm_inclk); if (rc) { return rc; } val = vmm_devtree_attrval(node, "baudrate"); imx_defterm_baud = (val) ? *val : 115200; imx_lowlevel_init(imx_defterm_base, imx_defterm_baud, imx_defterm_inclk); return VMM_OK; }
int __init arch_smp_init_cpus(void) { u32 ncores; int i, rc = VMM_OK; struct vmm_devtree_node *node; /* Get the PMU node in the dev tree */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING "pmu"); if (!node) { return VMM_EFAIL; } /* Map the PMU physical address to virtual address */ rc = vmm_devtree_regmap(node, &pmu_base, 0); if (rc) { return rc; } /* Get the SCU node in the dev tree */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING "scu"); if (!node) { return VMM_EFAIL; } /* Map the SCU physical address to virtual address */ rc = vmm_devtree_regmap(node, &scu_base, 0); if (rc) { return rc; } /* How many ARM core do we have */ ncores = scu_get_core_count((void *)scu_base); /* Update the cpu_possible bitmap based on SCU */ for (i = 0; i < CONFIG_CPU_COUNT; i++) { if ((i < ncores) && scu_cpu_core_is_smp((void *)scu_base, i)) { vmm_set_cpu_possible(i, TRUE); } } return VMM_OK; }
int __init arch_board_final_init(void) { int rc; struct vmm_devtree_node *node; struct vmm_chardev * cdev; #if defined(CONFIG_RTC) struct vmm_rtcdev * rdev; #endif /* All VMM API's are available here */ /* We can register a Board specific resource here */ #if 0 /* FIXME: */ /* Map control registers */ ca15x4_sys_base = vmm_host_iomap(VEXPRESS_SYS_BASE, 0x1000); /* Unlock Lockable registers */ vmm_writel(VEXPRESS_SYS_LOCKVAL, (void *)(ca15x4_sys_base + VEXPRESS_SYS_LOCK_OFFSET)); #endif /* Do Probing using device driver framework */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_HOSTINFO_NODE_NAME VMM_DEVTREE_PATH_SEPARATOR_STRING "nbridge"); if (!node) { return VMM_ENOTAVAIL; } rc = vmm_devdrv_probe(node, NULL); if (rc) { return rc; } /* Find uart0 character device and * set it as vmm_stdio character device */ if ((cdev = vmm_chardev_find("uart0"))) { vmm_stdio_change_indevice(cdev); vmm_stdio_change_outdevice(cdev); } /* Syncup wall-clock time from rtc0 */ #if defined(CONFIG_RTC) if ((rdev = vmm_rtcdev_find("rtc0"))) { if ((rc = vmm_rtcdev_sync_wallclock(rdev))) { return rc; } } #endif return VMM_OK; }
int __cpuinit arch_clockchip_init(void) { int rc; struct vmm_devtree_node *node; u32 val, cpu = vmm_smp_processor_id(); if (!cpu) { /* Map timer0 registers */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING "mct"); if (!node) { goto skip_mct_timer_init; } if (!mct_timer_base) { rc = vmm_devtree_regmap(node, &mct_timer_base, 0); if (rc) { return rc; } } rc = vmm_devtree_clock_frequency(node, &mct_clk_rate); if (rc) { return rc; } /* Get MCT irq */ rc = vmm_devtree_irq_get(node, &val, 0); if (rc) { return rc; } /* Initialize MCT as clockchip */ rc = exynos4_clockchip_init(mct_timer_base, val, node->name, 300, mct_clk_rate, 0); if (rc) { return rc; } } skip_mct_timer_init: #if CONFIG_SAMSUNG_MCT_LOCAL_TIMERS if (mct_timer_base) { exynos4_local_timer_init(mct_timer_base, 0, "mct_tick", 450, mct_clk_rate); } #endif return VMM_OK; }
static int __init daemon_mterm_init(void) { u8 mterm_priority; u32 mterm_time_slice; struct vmm_devtree_node * node; const char * attrval; /* Reset the control structure */ vmm_memset(&mtctrl, 0, sizeof(mtctrl)); /* Retrive mterm time slice */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_VMMINFO_NODE_NAME); if (!node) { return VMM_EFAIL; } attrval = vmm_devtree_attrval(node, "mterm_priority"); if (attrval) { mterm_priority = *((u32 *) attrval); } else { mterm_priority = VMM_THREAD_DEF_PRIORITY; } attrval = vmm_devtree_attrval(node, "mterm_time_slice"); if (attrval) { mterm_time_slice = *((u32 *) attrval); } else { mterm_time_slice = VMM_THREAD_DEF_TIME_SLICE; } /* Create mterm thread */ mtctrl.thread = vmm_threads_create("mterm", &mterm_main, NULL, mterm_priority, mterm_time_slice); if (!mtctrl.thread) { vmm_panic("Creation of system critical thread failed.\n"); } /* Start the mterm thread */ vmm_threads_start(mtctrl.thread); return VMM_OK; }
int __init arch_smp_prepare_cpus(void) { int rc = VMM_OK; struct vmm_devtree_node *node; virtual_addr_t ca9_scu_base; u32 ncores; int i; /* Get the SCU node in the dev tree */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_HOSTINFO_NODE_NAME VMM_DEVTREE_PATH_SEPARATOR_STRING "scu"); if (!node) { return VMM_EFAIL; } /* map the SCU physical address to virtual address */ rc = vmm_devtree_regmap(node, &ca9_scu_base, 0); if (rc) { return rc; } /* How many ARM core do we have */ ncores = scu_get_core_count((void *)ca9_scu_base); /* Find out the number of SMP-enabled cpu cores */ for (i = 0; i < CONFIG_CPU_COUNT; i++) { /* build the possible CPU map */ if ((i >= ncores) || !scu_cpu_core_is_smp((void *)ca9_scu_base, i)) { /* Update the cpu_possible bitmap */ vmm_set_cpu_possible(i, 0); } else { vmm_set_cpu_possible(i, 1); } } /* Enable snooping through SCU */ scu_enable((void *)ca9_scu_base); /* unmap the SCU node */ rc = vmm_devtree_regunmap(node, ca9_scu_base, 0); return rc; }
int initrd_devtree_update(u64 start, u64 end) { int rc = VMM_OK; struct vmm_devtree_node *node; /* Sanity checks */ if (start >= end) { return VMM_EINVALID; } if (initrd_rbd) { return VMM_EBUSY; } /* There should be a /chosen node */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_CHOSEN_NODE_NAME); if (!node) { return VMM_ENODEV; } /* Update start attribute in /chosen node */ rc = vmm_devtree_setattr(node, INITRD_START_ATTR2_NAME, &start, VMM_DEVTREE_ATTRTYPE_UINT64, sizeof(start), FALSE); if (rc) { goto done; } /* Update end attribute in /chosen node */ rc = vmm_devtree_setattr(node, INITRD_END_ATTR2_NAME, &end, VMM_DEVTREE_ATTRTYPE_UINT64, sizeof(end), FALSE); if (rc) { goto done; } done: vmm_devtree_dref_node(node); return rc; }
int __init arch_smp_start_cpu(u32 cpu) { const struct vmm_cpumask *mask; int rc; struct vmm_devtree_node *node; virtual_addr_t ca9_pmu_base; if (cpu == 0) { /* Nothing to do for first CPU */ return VMM_OK; } /* Get the PMU node in the dev tree */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_HOSTINFO_NODE_NAME VMM_DEVTREE_PATH_SEPARATOR_STRING "pmu"); if (!node) { return VMM_EFAIL; } /* map the PMU physical address to virtual address */ rc = vmm_devtree_regmap(node, &ca9_pmu_base, 0); if (rc) { return rc; } mask = get_cpu_mask(cpu); /* Write the entry address for the secondary cpus */ vmm_writel((u32)_load_start, (void *)ca9_pmu_base + 0x814); /* unmap the PMU node */ rc = vmm_devtree_regunmap(node, ca9_pmu_base, 0); /* Wakeup target cpu from wfe/wfi by sending an IPI */ gic_raise_softirq(mask, 0); return rc; }
int __init arch_board_final_init(void) { int rc; struct vmm_devtree_node *node; struct vmm_chardev * cdev; /* All VMM API's are available here */ /* We can register a Board specific resource here */ /* Map control registers */ pba8_sys_base = vmm_host_iomap(REALVIEW_SYS_BASE, 0x1000); /* Unlock Lockable registers */ vmm_writel(REALVIEW_SYS_LOCKVAL, (void *)(pba8_sys_base + REALVIEW_SYS_LOCK_OFFSET)); /* Do Probing using device driver framework */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_HOSTINFO_NODE_NAME VMM_DEVTREE_PATH_SEPARATOR_STRING "nbridge"); if (!node) { return VMM_ENOTAVAIL; } rc = vmm_devdrv_probe(node); if (rc) { return rc; } /* Find uart0 character device and * set it as vmm_stdio character device */ if ((cdev = vmm_chardev_find("uart0"))) { vmm_stdio_change_device(cdev); } return VMM_OK; }
static int cmd_host_info(struct vmm_chardev *cdev) { int rc; const char *attr; unsigned long hwid; struct vmm_devtree_node *node; u32 total = vmm_host_ram_total_frame_count(); attr = NULL; node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING); if (node) { vmm_devtree_read_string(node, VMM_DEVTREE_MODEL_ATTR_NAME, &attr); vmm_devtree_dref_node(node); } if (attr) { vmm_cprintf(cdev, "%-25s: %s\n", "Host Name", attr); } else { vmm_cprintf(cdev, "%-25s: %s\n", "Host Name", CONFIG_BOARD); } rc = vmm_smp_map_hwid(vmm_smp_bootcpu_id(), &hwid); if (rc) return rc; vmm_cprintf(cdev, "%-25s: 0x%lx\n", "Boot CPU Hardware ID", hwid); vmm_cprintf(cdev, "%-25s: %u\n", "Total Online CPUs", vmm_num_online_cpus()); vmm_cprintf(cdev, "%-25s: %u MB\n", "Total VAPOOL", CONFIG_VAPOOL_SIZE_MB); vmm_cprintf(cdev, "%-25s: %lu MB\n", "Total RAM", ((total *VMM_PAGE_SIZE) >> 20)); arch_board_print_info(cdev); return VMM_OK; }
int __init arch_cpu_early_init(void) { char *attr; struct vmm_devtree_node *node; /* * Host virtual memory, device tree, heap is up. * Do necessary early stuff like iomapping devices * memory or boot time memory reservation here. */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_CHOSEN_NODE_NAME); if (!node) { return VMM_ENODEV; } attr = vmm_devtree_attrval(node, VMM_DEVTREE_BOOTARGS_ATTR_NAME); if (attr) { vmm_parse_early_options(attr); } return VMM_OK; }
int __init arch_smp_init_cpus(void) { int rc; unsigned int i, cpu = 1; bool bootcpu_valid = false; struct vmm_devtree_node *dn, *cpus; cpus = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING "cpus"); if (!cpus) { vmm_printf("%s: Failed to find cpus node\n", __func__); return VMM_ENOTAVAIL; } dn = NULL; vmm_devtree_for_each_child(dn, cpus) { break; } if (!dn) { vmm_printf("%s: Failed to find node for boot cpu\n", __func__); vmm_devtree_dref_node(cpus); return VMM_ENODEV; } rc = vmm_devtree_read_physaddr(dn, VMM_DEVTREE_REG_ATTR_NAME, &smp_logical_map(0)); if (rc) { vmm_printf("%s: Failed to find reg property for boot cpu\n", __func__); vmm_devtree_dref_node(dn); vmm_devtree_dref_node(cpus); return rc; } smp_read_ops(dn, 0); vmm_devtree_dref_node(dn); dn = NULL; vmm_devtree_for_each_child(dn, cpus) { physical_addr_t hwid; /* * A cpu node with missing "reg" property is * considered invalid to build a smp_logical_map * entry. */ rc = vmm_devtree_read_physaddr(dn, VMM_DEVTREE_REG_ATTR_NAME, &hwid); if (rc) { vmm_printf("%s: missing reg property\n", dn->name); goto next; } /* * Non affinity bits must be set to 0 in the DT */ if (hwid & ~MPIDR_HWID_BITMASK) { vmm_printf("%s: invalid reg property\n", dn->name); goto next; } /* * Duplicate MPIDRs are a recipe for disaster. Scan * all initialized entries and check for * duplicates. If any is found just ignore the cpu. * smp_logical_map was initialized to MPIDR_INVALID to * avoid matching valid MPIDR values. */ for (i = 1; (i < cpu) && (i < CONFIG_CPU_COUNT); i++) { if (smp_logical_map(i) == hwid) { vmm_printf("%s: duplicate cpu reg properties" " in the DT\n", dn->name); goto next; } } /* * The numbering scheme requires that the boot CPU * must be assigned logical id 0. Record it so that * the logical map built from DT is validated and can * be used. */ if (hwid == smp_logical_map(0)) { if (bootcpu_valid) { vmm_printf("%s: duplicate boot cpu reg property" " in DT\n", dn->name); goto next; } bootcpu_valid = TRUE; /* * smp_logical_map has already been * initialized and the boot cpu doesn't need * the enable-method so continue without * incrementing cpu. */ continue; } if (cpu >= CONFIG_CPU_COUNT) goto next; if (smp_read_ops(dn, cpu) != 0) goto next; if (smp_cpu_ops[cpu]->cpu_init(dn, cpu)) goto next; DPRINTF("%s: smp logical map CPU%0 -> HWID 0x%llx\n", __func__, cpu, hwid); smp_logical_map(cpu) = hwid; next: cpu++; }
static int __init initrd_driver_init(void) { struct vmm_devtree_node *node; u64 initrd_start, initrd_end; /* There should be a /chosen node */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_CHOSEN_NODE_NAME); if (!node) { vmm_printf("initrd: No chosen node\n", __func__); return VMM_ENODEV; } /* Is there a start attribute */ if (vmm_devtree_read_u64(node, INITRD_START_ATTR_NAME, &initrd_start) != VMM_OK) { if (vmm_devtree_read_u64(node, INITRD_START_ATTR2_NAME, &initrd_start) != VMM_OK) { vmm_printf("initrd: %s/%s attribute not found\n", INITRD_START_ATTR_NAME, INITRD_START_ATTR2_NAME); goto error; } } /* If so is there also a end attribte */ if (vmm_devtree_read_u64(node, INITRD_END_ATTR_NAME, &initrd_end) != VMM_OK) { if (vmm_devtree_read_u64(node, INITRD_END_ATTR2_NAME, &initrd_end) != VMM_OK) { vmm_printf("initrd: %s/%s attribute not found\n", INITRD_END_ATTR_NAME, INITRD_END_ATTR2_NAME); goto error; } } /* Let's do a little bit os sanity check */ if (initrd_end <= initrd_start) { vmm_printf("initrd: error: initrd_start > initrd_end\n"); goto error; } /* OK, we know where the initrd device is located */ if ((initrd_rbd = rbd_create("initrd", (physical_addr_t)initrd_start, (physical_size_t)(initrd_end - initrd_start), true)) == NULL) { vmm_printf("initrd: rbd_create() failed\n"); goto error; } vmm_printf("initrd: RBD created at 0x%llx - 0x%llx\n", initrd_start, initrd_end); error: vmm_devtree_dref_node(node); return VMM_OK; }
static void system_init_work(struct vmm_work *work) { #define BOOTCMD_WIDTH 256 int ret; char bcmd[BOOTCMD_WIDTH]; const char *str; u32 c, freed; struct vmm_chardev *cdev; #if defined(CONFIG_RTC) struct vmm_rtcdev *rdev; #endif struct vmm_devtree_node *node, *node1; /* Initialize command manager */ vmm_printf("Initialize Command Manager\n"); ret = vmm_cmdmgr_init(); if (ret) { vmm_panic("Error %d\n", ret); } /* Initialize device driver framework */ vmm_printf("Initialize Device Driver Framework\n"); ret = vmm_devdrv_init(); if (ret) { vmm_panic("Error %d\n", ret); } /* Initialize device emulation framework */ vmm_printf("Initialize Device Emulation Framework\n"); ret = vmm_devemu_init(); if (ret) { vmm_panic("Error %d\n", ret); } /* Initialize character device framework */ vmm_printf("Initialize Character Device Framework\n"); ret = vmm_chardev_init(); if (ret) { vmm_panic("Error %d\n", ret); } /* Initialize virtual serial port framework */ vmm_printf("Initialize Virtual Serial Port Framework\n"); ret = vmm_vserial_init(); if (ret) { vmm_panic("Error %d\n", ret); } #if defined(CONFIG_SMP) /* Poll for all present CPUs to become online */ /* Note: There is a timeout of 1 second */ /* Note: The modules might use SMP IPIs or might have per-cpu context * so, we do this before vmm_modules_init() in-order to make sure that * correct number of online CPUs are visible to all modules. */ ret = 1000; while(ret--) { int all_cpu_online = 1; for_each_present_cpu(c) { if (!vmm_cpu_online(c)) { all_cpu_online = 0; } } if (all_cpu_online) { break; } vmm_mdelay(1); } #endif /* Initialize hypervisor modules */ vmm_printf("Initialize Hypervisor Modules\n"); ret = vmm_modules_init(); if (ret) { vmm_panic("Error %d\n", ret); } /* Initialize cpu final */ vmm_printf("Initialize CPU Final\n"); ret = arch_cpu_final_init(); if (ret) { vmm_panic("Error %d\n", ret); } /* Intialize board final */ vmm_printf("Initialize Board Final\n"); ret = arch_board_final_init(); if (ret) { vmm_panic("Error %d\n", ret); } /* Print status of present host CPUs */ for_each_present_cpu(c) { if (vmm_cpu_online(c)) { vmm_printf("CPU%d: Online\n", c); } else { vmm_printf("CPU%d: Possible\n", c); } } vmm_printf("Brought Up %d CPUs\n", vmm_num_online_cpus()); /* Free init memory */ vmm_printf("Freeing init memory: "); freed = vmm_host_free_initmem(); vmm_printf("%dK\n", freed); /* Process attributes in chosen node */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_CHOSEN_NODE_NAME); if (node) { /* Find character device based on console attribute */ str = vmm_devtree_attrval(node, VMM_DEVTREE_CONSOLE_ATTR_NAME); if (!(cdev = vmm_chardev_find(str))) { if ((node1 = vmm_devtree_getnode(str))) { cdev = vmm_chardev_find(node1->name); } } /* Set chosen console device as stdio device */ if (cdev) { vmm_printf("Change stdio device to %s\n", cdev->name); vmm_stdio_change_device(cdev); } #if defined(CONFIG_RTC) /* Find rtc device based on rtcdev attribute */ str = vmm_devtree_attrval(node, VMM_DEVTREE_RTCDEV_ATTR_NAME); if (!(rdev = vmm_rtcdev_find(str))) { if ((node1 = vmm_devtree_getnode(str))) { rdev = vmm_rtcdev_find(node1->name); } } /* Syncup wallclock time with chosen rtc device */ if (rdev) { ret = vmm_rtcdev_sync_wallclock(rdev); vmm_printf("Syncup wallclock using %s", rdev->name); if (ret) { vmm_printf("(error %d)", ret); } vmm_printf("\n"); } #endif /* Execute boot commands */ str = vmm_devtree_attrval(node, VMM_DEVTREE_BOOTCMD_ATTR_NAME); if (str) { c = vmm_devtree_attrlen(node, VMM_DEVTREE_BOOTCMD_ATTR_NAME); while (c) { #if defined(CONFIG_VERBOSE_MODE) /* Print boot command */ vmm_printf("bootcmd: %s\n", str); #endif /* Execute boot command */ strlcpy(bcmd, str, sizeof(bcmd)); cdev = vmm_stdio_device(); vmm_cmdmgr_execute_cmdstr(cdev, bcmd, NULL); /* Next boot command */ c -= strlen(str) + 1; str += strlen(str) + 1; } } } }
static int cmd_vfs_fdt_load(struct vmm_chardev *cdev, const char *devtree_path, const char *devtree_root_name, const char *path, int aliasc, char **aliasv) { int a, fd, rc = VMM_OK; char *astr; const char *aname, *apath, *aattr, *atype; size_t fdt_rd; void *fdt_data, *val = NULL; u32 val_type, val_len = 0; struct stat st; struct vmm_devtree_node *root, *anode, *node; struct vmm_devtree_node *parent; struct fdt_fileinfo fdt; parent = vmm_devtree_getnode(devtree_path); if (!parent) { vmm_cprintf(cdev, "Devtree path %s does not exist.\n", devtree_path); return VMM_EINVALID; } root = vmm_devtree_getchild(parent, devtree_root_name); if (root) { vmm_devtree_dref_node(root); vmm_cprintf(cdev, "Devtree path %s/%s already exist.\n", devtree_path, devtree_root_name); rc = VMM_EINVALID; goto fail; } fd = vfs_open(path, O_RDONLY, 0); if (fd < 0) { vmm_cprintf(cdev, "Failed to open %s\n", path); rc = fd; goto fail; } rc = vfs_fstat(fd, &st); if (rc) { vmm_cprintf(cdev, "Path %s does not exist.\n", path); goto fail_closefd; } if (!(st.st_mode & S_IFREG)) { vmm_cprintf(cdev, "Path %s should be regular file.\n", path); rc = VMM_EINVALID; goto fail_closefd; } if (!st.st_size) { vmm_cprintf(cdev, "File %s has zero %d bytes.\n", path); rc = VMM_EINVALID; goto fail_closefd; } if (st.st_size > VFS_MAX_FDT_SZ) { vmm_cprintf(cdev, "File %s has size %d bytes (> %d bytes).\n", path, (long)st.st_size, VFS_MAX_FDT_SZ); rc = VMM_EINVALID; goto fail_closefd; } fdt_data = vmm_zalloc(VFS_MAX_FDT_SZ); if (!fdt_data) { rc = VMM_ENOMEM; goto fail_closefd; } fdt_rd = vfs_read(fd, fdt_data, VFS_MAX_FDT_SZ); if (fdt_rd < st.st_size) { rc = VMM_EIO; goto fail_freedata; } rc = libfdt_parse_fileinfo((virtual_addr_t)fdt_data, &fdt); if (rc) { goto fail_freedata; } root = NULL; rc = libfdt_parse_devtree(&fdt, &root, devtree_root_name, parent); if (rc) { goto fail_freedata; } anode = vmm_devtree_getchild(root, VMM_DEVTREE_ALIASES_NODE_NAME); for (a = 0; a < aliasc; a++) { if (!anode) { vmm_cprintf(cdev, "Error: %s node not available\n", VMM_DEVTREE_ALIASES_NODE_NAME); continue; } astr = aliasv[a]; aname = astr; while (*astr != '\0' && *astr != ',') { astr++; } if (*astr == ',') { *astr = '\0'; astr++; } if (*astr == '\0') { continue; } aattr = astr; while (*astr != '\0' && *astr != ',') { astr++; } if (*astr == ',') { *astr = '\0'; astr++; } if (*astr == '\0') { continue; } atype = astr; while (*astr != '\0' && *astr != ',') { astr++; } if (*astr == ',') { *astr = '\0'; astr++; } if (*astr == '\0') { continue; } if (vmm_devtree_read_string(anode, aname, &apath)) { vmm_cprintf(cdev, "Error: Failed to read %s attribute " "of %s node\n", aname, VMM_DEVTREE_ALIASES_NODE_NAME); continue; } node = vmm_devtree_getchild(root, apath); if (!node) { vmm_cprintf(cdev, "Error: %s node not found under " "%s/%s\n", apath, devtree_path, devtree_root_name); continue; } if (!strcmp(atype, "unknown")) { val = NULL; val_len = 0; val_type = VMM_DEVTREE_MAX_ATTRTYPE; } else if (!strcmp(atype, "string")) { val_len = strlen(astr) + 1; val = vmm_zalloc(val_len); if (!val) { vmm_cprintf(cdev, "Error: vmm_zalloc(%d) " "failed\n", val_len); goto next_iter; } strcpy(val, astr); val_type = VMM_DEVTREE_ATTRTYPE_STRING; } else if (!strcmp(atype, "bytes")) { val_len = 1; val = vmm_zalloc(val_len); if (!val) { vmm_cprintf(cdev, "Error: vmm_zalloc(%d) " "failed\n", val_len); goto next_iter; } *((u8 *)val) = strtoul(astr, NULL, 0); val_type = VMM_DEVTREE_ATTRTYPE_BYTEARRAY; } else if (!strcmp(atype, "uint32")) { val_len = 4; val = vmm_zalloc(val_len); if (!val) { vmm_cprintf(cdev, "Error: vmm_zalloc(%d) " "failed\n", val_len); goto next_iter; } *((u32 *)val) = strtoul(astr, NULL, 0); val_type = VMM_DEVTREE_ATTRTYPE_UINT32; } else if (!strcmp(atype, "uint64")) { val_len = 8; val = vmm_zalloc(val_len); if (!val) { vmm_cprintf(cdev, "Error: vmm_zalloc(%d) " "failed\n", val_len); goto next_iter; } *((u64 *)val) = strtoull(astr, NULL, 0); val_type = VMM_DEVTREE_ATTRTYPE_UINT64; } else if (!strcmp(atype, "physaddr")) { val_len = sizeof(physical_addr_t); val = vmm_zalloc(val_len); if (!val) { vmm_cprintf(cdev, "Error: vmm_zalloc(%d) " "failed\n", val_len); goto next_iter; } *((physical_addr_t *)val) = strtoull(astr, NULL, 0); val_type = VMM_DEVTREE_ATTRTYPE_PHYSADDR; } else if (!strcmp(atype, "physsize")) { val_len = sizeof(physical_size_t); val = vmm_zalloc(val_len); if (!val) { vmm_cprintf(cdev, "Error: vmm_zalloc(%d) " "failed\n", val_len); goto next_iter; } *((physical_size_t *)val) = strtoull(astr, NULL, 0); val_type = VMM_DEVTREE_ATTRTYPE_PHYSSIZE; } else if (!strcmp(atype, "virtaddr")) { val_len = sizeof(virtual_addr_t); val = vmm_zalloc(val_len); if (!val) { vmm_cprintf(cdev, "Error: vmm_zalloc(%d) " "failed\n", val_len); goto next_iter; } *((virtual_addr_t *)val) = strtoull(astr, NULL, 0); val_type = VMM_DEVTREE_ATTRTYPE_VIRTADDR; } else if (!strcmp(atype, "virtsize")) { val_len = sizeof(virtual_size_t); val = vmm_zalloc(val_len); if (!val) { vmm_cprintf(cdev, "Error: vmm_zalloc(%d) " "failed\n", val_len); goto next_iter; } *((virtual_size_t *)val) = strtoull(astr, NULL, 0); val_type = VMM_DEVTREE_ATTRTYPE_VIRTSIZE; } else { vmm_cprintf(cdev, "Error: Invalid attribute type %s\n", atype); goto next_iter; } if (val && (val_len > 0)) { vmm_devtree_setattr(node, aattr, val, val_type, val_len, FALSE); vmm_free(val); } next_iter: vmm_devtree_dref_node(node); } vmm_devtree_dref_node(anode); fail_freedata: vmm_free(fdt_data); fail_closefd: vfs_close(fd); fail: vmm_devtree_dref_node(parent); return rc; }
static int __init lwip_netstack_init(void) { int rc; struct vmm_netswitch *nsw; struct vmm_devtree_node *node; const char *str; u8 ip[] = {169, 254, 1, 1}; u8 mask[] = {255, 255, 255, 0}; ip_addr_t __ip, __nm, __gw; /* Clear lwIP state */ memset(&lns, 0, sizeof(lns)); /* Get netstack device tree node if available */ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_VMMINFO_NODE_NAME VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_VMMNET_NODE_NAME VMM_DEVTREE_PATH_SEPARATOR_STRING VMM_DEVTREE_NETSTACK_NODE_NAME); /* Retrive preferred IP address */ if (vmm_devtree_read_string(node, "ipaddr", &str) == VMM_OK) { /* Read ip address from netstack node */ str2ipaddr(ip, str); } /* Retrive preferred IP address */ if (vmm_devtree_read_string(node, "netmask", &str) == VMM_OK) { /* Read network mask from netstack node */ str2ipaddr(mask, str); } /* Retrive preferred netswitch */ if (vmm_devtree_read_string(node, "netswitch", &str) == VMM_OK) { /* Find netswitch with given name */ nsw = vmm_netswitch_find(str); } else { /* Get default netswitch */ nsw = vmm_netswitch_default(); } if (!nsw) { vmm_panic("%s: No netswitch found\n", __func__); } /* Release netstack device tree node */ vmm_devtree_dref_node(node); /* Allocate a netport */ lns.port = vmm_netport_alloc("lwip-netport", VMM_NETPORT_DEF_QUEUE_SIZE); if (!lns.port) { vmm_printf("%s: vmm_netport_alloc() failed\n", __func__); rc = VMM_ENOMEM; goto fail; } /* Setup a netport */ lns.port->mtu = 1500; lns.port->link_changed = lwip_set_link; lns.port->can_receive = lwip_can_receive; lns.port->switch2port_xfer = lwip_switch2port_xfer; lns.port->priv = &lns; /* Register a netport */ rc = vmm_netport_register(lns.port); if (rc) { goto fail1; } /* Initialize lwIP + TCP/IP APIs */ tcpip_init(NULL, NULL); /* Add netif */ IP4_ADDR(&__ip, ip[0],ip[1],ip[2],ip[3]); IP4_ADDR(&__nm, mask[0],mask[1],mask[2],mask[3]); IP4_ADDR(&__gw, ip[0],ip[1],ip[2],ip[3]); netif_add(&lns.nif, &__ip, &__nm, &__gw, &lns, lwip_netstack_netif_init, ethernet_input); /* Set default netif */ netif_set_default(&lns.nif); /* Attach netport with netswitch * Note: This will cause netport link_change() */ rc = vmm_netswitch_port_add(nsw, lns.port); if (rc) { goto fail2; } #if !defined(PING_USE_SOCKETS) /* Initalize RAW PCB for ping */ ping_raw_init(); #endif return VMM_OK; fail2: vmm_netport_unregister(lns.port); fail1: vmm_netport_free(lns.port); fail: return rc; }