int vmm_devtree_irq_get(struct vmm_devtree_node *node, u32 *irq, int index) { u32 alen; const char *aval; if (!node || !irq || index < 0) { return VMM_EFAIL; } aval = vmm_devtree_attrval(node, VMM_DEVTREE_INTERRUPTS_ATTR_NAME); if (!aval) { return VMM_ENOTAVAIL; } alen = vmm_devtree_attrlen(node, VMM_DEVTREE_INTERRUPTS_ATTR_NAME); if (alen <= (index * sizeof(u32))) { return VMM_ENOTAVAIL; } aval += index * sizeof(u32); *irq = vmm_be32_to_cpu(*((u32 *)aval)); return VMM_OK; }
u32 vmm_devtree_irq_count(struct vmm_devtree_node *node) { u32 alen; if (!node) { return 0; } alen = vmm_devtree_attrlen(node, VMM_DEVTREE_INTERRUPTS_ATTR_NAME); return alen / sizeof(u32); }
static int devtree_node_is_compatible(const struct vmm_devtree_node *node, const char *compat) { const char *cp; int cplen, l; cp = vmm_devtree_attrval(node, VMM_DEVTREE_COMPATIBLE_ATTR_NAME); cplen = vmm_devtree_attrlen(node, VMM_DEVTREE_COMPATIBLE_ATTR_NAME); if (cp == NULL) return 0; while (cplen > 0) { if (strcmp(cp, compat) == 0) return 1; l = strlen(cp) + 1; cp += l; cplen -= l; } return 0; }
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; } } } }