Example #1
0
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;
}
Example #2
0
int libfdt_parse_devtree(struct fdt_fileinfo *fdt,
			 struct vmm_devtree_node **root)
{
	char *data;

	/* Sanity check */
	if (!fdt) {
		return VMM_EFAIL;
	}

	/* Get data pointer */
	data = fdt->data;

	/* Sanity check */
	if (LIBFDT_DATA32(data) != FDT_BEGIN_NODE)
		return VMM_EFAIL;

	/* Point to root node name */
	data += sizeof(fdt_cell_t);

	/* Create root node */
	*root = vmm_devtree_addnode(NULL, data);

	/* Skip root node name */
	data += strlen(data) + 1;
	while ((virtual_addr_t) (data) % sizeof(fdt_cell_t) != 0) {
		(data)++;
	}

	/* Parse FDT recursively */
	libfdt_parse_devtree_recursive(fdt, *root, &data);

	return VMM_OK;
}
Example #3
0
static void libfdt_parse_devtree_recursive(struct fdt_fileinfo * fdt,
					   struct vmm_devtree_node * node,
					   char **data)
{
	u32 type, len;
	const char * name;
	struct vmm_devtree_node *child;

	if (!fdt || !node) {
		return;
	}

	while (LIBFDT_DATA32(*data) != FDT_END_NODE) {
		switch (LIBFDT_DATA32(*data)) {
		case FDT_PROP:
			*data += sizeof(fdt_cell_t);
			len = LIBFDT_DATA32(*data);
			*data += sizeof(fdt_cell_t);
			name = &fdt->str[LIBFDT_DATA32(*data)];
			*data += sizeof(fdt_cell_t);
			type = vmm_devtree_estimate_attrtype(name);
			vmm_devtree_setattr(node, name, *data, type, len);
			*data += len;
			while ((virtual_addr_t) (*data) % sizeof(fdt_cell_t) != 0)
				(*data)++;
			break;
		case FDT_NOP:
			*data += sizeof(fdt_cell_t);
			break;
		case FDT_BEGIN_NODE:
			*data += sizeof(fdt_cell_t);
			type = VMM_DEVTREE_NODETYPE_UNKNOWN;
			child = vmm_devtree_addnode(node, *data, type, NULL);
			*data += vmm_strlen(*data) + 1;
			while ((virtual_addr_t) (*data) % sizeof(fdt_cell_t) != 0) {
				(*data)++;
			}
			libfdt_parse_devtree_recursive(fdt, child, data);
			break;
		default:
			return;
			break;
		};
	}

	*data += sizeof(fdt_cell_t);

	return;
}
Example #4
0
int libfdt_parse_devtree(struct fdt_fileinfo *fdt,
			 struct vmm_devtree_node **root,
			 const char *root_name,
			 struct vmm_devtree_node *root_parent)
{
	char *data;
	struct vmm_devtree_node *node;

	/* Sanity check */
	if (!fdt || !root_name) {
		return VMM_EFAIL;
	}

	/* Get data pointer */
	data = fdt->data;

	/* Sanity check */
	if (LIBFDT_DATA32(data) != FDT_BEGIN_NODE)
		return VMM_EFAIL;

	/* Skip root node name */
	data += sizeof(fdt_cell_t);

	/* Create root node */
	node = vmm_devtree_addnode(root_parent, root_name);
	if (!node) {
		return VMM_ENOMEM;
	}

	/* Update return pointer for root node */
	if (root) {
		*root = node;
	}

	/* Skip root node name */
	data += strlen(data) + 1;
	while ((virtual_addr_t) (data) % sizeof(fdt_cell_t) != 0) {
		(data)++;
	}

	/* Parse FDT recursively */
	libfdt_parse_devtree_recursive(fdt, node, &data);

	return VMM_OK;
}
Example #5
0
static int __init acpi_populate_lapic_devtree(struct acpi_madt_hdr *madt_hdr,
        struct vmm_devtree_node *cnode)
{
    unsigned int idx = 0;
    int ret = VMM_OK;
    struct acpi_madt_lapic *lapic;
    char lapic_nm[256];

    for (;;) {
        lapic = (struct acpi_madt_lapic *)
                acpi_madt_get_typed_item(madt_hdr, ACPI_MADT_TYPE_LAPIC,
                                         idx);
        if (!lapic)
            break;

        memset(lapic_nm, 0, sizeof(lapic_nm));
        vmm_sprintf(lapic_nm, VMM_DEVTREE_LAPIC_PCPU_NODE_FMT, idx);
        struct vmm_devtree_node *nnode = vmm_devtree_addnode(cnode, lapic_nm);

        if (vmm_devtree_setattr(nnode, VMM_DEVTREE_LAPIC_CPU_ID_ATTR_NAME,
                                &lapic->acpi_cpu_id, VMM_DEVTREE_ATTRTYPE_UINT32,
                                sizeof(lapic->acpi_cpu_id), FALSE) != VMM_OK) {
            ret = VMM_EFAIL;
            break;
        }

        if (vmm_devtree_setattr(nnode, VMM_DEVTREE_LAPIC_LAPIC_ID_ATTR_NAME,
                                &lapic->apic_id, VMM_DEVTREE_ATTRTYPE_UINT32,
                                sizeof(lapic->apic_id), FALSE) != VMM_OK) {
            ret = VMM_EFAIL;
            break;
        }

        idx++;
    }

