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; }
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; }
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; }
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; }
static int match_memory_node(struct fdt_node_header *fdt_node, int level, void *priv) { int rc; char dev_type[16]; struct match_info *info = priv; if (level == 1) { rc = libfdt_get_property(info->fdt, fdt_node, info->address_cells, info->size_cells, VMM_DEVTREE_DEVICE_TYPE_ATTR_NAME, dev_type, sizeof(dev_type)); if (rc) { return 0; } if (!strncmp(dev_type, "memory", sizeof(dev_type))) { return 1; } } return 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; }
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; }