All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.