@@ -365,26 +365,35 @@ static void create_fdt(LoongArchVirtMachineState *lvms)
365
365
static void fdt_add_cpu_nodes (const LoongArchVirtMachineState * lvms )
366
366
{
367
367
int num ;
368
- const MachineState * ms = MACHINE (lvms );
369
- int smp_cpus = ms -> smp .cpus ;
368
+ MachineState * ms = MACHINE (lvms );
369
+ MachineClass * mc = MACHINE_GET_CLASS (ms );
370
+ const CPUArchIdList * possible_cpus ;
371
+ LoongArchCPU * cpu ;
372
+ CPUState * cs ;
373
+ char * nodename , * map_path ;
370
374
371
375
qemu_fdt_add_subnode (ms -> fdt , "/cpus" );
372
376
qemu_fdt_setprop_cell (ms -> fdt , "/cpus" , "#address-cells" , 0x1 );
373
377
qemu_fdt_setprop_cell (ms -> fdt , "/cpus" , "#size-cells" , 0x0 );
374
378
375
379
/* cpu nodes */
376
- for (num = smp_cpus - 1 ; num >= 0 ; num -- ) {
377
- char * nodename = g_strdup_printf ("/cpus/cpu@%d" , num );
378
- LoongArchCPU * cpu = LOONGARCH_CPU (qemu_get_cpu (num ));
379
- CPUState * cs = CPU (cpu );
380
+ possible_cpus = mc -> possible_cpu_arch_ids (ms );
381
+ for (num = 0 ; num < possible_cpus -> len ; num ++ ) {
382
+ cs = possible_cpus -> cpus [num ].cpu ;
383
+ if (cs == NULL ) {
384
+ continue ;
385
+ }
386
+
387
+ nodename = g_strdup_printf ("/cpus/cpu@%d" , num );
388
+ cpu = LOONGARCH_CPU (cs );
380
389
381
390
qemu_fdt_add_subnode (ms -> fdt , nodename );
382
391
qemu_fdt_setprop_string (ms -> fdt , nodename , "device_type" , "cpu" );
383
392
qemu_fdt_setprop_string (ms -> fdt , nodename , "compatible" ,
384
393
cpu -> dtb_compatible );
385
- if (ms -> possible_cpus -> cpus [cs -> cpu_index ].props .has_node_id ) {
394
+ if (possible_cpus -> cpus [num ].props .has_node_id ) {
386
395
qemu_fdt_setprop_cell (ms -> fdt , nodename , "numa-node-id" ,
387
- ms -> possible_cpus -> cpus [cs -> cpu_index ].props .node_id );
396
+ possible_cpus -> cpus [num ].props .node_id );
388
397
}
389
398
qemu_fdt_setprop_cell (ms -> fdt , nodename , "reg" , num );
390
399
qemu_fdt_setprop_cell (ms -> fdt , nodename , "phandle" ,
@@ -394,11 +403,13 @@ static void fdt_add_cpu_nodes(const LoongArchVirtMachineState *lvms)
394
403
395
404
/*cpu map */
396
405
qemu_fdt_add_subnode (ms -> fdt , "/cpus/cpu-map" );
406
+ for (num = 0 ; num < possible_cpus -> len ; num ++ ) {
407
+ cs = possible_cpus -> cpus [num ].cpu ;
408
+ if (cs == NULL ) {
409
+ continue ;
410
+ }
397
411
398
- for (num = smp_cpus - 1 ; num >= 0 ; num -- ) {
399
- char * cpu_path = g_strdup_printf ("/cpus/cpu@%d" , num );
400
- char * map_path ;
401
-
412
+ nodename = g_strdup_printf ("/cpus/cpu@%d" , num );
402
413
if (ms -> smp .threads > 1 ) {
403
414
map_path = g_strdup_printf (
404
415
"/cpus/cpu-map/socket%d/core%d/thread%d" ,
@@ -412,10 +423,10 @@ static void fdt_add_cpu_nodes(const LoongArchVirtMachineState *lvms)
412
423
num % ms -> smp .cores );
413
424
}
414
425
qemu_fdt_add_path (ms -> fdt , map_path );
415
- qemu_fdt_setprop_phandle (ms -> fdt , map_path , "cpu" , cpu_path );
426
+ qemu_fdt_setprop_phandle (ms -> fdt , map_path , "cpu" , nodename );
416
427
417
428
g_free (map_path );
418
- g_free (cpu_path );
429
+ g_free (nodename );
419
430
}
420
431
}
421
432
@@ -615,12 +626,67 @@ static void virt_build_smbios(LoongArchVirtMachineState *lvms)
615
626
}
616
627
}
617
628
629
+ static void virt_fdt_setup (LoongArchVirtMachineState * lvms )
630
+ {
631
+ MachineState * machine = MACHINE (lvms );
632
+ uint32_t cpuintc_phandle , eiointc_phandle , pch_pic_phandle , pch_msi_phandle ;
633
+ int i ;
634
+
635
+ create_fdt (lvms );
636
+ fdt_add_cpu_nodes (lvms );
637
+ fdt_add_memory_nodes (machine );
638
+ fdt_add_fw_cfg_node (lvms );
639
+ fdt_add_flash_node (lvms );
640
+
641
+ /* Add cpu interrupt-controller */
642
+ fdt_add_cpuic_node (lvms , & cpuintc_phandle );
643
+ /* Add Extend I/O Interrupt Controller node */
644
+ fdt_add_eiointc_node (lvms , & cpuintc_phandle , & eiointc_phandle );
645
+ /* Add PCH PIC node */
646
+ fdt_add_pch_pic_node (lvms , & eiointc_phandle , & pch_pic_phandle );
647
+ /* Add PCH MSI node */
648
+ fdt_add_pch_msi_node (lvms , & eiointc_phandle , & pch_msi_phandle );
649
+ /* Add pcie node */
650
+ fdt_add_pcie_node (lvms , & pch_pic_phandle , & pch_msi_phandle );
651
+
652
+ /*
653
+ * Create uart fdt node in reverse order so that they appear
654
+ * in the finished device tree lowest address first
655
+ */
656
+ for (i = VIRT_UART_COUNT ; i -- > 0 ;) {
657
+ hwaddr base = VIRT_UART_BASE + i * VIRT_UART_SIZE ;
658
+ int irq = VIRT_UART_IRQ + i - VIRT_GSI_BASE ;
659
+ fdt_add_uart_node (lvms , & pch_pic_phandle , base , irq , i == 0 );
660
+ }
661
+
662
+ fdt_add_rtc_node (lvms , & pch_pic_phandle );
663
+ fdt_add_ged_reset (lvms );
664
+ platform_bus_add_all_fdt_nodes (machine -> fdt , "/platic" ,
665
+ VIRT_PLATFORM_BUS_BASEADDRESS ,
666
+ VIRT_PLATFORM_BUS_SIZE ,
667
+ VIRT_PLATFORM_BUS_IRQ );
668
+
669
+ /*
670
+ * Since lowmem region starts from 0 and Linux kernel legacy start address
671
+ * at 2 MiB, FDT base address is located at 1 MiB to avoid NULL pointer
672
+ * access. FDT size limit with 1 MiB.
673
+ * Put the FDT into the memory map as a ROM image: this will ensure
674
+ * the FDT is copied again upon reset, even if addr points into RAM.
675
+ */
676
+ qemu_fdt_dumpdtb (machine -> fdt , lvms -> fdt_size );
677
+ rom_add_blob_fixed_as ("fdt" , machine -> fdt , lvms -> fdt_size , FDT_BASE ,
678
+ & address_space_memory );
679
+ qemu_register_reset_nosnapshotload (qemu_fdt_randomize_seeds ,
680
+ rom_ptr_for_as (& address_space_memory , FDT_BASE , lvms -> fdt_size ));
681
+ }
682
+
618
683
static void virt_done (Notifier * notifier , void * data )
619
684
{
620
685
LoongArchVirtMachineState * lvms = container_of (notifier ,
621
686
LoongArchVirtMachineState , machine_done );
622
687
virt_build_smbios (lvms );
623
688
loongarch_acpi_setup (lvms );
689
+ virt_fdt_setup (lvms );
624
690
}
625
691
626
692
static void virt_powerdown_req (Notifier * notifier , void * opaque )
@@ -699,9 +765,7 @@ static DeviceState *create_platform_bus(DeviceState *pch_pic)
699
765
}
700
766
701
767
static void virt_devices_init (DeviceState * pch_pic ,
702
- LoongArchVirtMachineState * lvms ,
703
- uint32_t * pch_pic_phandle ,
704
- uint32_t * pch_msi_phandle )
768
+ LoongArchVirtMachineState * lvms )
705
769
{
706
770
MachineClass * mc = MACHINE_GET_CLASS (lvms );
707
771
DeviceState * gpex_dev ;
@@ -747,9 +811,6 @@ static void virt_devices_init(DeviceState *pch_pic,
747
811
gpex_set_irq_num (GPEX_HOST (gpex_dev ), i , 16 + i );
748
812
}
749
813
750
- /* Add pcie node */
751
- fdt_add_pcie_node (lvms , pch_pic_phandle , pch_msi_phandle );
752
-
753
814
/*
754
815
* Create uart fdt node in reverse order so that they appear
755
816
* in the finished device tree lowest address first
@@ -760,7 +821,6 @@ static void virt_devices_init(DeviceState *pch_pic,
760
821
serial_mm_init (get_system_memory (), base , 0 ,
761
822
qdev_get_gpio_in (pch_pic , irq ),
762
823
115200 , serial_hd (i ), DEVICE_LITTLE_ENDIAN );
763
- fdt_add_uart_node (lvms , pch_pic_phandle , base , irq , i == 0 );
764
824
}
765
825
766
826
/* Network init */
@@ -774,8 +834,6 @@ static void virt_devices_init(DeviceState *pch_pic,
774
834
sysbus_create_simple ("ls7a_rtc" , VIRT_RTC_REG_BASE ,
775
835
qdev_get_gpio_in (pch_pic ,
776
836
VIRT_RTC_IRQ - VIRT_GSI_BASE ));
777
- fdt_add_rtc_node (lvms , pch_pic_phandle );
778
- fdt_add_ged_reset (lvms );
779
837
780
838
/* acpi ged */
781
839
lvms -> acpi_ged = create_acpi_ged (pch_pic , lvms );
@@ -793,7 +851,6 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
793
851
CPULoongArchState * env ;
794
852
CPUState * cpu_state ;
795
853
int cpu , pin , i , start , num ;
796
- uint32_t cpuintc_phandle , eiointc_phandle , pch_pic_phandle , pch_msi_phandle ;
797
854
798
855
/*
799
856
* Extended IRQ model.
@@ -850,9 +907,6 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
850
907
memory_region_add_subregion (& lvms -> system_iocsr , MAIL_SEND_ADDR ,
851
908
sysbus_mmio_get_region (SYS_BUS_DEVICE (ipi ), 1 ));
852
909
853
- /* Add cpu interrupt-controller */
854
- fdt_add_cpuic_node (lvms , & cpuintc_phandle );
855
-
856
910
for (cpu = 0 ; cpu < ms -> smp .cpus ; cpu ++ ) {
857
911
cpu_state = qemu_get_cpu (cpu );
858
912
cpudev = DEVICE (cpu_state );
@@ -891,9 +945,6 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
891
945
}
892
946
}
893
947
894
- /* Add Extend I/O Interrupt Controller node */
895
- fdt_add_eiointc_node (lvms , & cpuintc_phandle , & eiointc_phandle );
896
-
897
948
pch_pic = qdev_new (TYPE_LOONGARCH_PIC );
898
949
num = VIRT_PCH_PIC_IRQ_NUM ;
899
950
qdev_prop_set_uint32 (pch_pic , "pch_pic_irq_num" , num );
@@ -913,9 +964,6 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
913
964
qdev_connect_gpio_out (DEVICE (d ), i , qdev_get_gpio_in (extioi , i ));
914
965
}
915
966
916
- /* Add PCH PIC node */
917
- fdt_add_pch_pic_node (lvms , & eiointc_phandle , & pch_pic_phandle );
918
-
919
967
pch_msi = qdev_new (TYPE_LOONGARCH_PCH_MSI );
920
968
start = num ;
921
969
num = EXTIOI_IRQS - start ;
@@ -930,10 +978,7 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
930
978
qdev_get_gpio_in (extioi , i + start ));
931
979
}
932
980
933
- /* Add PCH MSI node */
934
- fdt_add_pch_msi_node (lvms , & eiointc_phandle , & pch_msi_phandle );
935
-
936
- virt_devices_init (pch_pic , lvms , & pch_pic_phandle , & pch_msi_phandle );
981
+ virt_devices_init (pch_pic , lvms );
937
982
}
938
983
939
984
static void virt_firmware_init (LoongArchVirtMachineState * lvms )
@@ -1151,8 +1196,6 @@ static void virt_init(MachineState *machine)
1151
1196
cpu_model = LOONGARCH_CPU_TYPE_NAME ("la464" );
1152
1197
}
1153
1198
1154
- create_fdt (lvms );
1155
-
1156
1199
/* Create IOCSR space */
1157
1200
memory_region_init_io (& lvms -> system_iocsr , OBJECT (machine ), NULL ,
1158
1201
machine , "iocsr" , UINT64_MAX );
@@ -1171,8 +1214,6 @@ static void virt_init(MachineState *machine)
1171
1214
lacpu = LOONGARCH_CPU (cpu );
1172
1215
lacpu -> phy_id = machine -> possible_cpus -> cpus [i ].arch_id ;
1173
1216
}
1174
- fdt_add_cpu_nodes (lvms );
1175
- fdt_add_memory_nodes (machine );
1176
1217
fw_cfg_add_memory (machine );
1177
1218
1178
1219
/* Node0 memory */
@@ -1224,34 +1265,15 @@ static void virt_init(MachineState *machine)
1224
1265
memmap_table ,
1225
1266
sizeof (struct memmap_entry ) * (memmap_entries ));
1226
1267
}
1227
- fdt_add_fw_cfg_node (lvms );
1228
- fdt_add_flash_node (lvms );
1229
1268
1230
1269
/* Initialize the IO interrupt subsystem */
1231
1270
virt_irq_init (lvms );
1232
- platform_bus_add_all_fdt_nodes (machine -> fdt , "/platic" ,
1233
- VIRT_PLATFORM_BUS_BASEADDRESS ,
1234
- VIRT_PLATFORM_BUS_SIZE ,
1235
- VIRT_PLATFORM_BUS_IRQ );
1236
1271
lvms -> machine_done .notify = virt_done ;
1237
1272
qemu_add_machine_init_done_notifier (& lvms -> machine_done );
1238
1273
/* connect powerdown request */
1239
1274
lvms -> powerdown_notifier .notify = virt_powerdown_req ;
1240
1275
qemu_register_powerdown_notifier (& lvms -> powerdown_notifier );
1241
1276
1242
- /*
1243
- * Since lowmem region starts from 0 and Linux kernel legacy start address
1244
- * at 2 MiB, FDT base address is located at 1 MiB to avoid NULL pointer
1245
- * access. FDT size limit with 1 MiB.
1246
- * Put the FDT into the memory map as a ROM image: this will ensure
1247
- * the FDT is copied again upon reset, even if addr points into RAM.
1248
- */
1249
- qemu_fdt_dumpdtb (machine -> fdt , lvms -> fdt_size );
1250
- rom_add_blob_fixed_as ("fdt" , machine -> fdt , lvms -> fdt_size , FDT_BASE ,
1251
- & address_space_memory );
1252
- qemu_register_reset_nosnapshotload (qemu_fdt_randomize_seeds ,
1253
- rom_ptr_for_as (& address_space_memory , FDT_BASE , lvms -> fdt_size ));
1254
-
1255
1277
lvms -> bootinfo .ram_size = ram_size ;
1256
1278
loongarch_load_kernel (machine , & lvms -> bootinfo );
1257
1279
}
0 commit comments