    vmm_devtree_setattr(cnode, VMM_DEVTREE_NR_LAPIC_ATTR_NAME,
                        &idx, VMM_DEVTREE_ATTRTYPE_UINT32, sizeof(idx), FALSE);

    return ret;
}
Example #6
0
static int __init acpi_populate_ioapic_devtree(struct acpi_madt_hdr *madt_hdr,
        struct vmm_devtree_node *cnode)
{
    unsigned int idx = 0;
    int ret = VMM_OK;
    struct acpi_madt_ioapic *ioapic;
    char ioapic_nm[256];

    for (;;) {
        ioapic = (struct acpi_madt_ioapic *)
                 acpi_madt_get_typed_item(madt_hdr, ACPI_MADT_TYPE_IOAPIC,
                                          idx);
        if (!ioapic)
            break;

        memset(ioapic_nm, 0, sizeof(ioapic_nm));
        vmm_sprintf(ioapic_nm, VMM_DEVTREE_IOAPIC_NODE_FMT, idx);
        struct vmm_devtree_node *nnode = vmm_devtree_addnode(cnode, ioapic_nm);

        if (vmm_devtree_setattr(nnode, VMM_DEVTREE_IOAPIC_PADDR_ATTR_NAME,
                                &ioapic->address, VMM_DEVTREE_ATTRTYPE_PHYSADDR,
                                sizeof(physical_addr_t), FALSE) != VMM_OK) {
            ret = VMM_EFAIL;
            break;
        }

        if (vmm_devtree_setattr(nnode, VMM_DEVTREE_IOAPIC_GINT_BASE_ATTR_NAME,
                                &ioapic->global_int_base, VMM_DEVTREE_ATTRTYPE_UINT32,
                                sizeof(ioapic->global_int_base), FALSE) != VMM_OK) {
            ret = VMM_EFAIL;
            break;
        }

        idx++;
    }

    vmm_devtree_setattr(cnode, VMM_DEVTREE_NR_IOAPIC_ATTR_NAME,
                        &idx, VMM_DEVTREE_ATTRTYPE_UINT32, sizeof(idx), FALSE);

    return ret;
}
Example #7
0
static void libfdt_parse_devtree_recursive(struct fdt_fileinfo *fdt,
					   struct vmm_devtree_node *node,
					   char **data)
{
	void *val;
	const char *name;
	u32 type, len, alen, addr_cells, size_cells;
	struct vmm_devtree_node *child;

	if (!fdt || !node) {
		return;
	}

	if (vmm_devtree_read_u32(node->parent,
				 "#address-cells", &addr_cells)) {
		addr_cells = sizeof(physical_addr_t) / sizeof(fdt_cell_t);
	}
	if (vmm_devtree_read_u32(node->parent,
				 "#size-cells", &size_cells)) {
		size_cells = sizeof(physical_size_t) / sizeof(fdt_cell_t);
	}

	while (LIBFDT_DATA32(*data) != FDT_END_NODE) {
		switch (LIBFDT_DATA32(*data)) {
		case FDT_PROP:
			*data += sizeof(fdt_cell_t);
			len = LIBFDT_DATA32(*data);
			*data += sizeof(fdt_cell_t);
			name = &fdt->str[LIBFDT_DATA32(*data)];
			*data += sizeof(fdt_cell_t);
			type = vmm_devtree_estimate_attrtype(name);
			alen = libfdt_property_len(name, addr_cells, 
						   size_cells, len);
			val = vmm_zalloc(alen);
			libfdt_property_read(name, val, *data,
					     addr_cells, size_cells, len);
			vmm_devtree_setattr(node, name, val, type, alen);
			vmm_free(val);
			*data += len;
			while ((virtual_addr_t) (*data) % sizeof(fdt_cell_t) != 0)
				(*data)++;
			break;
		case FDT_NOP:
			*data += sizeof(fdt_cell_t);
			break;
		case FDT_BEGIN_NODE:
			*data += sizeof(fdt_cell_t);
			child = vmm_devtree_addnode(node, *data);
			*data += strlen(*data) + 1;
			while ((virtual_addr_t) (*data) % sizeof(fdt_cell_t) != 0) {
				(*data)++;
			}
			libfdt_parse_devtree_recursive(fdt, child, data);
			break;
		default:
			return;
			break;
		};
	}

	*data += sizeof(fdt_cell_t);

	return;
}