@@ -12,6 +12,7 @@
#include <console.h>
#include <chip.h>
#include <libstb/container.h>
+#include <libfdt/libfdt.h>
static struct dt_node *uv_fw_node;
static uint64_t uv_base_addr;
@@ -115,9 +116,27 @@ static int uv_decompress_image(void)
return OPAL_SUCCESS;
}
+static int create_dtb_uv(void *uv_fdt)
+{
+ if (fdt_create(uv_fdt, UV_FDT_MAX_SIZE)) {
+ prerror("UV: Failed to create uv_fdt\n");
+ return OPAL_NO_MEM;
+ }
+
+ fdt_finish_reservemap(uv_fdt);
+ fdt_begin_node(uv_fdt, "");
+ fdt_property_string(uv_fdt, "description", "Ultravisor fdt");
+ fdt_begin_node(uv_fdt, "ibm,uv-fdt");
+ fdt_property_string(uv_fdt, "compatible", "ibm,uv-fdt");
+ fdt_end_node(uv_fdt);
+ fdt_finish(uv_fdt);
+
+ return OPAL_SUCCESS;
+}
+
void init_uv()
{
- uint64_t uv_dt_src, uv_fw_sz;
+ uint64_t uv_dt_src, uv_fw_sz, uv_fdt_addr;
int ret;
if (!is_msr_bit_set(MSR_S)) {
@@ -131,6 +150,8 @@ void init_uv()
goto err;
}
+ uv_base_addr = dt_get_address(uv_fw_node, 0, &uv_fw_sz);
+
ret = uv_decompress_image();
if (ret) {
if (!dt_find_property(uv_fw_node, "uv-src-address")) {
@@ -149,6 +170,10 @@ void init_uv()
dt_add_property_u64(uv_fw_node, "memcons", (u64)&uv_memcons);
debug_descriptor.uv_memcons_phys = (u64)&uv_memcons;
+
+ uv_fdt_addr = uv_base_addr + UV_LOAD_MAX_SIZE;
+ create_dtb_uv((void *)uv_fdt_addr);
+ dt_add_property_u64(uv_fw_node, "uv-fdt", uv_fdt_addr);
err:
local_free(uv_image);
}
@@ -14,6 +14,7 @@
#define UCALL_BUFSIZE 4
#define UV_READ_SCOM 0xF114
#define UV_WRITE_SCOM 0xF118
+#define UV_FDT_MAX_SIZE 0x100000
extern long ucall(unsigned long opcode, unsigned long *retbuf, ...);
extern int start_uv(uint64_t entry, void *fdt);