* [PATCH 0/4] m68k: add Virtual M68k Machine
@ 2020-10-13 15:51 Laurent Vivier
2020-10-13 15:51 ` [PATCH 1/4] m68k: import bootinfo headers from linux Laurent Vivier
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Laurent Vivier @ 2020-10-13 15:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Laurent Vivier
The Quadra 800 machine is very limited to run linux, it manages
only 1 GiB of memory and only some specific interfaces.
The Virtual M68k Machine is based on Goldfish interfaces defined by Google
for Android simulator. It uses Goldfish-rtc (timer and RTC),
Goldfish-pic (PIC) and Goldfish-tty (for serial port and early tty).
https://android.googlesource.com/platform/external/qemu/+/master/docs/GOLDFIS=
H-VIRTUAL-HARDWARE.TXT
The machine is created with 128 virtio-mmio busses, and they can
be used to add serial console, GPU, disk, NIC, HID, ...
This series re-use the goldfish-rtc implemented for RISCV, and
adds the two others based on the goldfish specs, the kernel driver
and android simulator ones.
The machine can manage up to 3.2 GiB of memory, not because of an hardware
limitation but because the kernel crashes after this value.
Simply configure qemu with:
.../configure --target-list=3Dm68k-softmmu
To run the machine you need a modified kernel you can find here:
https://github.com/vivier/linux/tree/m68k-virt
You need to compile the kernel with:
make virt_defconfig
make vmlinux
The disk must be installed using the q800 machine because the debian installer
doesn't want to be used with a kernel that is not the one on the ISO.
And then you can run the machine with something like:
qemu-system-m68k -M virt \
-m 3399672K \
-chardev stdio,signal=3Doff,mux=3Don,id=3Dchar0 \
-mon chardev=3Dchar0,mode=3Dreadline \
-kernel vmlinux \
-append "console=3Dhvc0 root=3D/dev/vda2" \
-blockdev node-name=3Dsystem,driver=3Dfile,filename=3Ddebian-10.0.qcow2 \
-blockdev node-name=3Ddrive0,driver=3Dqcow2,file=3Dsystem \
-device virtio-blk-device,drive=3Ddrive0 \
-serial chardev:char0 \
-device virtio-net-device,netdev=3Dhostnet0 \
-netdev bridge,id=3Dhostnet0,br=3Dvirbr0 \
-device virtio-rng-device \
-device virtio-serial-device \
-device virtio-gpu-device \
-device virtconsole,chardev=3Dchar0 \
-device virtio-keyboard-device \
-device virtio-mouse-device
if you want to use Goldfish-tty for the console rather than virtconsole, you
can add "console=3DttyGF".
To start the debian-installer, you can try by adding:
-device virtio-scsi-device \
-blockdev node-name=3Ddebian10,driver=3Dfile,filename=3Ddebian-10.0.0-m68k-=
NETINST-1.iso \
-blockdev node-name=3Dcdrom0,driver=3Draw,file=3Ddebian10 \
-device scsi-cd,drive=3Dcdrom0 \
-initrd installer-m68k/20200315/images/cdrom/initrd.gz
ISO: https://cdimage.debian.org/cdimage/ports/snapshots/2020-10-12/debian-=
10.0.0-m68k-NETINST-1.iso
initrd: https://cdimage.debian.org/cdimage/ports/debian-installer/2020-10-12/=
m68k/debian-installer-images_20200315_m68k.tar.gz
I think there are some endianness issues with virtio-gpu, because when the
X server starts I have some errors in the kernel logs:
vmap allocation for size 3149824 failed: use vmalloc=3D<size> to increase s=
ize
I also tried virtiofsd but there is also an endianness problem and the server
stops.
Have Fun,
Laurent
PS:
By reading the message to the end you have won the right to download the disk=
image
and the vmlinux.
http://vivier.eu/debian-10.0.qcow2 343 MiB
http://vivier.eu/vmlinux-virt-m68k 5.2 MiB
Laurent Vivier (4):
m68k: import bootinfo headers from linux
char: add goldfish-tty
intc: add goldfish-pic
m68k: add Virtual M68k Machine
default-configs/devices/m68k-softmmu.mak | 1 +
hw/m68k/bootinfo.h | 55 ----
include/hw/char/goldfish_tty.h | 36 +++
include/hw/intc/goldfish_pic.h | 28 ++
.../standard-headers/asm-m68k/bootinfo-mac.h | 120 +++++++
.../standard-headers/asm-m68k/bootinfo-virt.h | 17 +
include/standard-headers/asm-m68k/bootinfo.h | 166 ++++++++++
hw/char/goldfish_tty.c | 265 ++++++++++++++++
hw/intc/goldfish_pic.c | 178 +++++++++++
hw/m68k/q800.c | 20 +-
hw/m68k/virt.c | 296 ++++++++++++++++++
MAINTAINERS | 11 +
hw/char/Kconfig | 3 +
hw/char/meson.build | 2 +
hw/char/trace-events | 9 +
hw/intc/Kconfig | 3 +
hw/intc/meson.build | 1 +
hw/intc/trace-events | 8 +
hw/m68k/Kconfig | 8 +
hw/m68k/meson.build | 1 +
20 files changed, 1160 insertions(+), 68 deletions(-)
create mode 100644 include/hw/char/goldfish_tty.h
create mode 100644 include/hw/intc/goldfish_pic.h
create mode 100644 include/standard-headers/asm-m68k/bootinfo-mac.h
create mode 100644 include/standard-headers/asm-m68k/bootinfo-virt.h
create mode 100644 include/standard-headers/asm-m68k/bootinfo.h
create mode 100644 hw/char/goldfish_tty.c
create mode 100644 hw/intc/goldfish_pic.c
create mode 100644 hw/m68k/virt.c
--=20
2.26.2
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/4] m68k: import bootinfo headers from linux
2020-10-13 15:51 [PATCH 0/4] m68k: add Virtual M68k Machine Laurent Vivier
@ 2020-10-13 15:51 ` Laurent Vivier
2020-10-13 15:51 ` [PATCH 2/4] char: add goldfish-tty Laurent Vivier
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Laurent Vivier @ 2020-10-13 15:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Laurent Vivier
Copy bootinfo.h and bootinfo-mac.h from arch/m68k/include/uapi/asm/
to include/standard-headers/asm-m68k/
Imported from linx v5.9 but didn't change since v4.14 (header update)
and since v4.10 (content update).
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
hw/m68k/bootinfo.h | 55 ------
.../standard-headers/asm-m68k/bootinfo-mac.h | 120 +++++++++++++
include/standard-headers/asm-m68k/bootinfo.h | 166 ++++++++++++++++++
hw/m68k/q800.c | 20 +--
MAINTAINERS | 2 +
5 files changed, 295 insertions(+), 68 deletions(-)
create mode 100644 include/standard-headers/asm-m68k/bootinfo-mac.h
create mode 100644 include/standard-headers/asm-m68k/bootinfo.h
diff --git a/hw/m68k/bootinfo.h b/hw/m68k/bootinfo.h
index c954270aad6c..adbf0c5521e5 100644
--- a/hw/m68k/bootinfo.h
+++ b/hw/m68k/bootinfo.h
@@ -11,61 +11,6 @@
#ifndef HW_M68K_BOOTINFO_H
#define HW_M68K_BOOTINFO_H
-struct bi_record {
- uint16_t tag; /* tag ID */
- uint16_t size; /* size of record */
- uint32_t data[]; /* data */
-};
-
-/* machine independent tags */
-
-#define BI_LAST 0x0000 /* last record */
-#define BI_MACHTYPE 0x0001 /* machine type (u_long) */
-#define BI_CPUTYPE 0x0002 /* cpu type (u_long) */
-#define BI_FPUTYPE 0x0003 /* fpu type (u_long) */
-#define BI_MMUTYPE 0x0004 /* mmu type (u_long) */
-#define BI_MEMCHUNK 0x0005 /* memory chunk address and size */
- /* (struct mem_info) */
-#define BI_RAMDISK 0x0006 /* ramdisk address and size */
- /* (struct mem_info) */
-#define BI_COMMAND_LINE 0x0007 /* kernel command line parameters */
- /* (string) */
-
-/* Macintosh-specific tags (all u_long) */
-
-#define BI_MAC_MODEL 0x8000 /* Mac Gestalt ID (model type) */
-#define BI_MAC_VADDR 0x8001 /* Mac video base address */
-#define BI_MAC_VDEPTH 0x8002 /* Mac video depth */
-#define BI_MAC_VROW 0x8003 /* Mac video rowbytes */
-#define BI_MAC_VDIM 0x8004 /* Mac video dimensions */
-#define BI_MAC_VLOGICAL 0x8005 /* Mac video logical base */
-#define BI_MAC_SCCBASE 0x8006 /* Mac SCC base address */
-#define BI_MAC_BTIME 0x8007 /* Mac boot time */
-#define BI_MAC_GMTBIAS 0x8008 /* Mac GMT timezone offset */
-#define BI_MAC_MEMSIZE 0x8009 /* Mac RAM size (sanity check) */
-#define BI_MAC_CPUID 0x800a /* Mac CPU type (sanity check) */
-#define BI_MAC_ROMBASE 0x800b /* Mac system ROM base address */
-
-/* Macintosh hardware profile data */
-
-#define BI_MAC_VIA1BASE 0x8010 /* Mac VIA1 base address (always present) */
-#define BI_MAC_VIA2BASE 0x8011 /* Mac VIA2 base address (type varies) */
-#define BI_MAC_VIA2TYPE 0x8012 /* Mac VIA2 type (VIA, RBV, OSS) */
-#define BI_MAC_ADBTYPE 0x8013 /* Mac ADB interface type */
-#define BI_MAC_ASCBASE 0x8014 /* Mac Apple Sound Chip base address */
-#define BI_MAC_SCSI5380 0x8015 /* Mac NCR 5380 SCSI (base address, multi) */
-#define BI_MAC_SCSIDMA 0x8016 /* Mac SCSI DMA (base address) */
-#define BI_MAC_SCSI5396 0x8017 /* Mac NCR 53C96 SCSI (base address, multi) */
-#define BI_MAC_IDETYPE 0x8018 /* Mac IDE interface type */
-#define BI_MAC_IDEBASE 0x8019 /* Mac IDE interface base address */
-#define BI_MAC_NUBUS 0x801a /* Mac Nubus type (none, regular, pseudo) */
-#define BI_MAC_SLOTMASK 0x801b /* Mac Nubus slots present */
-#define BI_MAC_SCCTYPE 0x801c /* Mac SCC serial type (normal, IOP) */
-#define BI_MAC_ETHTYPE 0x801d /* Mac builtin ethernet type (Sonic, MACE */
-#define BI_MAC_ETHBASE 0x801e /* Mac builtin ethernet base address */
-#define BI_MAC_PMU 0x801f /* Mac power management / poweroff hardware */
-#define BI_MAC_IOP_SWIM 0x8020 /* Mac SWIM floppy IOP */
-#define BI_MAC_IOP_ADB 0x8021 /* Mac ADB IOP */
#define BOOTINFO0(as, base, id) \
do { \
diff --git a/include/standard-headers/asm-m68k/bootinfo-mac.h b/include/standard-headers/asm-m68k/bootinfo-mac.h
new file mode 100644
index 000000000000..449928cfcbf2
--- /dev/null
+++ b/include/standard-headers/asm-m68k/bootinfo-mac.h
@@ -0,0 +1,120 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+** asm/bootinfo-mac.h -- Macintosh-specific boot information definitions
+*/
+
+#ifndef _UAPI_ASM_M68K_BOOTINFO_MAC_H
+#define _UAPI_ASM_M68K_BOOTINFO_MAC_H
+
+
+ /*
+ * Macintosh-specific tags (all __be32)
+ */
+
+#define BI_MAC_MODEL 0x8000 /* Mac Gestalt ID (model type) */
+#define BI_MAC_VADDR 0x8001 /* Mac video base address */
+#define BI_MAC_VDEPTH 0x8002 /* Mac video depth */
+#define BI_MAC_VROW 0x8003 /* Mac video rowbytes */
+#define BI_MAC_VDIM 0x8004 /* Mac video dimensions */
+#define BI_MAC_VLOGICAL 0x8005 /* Mac video logical base */
+#define BI_MAC_SCCBASE 0x8006 /* Mac SCC base address */
+#define BI_MAC_BTIME 0x8007 /* Mac boot time */
+#define BI_MAC_GMTBIAS 0x8008 /* Mac GMT timezone offset */
+#define BI_MAC_MEMSIZE 0x8009 /* Mac RAM size (sanity check) */
+#define BI_MAC_CPUID 0x800a /* Mac CPU type (sanity check) */
+#define BI_MAC_ROMBASE 0x800b /* Mac system ROM base address */
+
+
+ /*
+ * Macintosh hardware profile data - unused, see macintosh.h for
+ * reasonable type values
+ */
+
+#define BI_MAC_VIA1BASE 0x8010 /* Mac VIA1 base address (always present) */
+#define BI_MAC_VIA2BASE 0x8011 /* Mac VIA2 base address (type varies) */
+#define BI_MAC_VIA2TYPE 0x8012 /* Mac VIA2 type (VIA, RBV, OSS) */
+#define BI_MAC_ADBTYPE 0x8013 /* Mac ADB interface type */
+#define BI_MAC_ASCBASE 0x8014 /* Mac Apple Sound Chip base address */
+#define BI_MAC_SCSI5380 0x8015 /* Mac NCR 5380 SCSI (base address, multi) */
+#define BI_MAC_SCSIDMA 0x8016 /* Mac SCSI DMA (base address) */
+#define BI_MAC_SCSI5396 0x8017 /* Mac NCR 53C96 SCSI (base address, multi) */
+#define BI_MAC_IDETYPE 0x8018 /* Mac IDE interface type */
+#define BI_MAC_IDEBASE 0x8019 /* Mac IDE interface base address */
+#define BI_MAC_NUBUS 0x801a /* Mac Nubus type (none, regular, pseudo) */
+#define BI_MAC_SLOTMASK 0x801b /* Mac Nubus slots present */
+#define BI_MAC_SCCTYPE 0x801c /* Mac SCC serial type (normal, IOP) */
+#define BI_MAC_ETHTYPE 0x801d /* Mac builtin ethernet type (Sonic, MACE */
+#define BI_MAC_ETHBASE 0x801e /* Mac builtin ethernet base address */
+#define BI_MAC_PMU 0x801f /* Mac power management / poweroff hardware */
+#define BI_MAC_IOP_SWIM 0x8020 /* Mac SWIM floppy IOP */
+#define BI_MAC_IOP_ADB 0x8021 /* Mac ADB IOP */
+
+
+ /*
+ * Macintosh Gestalt numbers (BI_MAC_MODEL)
+ */
+
+#define MAC_MODEL_II 6
+#define MAC_MODEL_IIX 7
+#define MAC_MODEL_IICX 8
+#define MAC_MODEL_SE30 9
+#define MAC_MODEL_IICI 11
+#define MAC_MODEL_IIFX 13 /* And well numbered it is too */
+#define MAC_MODEL_IISI 18
+#define MAC_MODEL_LC 19
+#define MAC_MODEL_Q900 20
+#define MAC_MODEL_PB170 21
+#define MAC_MODEL_Q700 22
+#define MAC_MODEL_CLII 23 /* aka: P200 */
+#define MAC_MODEL_PB140 25
+#define MAC_MODEL_Q950 26 /* aka: WGS95 */
+#define MAC_MODEL_LCIII 27 /* aka: P450 */
+#define MAC_MODEL_PB210 29
+#define MAC_MODEL_C650 30
+#define MAC_MODEL_PB230 32
+#define MAC_MODEL_PB180 33
+#define MAC_MODEL_PB160 34
+#define MAC_MODEL_Q800 35 /* aka: WGS80 */
+#define MAC_MODEL_Q650 36
+#define MAC_MODEL_LCII 37 /* aka: P400/405/410/430 */
+#define MAC_MODEL_PB250 38
+#define MAC_MODEL_IIVI 44
+#define MAC_MODEL_P600 45 /* aka: P600CD */
+#define MAC_MODEL_IIVX 48
+#define MAC_MODEL_CCL 49 /* aka: P250 */
+#define MAC_MODEL_PB165C 50
+#define MAC_MODEL_C610 52 /* aka: WGS60 */
+#define MAC_MODEL_Q610 53
+#define MAC_MODEL_PB145 54 /* aka: PB145B */
+#define MAC_MODEL_P520 56 /* aka: LC520 */
+#define MAC_MODEL_C660 60
+#define MAC_MODEL_P460 62 /* aka: LCIII+, P466/P467 */
+#define MAC_MODEL_PB180C 71
+#define MAC_MODEL_PB520 72 /* aka: PB520C, PB540, PB540C, PB550C */
+#define MAC_MODEL_PB270C 77
+#define MAC_MODEL_Q840 78
+#define MAC_MODEL_P550 80 /* aka: LC550, P560 */
+#define MAC_MODEL_CCLII 83 /* aka: P275 */
+#define MAC_MODEL_PB165 84
+#define MAC_MODEL_PB190 85 /* aka: PB190CS */
+#define MAC_MODEL_TV 88
+#define MAC_MODEL_P475 89 /* aka: LC475, P476 */
+#define MAC_MODEL_P475F 90 /* aka: P475 w/ FPU (no LC040) */
+#define MAC_MODEL_P575 92 /* aka: LC575, P577/P578 */
+#define MAC_MODEL_Q605 94
+#define MAC_MODEL_Q605_ACC 95 /* Q605 accelerated to 33 MHz */
+#define MAC_MODEL_Q630 98 /* aka: LC630, P630/631/635/636/637/638/640 */
+#define MAC_MODEL_P588 99 /* aka: LC580, P580 */
+#define MAC_MODEL_PB280 102
+#define MAC_MODEL_PB280C 103
+#define MAC_MODEL_PB150 115
+
+
+ /*
+ * Latest Macintosh bootinfo version
+ */
+
+#define MAC_BOOTI_VERSION MK_BI_VERSION(2, 0)
+
+
+#endif /* _UAPI_ASM_M68K_BOOTINFO_MAC_H */
diff --git a/include/standard-headers/asm-m68k/bootinfo.h b/include/standard-headers/asm-m68k/bootinfo.h
new file mode 100644
index 000000000000..7b790e8ec8d6
--- /dev/null
+++ b/include/standard-headers/asm-m68k/bootinfo.h
@@ -0,0 +1,166 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * asm/bootinfo.h -- Definition of the Linux/m68k boot information structure
+ *
+ * Copyright 1992 by Greg Harp
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _UAPI_ASM_M68K_BOOTINFO_H
+#define _UAPI_ASM_M68K_BOOTINFO_H
+
+
+ /*
+ * Bootinfo definitions
+ *
+ * This is an easily parsable and extendable structure containing all
+ * information to be passed from the bootstrap to the kernel.
+ *
+ * This way I hope to keep all future changes back/forewards compatible.
+ * Thus, keep your fingers crossed...
+ *
+ * This structure is copied right after the kernel by the bootstrap
+ * routine.
+ */
+
+struct bi_record {
+ uint16_t tag; /* tag ID */
+ uint16_t size; /* size of record (in bytes) */
+ uint32_t data[0]; /* data */
+};
+
+
+struct mem_info {
+ uint32_t addr; /* physical address of memory chunk */
+ uint32_t size; /* length of memory chunk (in bytes) */
+};
+
+
+ /*
+ * Tag Definitions
+ *
+ * Machine independent tags start counting from 0x0000
+ * Machine dependent tags start counting from 0x8000
+ */
+
+#define BI_LAST 0x0000 /* last record (sentinel) */
+#define BI_MACHTYPE 0x0001 /* machine type (uint32_t) */
+#define BI_CPUTYPE 0x0002 /* cpu type (uint32_t) */
+#define BI_FPUTYPE 0x0003 /* fpu type (uint32_t) */
+#define BI_MMUTYPE 0x0004 /* mmu type (uint32_t) */
+#define BI_MEMCHUNK 0x0005 /* memory chunk address and size */
+ /* (struct mem_info) */
+#define BI_RAMDISK 0x0006 /* ramdisk address and size */
+ /* (struct mem_info) */
+#define BI_COMMAND_LINE 0x0007 /* kernel command line parameters */
+ /* (string) */
+
+
+ /*
+ * Linux/m68k Architectures (BI_MACHTYPE)
+ */
+
+#define MACH_AMIGA 1
+#define MACH_ATARI 2
+#define MACH_MAC 3
+#define MACH_APOLLO 4
+#define MACH_SUN3 5
+#define MACH_MVME147 6
+#define MACH_MVME16x 7
+#define MACH_BVME6000 8
+#define MACH_HP300 9
+#define MACH_Q40 10
+#define MACH_SUN3X 11
+#define MACH_M54XX 12
+#define MACH_M5441X 13
+#define MACH_VIRT 14
+
+
+ /*
+ * CPU, FPU and MMU types (BI_CPUTYPE, BI_FPUTYPE, BI_MMUTYPE)
+ *
+ * Note: we may rely on the following equalities:
+ *
+ * CPU_68020 == MMU_68851
+ * CPU_68030 == MMU_68030
+ * CPU_68040 == FPU_68040 == MMU_68040
+ * CPU_68060 == FPU_68060 == MMU_68060
+ */
+
+#define CPUB_68020 0
+#define CPUB_68030 1
+#define CPUB_68040 2
+#define CPUB_68060 3
+#define CPUB_COLDFIRE 4
+
+#define CPU_68020 (1 << CPUB_68020)
+#define CPU_68030 (1 << CPUB_68030)
+#define CPU_68040 (1 << CPUB_68040)
+#define CPU_68060 (1 << CPUB_68060)
+#define CPU_COLDFIRE (1 << CPUB_COLDFIRE)
+
+#define FPUB_68881 0
+#define FPUB_68882 1
+#define FPUB_68040 2 /* Internal FPU */
+#define FPUB_68060 3 /* Internal FPU */
+#define FPUB_SUNFPA 4 /* Sun-3 FPA */
+#define FPUB_COLDFIRE 5 /* ColdFire FPU */
+
+#define FPU_68881 (1 << FPUB_68881)
+#define FPU_68882 (1 << FPUB_68882)
+#define FPU_68040 (1 << FPUB_68040)
+#define FPU_68060 (1 << FPUB_68060)
+#define FPU_SUNFPA (1 << FPUB_SUNFPA)
+#define FPU_COLDFIRE (1 << FPUB_COLDFIRE)
+
+#define MMUB_68851 0
+#define MMUB_68030 1 /* Internal MMU */
+#define MMUB_68040 2 /* Internal MMU */
+#define MMUB_68060 3 /* Internal MMU */
+#define MMUB_APOLLO 4 /* Custom Apollo */
+#define MMUB_SUN3 5 /* Custom Sun-3 */
+#define MMUB_COLDFIRE 6 /* Internal MMU */
+
+#define MMU_68851 (1 << MMUB_68851)
+#define MMU_68030 (1 << MMUB_68030)
+#define MMU_68040 (1 << MMUB_68040)
+#define MMU_68060 (1 << MMUB_68060)
+#define MMU_SUN3 (1 << MMUB_SUN3)
+#define MMU_APOLLO (1 << MMUB_APOLLO)
+#define MMU_COLDFIRE (1 << MMUB_COLDFIRE)
+
+
+ /*
+ * Stuff for bootinfo interface versioning
+ *
+ * At the start of kernel code, a 'struct bootversion' is located.
+ * bootstrap checks for a matching version of the interface before booting
+ * a kernel, to avoid user confusion if kernel and bootstrap don't work
+ * together :-)
+ *
+ * If incompatible changes are made to the bootinfo interface, the major
+ * number below should be stepped (and the minor reset to 0) for the
+ * appropriate machine. If a change is backward-compatible, the minor
+ * should be stepped. "Backwards-compatible" means that booting will work,
+ * but certain features may not.
+ */
+
+#define BOOTINFOV_MAGIC 0x4249561A /* 'BIV^Z' */
+#define MK_BI_VERSION(major, minor) (((major) << 16) + (minor))
+#define BI_VERSION_MAJOR(v) (((v) >> 16) & 0xffff)
+#define BI_VERSION_MINOR(v) ((v) & 0xffff)
+
+struct bootversion {
+ uint16_t branch;
+ uint32_t magic;
+ struct {
+ uint32_t machtype;
+ uint32_t version;
+ } machversions[0];
+} QEMU_PACKED;
+
+
+#endif /* _UAPI_ASM_M68K_BOOTINFO_H */
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index ce4b47c3e34d..961044b3aca1 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -35,6 +35,8 @@
#include "hw/char/escc.h"
#include "hw/sysbus.h"
#include "hw/scsi/esp.h"
+#include "standard-headers/asm-m68k/bootinfo.h"
+#include "standard-headers/asm-m68k/bootinfo-mac.h"
#include "bootinfo.h"
#include "hw/misc/mac_via.h"
#include "hw/input/adb.h"
@@ -52,14 +54,6 @@
#define MACROM_FILENAME "MacROM.bin"
-#define Q800_MACHINE_ID 35
-#define Q800_CPU_ID (1 << 2)
-#define Q800_FPU_ID (1 << 2)
-#define Q800_MMU_ID (1 << 2)
-
-#define MACH_MAC 3
-#define Q800_MAC_CPU_ID 2
-
#define IO_BASE 0x50000000
#define IO_SLICE 0x00040000
#define IO_SIZE 0x04000000
@@ -348,11 +342,11 @@ static void q800_init(MachineState *machine)
parameters_base = (high + 1) & ~1;
BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_MAC);
- BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, Q800_FPU_ID);
- BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, Q800_MMU_ID);
- BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, Q800_CPU_ID);
- BOOTINFO1(cs->as, parameters_base, BI_MAC_CPUID, Q800_MAC_CPU_ID);
- BOOTINFO1(cs->as, parameters_base, BI_MAC_MODEL, Q800_MACHINE_ID);
+ BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040);
+ BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040);
+ BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040);
+ BOOTINFO1(cs->as, parameters_base, BI_MAC_CPUID, CPUB_68040);
+ BOOTINFO1(cs->as, parameters_base, BI_MAC_MODEL, MAC_MODEL_Q800);
BOOTINFO1(cs->as, parameters_base,
BI_MAC_MEMSIZE, ram_size >> 20); /* in MB */
BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size);
diff --git a/MAINTAINERS b/MAINTAINERS
index 47dd38a8cc5d..d0962a22e1b4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1094,6 +1094,8 @@ F: hw/nubus/*
F: hw/display/macfb.c
F: hw/block/swim.c
F: hw/m68k/bootinfo.h
+F: include/standard-headers/asm-m68k/bootinfo.h
+F: include/standard-headers/asm-m68k/bootinfo-mac.h
F: include/hw/misc/mac_via.h
F: include/hw/nubus/*
F: include/hw/display/macfb.h
--
2.26.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/4] char: add goldfish-tty
2020-10-13 15:51 [PATCH 0/4] m68k: add Virtual M68k Machine Laurent Vivier
2020-10-13 15:51 ` [PATCH 1/4] m68k: import bootinfo headers from linux Laurent Vivier
@ 2020-10-13 15:51 ` Laurent Vivier
2020-10-13 15:51 ` [PATCH 3/4] intc: add goldfish-pic Laurent Vivier
2020-10-13 15:51 ` [PATCH 4/4] m68k: add Virtual M68k Machine Laurent Vivier
3 siblings, 0 replies; 7+ messages in thread
From: Laurent Vivier @ 2020-10-13 15:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Laurent Vivier
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
include/hw/char/goldfish_tty.h | 36 +++++
hw/char/goldfish_tty.c | 265 +++++++++++++++++++++++++++++++++
hw/char/Kconfig | 3 +
hw/char/meson.build | 2 +
hw/char/trace-events | 9 ++
5 files changed, 315 insertions(+)
create mode 100644 include/hw/char/goldfish_tty.h
create mode 100644 hw/char/goldfish_tty.c
diff --git a/include/hw/char/goldfish_tty.h b/include/hw/char/goldfish_tty.h
new file mode 100644
index 000000000000..84d78f8cff54
--- /dev/null
+++ b/include/hw/char/goldfish_tty.h
@@ -0,0 +1,36 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * Goldfish TTY
+ *
+ * (c) 2020 Laurent Vivier <laurent@vivier.eu>
+ *
+ */
+
+#ifndef HW_CHAR_GOLDFISH_TTY_H
+#define HW_CHAR_GOLDFISH_TTY_H
+
+#include "chardev/char-fe.h"
+
+#define TYPE_GOLDFISH_TTY "goldfish_tty"
+OBJECT_DECLARE_SIMPLE_TYPE(GoldfishTTYState, GOLDFISH_TTY)
+
+#define GOLFISH_TTY_BUFFER_SIZE 128
+
+struct GoldfishTTYState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion iomem;
+ qemu_irq irq;
+ CharBackend chr;
+
+ uint32_t data_len;
+ uint64_t data_ptr;
+ bool int_enabled;
+
+ uint32_t data_in_count;
+ uint8_t data_in[GOLFISH_TTY_BUFFER_SIZE];
+ uint8_t data_out[GOLFISH_TTY_BUFFER_SIZE];
+};
+
+#endif
diff --git a/hw/char/goldfish_tty.c b/hw/char/goldfish_tty.c
new file mode 100644
index 000000000000..16cab94f333d
--- /dev/null
+++ b/hw/char/goldfish_tty.c
@@ -0,0 +1,265 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * Goldfish TTY
+ *
+ * (c) 2020 Laurent Vivier <laurent@vivier.eu>
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/sysbus.h"
+#include "migration/vmstate.h"
+#include "chardev/char-fe.h"
+#include "qemu/log.h"
+#include "trace.h"
+#include "exec/address-spaces.h"
+#include "hw/char/goldfish_tty.h"
+
+/* registers */
+
+enum {
+ REG_PUT_CHAR = 0x00,
+ REG_BYTES_READY = 0x04,
+ REG_CMD = 0x08,
+ REG_DATA_PTR = 0x10,
+ REG_DATA_LEN = 0x14,
+ REG_DATA_PTR_HIGH = 0x18,
+ REG_VERSION = 0x20,
+};
+
+/* commands */
+
+enum {
+ CMD_INT_DISABLE = 0x00,
+ CMD_INT_ENABLE = 0x01,
+ CMD_WRITE_BUFFER = 0x02,
+ CMD_READ_BUFFER = 0x03,
+};
+
+static uint64_t goldfish_tty_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ GoldfishTTYState *s = opaque;
+ uint64_t value = 0;
+
+ switch (addr) {
+ case REG_BYTES_READY:
+ value = s->data_in_count;
+ break;
+ case REG_VERSION:
+ value = 0;
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP,
+ "%s: unimplemented register read 0x%02"HWADDR_PRIx"\n",
+ __func__, addr);
+ break;
+ }
+
+ trace_goldfish_tty_read(s, addr, size, value);
+
+ return value;
+}
+
+static void goldfish_tty_cmd(GoldfishTTYState *s, uint32_t cmd)
+{
+ int to_copy;
+
+ switch (cmd) {
+ case CMD_INT_DISABLE:
+ if (s->int_enabled) {
+ if (s->data_in_count) {
+ qemu_set_irq(s->irq, 0);
+ }
+ s->int_enabled = false;
+ }
+ break;
+ case CMD_INT_ENABLE:
+ if (!s->int_enabled) {
+ if (s->data_in_count) {
+ qemu_set_irq(s->irq, 1);
+ }
+ s->int_enabled = true;
+ }
+ break;
+ case CMD_WRITE_BUFFER:
+ to_copy = s->data_len;
+ while (to_copy) {
+ int len;
+
+ len = MIN(GOLFISH_TTY_BUFFER_SIZE, to_copy);
+
+ address_space_rw(&address_space_memory, s->data_ptr,
+ MEMTXATTRS_UNSPECIFIED, s->data_out, len, 0);
+ to_copy -= len;
+ qemu_chr_fe_write_all(&s->chr, s->data_out, len);
+ }
+ break;
+ case CMD_READ_BUFFER:
+ to_copy = MIN(s->data_len, s->data_in_count);
+ address_space_rw(&address_space_memory, s->data_ptr,
+ MEMTXATTRS_UNSPECIFIED, s->data_in, to_copy, 1);
+ s->data_in_count -= to_copy;
+ memmove(s->data_in, s->data_in + to_copy, s->data_in_count);
+ if (s->int_enabled && !s->data_in_count) {
+ qemu_set_irq(s->irq, 0);
+ }
+ break;
+ }
+}
+
+static void goldfish_tty_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
+{
+ GoldfishTTYState *s = opaque;
+ unsigned char c;
+
+ trace_goldfish_tty_write(s, addr, size, value);
+
+ switch (addr) {
+ case REG_PUT_CHAR:
+ c = value;
+ qemu_chr_fe_write_all(&s->chr, &c, sizeof(c));
+ break;
+ case REG_CMD:
+ goldfish_tty_cmd(s, value);
+ break;
+ case REG_DATA_PTR:
+ s->data_ptr = value;
+ break;
+ case REG_DATA_PTR_HIGH:
+ s->data_ptr = (value << 32) | (uint32_t)s->data_ptr;
+ break;
+ case REG_DATA_LEN:
+ s->data_len = value;
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP,
+ "%s: unimplemented register write 0x%02"HWADDR_PRIx"\n",
+ __func__, addr);
+ break;
+ }
+}
+
+static const MemoryRegionOps goldfish_tty_ops = {
+ .read = goldfish_tty_read,
+ .write = goldfish_tty_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid.max_access_size = 4,
+ .impl.max_access_size = 4,
+};
+
+static int goldfish_tty_can_receive(void *opaque)
+{
+ GoldfishTTYState *s = opaque;
+ int available = GOLFISH_TTY_BUFFER_SIZE - s->data_in_count;
+
+ trace_goldfish_tty_can_receive(s, available);
+
+ return available;
+}
+
+static void goldfish_tty_receive(void *opaque, const uint8_t *buffer, int size)
+{
+ GoldfishTTYState *s = opaque;
+
+ trace_goldfish_tty_receive(s, size);
+
+ g_assert(size <= GOLFISH_TTY_BUFFER_SIZE - s->data_in_count);
+
+ memcpy(s->data_in + s->data_in_count, buffer, size);
+ s->data_in_count += size;
+
+ if (s->int_enabled && s->data_in_count) {
+ qemu_set_irq(s->irq, 1);
+ }
+}
+
+static void goldfish_tty_reset(DeviceState *dev)
+{
+ GoldfishTTYState *s = GOLDFISH_TTY(dev);
+
+ trace_goldfish_tty_reset(s);
+
+ memset(s->data_in, 0, GOLFISH_TTY_BUFFER_SIZE);
+ memset(s->data_out, 0, GOLFISH_TTY_BUFFER_SIZE);
+ s->data_in_count = 0;
+ s->int_enabled = false;
+ s->data_ptr = 0;
+ s->data_len = 0;
+}
+
+static void goldfish_tty_realize(DeviceState *dev, Error **errp)
+{
+ GoldfishTTYState *s = GOLDFISH_TTY(dev);
+
+ trace_goldfish_tty_realize(s);
+
+ memory_region_init_io(&s->iomem, OBJECT(s), &goldfish_tty_ops, s,
+ "goldfish_tty", 0x24);
+
+ if (qemu_chr_fe_backend_connected(&s->chr)) {
+ qemu_chr_fe_set_handlers(&s->chr, goldfish_tty_can_receive,
+ goldfish_tty_receive, NULL, NULL,
+ s, NULL, true);
+ }
+}
+
+static const VMStateDescription vmstate_goldfish_tty = {
+ .name = "goldfish_tty",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(data_len, GoldfishTTYState),
+ VMSTATE_UINT64(data_ptr, GoldfishTTYState),
+ VMSTATE_BOOL(int_enabled, GoldfishTTYState),
+ VMSTATE_UINT32(data_in_count, GoldfishTTYState),
+ VMSTATE_BUFFER(data_in, GoldfishTTYState),
+ VMSTATE_BUFFER(data_out, GoldfishTTYState),
+ }
+};
+
+static Property goldfish_tty_properties[] = {
+ DEFINE_PROP_CHR("chardev", GoldfishTTYState, chr),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void goldfish_tty_instance_init(Object *obj)
+{
+ SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+ GoldfishTTYState *s = GOLDFISH_TTY(obj);
+
+ trace_goldfish_tty_instance_init(s);
+
+ sysbus_init_mmio(dev, &s->iomem);
+ sysbus_init_irq(dev, &s->irq);
+}
+
+static void goldfish_tty_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ device_class_set_props(dc, goldfish_tty_properties);
+ dc->reset = goldfish_tty_reset;
+ dc->realize = goldfish_tty_realize;
+ dc->vmsd = &vmstate_goldfish_tty;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
+}
+
+static const TypeInfo goldfish_tty_info = {
+ .name = TYPE_GOLDFISH_TTY,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .class_init = goldfish_tty_class_init,
+ .instance_init = goldfish_tty_instance_init,
+ .instance_size = sizeof(GoldfishTTYState),
+};
+
+static void goldfish_tty_register_types(void)
+{
+ type_register_static(&goldfish_tty_info);
+}
+
+type_init(goldfish_tty_register_types)
diff --git a/hw/char/Kconfig b/hw/char/Kconfig
index 939bc4475883..a8bf0c6a7708 100644
--- a/hw/char/Kconfig
+++ b/hw/char/Kconfig
@@ -61,3 +61,6 @@ config MCHP_PFSOC_MMUART
config SIFIVE_UART
bool
+
+config GOLDFISH_TTY
+ bool
diff --git a/hw/char/meson.build b/hw/char/meson.build
index 196ac91fa29a..69d974873606 100644
--- a/hw/char/meson.build
+++ b/hw/char/meson.build
@@ -39,3 +39,5 @@ specific_ss.add(when: 'CONFIG_HTIF', if_true: files('riscv_htif.c'))
specific_ss.add(when: 'CONFIG_TERMINAL3270', if_true: files('terminal3270.c'))
specific_ss.add(when: 'CONFIG_VIRTIO', if_true: files('virtio-serial-bus.c'))
specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_vty.c'))
+
+specific_ss.add(when: 'CONFIG_GOLDFISH_TTY', if_true: files('goldfish_tty.c'))
diff --git a/hw/char/trace-events b/hw/char/trace-events
index 609df10fed41..88b4a6b92e39 100644
--- a/hw/char/trace-events
+++ b/hw/char/trace-events
@@ -20,6 +20,15 @@ virtio_console_flush_buf(unsigned int port, size_t len, ssize_t ret) "port %u, i
virtio_console_chr_read(unsigned int port, int size) "port %u, size %d"
virtio_console_chr_event(unsigned int port, int event) "port %u, event %d"
+# goldfish_tty.c
+goldfish_tty_read(void *dev, unsigned int addr, unsigned int size, uint64_t value) "tty: %p reg: 0x%02x size: %d value: 0x%"PRIx64
+goldfish_tty_write(void *dev, unsigned int addr, unsigned int size, uint64_t value) "tty: %p reg: 0x%02x size: %d value: 0x%"PRIx64
+goldfish_tty_can_receive(void *dev, unsigned int available) "tty: %p available: %u"
+goldfish_tty_receive(void *dev, unsigned int size) "tty: %p size: %u"
+goldfish_tty_reset(void *dev) "tty: %p"
+goldfish_tty_realize(void *dev) "tty: %p"
+goldfish_tty_instance_init(void *dev) "tty: %p"
+
# grlib_apbuart.c
grlib_apbuart_event(int event) "event:%d"
grlib_apbuart_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
--
2.26.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/4] intc: add goldfish-pic
2020-10-13 15:51 [PATCH 0/4] m68k: add Virtual M68k Machine Laurent Vivier
2020-10-13 15:51 ` [PATCH 1/4] m68k: import bootinfo headers from linux Laurent Vivier
2020-10-13 15:51 ` [PATCH 2/4] char: add goldfish-tty Laurent Vivier
@ 2020-10-13 15:51 ` Laurent Vivier
2020-10-13 15:51 ` [PATCH 4/4] m68k: add Virtual M68k Machine Laurent Vivier
3 siblings, 0 replies; 7+ messages in thread
From: Laurent Vivier @ 2020-10-13 15:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Laurent Vivier
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
include/hw/intc/goldfish_pic.h | 28 ++++++
hw/intc/goldfish_pic.c | 178 +++++++++++++++++++++++++++++++++
hw/intc/Kconfig | 3 +
hw/intc/meson.build | 1 +
hw/intc/trace-events | 8 ++
5 files changed, 218 insertions(+)
create mode 100644 include/hw/intc/goldfish_pic.h
create mode 100644 hw/intc/goldfish_pic.c
diff --git a/include/hw/intc/goldfish_pic.h b/include/hw/intc/goldfish_pic.h
new file mode 100644
index 000000000000..7886caf9df66
--- /dev/null
+++ b/include/hw/intc/goldfish_pic.h
@@ -0,0 +1,28 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * Goldfish PIC
+ *
+ * (c) 2020 Laurent Vivier <laurent@vivier.eu>
+ *
+ */
+
+#ifndef HW_INTC_GOLDFISH_PIC_H
+#define HW_INTC_GOLDFISH_PIC_H
+
+#define TYPE_GOLDFISH_PIC "goldfish_pic"
+OBJECT_DECLARE_SIMPLE_TYPE(GoldfishPICState, GOLDFISH_PIC)
+
+#define GOLDFISH_PIC_IRQ_NB 32
+
+struct GoldfishPICState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion iomem;
+ qemu_irq irq;
+
+ uint32_t pending;
+ uint32_t enabled;
+};
+
+#endif
diff --git a/hw/intc/goldfish_pic.c b/hw/intc/goldfish_pic.c
new file mode 100644
index 000000000000..9007928e0aca
--- /dev/null
+++ b/hw/intc/goldfish_pic.c
@@ -0,0 +1,178 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * Goldfish PIC
+ *
+ * (c) 2020 Laurent Vivier <laurent@vivier.eu>
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/sysbus.h"
+#include "migration/vmstate.h"
+#include "qemu/log.h"
+#include "trace.h"
+#include "hw/intc/goldfish_pic.h"
+
+/* registers */
+
+enum {
+ REG_STATUS = 0x00,
+ REG_IRQ_PENDING = 0x04,
+ REG_IRQ_DISABLE_ALL = 0x08,
+ REG_DISABLE = 0x0c,
+ REG_ENABLE = 0x10,
+};
+
+static void goldfish_pic_update(GoldfishPICState *s)
+{
+ if (s->pending & s->enabled) {
+ qemu_irq_raise(s->irq);
+ } else {
+ qemu_irq_lower(s->irq);
+ }
+}
+
+static void goldfish_irq_request(void *opaque, int irq, int level)
+{
+ GoldfishPICState *s = opaque;
+
+ trace_goldfish_irq_request(s, irq, level);
+
+ if (level) {
+ s->pending |= 1 << irq;
+ } else {
+ s->pending &= ~(1 << irq);
+ }
+ goldfish_pic_update(s);
+}
+
+static uint64_t goldfish_pic_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ GoldfishPICState *s = opaque;
+ uint64_t value = 0;
+
+ switch (addr) {
+ case REG_STATUS:
+ /* The number of pending interrupts (0 to 32) */
+ value = ctpop32(s->pending & s->enabled);
+ break;
+ case REG_IRQ_PENDING:
+ /* The pending interrupt mask */
+ value = s->pending & s->enabled;
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP,
+ "%s: unimplemented register read 0x%02"HWADDR_PRIx"\n",
+ __func__, addr);
+ break;
+ }
+
+ trace_goldfish_pic_read(s, addr, size, value);
+
+ return value;
+}
+
+static void goldfish_pic_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
+{
+ GoldfishPICState *s = opaque;
+
+ trace_goldfish_pic_write(s, addr, size, value);
+
+ switch (addr) {
+ case REG_IRQ_DISABLE_ALL:
+ s->enabled = 0;
+ s->pending = 0;
+ break;
+ case REG_DISABLE:
+ s->enabled &= ~value;
+ break;
+ case REG_ENABLE:
+ s->enabled |= value;
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP,
+ "%s: unimplemented register write 0x%02"HWADDR_PRIx"\n",
+ __func__, addr);
+ break;
+ }
+ goldfish_pic_update(s);
+}
+
+static const MemoryRegionOps goldfish_pic_ops = {
+ .read = goldfish_pic_read,
+ .write = goldfish_pic_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid.max_access_size = 4,
+ .impl.max_access_size = 4,
+};
+
+static void goldfish_pic_reset(DeviceState *dev)
+{
+ GoldfishPICState *s = GOLDFISH_PIC(dev);
+
+ trace_goldfish_pic_reset(s);
+ s->pending = 0;
+ s->enabled = 0;
+}
+
+static void goldfish_pic_realize(DeviceState *dev, Error **errp)
+{
+ GoldfishPICState *s = GOLDFISH_PIC(dev);
+
+ trace_goldfish_pic_realize(s);
+
+ memory_region_init_io(&s->iomem, OBJECT(s), &goldfish_pic_ops, s,
+ "goldfish_pic", 0x24);
+}
+
+static const VMStateDescription vmstate_goldfish_pic = {
+ .name = "goldfish_pic",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(pending, GoldfishPICState),
+ VMSTATE_UINT32(enabled, GoldfishPICState),
+ }
+};
+
+static void goldfish_pic_instance_init(Object *obj)
+{
+ SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+ GoldfishPICState *s = GOLDFISH_PIC(obj);
+
+ trace_goldfish_pic_instance_init(s);
+
+ sysbus_init_mmio(dev, &s->iomem);
+ sysbus_init_irq(dev, &s->irq);
+
+ qdev_init_gpio_in(DEVICE(obj), goldfish_irq_request, GOLDFISH_PIC_IRQ_NB);
+}
+
+static void goldfish_pic_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ dc->reset = goldfish_pic_reset;
+ dc->realize = goldfish_pic_realize;
+ dc->vmsd = &vmstate_goldfish_pic;
+}
+
+static const TypeInfo goldfish_pic_info = {
+ .name = TYPE_GOLDFISH_PIC,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .class_init = goldfish_pic_class_init,
+ .instance_init = goldfish_pic_instance_init,
+ .instance_size = sizeof(GoldfishPICState),
+};
+
+static void goldfish_pic_register_types(void)
+{
+ type_register_static(&goldfish_pic_info);
+}
+
+type_init(goldfish_pic_register_types)
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index d07954086a59..7ed79e7ac29f 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -73,3 +73,6 @@ config SIFIVE_CLINT
config SIFIVE_PLIC
bool
+
+config GOLDFISH_PIC
+ bool
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index 3f82cc230ad7..395bc2f64036 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -55,3 +55,4 @@ specific_ss.add(when: 'CONFIG_XICS_SPAPR', if_true: files('xics_spapr.c'))
specific_ss.add(when: 'CONFIG_XIVE', if_true: files('xive.c'))
specific_ss.add(when: 'CONFIG_XIVE_KVM', if_true: files('spapr_xive_kvm.c'))
specific_ss.add(when: 'CONFIG_XIVE_SPAPR', if_true: files('spapr_xive.c'))
+specific_ss.add(when: 'CONFIG_GOLDFISH_PIC', if_true: files('goldfish_pic.c'))
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 527c3f76caed..4b4c679c8b41 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -199,3 +199,11 @@ nvic_sysreg_write(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg wri
heathrow_write(uint64_t addr, unsigned int n, uint64_t value) "0x%"PRIx64" %u: 0x%"PRIx64
heathrow_read(uint64_t addr, unsigned int n, uint64_t value) "0x%"PRIx64" %u: 0x%"PRIx64
heathrow_set_irq(int num, int level) "set_irq: num=0x%02x level=%d"
+
+# # goldfish_pic.c
+goldfish_irq_request(void *dev, int irq, int level) "pic: %p irq: %d level: %d"
+goldfish_pic_read(void *dev, unsigned int addr, unsigned int size, uint64_t value) "pic: %p reg: 0x%02x size: %d value: 0x%"PRIx64
+goldfish_pic_write(void *dev, unsigned int addr, unsigned int size, uint64_t value) "pic: %p reg: 0x%02x size: %d value: 0x%"PRIx64
+goldfish_pic_reset(void *dev) "pic: %p"
+goldfish_pic_realize(void *dev) "pic: %p"
+goldfish_pic_instance_init(void *dev) "pic: %p"
--
2.26.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 4/4] m68k: add Virtual M68k Machine
2020-10-13 15:51 [PATCH 0/4] m68k: add Virtual M68k Machine Laurent Vivier
` (2 preceding siblings ...)
2020-10-13 15:51 ` [PATCH 3/4] intc: add goldfish-pic Laurent Vivier
@ 2020-10-13 15:51 ` Laurent Vivier
2020-10-13 17:56 ` Philippe Mathieu-Daudé
3 siblings, 1 reply; 7+ messages in thread
From: Laurent Vivier @ 2020-10-13 15:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Laurent Vivier
The machine is based on Goldfish interfaces defined by Google
for Android simulator. It uses Goldfish-rtc (timer and RTC),
Goldfish-pic (PIC) and Goldfish-tty (for serial port and early tty).
The machine is created with 128 virtio-mmio bus, and they can
be used to use serial console, GPU, disk, NIC, HID, ...
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
default-configs/devices/m68k-softmmu.mak | 1 +
.../standard-headers/asm-m68k/bootinfo-virt.h | 17 +
hw/m68k/virt.c | 296 ++++++++++++++++++
MAINTAINERS | 9 +
hw/m68k/Kconfig | 8 +
hw/m68k/meson.build | 1 +
6 files changed, 332 insertions(+)
create mode 100644 include/standard-headers/asm-m68k/bootinfo-virt.h
create mode 100644 hw/m68k/virt.c
diff --git a/default-configs/devices/m68k-softmmu.mak b/default-configs/devices/m68k-softmmu.mak
index 6629fd2aa330..7f8619e42786 100644
--- a/default-configs/devices/m68k-softmmu.mak
+++ b/default-configs/devices/m68k-softmmu.mak
@@ -8,3 +8,4 @@ CONFIG_AN5206=y
CONFIG_MCF5208=y
CONFIG_NEXTCUBE=y
CONFIG_Q800=y
+CONFIG_M68K_VIRT=y
diff --git a/include/standard-headers/asm-m68k/bootinfo-virt.h b/include/standard-headers/asm-m68k/bootinfo-virt.h
new file mode 100644
index 000000000000..b3d90a601513
--- /dev/null
+++ b/include/standard-headers/asm-m68k/bootinfo-virt.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+** asm/bootinfo-virt.h -- Virtual-m68k-specific boot information definitions
+*/
+
+#ifndef _UAPI_ASM_M68K_BOOTINFO_VIRT_H
+#define _UAPI_ASM_M68K_BOOTINFO_VIRT_H
+
+#define BI_VIRT_QEMU_VERSION 0x8000
+#define BI_VIRT_GF_PIC_BASE 0x8001
+#define BI_VIRT_GF_RTC_BASE 0x8002
+#define BI_VIRT_GF_TTY_BASE 0x8003
+#define BI_VIRT_VIRTIO_BASE 0x8004
+
+#define VIRT_BOOTI_VERSION MK_BI_VERSION(2, 0)
+
+#endif /* _UAPI_ASM_M68K_BOOTINFO_MAC_H */
diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
new file mode 100644
index 000000000000..8b89373dafdb
--- /dev/null
+++ b/hw/m68k/virt.c
@@ -0,0 +1,296 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * QEMU Vitual M68K Machine
+ *
+ * (c) 2020 Laurent Vivier <laurent@vivier.eu>
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qemu-common.h"
+#include "sysemu/sysemu.h"
+#include "cpu.h"
+#include "hw/hw.h"
+#include "hw/boards.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "elf.h"
+#include "hw/loader.h"
+#include "ui/console.h"
+#include "exec/address-spaces.h"
+#include "hw/sysbus.h"
+#include "standard-headers/asm-m68k/bootinfo.h"
+#include "standard-headers/asm-m68k/bootinfo-virt.h"
+#include "bootinfo.h"
+#include "net/net.h"
+#include "qapi/error.h"
+#include "sysemu/qtest.h"
+#include "sysemu/runstate.h"
+#include "sysemu/reset.h"
+
+#include "hw/char/goldfish_tty.h"
+#include "hw/rtc/goldfish_rtc.h"
+#include "hw/intc/goldfish_pic.h"
+#include "hw/virtio/virtio-mmio.h"
+#include "hw/virtio/virtio-blk.h"
+
+/*
+ * 6 goldfish-pic for CPU IRQ #1 to IRQ #6
+ * CPU IRQ #1 -> PIC #1
+ * IRQ #1 to IRQ #31 -> unused
+ * IRQ #32 -> goldfish-tty
+ * CPU IRQ #2 -> PIC #2
+ * IRQ #1 to IRQ #32 -> virtio-mmio from 1 to 32
+ * CPU IRQ #3 -> PIC #3
+ * IRQ #1 to IRQ #32 -> virtio-mmio from 33 to 64
+ * CPU IRQ #4 -> PIC #4
+ * IRQ #1 to IRQ #32 -> virtio-mmio from 65 to 96
+ * CPU IRQ #5 -> PIC #5
+ * IRQ #1 to IRQ #32 -> virtio-mmio from 97 to 128
+ * CPU IRQ #6 -> PIC #5
+ * IRQ #1 -> goldfish-rtc
+ * IRQ #2 to IRQ #32 -> unused
+ * CPU IRQ #7 -> NMI
+ */
+
+#define PIC_IRQ_BASE(num) (8 + (num - 1) * 32)
+#define PIC_IRQ(num, irq) (PIC_IRQ_BASE(num) + irq - 1)
+#define PIC_GPIO(pic_irq) (qdev_get_gpio_in(pic_dev[(pic_irq - 8) / 32], \
+ (pic_irq - 8) % 32))
+
+#define VIRT_GF_PIC_MMIO_BASE 0xff000000 /* MMIO: 0xff000000 - 0xff005fff */
+#define VIRT_GF_PIC_IRQ_BASE 1 /* IRQ: #1 -> #6 */
+
+/* 1 goldfish-rtc (and timer) */
+#define VIRT_GF_RTC_MMIO_BASE 0xff006000 /* MMIO: 0xff006000 - 0xff006fff */
+#define VIRT_GF_RTC_IRQ_BASE PIC_IRQ(6, 1) /* PIC: #6, IRQ: #1 */
+
+/* 1 goldfish-tty */
+#define VIRT_GF_TTY_MMIO_BASE 0xff007000 /* MMIO: 0xff007000 - 0xff007000 */
+#define VIRT_GF_TTY_IRQ_BASE PIC_IRQ(1, 32) /* PIC: #1, IRQ: #32 */
+/*
+ * virtio-mmio size is 0x200 bytes
+ * we use 4 goldfish-pic to attach them,
+ * we can attach 32 virtio devices / goldfish-pic
+ * -> we can manage 32 * 4 = 128 virtio devices
+ */
+#define VIRT_VIRTIO_MMIO_BASE 0xff010000 /* MMIO: 0xff010000 - 0xff01ffff */
+#define VIRT_VIRTIO_IRQ_BASE PIC_IRQ(2, 1) /* PIC: 2, 3, 4, 5, IRQ: ALL */
+
+/*
+ * The GLUE (General Logic Unit) is an Apple custom integrated circuit chip
+ * that performs a variety of functions (RAM management, clock generation, ...).
+ * The GLUE chip receives interrupt requests from various devices,
+ * assign priority to each, and asserts one or more interrupt line to the
+ * CPU.
+ */
+
+typedef struct {
+ M68kCPU *cpu;
+ uint8_t ipr;
+} GLUEState;
+
+static void GLUE_set_irq(void *opaque, int irq, int level)
+{
+ GLUEState *s = opaque;
+ int i;
+
+ if (level) {
+ s->ipr |= 1 << irq;
+ } else {
+ s->ipr &= ~(1 << irq);
+ }
+
+ for (i = 7; i >= 0; i--) {
+ if ((s->ipr >> i) & 1) {
+ m68k_set_irq_level(s->cpu, i + 1, i + 25);
+ return;
+ }
+ }
+ m68k_set_irq_level(s->cpu, 0, 0);
+}
+
+static void main_cpu_reset(void *opaque)
+{
+ M68kCPU *cpu = opaque;
+ CPUState *cs = CPU(cpu);
+
+ cpu_reset(cs);
+ cpu->env.aregs[7] = ldl_phys(cs->as, 0);
+ cpu->env.pc = ldl_phys(cs->as, 4);
+}
+
+static void virt_init(MachineState *machine)
+{
+ M68kCPU *cpu = NULL;
+ int32_t kernel_size;
+ uint64_t elf_entry;
+ ram_addr_t initrd_base;
+ int32_t initrd_size;
+ ram_addr_t ram_size = machine->ram_size;
+ const char *kernel_filename = machine->kernel_filename;
+ const char *initrd_filename = machine->initrd_filename;
+ const char *kernel_cmdline = machine->kernel_cmdline;
+ hwaddr parameters_base;
+ DeviceState *dev;
+ DeviceState *pic_dev[7];
+ GLUEState *irq;
+ qemu_irq *cpu_pic;
+ SysBusDevice *sysbus;
+ hwaddr io_base;
+ int i;
+
+
+ if (ram_size > 3399672 * KiB) {
+ /*
+ * The physical memory can be up to 4 GiB - 16 MiB, but linux
+ * kernel crashes after this limit (~ 3.2 GiB)
+ */
+ error_report("Too much memory for this machine: %" PRId64 " KiB, "
+ "maximum 3399672 KiB", ram_size / KiB);
+ exit(1);
+ }
+
+ /* init CPUs */
+ cpu = M68K_CPU(cpu_create(machine->cpu_type));
+ qemu_register_reset(main_cpu_reset, cpu);
+
+ /* RAM */
+ memory_region_add_subregion(get_system_memory(), 0, machine->ram);
+
+ /* IRQ Glue */
+
+ irq = g_new0(GLUEState, 1);
+ irq->cpu = cpu;
+ cpu_pic = qemu_allocate_irqs(GLUE_set_irq, irq, 8);
+
+ /*
+ * 6 goldfish-pic
+ *
+ * map: 0xff000000 - 0xff006fff = 28 KiB
+ * IRQ: #1 (lower priority) -> #6 (higher priority)
+ *
+ */
+ io_base = VIRT_GF_PIC_MMIO_BASE;
+ for (i = 0; i < 6; i++) {
+ pic_dev[i] = qdev_new(TYPE_GOLDFISH_PIC);
+ sysbus = SYS_BUS_DEVICE(pic_dev[i]);
+ sysbus_realize_and_unref(sysbus, &error_fatal);
+
+ sysbus_mmio_map(sysbus, 0, io_base);
+ sysbus_connect_irq(sysbus, 0, cpu_pic[i]);
+
+ io_base += 0x1000;
+ }
+
+ /* goldfish-rtc */
+ dev = qdev_new(TYPE_GOLDFISH_RTC);
+ sysbus = SYS_BUS_DEVICE(dev);
+ sysbus_realize_and_unref(sysbus, &error_fatal);
+ sysbus_mmio_map(sysbus, 0, VIRT_GF_RTC_MMIO_BASE);
+ sysbus_connect_irq(sysbus, 0, PIC_GPIO(VIRT_GF_RTC_IRQ_BASE));
+
+ /* goldfish-tty */
+ dev = qdev_new(TYPE_GOLDFISH_TTY);
+ sysbus = SYS_BUS_DEVICE(dev);
+ qdev_prop_set_chr(dev, "chardev", serial_hd(0));
+ sysbus_realize_and_unref(sysbus, &error_fatal);
+ sysbus_mmio_map(sysbus, 0, VIRT_GF_TTY_MMIO_BASE);
+ sysbus_connect_irq(sysbus, 0, PIC_GPIO(VIRT_GF_TTY_IRQ_BASE));
+
+ /* virtio-mmio */
+ io_base = VIRT_VIRTIO_MMIO_BASE;
+ for (i = 0; i < 128; i++) {
+ dev = qdev_new(TYPE_VIRTIO_MMIO);
+ qdev_prop_set_bit(dev, "force-legacy", false);
+ sysbus = SYS_BUS_DEVICE(dev);
+ sysbus_realize_and_unref(sysbus, &error_fatal);
+ sysbus_connect_irq(sysbus, 0, PIC_GPIO(VIRT_VIRTIO_IRQ_BASE + i));
+ sysbus_mmio_map(sysbus, 0, io_base);
+ io_base += 0x200;
+ }
+
+ if (kernel_filename) {
+ CPUState *cs = CPU(cpu);
+ uint64_t high;
+
+ kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
+ &elf_entry, NULL, &high, NULL, 1,
+ EM_68K, 0, 0);
+ if (kernel_size < 0) {
+ error_report("could not load kernel '%s'", kernel_filename);
+ exit(1);
+ }
+ stl_phys(cs->as, 4, elf_entry); /* reset initial PC */
+ parameters_base = (high + 1) & ~1;
+
+ BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_VIRT);
+ BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040);
+ BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040);
+ BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040);
+ BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size);
+
+ BOOTINFO1(cs->as, parameters_base, BI_VIRT_QEMU_VERSION,
+ ((QEMU_VERSION_MAJOR << 24) | (QEMU_VERSION_MICRO << 16) |
+ (QEMU_VERSION_MINOR << 8)));
+ BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_PIC_BASE,
+ VIRT_GF_PIC_MMIO_BASE, VIRT_GF_PIC_IRQ_BASE);
+ BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_RTC_BASE,
+ VIRT_GF_RTC_MMIO_BASE, VIRT_GF_RTC_IRQ_BASE);
+ BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_TTY_BASE,
+ VIRT_GF_TTY_MMIO_BASE, VIRT_GF_TTY_IRQ_BASE);
+ BOOTINFO2(cs->as, parameters_base, BI_VIRT_VIRTIO_BASE,
+ VIRT_VIRTIO_MMIO_BASE, VIRT_VIRTIO_IRQ_BASE);
+
+ if (kernel_cmdline) {
+ BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE,
+ kernel_cmdline);
+ }
+
+ /* load initrd */
+ if (initrd_filename) {
+ initrd_size = get_image_size(initrd_filename);
+ if (initrd_size < 0) {
+ error_report("could not load initial ram disk '%s'",
+ initrd_filename);
+ exit(1);
+ }
+
+ initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
+ load_image_targphys(initrd_filename, initrd_base,
+ ram_size - initrd_base);
+ BOOTINFO2(cs->as, parameters_base, BI_RAMDISK, initrd_base,
+ initrd_size);
+ } else {
+ initrd_base = 0;
+ initrd_size = 0;
+ }
+ BOOTINFO0(cs->as, parameters_base, BI_LAST);
+ }
+}
+
+static void virt_machine_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+ mc->desc = "M68k Virtual Machine";
+ mc->init = virt_init;
+ mc->default_cpu_type = M68K_CPU_TYPE_NAME("m68040");
+ mc->max_cpus = 1;
+ mc->block_default_type = IF_SCSI;
+ mc->default_ram_id = "m68k_virt.ram";
+}
+
+static const TypeInfo virt_machine_typeinfo = {
+ .name = MACHINE_TYPE_NAME("virt"),
+ .parent = TYPE_MACHINE,
+ .class_init = virt_machine_class_init,
+};
+
+static void virt_machine_register_types(void)
+{
+ type_register_static(&virt_machine_typeinfo);
+}
+
+type_init(virt_machine_register_types)
diff --git a/MAINTAINERS b/MAINTAINERS
index d0962a22e1b4..b08cf4251246 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1101,6 +1101,15 @@ F: include/hw/nubus/*
F: include/hw/display/macfb.h
F: include/hw/block/swim.h
+virt
+M: Laurent Vivier <laurent@vivier.eu>
+S: Maintained
+F: hw/m68k/virt.c
+F: hw/char/goldfish_tty.c
+F: hw/intc/goldfish_pic.c
+F: include/hw/char/goldfish_tty.h
+F: include/hw/intc/goldfish_pic.h
+
MicroBlaze Machines
-------------------
petalogix_s3adsp1800
diff --git a/hw/m68k/Kconfig b/hw/m68k/Kconfig
index c757e7dfa48b..f4b3b115270e 100644
--- a/hw/m68k/Kconfig
+++ b/hw/m68k/Kconfig
@@ -22,3 +22,11 @@ config Q800
select ESCC
select ESP
select DP8393X
+
+config M68K_VIRT
+ bool
+ select GOLDFISH_PIC
+ select GOLDFISH_TTY
+ select GOLDFISH_RTC
+ select VIRTIO
+ select VIRTIO_MMIO
diff --git a/hw/m68k/meson.build b/hw/m68k/meson.build
index ca0044c652d3..31248641d301 100644
--- a/hw/m68k/meson.build
+++ b/hw/m68k/meson.build
@@ -3,5 +3,6 @@ m68k_ss.add(when: 'CONFIG_AN5206', if_true: files('an5206.c', 'mcf5206.c'))
m68k_ss.add(when: 'CONFIG_MCF5208', if_true: files('mcf5208.c', 'mcf_intc.c'))
m68k_ss.add(when: 'CONFIG_NEXTCUBE', if_true: files('next-kbd.c', 'next-cube.c'))
m68k_ss.add(when: 'CONFIG_Q800', if_true: files('q800.c'))
+m68k_ss.add(when: 'CONFIG_M68K_VIRT', if_true: files('virt.c'))
hw_arch += {'m68k': m68k_ss}
--
2.26.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 4/4] m68k: add Virtual M68k Machine
2020-10-13 15:51 ` [PATCH 4/4] m68k: add Virtual M68k Machine Laurent Vivier
@ 2020-10-13 17:56 ` Philippe Mathieu-Daudé
2020-10-13 19:01 ` Laurent Vivier
0 siblings, 1 reply; 7+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-10-13 17:56 UTC (permalink / raw)
To: Laurent Vivier, qemu-devel
On 10/13/20 5:51 PM, Laurent Vivier wrote:
> The machine is based on Goldfish interfaces defined by Google
> for Android simulator. It uses Goldfish-rtc (timer and RTC),
> Goldfish-pic (PIC) and Goldfish-tty (for serial port and early tty).
>
> The machine is created with 128 virtio-mmio bus, and they can
> be used to use serial console, GPU, disk, NIC, HID, ...
>
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
> default-configs/devices/m68k-softmmu.mak | 1 +
> .../standard-headers/asm-m68k/bootinfo-virt.h | 17 +
> hw/m68k/virt.c | 296 ++++++++++++++++++
> MAINTAINERS | 9 +
> hw/m68k/Kconfig | 8 +
> hw/m68k/meson.build | 1 +
> 6 files changed, 332 insertions(+)
> create mode 100644 include/standard-headers/asm-m68k/bootinfo-virt.h
> create mode 100644 hw/m68k/virt.c
>
> diff --git a/default-configs/devices/m68k-softmmu.mak b/default-configs/devices/m68k-softmmu.mak
> index 6629fd2aa330..7f8619e42786 100644
> --- a/default-configs/devices/m68k-softmmu.mak
> +++ b/default-configs/devices/m68k-softmmu.mak
> @@ -8,3 +8,4 @@ CONFIG_AN5206=y
> CONFIG_MCF5208=y
> CONFIG_NEXTCUBE=y
> CONFIG_Q800=y
> +CONFIG_M68K_VIRT=y
> diff --git a/include/standard-headers/asm-m68k/bootinfo-virt.h b/include/standard-headers/asm-m68k/bootinfo-virt.h
> new file mode 100644
> index 000000000000..b3d90a601513
> --- /dev/null
> +++ b/include/standard-headers/asm-m68k/bootinfo-virt.h
> @@ -0,0 +1,17 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +/*
> +** asm/bootinfo-virt.h -- Virtual-m68k-specific boot information definitions
> +*/
> +
> +#ifndef _UAPI_ASM_M68K_BOOTINFO_VIRT_H
> +#define _UAPI_ASM_M68K_BOOTINFO_VIRT_H
> +
> +#define BI_VIRT_QEMU_VERSION 0x8000
> +#define BI_VIRT_GF_PIC_BASE 0x8001
> +#define BI_VIRT_GF_RTC_BASE 0x8002
> +#define BI_VIRT_GF_TTY_BASE 0x8003
> +#define BI_VIRT_VIRTIO_BASE 0x8004
> +
> +#define VIRT_BOOTI_VERSION MK_BI_VERSION(2, 0)
> +
> +#endif /* _UAPI_ASM_M68K_BOOTINFO_MAC_H */
> diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
> new file mode 100644
> index 000000000000..8b89373dafdb
> --- /dev/null
> +++ b/hw/m68k/virt.c
> @@ -0,0 +1,296 @@
> +/*
> + * SPDX-License-Identifer: GPL-2.0-or-later
> + *
> + * QEMU Vitual M68K Machine
> + *
> + * (c) 2020 Laurent Vivier <laurent@vivier.eu>
> + *
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/units.h"
> +#include "qemu-common.h"
> +#include "sysemu/sysemu.h"
> +#include "cpu.h"
> +#include "hw/hw.h"
> +#include "hw/boards.h"
> +#include "hw/irq.h"
> +#include "hw/qdev-properties.h"
> +#include "elf.h"
> +#include "hw/loader.h"
> +#include "ui/console.h"
> +#include "exec/address-spaces.h"
> +#include "hw/sysbus.h"
> +#include "standard-headers/asm-m68k/bootinfo.h"
> +#include "standard-headers/asm-m68k/bootinfo-virt.h"
> +#include "bootinfo.h"
> +#include "net/net.h"
> +#include "qapi/error.h"
> +#include "sysemu/qtest.h"
> +#include "sysemu/runstate.h"
> +#include "sysemu/reset.h"
> +
> +#include "hw/char/goldfish_tty.h"
> +#include "hw/rtc/goldfish_rtc.h"
> +#include "hw/intc/goldfish_pic.h"
> +#include "hw/virtio/virtio-mmio.h"
> +#include "hw/virtio/virtio-blk.h"
> +
> +/*
> + * 6 goldfish-pic for CPU IRQ #1 to IRQ #6
> + * CPU IRQ #1 -> PIC #1
> + * IRQ #1 to IRQ #31 -> unused
> + * IRQ #32 -> goldfish-tty
> + * CPU IRQ #2 -> PIC #2
> + * IRQ #1 to IRQ #32 -> virtio-mmio from 1 to 32
> + * CPU IRQ #3 -> PIC #3
> + * IRQ #1 to IRQ #32 -> virtio-mmio from 33 to 64
> + * CPU IRQ #4 -> PIC #4
> + * IRQ #1 to IRQ #32 -> virtio-mmio from 65 to 96
> + * CPU IRQ #5 -> PIC #5
> + * IRQ #1 to IRQ #32 -> virtio-mmio from 97 to 128
> + * CPU IRQ #6 -> PIC #5
> + * IRQ #1 -> goldfish-rtc
> + * IRQ #2 to IRQ #32 -> unused
> + * CPU IRQ #7 -> NMI
> + */
> +
> +#define PIC_IRQ_BASE(num) (8 + (num - 1) * 32)
> +#define PIC_IRQ(num, irq) (PIC_IRQ_BASE(num) + irq - 1)
> +#define PIC_GPIO(pic_irq) (qdev_get_gpio_in(pic_dev[(pic_irq - 8) / 32], \
> + (pic_irq - 8) % 32))
> +
> +#define VIRT_GF_PIC_MMIO_BASE 0xff000000 /* MMIO: 0xff000000 - 0xff005fff */
> +#define VIRT_GF_PIC_IRQ_BASE 1 /* IRQ: #1 -> #6 */
> +
> +/* 1 goldfish-rtc (and timer) */
> +#define VIRT_GF_RTC_MMIO_BASE 0xff006000 /* MMIO: 0xff006000 - 0xff006fff */
> +#define VIRT_GF_RTC_IRQ_BASE PIC_IRQ(6, 1) /* PIC: #6, IRQ: #1 */
> +
> +/* 1 goldfish-tty */
> +#define VIRT_GF_TTY_MMIO_BASE 0xff007000 /* MMIO: 0xff007000 - 0xff007000 */
> +#define VIRT_GF_TTY_IRQ_BASE PIC_IRQ(1, 32) /* PIC: #1, IRQ: #32 */
> +/*
> + * virtio-mmio size is 0x200 bytes
> + * we use 4 goldfish-pic to attach them,
> + * we can attach 32 virtio devices / goldfish-pic
> + * -> we can manage 32 * 4 = 128 virtio devices
> + */
> +#define VIRT_VIRTIO_MMIO_BASE 0xff010000 /* MMIO: 0xff010000 - 0xff01ffff */
> +#define VIRT_VIRTIO_IRQ_BASE PIC_IRQ(2, 1) /* PIC: 2, 3, 4, 5, IRQ: ALL */
> +
> +/*
> + * The GLUE (General Logic Unit) is an Apple custom integrated circuit chip
> + * that performs a variety of functions (RAM management, clock generation, ...).
> + * The GLUE chip receives interrupt requests from various devices,
> + * assign priority to each, and asserts one or more interrupt line to the
> + * CPU.
Does your virt machine really requires a GLUE? Or only another
cascaded PIC?
> + */
> +
> +typedef struct {
> + M68kCPU *cpu;
> + uint8_t ipr;
> +} GLUEState;
> +
> +static void GLUE_set_irq(void *opaque, int irq, int level)
> +{
> + GLUEState *s = opaque;
> + int i;
> +
> + if (level) {
> + s->ipr |= 1 << irq;
> + } else {
> + s->ipr &= ~(1 << irq);
> + }
> +
> + for (i = 7; i >= 0; i--) {
> + if ((s->ipr >> i) & 1) {
> + m68k_set_irq_level(s->cpu, i + 1, i + 25);
> + return;
> + }
> + }
> + m68k_set_irq_level(s->cpu, 0, 0);
> +}
> +
> +static void main_cpu_reset(void *opaque)
> +{
> + M68kCPU *cpu = opaque;
> + CPUState *cs = CPU(cpu);
> +
> + cpu_reset(cs);
> + cpu->env.aregs[7] = ldl_phys(cs->as, 0);
> + cpu->env.pc = ldl_phys(cs->as, 4);
> +}
> +
> +static void virt_init(MachineState *machine)
> +{
> + M68kCPU *cpu = NULL;
> + int32_t kernel_size;
> + uint64_t elf_entry;
> + ram_addr_t initrd_base;
> + int32_t initrd_size;
> + ram_addr_t ram_size = machine->ram_size;
> + const char *kernel_filename = machine->kernel_filename;
> + const char *initrd_filename = machine->initrd_filename;
> + const char *kernel_cmdline = machine->kernel_cmdline;
> + hwaddr parameters_base;
> + DeviceState *dev;
> + DeviceState *pic_dev[7];
> + GLUEState *irq;
> + qemu_irq *cpu_pic;
> + SysBusDevice *sysbus;
> + hwaddr io_base;
> + int i;
> +
> +
> + if (ram_size > 3399672 * KiB) {
> + /*
> + * The physical memory can be up to 4 GiB - 16 MiB, but linux
> + * kernel crashes after this limit (~ 3.2 GiB)
> + */
> + error_report("Too much memory for this machine: %" PRId64 " KiB, "
> + "maximum 3399672 KiB", ram_size / KiB);
> + exit(1);
> + }
> +
> + /* init CPUs */
> + cpu = M68K_CPU(cpu_create(machine->cpu_type));
Due to BOOTINFO1(..., BI_CPUTYPE, CPU_68040) below, don't you
need to check machine->cpu_type == M68K_CPU_TYPE_NAME("m68040")?
> + qemu_register_reset(main_cpu_reset, cpu);
> +
> + /* RAM */
> + memory_region_add_subregion(get_system_memory(), 0, machine->ram);
> +
> + /* IRQ Glue */
> +
> + irq = g_new0(GLUEState, 1);
> + irq->cpu = cpu;
> + cpu_pic = qemu_allocate_irqs(GLUE_set_irq, irq, 8);
> +
> + /*
> + * 6 goldfish-pic
> + *
> + * map: 0xff000000 - 0xff006fff = 28 KiB
> + * IRQ: #1 (lower priority) -> #6 (higher priority)
> + *
> + */
> + io_base = VIRT_GF_PIC_MMIO_BASE;
> + for (i = 0; i < 6; i++) {
> + pic_dev[i] = qdev_new(TYPE_GOLDFISH_PIC);
> + sysbus = SYS_BUS_DEVICE(pic_dev[i]);
> + sysbus_realize_and_unref(sysbus, &error_fatal);
> +
> + sysbus_mmio_map(sysbus, 0, io_base);
> + sysbus_connect_irq(sysbus, 0, cpu_pic[i]);
> +
> + io_base += 0x1000;
> + }
> +
> + /* goldfish-rtc */
> + dev = qdev_new(TYPE_GOLDFISH_RTC);
> + sysbus = SYS_BUS_DEVICE(dev);
> + sysbus_realize_and_unref(sysbus, &error_fatal);
> + sysbus_mmio_map(sysbus, 0, VIRT_GF_RTC_MMIO_BASE);
> + sysbus_connect_irq(sysbus, 0, PIC_GPIO(VIRT_GF_RTC_IRQ_BASE));
> +
> + /* goldfish-tty */
> + dev = qdev_new(TYPE_GOLDFISH_TTY);
> + sysbus = SYS_BUS_DEVICE(dev);
> + qdev_prop_set_chr(dev, "chardev", serial_hd(0));
> + sysbus_realize_and_unref(sysbus, &error_fatal);
> + sysbus_mmio_map(sysbus, 0, VIRT_GF_TTY_MMIO_BASE);
> + sysbus_connect_irq(sysbus, 0, PIC_GPIO(VIRT_GF_TTY_IRQ_BASE));
> +
> + /* virtio-mmio */
> + io_base = VIRT_VIRTIO_MMIO_BASE;
> + for (i = 0; i < 128; i++) {
> + dev = qdev_new(TYPE_VIRTIO_MMIO);
> + qdev_prop_set_bit(dev, "force-legacy", false);
> + sysbus = SYS_BUS_DEVICE(dev);
> + sysbus_realize_and_unref(sysbus, &error_fatal);
> + sysbus_connect_irq(sysbus, 0, PIC_GPIO(VIRT_VIRTIO_IRQ_BASE + i));
> + sysbus_mmio_map(sysbus, 0, io_base);
> + io_base += 0x200;
> + }
> +
> + if (kernel_filename) {
> + CPUState *cs = CPU(cpu);
> + uint64_t high;
> +
> + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
> + &elf_entry, NULL, &high, NULL, 1,
> + EM_68K, 0, 0);
> + if (kernel_size < 0) {
> + error_report("could not load kernel '%s'", kernel_filename);
> + exit(1);
> + }
> + stl_phys(cs->as, 4, elf_entry); /* reset initial PC */
> + parameters_base = (high + 1) & ~1;
> +
> + BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_VIRT);
> + BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040);
> + BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040);
> + BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040);
(see machine->cpu_type question earlier).
> + BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size);
> +
> + BOOTINFO1(cs->as, parameters_base, BI_VIRT_QEMU_VERSION,
> + ((QEMU_VERSION_MAJOR << 24) | (QEMU_VERSION_MICRO << 16) |
> + (QEMU_VERSION_MINOR << 8)));
> + BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_PIC_BASE,
> + VIRT_GF_PIC_MMIO_BASE, VIRT_GF_PIC_IRQ_BASE);
> + BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_RTC_BASE,
> + VIRT_GF_RTC_MMIO_BASE, VIRT_GF_RTC_IRQ_BASE);
> + BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_TTY_BASE,
> + VIRT_GF_TTY_MMIO_BASE, VIRT_GF_TTY_IRQ_BASE);
> + BOOTINFO2(cs->as, parameters_base, BI_VIRT_VIRTIO_BASE,
> + VIRT_VIRTIO_MMIO_BASE, VIRT_VIRTIO_IRQ_BASE);
> +
> + if (kernel_cmdline) {
> + BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE,
> + kernel_cmdline);
> + }
> +
> + /* load initrd */
> + if (initrd_filename) {
> + initrd_size = get_image_size(initrd_filename);
> + if (initrd_size < 0) {
> + error_report("could not load initial ram disk '%s'",
> + initrd_filename);
> + exit(1);
> + }
> +
> + initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
> + load_image_targphys(initrd_filename, initrd_base,
> + ram_size - initrd_base);
> + BOOTINFO2(cs->as, parameters_base, BI_RAMDISK, initrd_base,
> + initrd_size);
> + } else {
> + initrd_base = 0;
> + initrd_size = 0;
> + }
> + BOOTINFO0(cs->as, parameters_base, BI_LAST);
> + }
> +}
> +
> +static void virt_machine_class_init(ObjectClass *oc, void *data)
> +{
> + MachineClass *mc = MACHINE_CLASS(oc);
> + mc->desc = "M68k Virtual Machine";
> + mc->init = virt_init;
> + mc->default_cpu_type = M68K_CPU_TYPE_NAME("m68040");
> + mc->max_cpus = 1;
> + mc->block_default_type = IF_SCSI;
> + mc->default_ram_id = "m68k_virt.ram";
> +}
> +
> +static const TypeInfo virt_machine_typeinfo = {
> + .name = MACHINE_TYPE_NAME("virt"),
> + .parent = TYPE_MACHINE,
> + .class_init = virt_machine_class_init,
> +};
> +
> +static void virt_machine_register_types(void)
> +{
> + type_register_static(&virt_machine_typeinfo);
> +}
> +
> +type_init(virt_machine_register_types)
> diff --git a/MAINTAINERS b/MAINTAINERS
> index d0962a22e1b4..b08cf4251246 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1101,6 +1101,15 @@ F: include/hw/nubus/*
> F: include/hw/display/macfb.h
> F: include/hw/block/swim.h
>
> +virt
Maybe "m68k virt".
> +M: Laurent Vivier <laurent@vivier.eu>
> +S: Maintained
> +F: hw/m68k/virt.c
> +F: hw/char/goldfish_tty.c
> +F: hw/intc/goldfish_pic.c
> +F: include/hw/char/goldfish_tty.h
> +F: include/hw/intc/goldfish_pic.h
> +
> MicroBlaze Machines
> -------------------
> petalogix_s3adsp1800
> diff --git a/hw/m68k/Kconfig b/hw/m68k/Kconfig
> index c757e7dfa48b..f4b3b115270e 100644
> --- a/hw/m68k/Kconfig
> +++ b/hw/m68k/Kconfig
> @@ -22,3 +22,11 @@ config Q800
> select ESCC
> select ESP
> select DP8393X
> +
> +config M68K_VIRT
> + bool
> + select GOLDFISH_PIC
> + select GOLDFISH_TTY
> + select GOLDFISH_RTC
> + select VIRTIO
> + select VIRTIO_MMIO
> diff --git a/hw/m68k/meson.build b/hw/m68k/meson.build
> index ca0044c652d3..31248641d301 100644
> --- a/hw/m68k/meson.build
> +++ b/hw/m68k/meson.build
> @@ -3,5 +3,6 @@ m68k_ss.add(when: 'CONFIG_AN5206', if_true: files('an5206.c', 'mcf5206.c'))
> m68k_ss.add(when: 'CONFIG_MCF5208', if_true: files('mcf5208.c', 'mcf_intc.c'))
> m68k_ss.add(when: 'CONFIG_NEXTCUBE', if_true: files('next-kbd.c', 'next-cube.c'))
> m68k_ss.add(when: 'CONFIG_Q800', if_true: files('q800.c'))
> +m68k_ss.add(when: 'CONFIG_M68K_VIRT', if_true: files('virt.c'))
>
> hw_arch += {'m68k': m68k_ss}
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 4/4] m68k: add Virtual M68k Machine
2020-10-13 17:56 ` Philippe Mathieu-Daudé
@ 2020-10-13 19:01 ` Laurent Vivier
0 siblings, 0 replies; 7+ messages in thread
From: Laurent Vivier @ 2020-10-13 19:01 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Le 13/10/2020 à 19:56, Philippe Mathieu-Daudé a écrit :
> On 10/13/20 5:51 PM, Laurent Vivier wrote:
>> The machine is based on Goldfish interfaces defined by Google
>> for Android simulator. It uses Goldfish-rtc (timer and RTC),
>> Goldfish-pic (PIC) and Goldfish-tty (for serial port and early tty).
>>
>> The machine is created with 128 virtio-mmio bus, and they can
>> be used to use serial console, GPU, disk, NIC, HID, ...
>>
>> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
>> ---
>> default-configs/devices/m68k-softmmu.mak | 1 +
>> .../standard-headers/asm-m68k/bootinfo-virt.h | 17 +
>> hw/m68k/virt.c | 296 ++++++++++++++++++
>> MAINTAINERS | 9 +
>> hw/m68k/Kconfig | 8 +
>> hw/m68k/meson.build | 1 +
>> 6 files changed, 332 insertions(+)
>> create mode 100644 include/standard-headers/asm-m68k/bootinfo-virt.h
>> create mode 100644 hw/m68k/virt.c
...
>> +/*
>> + * The GLUE (General Logic Unit) is an Apple custom integrated
>> circuit chip
>> + * that performs a variety of functions (RAM management, clock
>> generation, ...).
>> + * The GLUE chip receives interrupt requests from various devices,
>> + * assign priority to each, and asserts one or more interrupt line to
>> the
>> + * CPU.
>
> Does your virt machine really requires a GLUE? Or only another
> cascaded PIC?
I agree code needs cleanup here.
We need something to set the ÌRQ level (priority) and vector (see
m68k_set_irq_level()).
>> + */
>> +
>> +typedef struct {
>> + M68kCPU *cpu;
>> + uint8_t ipr;
>> +} GLUEState;
>> +
>> +static void GLUE_set_irq(void *opaque, int irq, int level)
>> +{
>> + GLUEState *s = opaque;
>> + int i;
>> +
>> + if (level) {
>> + s->ipr |= 1 << irq;
>> + } else {
>> + s->ipr &= ~(1 << irq);
>> + }
>> +
>> + for (i = 7; i >= 0; i--) {
>> + if ((s->ipr >> i) & 1) {
>> + m68k_set_irq_level(s->cpu, i + 1, i + 25);
>> + return;
>> + }
>> + }
>> + m68k_set_irq_level(s->cpu, 0, 0);
>> +}
>> +
>> +static void main_cpu_reset(void *opaque)
>> +{
>> + M68kCPU *cpu = opaque;
>> + CPUState *cs = CPU(cpu);
>> +
>> + cpu_reset(cs);
>> + cpu->env.aregs[7] = ldl_phys(cs->as, 0);
>> + cpu->env.pc = ldl_phys(cs->as, 4);
>> +}
>> +
>> +static void virt_init(MachineState *machine)
>> +{
>> + M68kCPU *cpu = NULL;
>> + int32_t kernel_size;
>> + uint64_t elf_entry;
>> + ram_addr_t initrd_base;
>> + int32_t initrd_size;
>> + ram_addr_t ram_size = machine->ram_size;
>> + const char *kernel_filename = machine->kernel_filename;
>> + const char *initrd_filename = machine->initrd_filename;
>> + const char *kernel_cmdline = machine->kernel_cmdline;
>> + hwaddr parameters_base;
>> + DeviceState *dev;
>> + DeviceState *pic_dev[7];
>> + GLUEState *irq;
>> + qemu_irq *cpu_pic;
>> + SysBusDevice *sysbus;
>> + hwaddr io_base;
>> + int i;
>> +
>> +
>> + if (ram_size > 3399672 * KiB) {
>> + /*
>> + * The physical memory can be up to 4 GiB - 16 MiB, but linux
>> + * kernel crashes after this limit (~ 3.2 GiB)
>> + */
>> + error_report("Too much memory for this machine: %" PRId64 "
>> KiB, "
>> + "maximum 3399672 KiB", ram_size / KiB);
>> + exit(1);
>> + }
>> +
>> + /* init CPUs */
>> + cpu = M68K_CPU(cpu_create(machine->cpu_type));
>
> Due to BOOTINFO1(..., BI_CPUTYPE, CPU_68040) below, don't you
> need to check machine->cpu_type == M68K_CPU_TYPE_NAME("m68040")?
Yes, you're right.
68030MMU is not implemented. So we can't use other CPU than 68040.
>
>> + qemu_register_reset(main_cpu_reset, cpu);
>> +
>> + /* RAM */
>> + memory_region_add_subregion(get_system_memory(), 0, machine->ram);
>> +
>> + /* IRQ Glue */
>> +
>> + irq = g_new0(GLUEState, 1);
>> + irq->cpu = cpu;
>> + cpu_pic = qemu_allocate_irqs(GLUE_set_irq, irq, 8);
>> +
>> + /*
>> + * 6 goldfish-pic
>> + *
>> + * map: 0xff000000 - 0xff006fff = 28 KiB
>> + * IRQ: #1 (lower priority) -> #6 (higher priority)
>> + *
>> + */
>> + io_base = VIRT_GF_PIC_MMIO_BASE;
>> + for (i = 0; i < 6; i++) {
>> + pic_dev[i] = qdev_new(TYPE_GOLDFISH_PIC);
>> + sysbus = SYS_BUS_DEVICE(pic_dev[i]);
>> + sysbus_realize_and_unref(sysbus, &error_fatal);
>> +
>> + sysbus_mmio_map(sysbus, 0, io_base);
>> + sysbus_connect_irq(sysbus, 0, cpu_pic[i]);
>> +
>> + io_base += 0x1000;
>> + }
>> +
>> + /* goldfish-rtc */
>> + dev = qdev_new(TYPE_GOLDFISH_RTC);
>> + sysbus = SYS_BUS_DEVICE(dev);
>> + sysbus_realize_and_unref(sysbus, &error_fatal);
>> + sysbus_mmio_map(sysbus, 0, VIRT_GF_RTC_MMIO_BASE);
>> + sysbus_connect_irq(sysbus, 0, PIC_GPIO(VIRT_GF_RTC_IRQ_BASE));
>> +
>> + /* goldfish-tty */
>> + dev = qdev_new(TYPE_GOLDFISH_TTY);
>> + sysbus = SYS_BUS_DEVICE(dev);
>> + qdev_prop_set_chr(dev, "chardev", serial_hd(0));
>> + sysbus_realize_and_unref(sysbus, &error_fatal);
>> + sysbus_mmio_map(sysbus, 0, VIRT_GF_TTY_MMIO_BASE);
>> + sysbus_connect_irq(sysbus, 0, PIC_GPIO(VIRT_GF_TTY_IRQ_BASE));
>> +
>> + /* virtio-mmio */
>> + io_base = VIRT_VIRTIO_MMIO_BASE;
>> + for (i = 0; i < 128; i++) {
>> + dev = qdev_new(TYPE_VIRTIO_MMIO);
>> + qdev_prop_set_bit(dev, "force-legacy", false);
>> + sysbus = SYS_BUS_DEVICE(dev);
>> + sysbus_realize_and_unref(sysbus, &error_fatal);
>> + sysbus_connect_irq(sysbus, 0, PIC_GPIO(VIRT_VIRTIO_IRQ_BASE +
>> i));
>> + sysbus_mmio_map(sysbus, 0, io_base);
>> + io_base += 0x200;
>> + }
>> +
>> + if (kernel_filename) {
>> + CPUState *cs = CPU(cpu);
>> + uint64_t high;
>> +
>> + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
>> + &elf_entry, NULL, &high, NULL, 1,
>> + EM_68K, 0, 0);
>> + if (kernel_size < 0) {
>> + error_report("could not load kernel '%s'", kernel_filename);
>> + exit(1);
>> + }
>> + stl_phys(cs->as, 4, elf_entry); /* reset initial PC */
>> + parameters_base = (high + 1) & ~1;
>> +
>> + BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_VIRT);
>> + BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040);
>> + BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040);
>> + BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040);
>
> (see machine->cpu_type question earlier).
see answer above.
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index d0962a22e1b4..b08cf4251246 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -1101,6 +1101,15 @@ F: include/hw/nubus/*
>> F: include/hw/display/macfb.h
>> F: include/hw/block/swim.h
>> +virt
>
> Maybe "m68k virt".
We have "virt" only for ARM, RISCV, Xtensa, ...
the m68k is implied by the qemu-system-m68k
>
>> +M: Laurent Vivier <laurent@vivier.eu>
>> +S: Maintained
>> +F: hw/m68k/virt.c
>> +F: hw/char/goldfish_tty.c
>> +F: hw/intc/goldfish_pic.c
>> +F: include/hw/char/goldfish_tty.h
>> +F: include/hw/intc/goldfish_pic.h
>> +
Thanks,
Laurent
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2020-10-13 19:02 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-13 15:51 [PATCH 0/4] m68k: add Virtual M68k Machine Laurent Vivier
2020-10-13 15:51 ` [PATCH 1/4] m68k: import bootinfo headers from linux Laurent Vivier
2020-10-13 15:51 ` [PATCH 2/4] char: add goldfish-tty Laurent Vivier
2020-10-13 15:51 ` [PATCH 3/4] intc: add goldfish-pic Laurent Vivier
2020-10-13 15:51 ` [PATCH 4/4] m68k: add Virtual M68k Machine Laurent Vivier
2020-10-13 17:56 ` Philippe Mathieu-Daudé
2020-10-13 19:01 ` Laurent Vivier
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.