Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: KVM: Add kvm guest support for Loongson-3

Loongson-3 KVM guest is based on virtio, it use liointc as its interrupt
controller and use GPEX as the pci controller.

Signed-off-by: Huacai Chen <chenhc@lemote.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>

authored by

Huacai Chen and committed by
Thomas Bogendoerfer
39c1485c a84a334f

+125 -3
+1
arch/mips/Kconfig
··· 478 478 select COMMON_CLK 479 479 select USE_OF 480 480 select BUILTIN_DTB 481 + select PCI_HOST_GENERIC 481 482 help 482 483 This enables the support of Loongson-2/3 family of machines. 483 484
+1
arch/mips/boot/dts/loongson/Makefile
··· 3 3 dtb-$(CONFIG_MACH_LOONGSON64) += loongson64c_4core_rs780e.dtb 4 4 dtb-$(CONFIG_MACH_LOONGSON64) += loongson64c_8core_rs780e.dtb 5 5 dtb-$(CONFIG_MACH_LOONGSON64) += loongson64g_4core_ls7a.dtb 6 + dtb-$(CONFIG_MACH_LOONGSON64) += loongson64v_4core_virtio.dtb 6 7 7 8 obj-$(CONFIG_BUILTIN_DTB) += $(addsuffix .o, $(dtb-y))
+102
arch/mips/boot/dts/loongson/loongson64v_4core_virtio.dts
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <dt-bindings/interrupt-controller/irq.h> 4 + 5 + /dts-v1/; 6 + / { 7 + compatible = "loongson,loongson64v-4core-virtio"; 8 + #address-cells = <2>; 9 + #size-cells = <2>; 10 + 11 + cpuintc: interrupt-controller { 12 + #address-cells = <0>; 13 + #interrupt-cells = <1>; 14 + interrupt-controller; 15 + compatible = "mti,cpu-interrupt-controller"; 16 + }; 17 + 18 + package0: bus@1fe00000 { 19 + compatible = "simple-bus"; 20 + #address-cells = <2>; 21 + #size-cells = <1>; 22 + ranges = <0 0x1fe00000 0 0x1fe00000 0x100000 23 + 0 0x3ff00000 0 0x3ff00000 0x100000 24 + 0xefd 0xfb000000 0xefd 0xfb000000 0x10000000>; 25 + 26 + liointc: interrupt-controller@3ff01400 { 27 + compatible = "loongson,liointc-1.0"; 28 + reg = <0 0x3ff01400 0x64>; 29 + 30 + interrupt-controller; 31 + #interrupt-cells = <2>; 32 + 33 + interrupt-parent = <&cpuintc>; 34 + interrupts = <2>, <3>; 35 + interrupt-names = "int0", "int1"; 36 + 37 + loongson,parent_int_map = <0x00000001>, /* int0 */ 38 + <0xfffffffe>, /* int1 */ 39 + <0x00000000>, /* int2 */ 40 + <0x00000000>; /* int3 */ 41 + 42 + }; 43 + 44 + cpu_uart0: serial@1fe001e0 { 45 + compatible = "ns16550a"; 46 + reg = <0 0x1fe001e0 0x8>; 47 + clock-frequency = <33000000>; 48 + interrupt-parent = <&liointc>; 49 + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; 50 + no-loopback-test; 51 + }; 52 + }; 53 + 54 + bus@10000000 { 55 + compatible = "simple-bus"; 56 + #address-cells = <2>; 57 + #size-cells = <2>; 58 + ranges = <0 0x10000000 0 0x10000000 0 0x10000000 /* PIO & CONF & APB */ 59 + 0 0x40000000 0 0x40000000 0 0x40000000>; /* PCI MEM */ 60 + 61 + rtc0: rtc@10081000 { 62 + compatible = "google,goldfish-rtc"; 63 + reg = <0 0x10081000 0 0x1000>; 64 + interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; 65 + interrupt-parent = <&liointc>; 66 + }; 67 + 68 + pci@1a000000 { 69 + compatible = "pci-host-ecam-generic"; 70 + device_type = "pci"; 71 + #address-cells = <3>; 72 + #size-cells = <2>; 73 + #interrupt-cells = <1>; 74 + 75 + bus-range = <0x0 0x1f>; 76 + reg = <0 0x1a000000 0 0x02000000>; 77 + 78 + ranges = <0x01000000 0x0 0x00004000 0x0 0x18004000 0x0 0x0000c000>, 79 + <0x02000000 0x0 0x40000000 0x0 0x40000000 0x0 0x40000000>; 80 + 81 + interrupt-map = < 82 + 0x0000 0x0 0x0 0x1 &liointc 0x2 IRQ_TYPE_LEVEL_HIGH 83 + 0x0800 0x0 0x0 0x1 &liointc 0x3 IRQ_TYPE_LEVEL_HIGH 84 + 0x1000 0x0 0x0 0x1 &liointc 0x4 IRQ_TYPE_LEVEL_HIGH 85 + 0x1800 0x0 0x0 0x1 &liointc 0x5 IRQ_TYPE_LEVEL_HIGH 86 + >; 87 + 88 + interrupt-map-mask = <0x1800 0x0 0x0 0x7>; 89 + }; 90 + 91 + isa { 92 + compatible = "isa"; 93 + #address-cells = <2>; 94 + #size-cells = <1>; 95 + ranges = <1 0 0 0x18000000 0x4000>; 96 + }; 97 + }; 98 + 99 + hypervisor { 100 + compatible = "linux,kvm"; 101 + }; 102 + };
+3 -1
arch/mips/include/asm/mach-loongson64/boot_param.h
··· 194 194 195 195 enum loongson_bridge_type { 196 196 LS7A = 1, 197 - RS780E = 2 197 + RS780E = 2, 198 + VIRTUAL = 3 198 199 }; 199 200 200 201 struct loongson_system_configuration { ··· 231 230 extern u32 node_id_offset; 232 231 extern void ls7a_early_config(void); 233 232 extern void rs780e_early_config(void); 233 + extern void virtual_early_config(void); 234 234 235 235 #endif
+1
arch/mips/include/asm/mach-loongson64/builtin_dtbs.h
··· 12 12 extern u32 __dtb_loongson64c_4core_rs780e_begin[]; 13 13 extern u32 __dtb_loongson64c_8core_rs780e_begin[]; 14 14 extern u32 __dtb_loongson64g_4core_ls7a_begin[]; 15 + extern u32 __dtb_loongson64v_4core_virtio_begin[]; 15 16 #endif
+12 -2
arch/mips/loongson64/env.c
··· 167 167 vendor = id & 0xffff; 168 168 device = (id >> 16) & 0xffff; 169 169 170 - if (vendor == PCI_VENDOR_ID_LOONGSON && device == 0x7a00) { 170 + switch (vendor) { 171 + case PCI_VENDOR_ID_LOONGSON: 171 172 pr_info("The bridge chip is LS7A\n"); 172 173 loongson_sysconf.bridgetype = LS7A; 173 174 loongson_sysconf.early_config = ls7a_early_config; 174 - } else { 175 + break; 176 + case PCI_VENDOR_ID_AMD: 177 + case PCI_VENDOR_ID_ATI: 175 178 pr_info("The bridge chip is RS780E or SR5690\n"); 176 179 loongson_sysconf.bridgetype = RS780E; 177 180 loongson_sysconf.early_config = rs780e_early_config; 181 + break; 182 + default: 183 + pr_info("The bridge chip is VIRTUAL\n"); 184 + loongson_sysconf.bridgetype = VIRTUAL; 185 + loongson_sysconf.early_config = virtual_early_config; 186 + loongson_fdt_blob = __dtb_loongson64v_4core_virtio_begin; 187 + break; 178 188 } 179 189 180 190 if ((read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64C) {
+5
arch/mips/loongson64/init.c
··· 42 42 node_id_offset = 37; 43 43 } 44 44 45 + void virtual_early_config(void) 46 + { 47 + node_id_offset = 44; 48 + } 49 + 45 50 void __init prom_init(void) 46 51 { 47 52 fw_init_cmdline();