qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

virt.c (12835B)


      1 /*
      2  * SPDX-License-Identifier: GPL-2.0-or-later
      3  *
      4  * QEMU Vitual M68K Machine
      5  *
      6  * (c) 2020 Laurent Vivier <laurent@vivier.eu>
      7  *
      8  */
      9 
     10 #include "qemu/osdep.h"
     11 #include "qemu/units.h"
     12 #include "qemu/guest-random.h"
     13 #include "sysemu/sysemu.h"
     14 #include "cpu.h"
     15 #include "hw/boards.h"
     16 #include "hw/qdev-properties.h"
     17 #include "elf.h"
     18 #include "hw/loader.h"
     19 #include "ui/console.h"
     20 #include "hw/sysbus.h"
     21 #include "standard-headers/asm-m68k/bootinfo.h"
     22 #include "standard-headers/asm-m68k/bootinfo-virt.h"
     23 #include "bootinfo.h"
     24 #include "net/net.h"
     25 #include "qapi/error.h"
     26 #include "sysemu/qtest.h"
     27 #include "sysemu/runstate.h"
     28 #include "sysemu/reset.h"
     29 
     30 #include "hw/intc/m68k_irqc.h"
     31 #include "hw/misc/virt_ctrl.h"
     32 #include "hw/char/goldfish_tty.h"
     33 #include "hw/rtc/goldfish_rtc.h"
     34 #include "hw/intc/goldfish_pic.h"
     35 #include "hw/virtio/virtio-mmio.h"
     36 #include "hw/virtio/virtio-blk.h"
     37 
     38 /*
     39  * 6 goldfish-pic for CPU IRQ #1 to IRQ #6
     40  * CPU IRQ #1 -> PIC #1
     41  *               IRQ #1 to IRQ #31 -> unused
     42  *               IRQ #32 -> goldfish-tty
     43  * CPU IRQ #2 -> PIC #2
     44  *               IRQ #1 to IRQ #32 -> virtio-mmio from 1 to 32
     45  * CPU IRQ #3 -> PIC #3
     46  *               IRQ #1 to IRQ #32 -> virtio-mmio from 33 to 64
     47  * CPU IRQ #4 -> PIC #4
     48  *               IRQ #1 to IRQ #32 -> virtio-mmio from 65 to 96
     49  * CPU IRQ #5 -> PIC #5
     50  *               IRQ #1 to IRQ #32 -> virtio-mmio from 97 to 128
     51  * CPU IRQ #6 -> PIC #6
     52  *               IRQ #1 -> goldfish-rtc
     53  *               IRQ #2 to IRQ #32 -> unused
     54  * CPU IRQ #7 -> NMI
     55  */
     56 
     57 #define PIC_IRQ_BASE(num)     (8 + (num - 1) * 32)
     58 #define PIC_IRQ(num, irq)     (PIC_IRQ_BASE(num) + irq - 1)
     59 #define PIC_GPIO(pic_irq)     (qdev_get_gpio_in(pic_dev[(pic_irq - 8) / 32], \
     60                                                 (pic_irq - 8) % 32))
     61 
     62 #define VIRT_GF_PIC_MMIO_BASE 0xff000000     /* MMIO: 0xff000000 - 0xff005fff */
     63 #define VIRT_GF_PIC_IRQ_BASE  1              /* IRQ: #1 -> #6 */
     64 #define VIRT_GF_PIC_NB        6
     65 
     66 /* 2 goldfish-rtc (and timer) */
     67 #define VIRT_GF_RTC_MMIO_BASE 0xff006000     /* MMIO: 0xff006000 - 0xff007fff */
     68 #define VIRT_GF_RTC_IRQ_BASE  PIC_IRQ(6, 1)  /* PIC: #6, IRQ: #1 */
     69 #define VIRT_GF_RTC_NB        2
     70 
     71 /* 1 goldfish-tty */
     72 #define VIRT_GF_TTY_MMIO_BASE 0xff008000     /* MMIO: 0xff008000 - 0xff008fff */
     73 #define VIRT_GF_TTY_IRQ_BASE  PIC_IRQ(1, 32) /* PIC: #1, IRQ: #32 */
     74 
     75 /* 1 virt-ctrl */
     76 #define VIRT_CTRL_MMIO_BASE 0xff009000    /* MMIO: 0xff009000 - 0xff009fff */
     77 #define VIRT_CTRL_IRQ_BASE  PIC_IRQ(1, 1) /* PIC: #1, IRQ: #1 */
     78 
     79 /*
     80  * virtio-mmio size is 0x200 bytes
     81  * we use 4 goldfish-pic to attach them,
     82  * we can attach 32 virtio devices / goldfish-pic
     83  * -> we can manage 32 * 4 = 128 virtio devices
     84  */
     85 #define VIRT_VIRTIO_MMIO_BASE 0xff010000     /* MMIO: 0xff010000 - 0xff01ffff */
     86 #define VIRT_VIRTIO_IRQ_BASE  PIC_IRQ(2, 1)  /* PIC: 2, 3, 4, 5, IRQ: ALL */
     87 
     88 typedef struct {
     89     M68kCPU *cpu;
     90     hwaddr initial_pc;
     91     hwaddr initial_stack;
     92 } ResetInfo;
     93 
     94 static void main_cpu_reset(void *opaque)
     95 {
     96     ResetInfo *reset_info = opaque;
     97     M68kCPU *cpu = reset_info->cpu;
     98     CPUState *cs = CPU(cpu);
     99 
    100     cpu_reset(cs);
    101     cpu->env.aregs[7] = reset_info->initial_stack;
    102     cpu->env.pc = reset_info->initial_pc;
    103 }
    104 
    105 static void rerandomize_rng_seed(void *opaque)
    106 {
    107     struct bi_record *rng_seed = opaque;
    108     qemu_guest_getrandom_nofail((void *)rng_seed->data + 2,
    109                                 be16_to_cpu(*(uint16_t *)rng_seed->data));
    110 }
    111 
    112 static void virt_init(MachineState *machine)
    113 {
    114     M68kCPU *cpu = NULL;
    115     int32_t kernel_size;
    116     uint64_t elf_entry;
    117     ram_addr_t initrd_base;
    118     int32_t initrd_size;
    119     ram_addr_t ram_size = machine->ram_size;
    120     const char *kernel_filename = machine->kernel_filename;
    121     const char *initrd_filename = machine->initrd_filename;
    122     const char *kernel_cmdline = machine->kernel_cmdline;
    123     hwaddr parameters_base;
    124     DeviceState *dev;
    125     DeviceState *irqc_dev;
    126     DeviceState *pic_dev[VIRT_GF_PIC_NB];
    127     SysBusDevice *sysbus;
    128     hwaddr io_base;
    129     int i;
    130     ResetInfo *reset_info;
    131     uint8_t rng_seed[32];
    132 
    133     if (ram_size > 3399672 * KiB) {
    134         /*
    135          * The physical memory can be up to 4 GiB - 16 MiB, but linux
    136          * kernel crashes after this limit (~ 3.2 GiB)
    137          */
    138         error_report("Too much memory for this machine: %" PRId64 " KiB, "
    139                      "maximum 3399672 KiB", ram_size / KiB);
    140         exit(1);
    141     }
    142 
    143     reset_info = g_new0(ResetInfo, 1);
    144 
    145     /* init CPUs */
    146     cpu = M68K_CPU(cpu_create(machine->cpu_type));
    147 
    148     reset_info->cpu = cpu;
    149     qemu_register_reset(main_cpu_reset, reset_info);
    150 
    151     /* RAM */
    152     memory_region_add_subregion(get_system_memory(), 0, machine->ram);
    153 
    154     /* IRQ Controller */
    155 
    156     irqc_dev = qdev_new(TYPE_M68K_IRQC);
    157     sysbus_realize_and_unref(SYS_BUS_DEVICE(irqc_dev), &error_fatal);
    158 
    159     /*
    160      * 6 goldfish-pic
    161      *
    162      * map: 0xff000000 - 0xff006fff = 28 KiB
    163      * IRQ: #1 (lower priority) -> #6 (higher priority)
    164      *
    165      */
    166     io_base = VIRT_GF_PIC_MMIO_BASE;
    167     for (i = 0; i < VIRT_GF_PIC_NB; i++) {
    168         pic_dev[i] = qdev_new(TYPE_GOLDFISH_PIC);
    169         sysbus = SYS_BUS_DEVICE(pic_dev[i]);
    170         qdev_prop_set_uint8(pic_dev[i], "index", i);
    171         sysbus_realize_and_unref(sysbus, &error_fatal);
    172 
    173         sysbus_mmio_map(sysbus, 0, io_base);
    174         sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(irqc_dev, i));
    175 
    176         io_base += 0x1000;
    177     }
    178 
    179     /* goldfish-rtc */
    180     io_base = VIRT_GF_RTC_MMIO_BASE;
    181     for (i = 0; i < VIRT_GF_RTC_NB; i++) {
    182         dev = qdev_new(TYPE_GOLDFISH_RTC);
    183         qdev_prop_set_bit(dev, "big-endian", true);
    184         sysbus = SYS_BUS_DEVICE(dev);
    185         sysbus_realize_and_unref(sysbus, &error_fatal);
    186         sysbus_mmio_map(sysbus, 0, io_base);
    187         sysbus_connect_irq(sysbus, 0, PIC_GPIO(VIRT_GF_RTC_IRQ_BASE + i));
    188 
    189         io_base += 0x1000;
    190     }
    191 
    192     /* goldfish-tty */
    193     dev = qdev_new(TYPE_GOLDFISH_TTY);
    194     sysbus = SYS_BUS_DEVICE(dev);
    195     qdev_prop_set_chr(dev, "chardev", serial_hd(0));
    196     sysbus_realize_and_unref(sysbus, &error_fatal);
    197     sysbus_mmio_map(sysbus, 0, VIRT_GF_TTY_MMIO_BASE);
    198     sysbus_connect_irq(sysbus, 0, PIC_GPIO(VIRT_GF_TTY_IRQ_BASE));
    199 
    200     /* virt controller */
    201     dev = qdev_new(TYPE_VIRT_CTRL);
    202     sysbus = SYS_BUS_DEVICE(dev);
    203     sysbus_realize_and_unref(sysbus, &error_fatal);
    204     sysbus_mmio_map(sysbus, 0, VIRT_CTRL_MMIO_BASE);
    205     sysbus_connect_irq(sysbus, 0, PIC_GPIO(VIRT_CTRL_IRQ_BASE));
    206 
    207     /* virtio-mmio */
    208     io_base = VIRT_VIRTIO_MMIO_BASE;
    209     for (i = 0; i < 128; i++) {
    210         dev = qdev_new(TYPE_VIRTIO_MMIO);
    211         qdev_prop_set_bit(dev, "force-legacy", false);
    212         sysbus = SYS_BUS_DEVICE(dev);
    213         sysbus_realize_and_unref(sysbus, &error_fatal);
    214         sysbus_connect_irq(sysbus, 0, PIC_GPIO(VIRT_VIRTIO_IRQ_BASE + i));
    215         sysbus_mmio_map(sysbus, 0, io_base);
    216         io_base += 0x200;
    217     }
    218 
    219     if (kernel_filename) {
    220         CPUState *cs = CPU(cpu);
    221         uint64_t high;
    222         void *param_blob, *param_ptr, *param_rng_seed;
    223 
    224         if (kernel_cmdline) {
    225             param_blob = g_malloc(strlen(kernel_cmdline) + 1024);
    226         } else {
    227             param_blob = g_malloc(1024);
    228         }
    229 
    230         kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
    231                                &elf_entry, NULL, &high, NULL, 1,
    232                                EM_68K, 0, 0);
    233         if (kernel_size < 0) {
    234             error_report("could not load kernel '%s'", kernel_filename);
    235             exit(1);
    236         }
    237         reset_info->initial_pc = elf_entry;
    238         parameters_base = (high + 1) & ~1;
    239         param_ptr = param_blob;
    240 
    241         BOOTINFO1(param_ptr, BI_MACHTYPE, MACH_VIRT);
    242         BOOTINFO1(param_ptr, BI_FPUTYPE, FPU_68040);
    243         BOOTINFO1(param_ptr, BI_MMUTYPE, MMU_68040);
    244         BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68040);
    245         BOOTINFO2(param_ptr, BI_MEMCHUNK, 0, ram_size);
    246 
    247         BOOTINFO1(param_ptr, BI_VIRT_QEMU_VERSION,
    248                   ((QEMU_VERSION_MAJOR << 24) | (QEMU_VERSION_MINOR << 16) |
    249                    (QEMU_VERSION_MICRO << 8)));
    250         BOOTINFO2(param_ptr, BI_VIRT_GF_PIC_BASE,
    251                   VIRT_GF_PIC_MMIO_BASE, VIRT_GF_PIC_IRQ_BASE);
    252         BOOTINFO2(param_ptr, BI_VIRT_GF_RTC_BASE,
    253                   VIRT_GF_RTC_MMIO_BASE, VIRT_GF_RTC_IRQ_BASE);
    254         BOOTINFO2(param_ptr, BI_VIRT_GF_TTY_BASE,
    255                   VIRT_GF_TTY_MMIO_BASE, VIRT_GF_TTY_IRQ_BASE);
    256         BOOTINFO2(param_ptr, BI_VIRT_CTRL_BASE,
    257                   VIRT_CTRL_MMIO_BASE, VIRT_CTRL_IRQ_BASE);
    258         BOOTINFO2(param_ptr, BI_VIRT_VIRTIO_BASE,
    259                   VIRT_VIRTIO_MMIO_BASE, VIRT_VIRTIO_IRQ_BASE);
    260 
    261         if (kernel_cmdline) {
    262             BOOTINFOSTR(param_ptr, BI_COMMAND_LINE,
    263                         kernel_cmdline);
    264         }
    265 
    266         /* Pass seed to RNG. */
    267         param_rng_seed = param_ptr;
    268         qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
    269         BOOTINFODATA(param_ptr, BI_RNG_SEED,
    270                      rng_seed, sizeof(rng_seed));
    271 
    272         /* load initrd */
    273         if (initrd_filename) {
    274             initrd_size = get_image_size(initrd_filename);
    275             if (initrd_size < 0) {
    276                 error_report("could not load initial ram disk '%s'",
    277                              initrd_filename);
    278                 exit(1);
    279             }
    280 
    281             initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
    282             load_image_targphys(initrd_filename, initrd_base,
    283                                 ram_size - initrd_base);
    284             BOOTINFO2(param_ptr, BI_RAMDISK, initrd_base,
    285                       initrd_size);
    286         } else {
    287             initrd_base = 0;
    288             initrd_size = 0;
    289         }
    290         BOOTINFO0(param_ptr, BI_LAST);
    291         rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob,
    292                               parameters_base, cs->as);
    293         qemu_register_reset_nosnapshotload(rerandomize_rng_seed,
    294                             rom_ptr_for_as(cs->as, parameters_base,
    295                                            param_ptr - param_blob) +
    296                             (param_rng_seed - param_blob));
    297         g_free(param_blob);
    298     }
    299 }
    300 
    301 static void virt_machine_class_init(ObjectClass *oc, void *data)
    302 {
    303     MachineClass *mc = MACHINE_CLASS(oc);
    304     mc->desc = "QEMU M68K Virtual Machine";
    305     mc->init = virt_init;
    306     mc->default_cpu_type = M68K_CPU_TYPE_NAME("m68040");
    307     mc->max_cpus = 1;
    308     mc->no_floppy = 1;
    309     mc->no_parallel = 1;
    310     mc->default_ram_id = "m68k_virt.ram";
    311 }
    312 
    313 static const TypeInfo virt_machine_info = {
    314     .name       = MACHINE_TYPE_NAME("virt"),
    315     .parent     = TYPE_MACHINE,
    316     .abstract   = true,
    317     .class_init = virt_machine_class_init,
    318 };
    319 
    320 static void virt_machine_register_types(void)
    321 {
    322     type_register_static(&virt_machine_info);
    323 }
    324 
    325 type_init(virt_machine_register_types)
    326 
    327 #define DEFINE_VIRT_MACHINE(major, minor, latest) \
    328     static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
    329                                                     void *data) \
    330     { \
    331         MachineClass *mc = MACHINE_CLASS(oc); \
    332         virt_machine_##major##_##minor##_options(mc); \
    333         mc->desc = "QEMU " # major "." # minor " M68K Virtual Machine"; \
    334         if (latest) { \
    335             mc->alias = "virt"; \
    336         } \
    337     } \
    338     static const TypeInfo machvirt_##major##_##minor##_info = { \
    339         .name = MACHINE_TYPE_NAME("virt-" # major "." # minor), \
    340         .parent = MACHINE_TYPE_NAME("virt"), \
    341         .class_init = virt_##major##_##minor##_class_init, \
    342     }; \
    343     static void machvirt_machine_##major##_##minor##_init(void) \
    344     { \
    345         type_register_static(&machvirt_##major##_##minor##_info); \
    346     } \
    347     type_init(machvirt_machine_##major##_##minor##_init);
    348 
    349 static void virt_machine_7_2_options(MachineClass *mc)
    350 {
    351 }
    352 DEFINE_VIRT_MACHINE(7, 2, true)
    353 
    354 static void virt_machine_7_1_options(MachineClass *mc)
    355 {
    356     virt_machine_7_2_options(mc);
    357     compat_props_add(mc->compat_props, hw_compat_7_1, hw_compat_7_1_len);
    358 }
    359 DEFINE_VIRT_MACHINE(7, 1, false)
    360 
    361 static void virt_machine_7_0_options(MachineClass *mc)
    362 {
    363     virt_machine_7_1_options(mc);
    364     compat_props_add(mc->compat_props, hw_compat_7_0, hw_compat_7_0_len);
    365 }
    366 DEFINE_VIRT_MACHINE(7, 0, false)
    367 
    368 static void virt_machine_6_2_options(MachineClass *mc)
    369 {
    370     virt_machine_7_0_options(mc);
    371     compat_props_add(mc->compat_props, hw_compat_6_2, hw_compat_6_2_len);
    372 }
    373 DEFINE_VIRT_MACHINE(6, 2, false)
    374 
    375 static void virt_machine_6_1_options(MachineClass *mc)
    376 {
    377     virt_machine_6_2_options(mc);
    378     compat_props_add(mc->compat_props, hw_compat_6_1, hw_compat_6_1_len);
    379 }
    380 DEFINE_VIRT_MACHINE(6, 1, false)
    381 
    382 static void virt_machine_6_0_options(MachineClass *mc)
    383 {
    384     virt_machine_6_1_options(mc);
    385     compat_props_add(mc->compat_props, hw_compat_6_0, hw_compat_6_0_len);
    386 }
    387 DEFINE_VIRT_MACHINE(6, 0, false)