17c9aac00SAnup Patel #include "kvm/devices.h" 27c9aac00SAnup Patel #include "kvm/fdt.h" 37c9aac00SAnup Patel #include "kvm/kvm.h" 47c9aac00SAnup Patel #include "kvm/kvm-cpu.h" 57c9aac00SAnup Patel 67c9aac00SAnup Patel #include <stdbool.h> 77c9aac00SAnup Patel 87c9aac00SAnup Patel #include <linux/byteorder.h> 97c9aac00SAnup Patel #include <linux/kernel.h> 107c9aac00SAnup Patel #include <linux/sizes.h> 117c9aac00SAnup Patel 128aff29e1SAtish Patra struct isa_ext_info { 138aff29e1SAtish Patra const char *name; 148aff29e1SAtish Patra unsigned long ext_id; 158aff29e1SAtish Patra }; 168aff29e1SAtish Patra 178aff29e1SAtish Patra struct isa_ext_info isa_info_arr[] = { 18b346fabeSAnup Patel /* sorted alphabetically */ 198d02d5a8SAnup Patel {"smstateen", KVM_RISCV_ISA_EXT_SMSTATEEN}, 208659200fSAnup Patel {"ssaia", KVM_RISCV_ISA_EXT_SSAIA}, 213c07aeafSAtish Patra {"sstc", KVM_RISCV_ISA_EXT_SSTC}, 22ac16e943SAnup Patel {"svinval", KVM_RISCV_ISA_EXT_SVINVAL}, 2356e2d678SAnup Patel {"svnapot", KVM_RISCV_ISA_EXT_SVNAPOT}, 24b346fabeSAnup Patel {"svpbmt", KVM_RISCV_ISA_EXT_SVPBMT}, 256331850dSAnup Patel {"zba", KVM_RISCV_ISA_EXT_ZBA}, 268c1584e7SAnup Patel {"zbb", KVM_RISCV_ISA_EXT_ZBB}, 278b4cc705SAnup Patel {"zbc", KVM_RISCV_ISA_EXT_ZBC}, 28d9052a96SAnup Patel {"zbkb", KVM_RISCV_ISA_EXT_ZBKB}, 29d9052a96SAnup Patel {"zbkc", KVM_RISCV_ISA_EXT_ZBKC}, 30d9052a96SAnup Patel {"zbkx", KVM_RISCV_ISA_EXT_ZBKX}, 316331850dSAnup Patel {"zbs", KVM_RISCV_ISA_EXT_ZBS}, 32*9cf213d6SAnup Patel {"zfa", KVM_RISCV_ISA_EXT_ZFA}, 33bd7f13c1SAnup Patel {"zfh", KVM_RISCV_ISA_EXT_ZFH}, 34bd7f13c1SAnup Patel {"zfhmin", KVM_RISCV_ISA_EXT_ZFHMIN}, 35798398f4SAndrew Jones {"zicbom", KVM_RISCV_ISA_EXT_ZICBOM}, 368f1e47caSAndrew Jones {"zicboz", KVM_RISCV_ISA_EXT_ZICBOZ}, 3766768569SAnup Patel {"zicntr", KVM_RISCV_ISA_EXT_ZICNTR}, 388cd71ca5SAnup Patel {"zicond", KVM_RISCV_ISA_EXT_ZICOND}, 3934366849SAnup Patel {"zicsr", KVM_RISCV_ISA_EXT_ZICSR}, 4034366849SAnup Patel {"zifencei", KVM_RISCV_ISA_EXT_ZIFENCEI}, 41fce28652SAnup Patel {"zihintntl", KVM_RISCV_ISA_EXT_ZIHINTNTL}, 42b346fabeSAnup Patel {"zihintpause", KVM_RISCV_ISA_EXT_ZIHINTPAUSE}, 4366768569SAnup Patel {"zihpm", KVM_RISCV_ISA_EXT_ZIHPM}, 44d9052a96SAnup Patel {"zknd", KVM_RISCV_ISA_EXT_ZKND}, 45d9052a96SAnup Patel {"zkne", KVM_RISCV_ISA_EXT_ZKNE}, 46d9052a96SAnup Patel {"zknh", KVM_RISCV_ISA_EXT_ZKNH}, 47d9052a96SAnup Patel {"zkr", KVM_RISCV_ISA_EXT_ZKR}, 48d9052a96SAnup Patel {"zksed", KVM_RISCV_ISA_EXT_ZKSED}, 49d9052a96SAnup Patel {"zksh", KVM_RISCV_ISA_EXT_ZKSH}, 50d9052a96SAnup Patel {"zkt", KVM_RISCV_ISA_EXT_ZKT}, 5165b58f72SAnup Patel {"zvbb", KVM_RISCV_ISA_EXT_ZVBB}, 5265b58f72SAnup Patel {"zvbc", KVM_RISCV_ISA_EXT_ZVBC}, 535a64c1eaSAnup Patel {"zvfh", KVM_RISCV_ISA_EXT_ZVFH}, 545a64c1eaSAnup Patel {"zvfhmin", KVM_RISCV_ISA_EXT_ZVFHMIN}, 5565b58f72SAnup Patel {"zvkb", KVM_RISCV_ISA_EXT_ZVKB}, 5665b58f72SAnup Patel {"zvkg", KVM_RISCV_ISA_EXT_ZVKG}, 5765b58f72SAnup Patel {"zvkned", KVM_RISCV_ISA_EXT_ZVKNED}, 5865b58f72SAnup Patel {"zvknha", KVM_RISCV_ISA_EXT_ZVKNHA}, 5965b58f72SAnup Patel {"zvknhb", KVM_RISCV_ISA_EXT_ZVKNHB}, 6065b58f72SAnup Patel {"zvksed", KVM_RISCV_ISA_EXT_ZVKSED}, 6165b58f72SAnup Patel {"zvksh", KVM_RISCV_ISA_EXT_ZVKSH}, 6265b58f72SAnup Patel {"zvkt", KVM_RISCV_ISA_EXT_ZVKT}, 638aff29e1SAtish Patra }; 648aff29e1SAtish Patra 657c9aac00SAnup Patel static void dump_fdt(const char *dtb_file, void *fdt) 667c9aac00SAnup Patel { 677c9aac00SAnup Patel int count, fd; 687c9aac00SAnup Patel 697c9aac00SAnup Patel fd = open(dtb_file, O_CREAT | O_TRUNC | O_RDWR, 0666); 707c9aac00SAnup Patel if (fd < 0) 717c9aac00SAnup Patel die("Failed to write dtb to %s", dtb_file); 727c9aac00SAnup Patel 737c9aac00SAnup Patel count = write(fd, fdt, FDT_MAX_SIZE); 747c9aac00SAnup Patel if (count < 0) 757c9aac00SAnup Patel die_perror("Failed to dump dtb"); 767c9aac00SAnup Patel 777c9aac00SAnup Patel pr_debug("Wrote %d bytes to dtb %s", count, dtb_file); 787c9aac00SAnup Patel close(fd); 797c9aac00SAnup Patel } 807c9aac00SAnup Patel 817c9aac00SAnup Patel #define CPU_NAME_MAX_LEN 15 827c9aac00SAnup Patel static void generate_cpu_nodes(void *fdt, struct kvm *kvm) 837c9aac00SAnup Patel { 847c9aac00SAnup Patel int cpu, pos, i, index, valid_isa_len; 857c9aac00SAnup Patel const char *valid_isa_order = "IEMAFDQCLBJTPVNSUHKORWXYZG"; 868aff29e1SAtish Patra int arr_sz = ARRAY_SIZE(isa_info_arr); 87ef89838eSAnup Patel unsigned long cbom_blksz = 0, cboz_blksz = 0, satp_mode = 0; 887c9aac00SAnup Patel 897c9aac00SAnup Patel _FDT(fdt_begin_node(fdt, "cpus")); 907c9aac00SAnup Patel _FDT(fdt_property_cell(fdt, "#address-cells", 0x1)); 917c9aac00SAnup Patel _FDT(fdt_property_cell(fdt, "#size-cells", 0x0)); 927c9aac00SAnup Patel _FDT(fdt_property_cell(fdt, "timebase-frequency", 937c9aac00SAnup Patel kvm->cpus[0]->riscv_timebase)); 947c9aac00SAnup Patel 957c9aac00SAnup Patel for (cpu = 0; cpu < kvm->nrcpus; ++cpu) { 967c9aac00SAnup Patel char cpu_name[CPU_NAME_MAX_LEN]; 977887b398SAnup Patel #define CPU_ISA_MAX_LEN (ARRAY_SIZE(isa_info_arr) * 16) 987c9aac00SAnup Patel char cpu_isa[CPU_ISA_MAX_LEN]; 997c9aac00SAnup Patel struct kvm_cpu *vcpu = kvm->cpus[cpu]; 1008aff29e1SAtish Patra struct kvm_one_reg reg; 1018aff29e1SAtish Patra unsigned long isa_ext_out = 0; 1027c9aac00SAnup Patel 1037c9aac00SAnup Patel snprintf(cpu_name, CPU_NAME_MAX_LEN, "cpu@%x", cpu); 1047c9aac00SAnup Patel 1057c9aac00SAnup Patel snprintf(cpu_isa, CPU_ISA_MAX_LEN, "rv%ld", vcpu->riscv_xlen); 1067c9aac00SAnup Patel pos = strlen(cpu_isa); 1077c9aac00SAnup Patel valid_isa_len = strlen(valid_isa_order); 1087c9aac00SAnup Patel for (i = 0; i < valid_isa_len; i++) { 1097c9aac00SAnup Patel index = valid_isa_order[i] - 'A'; 1107c9aac00SAnup Patel if (vcpu->riscv_isa & (1 << (index))) 1117c9aac00SAnup Patel cpu_isa[pos++] = 'a' + index; 1127c9aac00SAnup Patel } 1138aff29e1SAtish Patra 1148aff29e1SAtish Patra for (i = 0; i < arr_sz; i++) { 1158aff29e1SAtish Patra reg.id = RISCV_ISA_EXT_REG(isa_info_arr[i].ext_id); 1168aff29e1SAtish Patra reg.addr = (unsigned long)&isa_ext_out; 1178aff29e1SAtish Patra if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 1188aff29e1SAtish Patra continue; 1198aff29e1SAtish Patra if (!isa_ext_out) 1208aff29e1SAtish Patra /* This extension is not available in hardware */ 1218aff29e1SAtish Patra continue; 1228aff29e1SAtish Patra 123e17d182aSAnup Patel if (kvm->cfg.arch.ext_disabled[isa_info_arr[i].ext_id]) { 124e17d182aSAnup Patel isa_ext_out = 0; 125e17d182aSAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 126e17d182aSAnup Patel pr_warning("Failed to disable %s ISA exension\n", 127e17d182aSAnup Patel isa_info_arr[i].name); 128e17d182aSAnup Patel continue; 129e17d182aSAnup Patel } 130e17d182aSAnup Patel 131798398f4SAndrew Jones if (isa_info_arr[i].ext_id == KVM_RISCV_ISA_EXT_ZICBOM && !cbom_blksz) { 132798398f4SAndrew Jones reg.id = RISCV_CONFIG_REG(zicbom_block_size); 133798398f4SAndrew Jones reg.addr = (unsigned long)&cbom_blksz; 134798398f4SAndrew Jones if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 135798398f4SAndrew Jones die("KVM_GET_ONE_REG failed (config.zicbom_block_size)"); 136798398f4SAndrew Jones } 137798398f4SAndrew Jones 1388f1e47caSAndrew Jones if (isa_info_arr[i].ext_id == KVM_RISCV_ISA_EXT_ZICBOZ && !cboz_blksz) { 1398f1e47caSAndrew Jones reg.id = RISCV_CONFIG_REG(zicboz_block_size); 1408f1e47caSAndrew Jones reg.addr = (unsigned long)&cboz_blksz; 1418f1e47caSAndrew Jones if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 1428f1e47caSAndrew Jones die("KVM_GET_ONE_REG failed (config.zicboz_block_size)"); 1438f1e47caSAndrew Jones } 1448f1e47caSAndrew Jones 1458aff29e1SAtish Patra if ((strlen(isa_info_arr[i].name) + pos + 1) >= CPU_ISA_MAX_LEN) { 146fcb07675SAnup Patel pr_warning("Insufficient space to append ISA exension %s\n", 147fcb07675SAnup Patel isa_info_arr[i].name); 1488aff29e1SAtish Patra break; 1498aff29e1SAtish Patra } 1508aff29e1SAtish Patra pos += snprintf(cpu_isa + pos, CPU_ISA_MAX_LEN, "_%s", 1518aff29e1SAtish Patra isa_info_arr[i].name); 1528aff29e1SAtish Patra } 1537c9aac00SAnup Patel cpu_isa[pos] = '\0'; 1547c9aac00SAnup Patel 155ef89838eSAnup Patel reg.id = RISCV_CONFIG_REG(satp_mode); 156ef89838eSAnup Patel reg.addr = (unsigned long)&satp_mode; 157ef89838eSAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 158ef89838eSAnup Patel satp_mode = (vcpu->riscv_xlen == 64) ? 8 : 1; 159ef89838eSAnup Patel 1607c9aac00SAnup Patel _FDT(fdt_begin_node(fdt, cpu_name)); 1617c9aac00SAnup Patel _FDT(fdt_property_string(fdt, "device_type", "cpu")); 1627c9aac00SAnup Patel _FDT(fdt_property_string(fdt, "compatible", "riscv")); 163ef89838eSAnup Patel if (vcpu->riscv_xlen == 64) { 164ef89838eSAnup Patel switch (satp_mode) { 165ef89838eSAnup Patel case 10: 166ef89838eSAnup Patel _FDT(fdt_property_string(fdt, "mmu-type", 167ef89838eSAnup Patel "riscv,sv57")); 168ef89838eSAnup Patel break; 169ef89838eSAnup Patel case 9: 1707c9aac00SAnup Patel _FDT(fdt_property_string(fdt, "mmu-type", 1717c9aac00SAnup Patel "riscv,sv48")); 172ef89838eSAnup Patel break; 173ef89838eSAnup Patel case 8: 174ef89838eSAnup Patel _FDT(fdt_property_string(fdt, "mmu-type", 175ef89838eSAnup Patel "riscv,sv39")); 176ef89838eSAnup Patel break; 177ef89838eSAnup Patel default: 178ef89838eSAnup Patel _FDT(fdt_property_string(fdt, "mmu-type", 179ef89838eSAnup Patel "riscv,none")); 180ef89838eSAnup Patel break; 181ef89838eSAnup Patel } 182ef89838eSAnup Patel } else { 183ef89838eSAnup Patel switch (satp_mode) { 184ef89838eSAnup Patel case 1: 1857c9aac00SAnup Patel _FDT(fdt_property_string(fdt, "mmu-type", 1867c9aac00SAnup Patel "riscv,sv32")); 187ef89838eSAnup Patel break; 188ef89838eSAnup Patel default: 189ef89838eSAnup Patel _FDT(fdt_property_string(fdt, "mmu-type", 190ef89838eSAnup Patel "riscv,none")); 191ef89838eSAnup Patel break; 192ef89838eSAnup Patel } 193ef89838eSAnup Patel } 1947c9aac00SAnup Patel _FDT(fdt_property_string(fdt, "riscv,isa", cpu_isa)); 195798398f4SAndrew Jones if (cbom_blksz) 196798398f4SAndrew Jones _FDT(fdt_property_cell(fdt, "riscv,cbom-block-size", cbom_blksz)); 1978f1e47caSAndrew Jones if (cboz_blksz) 1988f1e47caSAndrew Jones _FDT(fdt_property_cell(fdt, "riscv,cboz-block-size", cboz_blksz)); 1997c9aac00SAnup Patel _FDT(fdt_property_cell(fdt, "reg", cpu)); 2007c9aac00SAnup Patel _FDT(fdt_property_string(fdt, "status", "okay")); 2017c9aac00SAnup Patel 2027c9aac00SAnup Patel _FDT(fdt_begin_node(fdt, "interrupt-controller")); 2037c9aac00SAnup Patel _FDT(fdt_property_string(fdt, "compatible", "riscv,cpu-intc")); 2047c9aac00SAnup Patel _FDT(fdt_property_cell(fdt, "#interrupt-cells", 1)); 2057c9aac00SAnup Patel _FDT(fdt_property(fdt, "interrupt-controller", NULL, 0)); 2067c9aac00SAnup Patel _FDT(fdt_property_cell(fdt, "phandle", 2077c9aac00SAnup Patel PHANDLE_CPU_INTC_BASE + cpu)); 2087c9aac00SAnup Patel _FDT(fdt_end_node(fdt)); 2097c9aac00SAnup Patel 2107c9aac00SAnup Patel _FDT(fdt_end_node(fdt)); 2117c9aac00SAnup Patel } 2127c9aac00SAnup Patel 2137c9aac00SAnup Patel _FDT(fdt_end_node(fdt)); 2147c9aac00SAnup Patel } 2157c9aac00SAnup Patel 2167c9aac00SAnup Patel static int setup_fdt(struct kvm *kvm) 2177c9aac00SAnup Patel { 2187c9aac00SAnup Patel struct device_header *dev_hdr; 2197c9aac00SAnup Patel u8 staging_fdt[FDT_MAX_SIZE]; 2207c9aac00SAnup Patel u64 mem_reg_prop[] = { 2217c9aac00SAnup Patel cpu_to_fdt64(kvm->arch.memory_guest_start), 2227c9aac00SAnup Patel cpu_to_fdt64(kvm->ram_size), 2237c9aac00SAnup Patel }; 224ed805be5SAnup Patel char *str; 2257c9aac00SAnup Patel void *fdt = staging_fdt; 2267c9aac00SAnup Patel void *fdt_dest = guest_flat_to_host(kvm, 2277c9aac00SAnup Patel kvm->arch.dtb_guest_start); 2287c9aac00SAnup Patel void (*generate_mmio_fdt_nodes)(void *, struct device_header *, 2297c9aac00SAnup Patel void (*)(void *, u8, enum irq_type)); 2307c9aac00SAnup Patel 2317c9aac00SAnup Patel /* Create new tree without a reserve map */ 2327c9aac00SAnup Patel _FDT(fdt_create(fdt, FDT_MAX_SIZE)); 2337c9aac00SAnup Patel _FDT(fdt_finish_reservemap(fdt)); 2347c9aac00SAnup Patel 2357c9aac00SAnup Patel /* Header */ 2367c9aac00SAnup Patel _FDT(fdt_begin_node(fdt, "")); 2377c9aac00SAnup Patel _FDT(fdt_property_string(fdt, "compatible", "linux,dummy-virt")); 2387c9aac00SAnup Patel _FDT(fdt_property_cell(fdt, "#address-cells", 0x2)); 2397c9aac00SAnup Patel _FDT(fdt_property_cell(fdt, "#size-cells", 0x2)); 2407c9aac00SAnup Patel 2417c9aac00SAnup Patel /* /chosen */ 2427c9aac00SAnup Patel _FDT(fdt_begin_node(fdt, "chosen")); 2437c9aac00SAnup Patel 2447c9aac00SAnup Patel /* Pass on our amended command line to a Linux kernel only. */ 2457c9aac00SAnup Patel if (kvm->cfg.firmware_filename) { 2467c9aac00SAnup Patel if (kvm->cfg.kernel_cmdline) 2477c9aac00SAnup Patel _FDT(fdt_property_string(fdt, "bootargs", 2487c9aac00SAnup Patel kvm->cfg.kernel_cmdline)); 2497c9aac00SAnup Patel } else 2507c9aac00SAnup Patel _FDT(fdt_property_string(fdt, "bootargs", 2517c9aac00SAnup Patel kvm->cfg.real_cmdline)); 2527c9aac00SAnup Patel 2537c9aac00SAnup Patel _FDT(fdt_property_string(fdt, "stdout-path", "serial0")); 2547c9aac00SAnup Patel 2557c9aac00SAnup Patel /* Initrd */ 2567c9aac00SAnup Patel if (kvm->arch.initrd_size != 0) { 2577c9aac00SAnup Patel u64 ird_st_prop = cpu_to_fdt64(kvm->arch.initrd_guest_start); 2587c9aac00SAnup Patel u64 ird_end_prop = cpu_to_fdt64(kvm->arch.initrd_guest_start + 2597c9aac00SAnup Patel kvm->arch.initrd_size); 2607c9aac00SAnup Patel 2617c9aac00SAnup Patel _FDT(fdt_property(fdt, "linux,initrd-start", 2627c9aac00SAnup Patel &ird_st_prop, sizeof(ird_st_prop))); 2637c9aac00SAnup Patel _FDT(fdt_property(fdt, "linux,initrd-end", 2647c9aac00SAnup Patel &ird_end_prop, sizeof(ird_end_prop))); 2657c9aac00SAnup Patel } 2667c9aac00SAnup Patel 2677c9aac00SAnup Patel _FDT(fdt_end_node(fdt)); 2687c9aac00SAnup Patel 2697c9aac00SAnup Patel /* Memory */ 2707c9aac00SAnup Patel _FDT(fdt_begin_node(fdt, "memory")); 2717c9aac00SAnup Patel _FDT(fdt_property_string(fdt, "device_type", "memory")); 2727c9aac00SAnup Patel _FDT(fdt_property(fdt, "reg", mem_reg_prop, sizeof(mem_reg_prop))); 2737c9aac00SAnup Patel _FDT(fdt_end_node(fdt)); 2747c9aac00SAnup Patel 2757c9aac00SAnup Patel /* CPUs */ 2767c9aac00SAnup Patel generate_cpu_nodes(fdt, kvm); 2777c9aac00SAnup Patel 2780dff3501SAnup Patel /* IRQCHIP */ 2790dff3501SAnup Patel if (!riscv_irqchip_generate_fdt_node) 2800dff3501SAnup Patel die("No way to generate IRQCHIP FDT node\n"); 2810dff3501SAnup Patel riscv_irqchip_generate_fdt_node(fdt, kvm); 2820dff3501SAnup Patel 2837c9aac00SAnup Patel /* Simple Bus */ 2847c9aac00SAnup Patel _FDT(fdt_begin_node(fdt, "smb")); 2857c9aac00SAnup Patel _FDT(fdt_property_string(fdt, "compatible", "simple-bus")); 2867c9aac00SAnup Patel _FDT(fdt_property_cell(fdt, "#address-cells", 0x2)); 2877c9aac00SAnup Patel _FDT(fdt_property_cell(fdt, "#size-cells", 0x2)); 2880dff3501SAnup Patel _FDT(fdt_property_cell(fdt, "interrupt-parent", 2890dff3501SAnup Patel riscv_irqchip_phandle)); 2907c9aac00SAnup Patel _FDT(fdt_property(fdt, "ranges", NULL, 0)); 2917c9aac00SAnup Patel 2927c9aac00SAnup Patel /* Virtio MMIO devices */ 2937c9aac00SAnup Patel dev_hdr = device__first_dev(DEVICE_BUS_MMIO); 2947c9aac00SAnup Patel while (dev_hdr) { 2957c9aac00SAnup Patel generate_mmio_fdt_nodes = dev_hdr->data; 2960dff3501SAnup Patel generate_mmio_fdt_nodes(fdt, dev_hdr, 2970dff3501SAnup Patel riscv__generate_irq_prop); 2987c9aac00SAnup Patel dev_hdr = device__next_dev(dev_hdr); 2997c9aac00SAnup Patel } 3007c9aac00SAnup Patel 3017c9aac00SAnup Patel /* IOPORT devices */ 3027c9aac00SAnup Patel dev_hdr = device__first_dev(DEVICE_BUS_IOPORT); 3037c9aac00SAnup Patel while (dev_hdr) { 3047c9aac00SAnup Patel generate_mmio_fdt_nodes = dev_hdr->data; 3050dff3501SAnup Patel generate_mmio_fdt_nodes(fdt, dev_hdr, 3060dff3501SAnup Patel riscv__generate_irq_prop); 3077c9aac00SAnup Patel dev_hdr = device__next_dev(dev_hdr); 3087c9aac00SAnup Patel } 3097c9aac00SAnup Patel 310cdd7d8ccSAnup Patel /* PCI host controller */ 311cdd7d8ccSAnup Patel pci__generate_fdt_nodes(fdt); 312cdd7d8ccSAnup Patel 3137c9aac00SAnup Patel _FDT(fdt_end_node(fdt)); 3147c9aac00SAnup Patel 3157c9aac00SAnup Patel if (fdt_stdout_path) { 316ed805be5SAnup Patel str = malloc(strlen(fdt_stdout_path) + strlen("/smb") + 1); 317ed805be5SAnup Patel sprintf(str, "/smb%s", fdt_stdout_path); 3187c9aac00SAnup Patel free(fdt_stdout_path); 3197c9aac00SAnup Patel fdt_stdout_path = NULL; 320ed805be5SAnup Patel 321ed805be5SAnup Patel _FDT(fdt_begin_node(fdt, "aliases")); 322ed805be5SAnup Patel _FDT(fdt_property_string(fdt, "serial0", str)); 323ed805be5SAnup Patel _FDT(fdt_end_node(fdt)); 324ed805be5SAnup Patel free(str); 3257c9aac00SAnup Patel } 3267c9aac00SAnup Patel 3277c9aac00SAnup Patel /* Finalise. */ 3287c9aac00SAnup Patel _FDT(fdt_end_node(fdt)); 3297c9aac00SAnup Patel _FDT(fdt_finish(fdt)); 3307c9aac00SAnup Patel 3317c9aac00SAnup Patel _FDT(fdt_open_into(fdt, fdt_dest, FDT_MAX_SIZE)); 3327c9aac00SAnup Patel _FDT(fdt_pack(fdt_dest)); 3337c9aac00SAnup Patel 3347c9aac00SAnup Patel if (kvm->cfg.arch.dump_dtb_filename) 3357c9aac00SAnup Patel dump_fdt(kvm->cfg.arch.dump_dtb_filename, fdt_dest); 3367c9aac00SAnup Patel return 0; 3377c9aac00SAnup Patel } 3387c9aac00SAnup Patel late_init(setup_fdt); 339