[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH V16 5/6] hw/mips: Add Loongson-3 machine support
|
From: |
Huacai Chen |
|
Subject: |
Re: [PATCH V16 5/6] hw/mips: Add Loongson-3 machine support |
|
Date: |
Wed, 4 Nov 2020 11:33:24 +0800 |
Hi, Philippe,
On Wed, Nov 4, 2020 at 4:23 AM Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>
> Hi Huacai,
>
> On 10/30/20 11:25 AM, Huacai Chen wrote:
> > Add Loongson-3 based machine support, it use liointc as the interrupt
> > controler and use GPEX as the pci controller. Currently it can work with
> > both TCG and KVM.
> >
> > As the machine model is not based on any exiting physical hardware, the
> > name of the machine is "loongson3-virt". It may be superseded in future
> > by a real machine model. If this happens, then a regular deprecation
> > procedure shall occur for "loongson3-virt" machine.
> >
> > We now already have a full functional Linux kernel (based on Linux-5.4.x
> > LTS, the kvm host side and guest side have both been upstream for Linux-
> > 5.9, but Linux-5.9 has not been released yet) here:
> >
> > https://github.com/chenhuacai/linux
> >
> > Of course the upstream kernel is also usable (though it is "unstable"
> > now):
> >
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
> >
> > How to use QEMU/Loongson-3?
> > 1, Download kernel source from the above URL;
> > 2, Build a kernel with arch/mips/configs/loongson3_defconfig;
> > 3, Boot a Loongson-3A4000 host with this kernel (for KVM mode);
> > 4, Build QEMU-master with this patchset;
> > 5, modprobe kvm (only necessary for KVM mode);
> > 6, Use QEMU with TCG:
> > qemu-system-mips64el -M loongson3-virt,accel=tcg -cpu
> > Loongson-3A1000 -kernel <path_to_kernel> -append ...
> > Use QEMU with KVM:
> > qemu-system-mips64el -M loongson3-virt,accel=kvm -cpu
> > Loongson-3A4000 -kernel <path_to_kernel> -append ...
> >
> > The "-cpu" parameter is optional here and QEMU will use the correct type
> > for TCG/KVM automatically.
> >
> > Signed-off-by: Huacai Chen <chenhc@lemote.com>
> > Co-developed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> > Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> > ---
> > default-configs/devices/mips64el-softmmu.mak | 1 +
> > hw/mips/Kconfig | 12 +
> > hw/mips/loongson3_virt.c | 620
> > +++++++++++++++++++++++++++
> > hw/mips/meson.build | 2 +-
> > 4 files changed, 634 insertions(+), 1 deletion(-)
> > create mode 100644 hw/mips/loongson3_virt.c
> ...
> > +static inline void loongson3_virt_devices_init(MachineState *machine,
> > DeviceState *pic)
> > +{
> > + int i;
> > + qemu_irq irq;
> > + PCIBus *pci_bus;
> > + DeviceState *dev;
> > + MemoryRegion *pio_alias;
> > + MemoryRegion *mmio_alias, *mmio_reg;
> > + MemoryRegion *ecam_alias, *ecam_reg;
> > +
> > + dev = qdev_new(TYPE_GPEX_HOST);
> > + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
> > + pci_bus = PCI_HOST_BRIDGE(dev)->bus;
> > +
> > + ecam_alias = g_new0(MemoryRegion, 1);
> > + ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
> > + memory_region_init_alias(ecam_alias, OBJECT(dev), "pcie-ecam",
> > + ecam_reg, 0,
> > virt_memmap[VIRT_PCIE_ECAM].size);
> > + memory_region_add_subregion(get_system_memory(),
> > + virt_memmap[VIRT_PCIE_ECAM].base,
> > ecam_alias);
> > +
> > + mmio_alias = g_new0(MemoryRegion, 1);
> > + mmio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
> > + memory_region_init_alias(mmio_alias, OBJECT(dev), "pcie-mmio",
> > + mmio_reg, virt_memmap[VIRT_PCIE_MMIO].base,
> > + virt_memmap[VIRT_PCIE_MMIO].size);
> > + memory_region_add_subregion(get_system_memory(),
> > + virt_memmap[VIRT_PCIE_MMIO].base,
> > mmio_alias);
> > +
> > + pio_alias = g_new0(MemoryRegion, 1);
> > + memory_region_init_alias(pio_alias, OBJECT(dev), "pcie-pio",
> > + get_system_io(), 0,
> > virt_memmap[VIRT_PCIE_PIO].size);
> > + memory_region_add_subregion(get_system_memory(),
> > + virt_memmap[VIRT_PCIE_PIO].base,
> > pio_alias);
> > + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2,
> > virt_memmap[VIRT_PCIE_PIO].base);
> > +
> > + for (i = 0; i < GPEX_NUM_IRQS; i++) {
> > + irq = qdev_get_gpio_in(pic, PCIE_IRQ_BASE + i);
> > + sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, irq);
> > + gpex_set_irq_num(GPEX_HOST(dev), i, PCIE_IRQ_BASE + i);
> > + }
> > +
> > + pci_vga_init(pci_bus);
> > +
> > + if (defaults_enabled()) {
> > + pci_create_simple(pci_bus, -1, "pci-ohci");
> > + usb_create_simple(usb_bus_find(-1), "usb-kbd");
> > + usb_create_simple(usb_bus_find(-1), "usb-tablet");
> > + }
> > +
> > + for (i = 0; i < nb_nics; i++) {
> > + NICInfo *nd = &nd_table[i];
> > +
> > + if (!nd->model) {
> > + nd->model = g_strdup("virtio");
> > + }
> > +
> > + pci_nic_init_nofail(nd, pci_bus, nd->model, NULL);
> > + }
> > +}
> > +
> > +static void mips_loongson3_virt_init(MachineState *machine)
> > +{
> > + int i;
> > + long bios_size;
> > + MIPSCPU *cpu;
> > + Clock *cpuclk;
> > + CPUMIPSState *env;
> > + DeviceState *liointc;
> > + char *filename;
> > + const char *kernel_cmdline = machine->kernel_cmdline;
> > + const char *kernel_filename = machine->kernel_filename;
> > + const char *initrd_filename = machine->initrd_filename;
> > + ram_addr_t ram_size = machine->ram_size;
> > + MemoryRegion *address_space_mem = get_system_memory();
> > + MemoryRegion *ram = g_new(MemoryRegion, 1);
> > + MemoryRegion *bios = g_new(MemoryRegion, 1);
> > + MemoryRegion *iomem = g_new(MemoryRegion, 1);
> > +
> > + /* TODO: TCG will support all CPU types */
> > + if (!kvm_enabled()) {
> > + if (!machine->cpu_type) {
> > + machine->cpu_type = MIPS_CPU_TYPE_NAME("Loongson-3A1000");
> > + }
> > + if (!strstr(machine->cpu_type, "Loongson-3A1000")) {
> > + error_report("Loongson-3/TCG needs cpu type Loongson-3A1000");
> > + exit(1);
> > + }
> > + } else {
> > + if (!machine->cpu_type) {
> > + machine->cpu_type = MIPS_CPU_TYPE_NAME("Loongson-3A4000");
> > + }
> > + if (!strstr(machine->cpu_type, "Loongson-3A4000")) {
> > + error_report("Loongson-3/KVM needs cpu type Loongson-3A4000");
> > + exit(1);
> > + }
> > + }
> > +
> > + if (ram_size < 512 * MiB) {
> > + error_report("Loongson-3 machine needs at least 512MB memory");
> > + exit(1);
> > + }
> > +
> > + /*
> > + * The whole MMIO range among configure registers doesn't generate
> > + * exception when accessing invalid memory. Create some unimplememted
> > + * devices to emulate this feature.
> > + */
> > + create_unimplemented_device("mmio fallback 0", 0x10000000, 256 * MiB);
> > + create_unimplemented_device("mmio fallback 1", 0x30000000, 256 * MiB);
> > +
> > + liointc = qdev_new("loongson.liointc");
>
> Please use TYPE_name when creating QOM (here TYPE_LOONGSON_LIOINTC).
> Similarly loongson3_virt_devices_init(). (no need to respin yet).
OK, thanks.
Huacai
>
> > + sysbus_realize_and_unref(SYS_BUS_DEVICE(liointc), &error_fatal);
> > +
> > + sysbus_mmio_map(SYS_BUS_DEVICE(liointc), 0,
> > virt_memmap[VIRT_LIOINTC].base);
> > +
> > + serial_mm_init(address_space_mem, virt_memmap[VIRT_UART].base, 0,
> > + qdev_get_gpio_in(liointc, UART_IRQ), 115200,
> > serial_hd(0),
> > + DEVICE_NATIVE_ENDIAN);
> > +
> > + sysbus_create_simple("goldfish_rtc", virt_memmap[VIRT_RTC].base,
> > + qdev_get_gpio_in(liointc, RTC_IRQ));
> > +
> > + cpuclk = clock_new(OBJECT(machine), "cpu-refclk");
> > + clock_set_hz(cpuclk, DEF_LOONGSON3_FREQ);
> > +
> > + for (i = 0; i < machine->smp.cpus; i++) {
> > + int ip;
> > +
> > + /* init CPUs */
> > + cpu = mips_cpu_create_with_clock(machine->cpu_type, cpuclk);
> > +
> > + /* Init internal devices */
> > + cpu_mips_irq_init_cpu(cpu);
> > + cpu_mips_clock_init(cpu);
> > + qemu_register_reset(main_cpu_reset, cpu);
> > +
> > + if (i >= 4) {
> > + continue; /* Only node-0 can be connected to LIOINTC */
> > + }
> > +
> > + for (ip = 0; ip < 4 ; ip++) {
> > + int pin = i * 4 + ip;
> > + sysbus_connect_irq(SYS_BUS_DEVICE(liointc),
> > + pin, cpu->env.irq[ip + 2]);
> > + }
> > + }
> > + env = &MIPS_CPU(first_cpu)->env;
> ...