Esempio n. 1
0
int arch_board_ram_size(physical_size_t * size)
{
    int rc = VMM_OK;
    struct fdt_fileinfo fdt;
    struct fdt_node_header * fdt_node;
    struct fdt_property * prop;

    rc = libfdt_parse_fileinfo((virtual_addr_t) & dt_blob_start, &fdt);
    if (rc) {
        return rc;
    }

    fdt_node = libfdt_find_node(&fdt,
                                VMM_DEVTREE_PATH_SEPARATOR_STRING
                                VMM_DEVTREE_HOSTINFO_NODE_NAME
                                VMM_DEVTREE_PATH_SEPARATOR_STRING
                                VMM_DEVTREE_MEMORY_NODE_NAME);
    if (!fdt_node) {
        return VMM_EFAIL;
    }

    prop = libfdt_get_property(&fdt, fdt_node,
                               VMM_DEVTREE_MEMORY_PHYS_SIZE_ATTR_NAME);
    if (!prop) {
        return VMM_EFAIL;
    }
    *size = *((physical_size_t *)prop->data);

    return VMM_OK;
}
Esempio n. 2
0
int arch_devtree_reserve_size(u32 index, physical_size_t *size)
{
	u64 tmp;
	int rc = VMM_OK;
	struct fdt_fileinfo fdt;

	if (load_bank_resv_sz) {
		if (index == 0) {
			*size = load_bank_resv_sz;
			return VMM_OK;
		} else {
			index -= 1;
		}
	}

	rc = libfdt_parse_fileinfo((virtual_addr_t)&dt_blob_start, &fdt);
	if (rc) {
		return rc;
	}

	rc = libfdt_reserve_size(&fdt, index, &tmp);
	if (rc) {
		return rc;
	}

	*size = (physical_size_t)tmp;

	return VMM_OK;
}
Esempio n. 3
0
int arch_board_ram_start(physical_addr_t * addr)
{
	int rc = VMM_OK;
	struct fdt_fileinfo fdt;
	struct fdt_node_header * fdt_node = NULL;
	struct fdt_property * prop = NULL;
	physical_addr_t *phys_adr = NULL;

	rc = libfdt_parse_fileinfo((virtual_addr_t) & dt_blob_start, &fdt);
	if (rc) {
		return rc;
	}

	fdt_node = libfdt_find_node(&fdt,
				    VMM_DEVTREE_PATH_SEPARATOR_STRING
				    VMM_DEVTREE_HOSTINFO_NODE_NAME
				    VMM_DEVTREE_PATH_SEPARATOR_STRING
				    VMM_DEVTREE_MEMORY_NODE_NAME);
	if (!fdt_node) {
		return VMM_EFAIL;
	}

	prop = libfdt_get_property(&fdt, fdt_node,
				   VMM_DEVTREE_MEMORY_PHYS_ADDR_ATTR_NAME);
	if (!prop) {
		return VMM_EFAIL;
	}

	phys_adr = (physical_addr_t *)prop->data;
	*addr = *phys_adr;

	return VMM_OK;
}
Esempio n. 4
0
int arch_devtree_ram_start(physical_addr_t *addr)
{
#if 0
	int rc = VMM_OK;
	struct fdt_fileinfo fdt;
	struct fdt_node_header *fdt_node;
	physical_addr_t data[2];
	
	rc = libfdt_parse_fileinfo((virtual_addr_t)&dt_blob_start, &fdt);
	if (rc) {
		return rc;
	}

	fdt_node = libfdt_find_node(&fdt, 
				    VMM_DEVTREE_PATH_SEPARATOR_STRING
				    VMM_DEVTREE_MEMORY_NODE_NAME);
	if (!fdt_node) {
		return VMM_EFAIL;
	}

	rc = libfdt_get_property(&fdt, fdt_node,
				 VMM_DEVTREE_REG_ATTR_NAME, data);
	if (rc) {
		return rc;
	}

	*addr = data[0];
#else
	*addr = 0x100000UL;
#endif
	return VMM_OK;
}
Esempio n. 5
0
int arch_devtree_populate(struct vmm_devtree_node **root)
{
	int rc = VMM_OK;
	struct fdt_fileinfo fdt;

	/* Parse skeletal FDT */
	rc = libfdt_parse_fileinfo((virtual_addr_t) & dt_blob_start, &fdt);
	if (rc) {
		return rc;
	}

	/* Populate skeletal FDT */
	rc = libfdt_parse_devtree(&fdt, root);
	if (rc) {
		return rc;
	}

	/* FIXME: Populate device tree from ACPI table */	
#if CONFIG_ACPI
	/*
	 * Initialize the ACPI table to help initialize
	 * other devices.
	 */
	acpi_init();
#endif

	return VMM_OK;
}
Esempio n. 6
0
int arch_board_ram_start(physical_addr_t *addr)
{
	int rc = VMM_OK;
	struct fdt_fileinfo fdt;
	struct fdt_node_header *fdt_node;

	*addr = 0xffffffff;

	if (libfdt_parse_fileinfo((virtual_addr_t) & dt_blob_start, &fdt)) {
		return VMM_EFAIL;
	}

	fdt_node = libfdt_find_node(&fdt,
				    VMM_DEVTREE_PATH_SEPARATOR_STRING
				    VMM_DEVTREE_HOSTINFO_NODE_NAME
				    VMM_DEVTREE_PATH_SEPARATOR_STRING
				    VMM_DEVTREE_MEMORY_NODE_NAME);
	if (!fdt_node) {
		return VMM_EFAIL;
	}

	rc = libfdt_get_property(&fdt, fdt_node,
				 VMM_DEVTREE_MEMORY_PHYS_ADDR_ATTR_NAME, addr);
	if (rc) {
		return rc;
	}

	return VMM_OK;
}
Esempio n. 7
0
int arch_board_devtree_populate(struct vmm_devtree_node **root)
{
    struct fdt_fileinfo fdt;

    if (libfdt_parse_fileinfo((virtual_addr_t) & dt_blob_start, &fdt)) {
        return VMM_EFAIL;
    }

    return libfdt_parse_devtree(&fdt, root);
}
Esempio n. 8
0
int arch_devtree_populate(struct vmm_devtree_node **root)
{
	int rc = VMM_OK;
	struct fdt_fileinfo fdt;
	
	rc = libfdt_parse_fileinfo((virtual_addr_t)&dt_blob_start, &fdt);
	if (rc) {
		return rc;
	}

	return libfdt_parse_devtree(&fdt, root, "\0", NULL);
}
Esempio n. 9
0
int arch_devtree_reserve_count(u32 *count)
{
	int rc = VMM_OK;
	struct fdt_fileinfo fdt;

	rc = libfdt_parse_fileinfo((virtual_addr_t)&dt_blob_start, &fdt);
	if (rc) {
		return rc;
	}

	*count = libfdt_reserve_count(&fdt);

	return VMM_OK;
}
Esempio n. 10
0
int arch_devtree_reserve_size(u32 index, physical_size_t *size)
{
	u64 tmp;
	int rc = VMM_OK;
	struct fdt_fileinfo fdt;

	rc = libfdt_parse_fileinfo((virtual_addr_t)&dt_blob_start, &fdt);
	if (rc) {
		return rc;
	}

	rc = libfdt_reserve_size(&fdt, index, &tmp);
	if (rc) {
		return rc;
	}

	*size = (physical_size_t)tmp;

	return VMM_OK;
}
Esempio n. 11
0
int arch_devtree_ram_bank_setup(void)
{
	int rc = VMM_OK;
	physical_addr_t tmp;
	struct match_info info;
	struct fdt_fileinfo fdt;
	struct fdt_node_header *fdt_root;
	struct fdt_node_header *fdt_node;
	u32 i, j, address_cells, size_cells;

	address_cells = sizeof(physical_addr_t) / sizeof(fdt_cell_t);
	size_cells = sizeof(physical_size_t) / sizeof(fdt_cell_t);

	rc = libfdt_parse_fileinfo((virtual_addr_t)&dt_blob_start, &fdt);
	if (rc) {
		return rc;
	}

	fdt_root = libfdt_find_node(&fdt,
				    VMM_DEVTREE_PATH_SEPARATOR_STRING);
	if (!fdt_root) {
		return VMM_EFAIL;
	}

	rc = libfdt_get_property(&fdt, fdt_root, address_cells, size_cells,
				 VMM_DEVTREE_ADDR_CELLS_ATTR_NAME,
				 &i, sizeof(i));
	if (!rc) {
		address_cells = i;
	}

	rc = libfdt_get_property(&fdt, fdt_root, address_cells, size_cells,
				 VMM_DEVTREE_SIZE_CELLS_ATTR_NAME,
				 &i, sizeof(i));
	if (!rc) {
		size_cells = i;
	}

	info.fdt = &fdt;
	info.address_cells = address_cells;
	info.size_cells = size_cells;
	fdt_node = libfdt_find_matching_node(&fdt, match_memory_node, &info);
	if (!fdt_node) {
		return VMM_EFAIL;
	}

	rc = libfdt_get_property(&fdt, fdt_node, address_cells, size_cells,
				 VMM_DEVTREE_ADDR_CELLS_ATTR_NAME,
				 &i, sizeof(i));
	if (!rc) {
		address_cells = i;
	}

	rc = libfdt_get_property(&fdt, fdt_node, address_cells, size_cells,
				 VMM_DEVTREE_SIZE_CELLS_ATTR_NAME,
				 &i, sizeof(i));
	if (!rc) {
		size_cells = i;
	}

	memset(bank_data, 0, sizeof(bank_data));
	memset(dt_bank_data, 0, sizeof(dt_bank_data));

	rc = libfdt_get_property(&fdt, fdt_node, address_cells, size_cells,
				 VMM_DEVTREE_REG_ATTR_NAME,
				 dt_bank_data, sizeof(dt_bank_data));
	if (rc) {
		return rc;
	}

	/* Remove Zero sized banks */
	for (i = 0, j = 0 ; i < array_size(dt_bank_data); i += 2) {
		if (dt_bank_data[i + 1]) {
			bank_data[j] = dt_bank_data[i];
			bank_data[j + 1] = dt_bank_data[i + 1];
			j += 2;
		}
	}

	/* Count of RAM banks */
	bank_nr = 0;
	for (i = 0; i < array_size(bank_data); i += 2) {
		if (bank_data[i+1]) {
			bank_nr++;
		} else {
			break;
		}
	}
	if (!bank_nr) {
		return VMM_OK;
	}

	/* Sort banks based on start address */
	for (i = 0; i < (bank_nr - 1); i++) {
		for (j = i+1; j < bank_nr; j++) {
			if (bank_data[(2*i)] > bank_data[(2*j)]) {
				tmp = bank_data[(2*i)];
				bank_data[(2*i)] = bank_data[(2*j)];
				bank_data[(2*j)] = tmp;
				tmp = bank_data[(2*i)+1];
				bank_data[(2*i)+1] = bank_data[(2*j)+1];
				bank_data[(2*j)+1] = tmp;
			}
		}
	}

	/*
	 * For quite a few RISC-V systems, the RUNTIME M-mode firmware
	 * is located at start of a RAM bank. Unfortunately in most cases,
	 * the DTB passed to Xvisor (or Linux) does not have memreserve
	 * entry for the RUNTIME M-mode firmware. To be safe, we reserve
	 * RAM from start of the RAM bank to location where Xvisor is
	 * loaded in the RAM bank.
	 */
	load_bank_nr = 0;
	load_bank_resv_pa = 0;
	load_bank_resv_sz = 0;
	for (i = 0; i < bank_nr; i++) {
		if (bank_data[2*i] <= arch_code_paddr_start() &&
		    arch_code_paddr_start() < (bank_data[2*i] + bank_data[2*i + 1])) {
			load_bank_nr = i;
			load_bank_resv_pa = bank_data[2*i];
			load_bank_resv_sz = arch_code_paddr_start() - bank_data[2*i];
			break;
		}
	}

	return VMM_OK;
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
int arch_devtree_ram_start(physical_addr_t *addr)
{
	int rc = VMM_OK;
	struct fdt_fileinfo fdt;
	struct fdt_node_header *fdt_root;
	struct fdt_node_header *fdt_node;
	u32 tmp, address_cells, size_cells;
	physical_addr_t data[2];

	address_cells = sizeof(physical_addr_t) / sizeof(fdt_cell_t);
	size_cells = sizeof(physical_size_t) / sizeof(fdt_cell_t);

	rc = libfdt_parse_fileinfo((virtual_addr_t)&dt_blob_start, &fdt);
	if (rc) {
		return rc;
	}

	fdt_root = libfdt_find_node(&fdt,
				    VMM_DEVTREE_PATH_SEPARATOR_STRING);
	if (!fdt_root) {
		return VMM_EFAIL;
	}

	rc = libfdt_get_property(&fdt, fdt_root, address_cells, size_cells,
				 VMM_DEVTREE_ADDR_CELLS_ATTR_NAME,
				 &tmp, sizeof(tmp));
	if (!rc) {
		address_cells = tmp;
	}

	rc = libfdt_get_property(&fdt, fdt_root, address_cells, size_cells,
				 VMM_DEVTREE_SIZE_CELLS_ATTR_NAME,
				 &tmp, sizeof(tmp));
	if (!rc) {
		size_cells = tmp;
	}

	fdt_node = libfdt_find_node(&fdt,
				    VMM_DEVTREE_PATH_SEPARATOR_STRING
				    VMM_DEVTREE_MEMORY_NODE_NAME);
	if (!fdt_node) {
		return VMM_EFAIL;
	}

	rc = libfdt_get_property(&fdt, fdt_node, address_cells, size_cells,
				 VMM_DEVTREE_ADDR_CELLS_ATTR_NAME,
				 &tmp, sizeof(tmp));
	if (!rc) {
		address_cells = tmp;
	}

	rc = libfdt_get_property(&fdt, fdt_node, address_cells, size_cells,
				 VMM_DEVTREE_SIZE_CELLS_ATTR_NAME,
				 &tmp, sizeof(tmp));
	if (!rc) {
		size_cells = tmp;
	}

	rc = libfdt_get_property(&fdt, fdt_node, address_cells, size_cells,
				 VMM_DEVTREE_REG_ATTR_NAME,
				 data, sizeof(data));
	if (rc) {
		return rc;
	}

	*addr = data[0];

	return VMM_OK;
}