* [PATCH v2 1/7] m68k: import bootinfo headers from linux
2020-12-20 11:26 [PATCH v2 0/7] m68k: add Virtual M68k Machine Laurent Vivier
@ 2020-12-20 11:26 ` Laurent Vivier
2020-12-20 11:26 ` [PATCH v2 2/7] char: add goldfish-tty Laurent Vivier
` (5 subsequent siblings)
6 siblings, 0 replies; 24+ messages in thread
From: Laurent Vivier @ 2020-12-20 11:26 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 linux 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 2af0e2532eb2..d4eca467671b 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -37,6 +37,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"
@@ -55,14 +57,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
@@ -415,11 +409,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 1e7c8f04885d..7640dfb5f0fc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1098,6 +1098,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.29.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 2/7] char: add goldfish-tty
2020-12-20 11:26 [PATCH v2 0/7] m68k: add Virtual M68k Machine Laurent Vivier
2020-12-20 11:26 ` [PATCH v2 1/7] m68k: import bootinfo headers from linux Laurent Vivier
@ 2020-12-20 11:26 ` Laurent Vivier
2021-01-24 0:13 ` Philippe Mathieu-Daudé
2020-12-20 11:26 ` [PATCH v2 3/7] intc: add goldfish-pic Laurent Vivier
` (4 subsequent siblings)
6 siblings, 1 reply; 24+ messages in thread
From: Laurent Vivier @ 2020-12-20 11:26 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 | 266 +++++++++++++++++++++++++++++++++
hw/char/Kconfig | 3 +
hw/char/meson.build | 2 +
hw/char/trace-events | 9 ++
5 files changed, 316 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..7780940a8817
--- /dev/null
+++ b/hw/char/goldfish_tty.c
@@ -0,0 +1,266 @@
+/*
+ * 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),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+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 81026f661277..dc7fb717e13b 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.29.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v2 2/7] char: add goldfish-tty
2020-12-20 11:26 ` [PATCH v2 2/7] char: add goldfish-tty Laurent Vivier
@ 2021-01-24 0:13 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 24+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-24 0:13 UTC (permalink / raw)
To: Laurent Vivier, qemu-devel
On 12/20/20 12:26 PM, Laurent Vivier wrote:
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
> include/hw/char/goldfish_tty.h | 36 +++++
> hw/char/goldfish_tty.c | 266 +++++++++++++++++++++++++++++++++
> hw/char/Kconfig | 3 +
> hw/char/meson.build | 2 +
> hw/char/trace-events | 9 ++
> 5 files changed, 316 insertions(+)
> create mode 100644 include/hw/char/goldfish_tty.h
> create mode 100644 hw/char/goldfish_tty.c
...
> +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);
Could this fail, no need to check return value?
> + 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);
Ditto.
> + 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,
Missing:
.impl.min = 4,
Otherwise:
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> +};
> +
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 3/7] intc: add goldfish-pic
2020-12-20 11:26 [PATCH v2 0/7] m68k: add Virtual M68k Machine Laurent Vivier
2020-12-20 11:26 ` [PATCH v2 1/7] m68k: import bootinfo headers from linux Laurent Vivier
2020-12-20 11:26 ` [PATCH v2 2/7] char: add goldfish-tty Laurent Vivier
@ 2020-12-20 11:26 ` Laurent Vivier
2021-01-24 0:08 ` Philippe Mathieu-Daudé
2020-12-20 11:26 ` [PATCH v2 4/7] m68k: add an interrupt controller Laurent Vivier
` (3 subsequent siblings)
6 siblings, 1 reply; 24+ messages in thread
From: Laurent Vivier @ 2020-12-20 11:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Laurent Vivier
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
include/hw/intc/goldfish_pic.h | 33 +++++
hw/intc/goldfish_pic.c | 214 +++++++++++++++++++++++++++++++++
hw/intc/Kconfig | 3 +
hw/intc/meson.build | 1 +
hw/intc/trace-events | 8 ++
5 files changed, 259 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..26e7ca75a3ec
--- /dev/null
+++ b/include/hw/intc/goldfish_pic.h
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+ /* statistics */
+ uint64_t stats_irq_count[32];
+ /* for tracing */
+ int idx;
+};
+
+#endif
diff --git a/hw/intc/goldfish_pic.c b/hw/intc/goldfish_pic.c
new file mode 100644
index 000000000000..4ed08b17cfe2
--- /dev/null
+++ b/hw/intc/goldfish_pic.c
@@ -0,0 +1,214 @@
+/*
+ * 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 "monitor/monitor.h"
+#include "qemu/log.h"
+#include "trace.h"
+#include "hw/intc/intc.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 bool goldfish_pic_get_statistics(InterruptStatsProvider *obj,
+ uint64_t **irq_counts,
+ unsigned int *nb_irqs)
+{
+ GoldfishPICState *s = GOLDFISH_PIC(obj);
+
+ *irq_counts = s->stats_irq_count;
+ *nb_irqs = ARRAY_SIZE(s->stats_irq_count);
+ return true;
+}
+
+static void goldfish_pic_print_info(InterruptStatsProvider *obj, Monitor *mon)
+{
+ GoldfishPICState *s = GOLDFISH_PIC(obj);
+ monitor_printf(mon, "goldfish-pic.%d: pending=0x%08x enabled=0x%08x\n",
+ s->idx, s->pending, s->enabled);
+}
+
+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, s->idx, irq, level);
+
+ if (level) {
+ s->pending |= 1 << irq;
+ s->stats_irq_count[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, s->idx, 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, s->idx, 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);
+ int i;
+
+ trace_goldfish_pic_reset(s, s->idx);
+ s->pending = 0;
+ s->enabled = 0;
+
+ for (i = 0; i < ARRAY_SIZE(s->stats_irq_count); i++) {
+ s->stats_irq_count[i] = 0;
+ }
+}
+
+static void goldfish_pic_realize(DeviceState *dev, Error **errp)
+{
+ GoldfishPICState *s = GOLDFISH_PIC(dev);
+ static int counter;
+
+ s->idx = counter++;
+ trace_goldfish_pic_realize(s, s->idx);
+
+ 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),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+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, s->idx);
+
+ 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);
+ InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(oc);
+
+ dc->reset = goldfish_pic_reset;
+ dc->realize = goldfish_pic_realize;
+ dc->vmsd = &vmstate_goldfish_pic;
+ ic->get_statistics = goldfish_pic_get_statistics;
+ ic->print_info = goldfish_pic_print_info;
+}
+
+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),
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_INTERRUPT_STATS_PROVIDER },
+ { }
+ },
+};
+
+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 7c3e9daf586e..8a5dfe4289ae 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -54,3 +54,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 8ed397a0d587..e9b64ee568fd 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -236,3 +236,11 @@ xive_tctx_tm_write(uint64_t offset, unsigned int size, uint64_t value) "@0x0x%"P
xive_tctx_tm_read(uint64_t offset, unsigned int size, uint64_t value) "@0x0x%"PRIx64" sz=%d val=0x%" PRIx64
xive_presenter_notify(uint8_t nvt_blk, uint32_t nvt_idx, uint8_t ring) "found NVT 0x%x/0x%x ring=0x%x"
xive_end_source_read(uint8_t end_blk, uint32_t end_idx, uint64_t addr) "END 0x%x/0x%x @0x0x%"PRIx64
+
+# goldfish_pic.c
+goldfish_irq_request(void *dev, int idx, int irq, int level) "pic: %p goldfish-irq.%d irq: %d level: %d"
+goldfish_pic_read(void *dev, int idx, unsigned int addr, unsigned int size, uint64_t value) "pic: %p goldfish-irq.%d reg: 0x%02x size: %d value: 0x%"PRIx64
+goldfish_pic_write(void *dev, int idx, unsigned int addr, unsigned int size, uint64_t value) "pic: %p goldfish-irq.%d reg: 0x%02x size: %d value: 0x%"PRIx64
+goldfish_pic_reset(void *dev, int idx) "pic: %p goldfish-irq.%d"
+goldfish_pic_realize(void *dev, int idx) "pic: %p goldfish-irq.%d"
+goldfish_pic_instance_init(void *dev, int idx) "pic: %p goldfish-irq.%d"
--
2.29.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v2 3/7] intc: add goldfish-pic
2020-12-20 11:26 ` [PATCH v2 3/7] intc: add goldfish-pic Laurent Vivier
@ 2021-01-24 0:08 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 24+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-24 0:08 UTC (permalink / raw)
To: Laurent Vivier, qemu-devel
On 12/20/20 12:26 PM, Laurent Vivier wrote:
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
> include/hw/intc/goldfish_pic.h | 33 +++++
> hw/intc/goldfish_pic.c | 214 +++++++++++++++++++++++++++++++++
> hw/intc/Kconfig | 3 +
> hw/intc/meson.build | 1 +
> hw/intc/trace-events | 8 ++
> 5 files changed, 259 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..26e7ca75a3ec
> --- /dev/null
> +++ b/include/hw/intc/goldfish_pic.h
> @@ -0,0 +1,33 @@
> +/*
> + * 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;
> +
> + /* statistics */
> + uint64_t stats_irq_count[32];
GOLDFISH_PIC_IRQ_NB?
> + /* for tracing */
> + int idx;
> +};
> +
> +#endif
> diff --git a/hw/intc/goldfish_pic.c b/hw/intc/goldfish_pic.c
> +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,
Missing:
.impl.min_access_size = 4,
Otherwise:
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> +};
> +
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 4/7] m68k: add an interrupt controller
2020-12-20 11:26 [PATCH v2 0/7] m68k: add Virtual M68k Machine Laurent Vivier
` (2 preceding siblings ...)
2020-12-20 11:26 ` [PATCH v2 3/7] intc: add goldfish-pic Laurent Vivier
@ 2020-12-20 11:26 ` Laurent Vivier
2021-01-24 16:46 ` Philippe Mathieu-Daudé
2021-02-12 18:44 ` Philippe Mathieu-Daudé
2020-12-20 11:26 ` [PATCH v2 5/7] m68k: add a system controller Laurent Vivier
` (2 subsequent siblings)
6 siblings, 2 replies; 24+ messages in thread
From: Laurent Vivier @ 2020-12-20 11:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Laurent Vivier
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
include/hw/intc/m68k_irqc.h | 28 +++++++++
hw/intc/m68k_irqc.c | 120 ++++++++++++++++++++++++++++++++++++
hw/intc/Kconfig | 3 +
hw/intc/meson.build | 1 +
4 files changed, 152 insertions(+)
create mode 100644 include/hw/intc/m68k_irqc.h
create mode 100644 hw/intc/m68k_irqc.c
diff --git a/include/hw/intc/m68k_irqc.h b/include/hw/intc/m68k_irqc.h
new file mode 100644
index 000000000000..c40b1b4df8fa
--- /dev/null
+++ b/include/hw/intc/m68k_irqc.h
@@ -0,0 +1,28 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * QEMU Motorla 680x0 IRQ Controller
+ *
+ * (c) 2020 Laurent Vivier <laurent@vivier.eu>
+ *
+ */
+
+#ifndef M68K_IRQC_H
+#define M68K_IRQC_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_M68K_IRQC "m68k-irq-controller"
+#define M68K_IRQC(obj) OBJECT_CHECK(M68KIRQCState, (obj), \
+ TYPE_M68K_IRQC)
+
+typedef struct M68KIRQCState {
+ SysBusDevice parent_obj;
+
+ uint8_t ipr;
+
+ /* statistics */
+ uint64_t stats_irq_count[7];
+} M68KIRQCState;
+
+#endif
diff --git a/hw/intc/m68k_irqc.c b/hw/intc/m68k_irqc.c
new file mode 100644
index 000000000000..bc68d8fe084a
--- /dev/null
+++ b/hw/intc/m68k_irqc.c
@@ -0,0 +1,120 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * QEMU Motorla 680x0 IRQ Controller
+ *
+ * (c) 2020 Laurent Vivier <laurent@vivier.eu>
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "migration/vmstate.h"
+#include "monitor/monitor.h"
+#include "hw/nmi.h"
+#include "hw/intc/intc.h"
+#include "hw/intc/m68k_irqc.h"
+
+
+static bool m68k_irqc_get_statistics(InterruptStatsProvider *obj,
+ uint64_t **irq_counts, unsigned int *nb_irqs)
+{
+ M68KIRQCState *s = M68K_IRQC(obj);
+
+ *irq_counts = s->stats_irq_count;
+ *nb_irqs = ARRAY_SIZE(s->stats_irq_count);
+ return true;
+}
+
+static void m68k_irqc_print_info(InterruptStatsProvider *obj, Monitor *mon)
+{
+ M68KIRQCState *s = M68K_IRQC(obj);
+ monitor_printf(mon, "m68k-irqc: ipr=0x%x\n", s->ipr);
+}
+
+static void m68k_set_irq(void *opaque, int irq, int level)
+{
+ M68KIRQCState *s = opaque;
+ M68kCPU *cpu = M68K_CPU(first_cpu);
+ int i;
+
+
+ if (level) {
+ s->ipr |= 1 << irq;
+ s->stats_irq_count[irq]++;
+ } else {
+ s->ipr &= ~(1 << irq);
+ }
+
+ for (i = 7; i >= 0; i--) {
+ if ((s->ipr >> i) & 1) {
+ m68k_set_irq_level(cpu, i + 1, i + 25);
+ return;
+ }
+ }
+ m68k_set_irq_level(cpu, 0, 0);
+}
+
+static void m68k_irqc_reset(DeviceState *d)
+{
+ M68KIRQCState *s = M68K_IRQC(d);
+ int i;
+
+ s->ipr = 0;
+ for (i = 0; i < ARRAY_SIZE(s->stats_irq_count); i++) {
+ s->stats_irq_count[i] = 0;
+ }
+}
+
+static void m68k_irqc_instance_init(Object *obj)
+{
+ qdev_init_gpio_in(DEVICE(obj), m68k_set_irq, 8);
+}
+
+static void m68k_nmi(NMIState *n, int cpu_index, Error **errp)
+{
+ m68k_set_irq(n, 6, 1);
+}
+
+static const VMStateDescription vmstate_m68k_irqc = {
+ .name = "m68k-irqc",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(ipr, M68KIRQCState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void m68k_irqc_class_init(ObjectClass *oc, void *data)
+ {
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ NMIClass *nc = NMI_CLASS(oc);
+ InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(oc);
+
+ nc->nmi_monitor_handler = m68k_nmi;
+ dc->reset = m68k_irqc_reset;
+ dc->vmsd = &vmstate_m68k_irqc;
+ ic->get_statistics = m68k_irqc_get_statistics;
+ ic->print_info = m68k_irqc_print_info;
+}
+
+static const TypeInfo m68k_irqc_type_info = {
+ .name = TYPE_M68K_IRQC,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(M68KIRQCState),
+ .instance_init = m68k_irqc_instance_init,
+ .class_init = m68k_irqc_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_NMI },
+ { TYPE_INTERRUPT_STATS_PROVIDER },
+ { }
+ },
+};
+
+static void q800_irq_register_types(void)
+{
+ type_register_static(&m68k_irqc_type_info);
+}
+
+type_init(q800_irq_register_types);
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 7ed79e7ac29f..318d76c7cb52 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -76,3 +76,6 @@ config SIFIVE_PLIC
config GOLDFISH_PIC
bool
+
+config M68K_IRQC
+ bool
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index 8a5dfe4289ae..81bd0191f9cd 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -55,3 +55,4 @@ 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'))
+specific_ss.add(when: 'CONFIG_M68K_IRQC', if_true: files('m68k_irqc.c'))
--
2.29.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v2 4/7] m68k: add an interrupt controller
2020-12-20 11:26 ` [PATCH v2 4/7] m68k: add an interrupt controller Laurent Vivier
@ 2021-01-24 16:46 ` Philippe Mathieu-Daudé
2021-01-25 11:56 ` Laurent Vivier
2021-02-12 18:44 ` Philippe Mathieu-Daudé
1 sibling, 1 reply; 24+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-24 16:46 UTC (permalink / raw)
To: Laurent Vivier, qemu-devel
On 12/20/20 12:26 PM, Laurent Vivier wrote:
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
> include/hw/intc/m68k_irqc.h | 28 +++++++++
> hw/intc/m68k_irqc.c | 120 ++++++++++++++++++++++++++++++++++++
Missing MAINTAINERS entries?
> hw/intc/Kconfig | 3 +
> hw/intc/meson.build | 1 +
> 4 files changed, 152 insertions(+)
> create mode 100644 include/hw/intc/m68k_irqc.h
> create mode 100644 hw/intc/m68k_irqc.c
>
> diff --git a/include/hw/intc/m68k_irqc.h b/include/hw/intc/m68k_irqc.h
> new file mode 100644
> index 000000000000..c40b1b4df8fa
> --- /dev/null
> +++ b/include/hw/intc/m68k_irqc.h
> @@ -0,0 +1,28 @@
> +/*
> + * SPDX-License-Identifer: GPL-2.0-or-later
> + *
> + * QEMU Motorla 680x0 IRQ Controller
Typo "Motorola".
Are there any specs to refer at?
> + *
> + * (c) 2020 Laurent Vivier <laurent@vivier.eu>
> + *
> + */
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 4/7] m68k: add an interrupt controller
2021-01-24 16:46 ` Philippe Mathieu-Daudé
@ 2021-01-25 11:56 ` Laurent Vivier
0 siblings, 0 replies; 24+ messages in thread
From: Laurent Vivier @ 2021-01-25 11:56 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Le 24/01/2021 à 17:46, Philippe Mathieu-Daudé a écrit :
> On 12/20/20 12:26 PM, Laurent Vivier wrote:
>> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
>> ---
>> include/hw/intc/m68k_irqc.h | 28 +++++++++
>> hw/intc/m68k_irqc.c | 120 ++++++++++++++++++++++++++++++++++++
>
> Missing MAINTAINERS entries?
new devices are added in patch 7 (where I add the machine and the section in MAINTAINER), but I've
missed this one. Thanks.
>
>> hw/intc/Kconfig | 3 +
>> hw/intc/meson.build | 1 +
>> 4 files changed, 152 insertions(+)
>> create mode 100644 include/hw/intc/m68k_irqc.h
>> create mode 100644 hw/intc/m68k_irqc.c
>>
>> diff --git a/include/hw/intc/m68k_irqc.h b/include/hw/intc/m68k_irqc.h
>> new file mode 100644
>> index 000000000000..c40b1b4df8fa
>> --- /dev/null
>> +++ b/include/hw/intc/m68k_irqc.h
>> @@ -0,0 +1,28 @@
>> +/*
>> + * SPDX-License-Identifer: GPL-2.0-or-later
>> + *
>> + * QEMU Motorla 680x0 IRQ Controller
>
> Typo "Motorola".
Thank you (there is another typo: "q800_irq_register_types" that must be renamed)
> Are there any specs to refer at?
>
There is no specs. It's a (generic) copy of the GLUE device we already have for q800.
I don't update Q800 because the GLUE device may disappear because Q800 uses actually djMEMC that is
also a memory controller (I have that in my q800-dev branch, but for the moment it's only needed for
the MacROM and Mark is working on that).
Thanks,
Laurent
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 4/7] m68k: add an interrupt controller
2020-12-20 11:26 ` [PATCH v2 4/7] m68k: add an interrupt controller Laurent Vivier
2021-01-24 16:46 ` Philippe Mathieu-Daudé
@ 2021-02-12 18:44 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 24+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-02-12 18:44 UTC (permalink / raw)
To: Laurent Vivier, qemu-devel
On 12/20/20 12:26 PM, Laurent Vivier wrote:
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
> include/hw/intc/m68k_irqc.h | 28 +++++++++
> hw/intc/m68k_irqc.c | 120 ++++++++++++++++++++++++++++++++++++
> hw/intc/Kconfig | 3 +
> hw/intc/meson.build | 1 +
> 4 files changed, 152 insertions(+)
> create mode 100644 include/hw/intc/m68k_irqc.h
> create mode 100644 hw/intc/m68k_irqc.c
>
> diff --git a/include/hw/intc/m68k_irqc.h b/include/hw/intc/m68k_irqc.h
> new file mode 100644
> index 000000000000..c40b1b4df8fa
> --- /dev/null
> +++ b/include/hw/intc/m68k_irqc.h
> @@ -0,0 +1,28 @@
> +/*
> + * SPDX-License-Identifer: GPL-2.0-or-later
> + *
> + * QEMU Motorla 680x0 IRQ Controller
> + *
> + * (c) 2020 Laurent Vivier <laurent@vivier.eu>
> + *
> + */
> +
> +#ifndef M68K_IRQC_H
> +#define M68K_IRQC_H
> +
> +#include "hw/sysbus.h"
> +
> +#define TYPE_M68K_IRQC "m68k-irq-controller"
> +#define M68K_IRQC(obj) OBJECT_CHECK(M68KIRQCState, (obj), \
> + TYPE_M68K_IRQC)
> +
> +typedef struct M68KIRQCState {
> + SysBusDevice parent_obj;
> +
> + uint8_t ipr;
> +
> + /* statistics */
> + uint64_t stats_irq_count[7];
So we have 8 IRQs, one is NMI. Is that correct?
Could you add #definitions? Patch LGTM but I'll wait for
definitions to give a R-b ;)
> +} M68KIRQCState;
> +
> +#endif
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 5/7] m68k: add a system controller
2020-12-20 11:26 [PATCH v2 0/7] m68k: add Virtual M68k Machine Laurent Vivier
` (3 preceding siblings ...)
2020-12-20 11:26 ` [PATCH v2 4/7] m68k: add an interrupt controller Laurent Vivier
@ 2020-12-20 11:26 ` Laurent Vivier
2020-12-20 11:26 ` [PATCH v2 6/7] goldfish_rtc: re-arm the alarm after migration Laurent Vivier
2020-12-20 11:26 ` [PATCH v2 7/7] m68k: add Virtual M68k Machine Laurent Vivier
6 siblings, 0 replies; 24+ messages in thread
From: Laurent Vivier @ 2020-12-20 11:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Laurent Vivier
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
include/hw/misc/m68k_virt_ctrl.h | 22 +++++
hw/misc/m68k_virt_ctrl.c | 152 +++++++++++++++++++++++++++++++
hw/misc/Kconfig | 3 +
hw/misc/meson.build | 3 +
hw/misc/trace-events | 7 ++
5 files changed, 187 insertions(+)
create mode 100644 include/hw/misc/m68k_virt_ctrl.h
create mode 100644 hw/misc/m68k_virt_ctrl.c
diff --git a/include/hw/misc/m68k_virt_ctrl.h b/include/hw/misc/m68k_virt_ctrl.h
new file mode 100644
index 000000000000..1db7960e5477
--- /dev/null
+++ b/include/hw/misc/m68k_virt_ctrl.h
@@ -0,0 +1,22 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * Virt m68k system Controller
+ */
+
+#ifndef M68K_VIRT_CTRL_H
+#define M68K_VIRT_CTRL_H
+
+#define TYPE_M68K_VIRT_CTRL "m68k-virt-ctrl"
+OBJECT_DECLARE_SIMPLE_TYPE(M68KVirtCtrlState, M68K_VIRT_CTRL)
+
+struct M68KVirtCtrlState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion iomem;
+ qemu_irq irq;
+
+ uint32_t irq_enabled;
+};
+
+#endif
diff --git a/hw/misc/m68k_virt_ctrl.c b/hw/misc/m68k_virt_ctrl.c
new file mode 100644
index 000000000000..fb34aa10211a
--- /dev/null
+++ b/hw/misc/m68k_virt_ctrl.c
@@ -0,0 +1,152 @@
+/*
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ *
+ * Virt m68k system Controller
+ */
+
+#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 "sysemu/runstate.h"
+#include "hw/misc/m68k_virt_ctrl.h"
+
+enum {
+ REG_FEATURES = 0x00,
+ REG_CMD = 0x04,
+};
+
+#define FEAT_POWER_CTRL 0x00000001
+
+enum {
+ CMD_NOOP,
+ CMD_RESET,
+ CMD_HALT,
+ CMD_PANIC,
+};
+
+static uint64_t m68k_virt_ctrl_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ M68KVirtCtrlState *s = opaque;
+ uint64_t value = 0;
+
+ switch (addr) {
+ case REG_FEATURES:
+ value = FEAT_POWER_CTRL;
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP,
+ "%s: unimplemented register read 0x%02"HWADDR_PRIx"\n",
+ __func__, addr);
+ break;
+ }
+
+ trace_m68k_virt_ctrl_write(s, addr, size, value);
+
+ return value;
+}
+
+static void m68k_virt_ctrl_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
+{
+ M68KVirtCtrlState *s = opaque;
+
+ trace_m68k_virt_ctrl_write(s, addr, size, value);
+
+ switch (addr) {
+ case REG_CMD:
+ switch (value) {
+ case CMD_NOOP:
+ break;
+ case CMD_RESET:
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+ break;
+ case CMD_HALT:
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+ break;
+ case CMD_PANIC:
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
+ break;
+ }
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP,
+ "%s: unimplemented register write 0x%02"HWADDR_PRIx"\n",
+ __func__, addr);
+ break;
+ }
+}
+
+static const MemoryRegionOps m68k_virt_ctrl_ops = {
+ .read = m68k_virt_ctrl_read,
+ .write = m68k_virt_ctrl_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid.max_access_size = 4,
+ .impl.max_access_size = 4,
+};
+
+static void m68k_virt_ctrl_reset(DeviceState *dev)
+{
+ M68KVirtCtrlState *s = M68K_VIRT_CTRL(dev);
+
+ trace_m68k_virt_ctrl_reset(s);
+}
+
+static void m68k_virt_ctrl_realize(DeviceState *dev, Error **errp)
+{
+ M68KVirtCtrlState *s = M68K_VIRT_CTRL(dev);
+
+ trace_m68k_virt_ctrl_instance_init(s);
+
+ memory_region_init_io(&s->iomem, OBJECT(s), &m68k_virt_ctrl_ops, s,
+ "m68k-virt-ctrl", 0x100);
+}
+
+static const VMStateDescription vmstate_m68k_virt_ctrl = {
+ .name = "m68k-virt-ctrl",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(irq_enabled, M68KVirtCtrlState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void m68k_virt_ctrl_instance_init(Object *obj)
+{
+ SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+ M68KVirtCtrlState *s = M68K_VIRT_CTRL(obj);
+
+ trace_m68k_virt_ctrl_instance_init(s);
+
+ sysbus_init_mmio(dev, &s->iomem);
+ sysbus_init_irq(dev, &s->irq);
+}
+
+static void m68k_virt_ctrl_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ dc->reset = m68k_virt_ctrl_reset;
+ dc->realize = m68k_virt_ctrl_realize;
+ dc->vmsd = &vmstate_m68k_virt_ctrl;
+}
+
+static const TypeInfo m68k_virt_ctrl_info = {
+ .name = TYPE_M68K_VIRT_CTRL,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .class_init = m68k_virt_ctrl_class_init,
+ .instance_init = m68k_virt_ctrl_instance_init,
+ .instance_size = sizeof(M68KVirtCtrlState),
+};
+
+static void m68k_virt_ctrl_register_types(void)
+{
+ type_register_static(&m68k_virt_ctrl_info);
+}
+
+type_init(m68k_virt_ctrl_register_types)
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index cf18ac08e666..62fdabb5fb85 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -164,4 +164,7 @@ config SIFIVE_U_OTP
config SIFIVE_U_PRCI
bool
+config M68K_VIRT_CTRL
+ bool
+
source macio/Kconfig
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index ce15ffceb958..3e8aebc8eb72 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -23,6 +23,9 @@ softmmu_ss.add(when: 'CONFIG_ARM11SCU', if_true: files('arm11scu.c'))
# Mac devices
softmmu_ss.add(when: 'CONFIG_MOS6522', if_true: files('mos6522.c'))
+# virt m68k devices
+softmmu_ss.add(when: 'CONFIG_M68K_VIRT_CTRL', if_true: files('m68k_virt_ctrl.c'))
+
# RISC-V devices
softmmu_ss.add(when: 'CONFIG_MCHP_PFSOC_DMC', if_true: files('mchp_pfsoc_dmc.c'))
softmmu_ss.add(when: 'CONFIG_MCHP_PFSOC_IOSCB', if_true: files('mchp_pfsoc_ioscb.c'))
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index b5118acd3fd5..f8a4b74d8154 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -237,3 +237,10 @@ pca955x_gpio_change(const char *description, unsigned id, unsigned prev_state, u
bcm2835_cprman_read(uint64_t offset, uint64_t value) "offset:0x%" PRIx64 " value:0x%" PRIx64
bcm2835_cprman_write(uint64_t offset, uint64_t value) "offset:0x%" PRIx64 " value:0x%" PRIx64
bcm2835_cprman_write_invalid_magic(uint64_t offset, uint64_t value) "offset:0x%" PRIx64 " value:0x%" PRIx64
+
+# m68k_virt_ctrl.c
+m68k_virt_ctrl_read(void *dev, unsigned int addr, unsigned int size, uint64_t value) "ctrl: %p reg: 0x%02x size: %d value: 0x%"PRIx64
+m68k_virt_ctrl_write(void *dev, unsigned int addr, unsigned int size, uint64_t value) "ctrl: %p reg: 0x%02x size: %d value: 0x%"PRIx64
+m68k_virt_ctrl_reset(void *dev) "ctrl: %p"
+m68k_virt_ctrl_realize(void *dev) "ctrl: %p"
+m68k_virt_ctrl_instance_init(void *dev) "ctrl: %p"
--
2.29.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 6/7] goldfish_rtc: re-arm the alarm after migration
2020-12-20 11:26 [PATCH v2 0/7] m68k: add Virtual M68k Machine Laurent Vivier
` (4 preceding siblings ...)
2020-12-20 11:26 ` [PATCH v2 5/7] m68k: add a system controller Laurent Vivier
@ 2020-12-20 11:26 ` Laurent Vivier
2021-01-23 15:05 ` Laurent Vivier
2021-01-24 0:15 ` Philippe Mathieu-Daudé
2020-12-20 11:26 ` [PATCH v2 7/7] m68k: add Virtual M68k Machine Laurent Vivier
6 siblings, 2 replies; 24+ messages in thread
From: Laurent Vivier @ 2020-12-20 11:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Alistair Francis, Laurent Vivier
After a migration the clock offset is updated, but we also
need to re-arm the alarm if needed.
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/rtc/goldfish_rtc.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
index 0f4e8185a796..e07ff0164e0c 100644
--- a/hw/rtc/goldfish_rtc.c
+++ b/hw/rtc/goldfish_rtc.c
@@ -211,6 +211,8 @@ static int goldfish_rtc_post_load(void *opaque, int version_id)
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
s->tick_offset = s->tick_offset_vmstate - delta;
+ goldfish_rtc_set_alarm(s);
+
return 0;
}
--
2.29.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v2 6/7] goldfish_rtc: re-arm the alarm after migration
2020-12-20 11:26 ` [PATCH v2 6/7] goldfish_rtc: re-arm the alarm after migration Laurent Vivier
@ 2021-01-23 15:05 ` Laurent Vivier
2021-01-24 0:15 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 24+ messages in thread
From: Laurent Vivier @ 2021-01-23 15:05 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-riscv, Alistair Francis
Is there someone to merge this?
Thanks,
Laurent
Le 20/12/2020 à 12:26, Laurent Vivier a écrit :
> After a migration the clock offset is updated, but we also
> need to re-arm the alarm if needed.
>
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> hw/rtc/goldfish_rtc.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
> index 0f4e8185a796..e07ff0164e0c 100644
> --- a/hw/rtc/goldfish_rtc.c
> +++ b/hw/rtc/goldfish_rtc.c
> @@ -211,6 +211,8 @@ static int goldfish_rtc_post_load(void *opaque, int version_id)
> qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> s->tick_offset = s->tick_offset_vmstate - delta;
>
> + goldfish_rtc_set_alarm(s);
> +
> return 0;
> }
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 6/7] goldfish_rtc: re-arm the alarm after migration
@ 2021-01-23 15:05 ` Laurent Vivier
0 siblings, 0 replies; 24+ messages in thread
From: Laurent Vivier @ 2021-01-23 15:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Alistair Francis, qemu-riscv
Is there someone to merge this?
Thanks,
Laurent
Le 20/12/2020 à 12:26, Laurent Vivier a écrit :
> After a migration the clock offset is updated, but we also
> need to re-arm the alarm if needed.
>
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> hw/rtc/goldfish_rtc.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
> index 0f4e8185a796..e07ff0164e0c 100644
> --- a/hw/rtc/goldfish_rtc.c
> +++ b/hw/rtc/goldfish_rtc.c
> @@ -211,6 +211,8 @@ static int goldfish_rtc_post_load(void *opaque, int version_id)
> qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> s->tick_offset = s->tick_offset_vmstate - delta;
>
> + goldfish_rtc_set_alarm(s);
> +
> return 0;
> }
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 6/7] goldfish_rtc: re-arm the alarm after migration
2021-01-23 15:05 ` Laurent Vivier
@ 2021-01-25 23:44 ` Alistair Francis
-1 siblings, 0 replies; 24+ messages in thread
From: Alistair Francis @ 2021-01-25 23:44 UTC (permalink / raw)
To: Laurent Vivier
Cc: Alistair Francis, open list:RISC-V, qemu-devel@nongnu.org Developers
On Sat, Jan 23, 2021 at 7:06 AM Laurent Vivier <laurent@vivier.eu> wrote:
>
> Is there someone to merge this?
Do you mean just this patch or the whole series?
Alistair
>
> Thanks,
> Laurent
>
> Le 20/12/2020 à 12:26, Laurent Vivier a écrit :
> > After a migration the clock offset is updated, but we also
> > need to re-arm the alarm if needed.
> >
> > Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> > Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> > ---
> > hw/rtc/goldfish_rtc.c | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
> > index 0f4e8185a796..e07ff0164e0c 100644
> > --- a/hw/rtc/goldfish_rtc.c
> > +++ b/hw/rtc/goldfish_rtc.c
> > @@ -211,6 +211,8 @@ static int goldfish_rtc_post_load(void *opaque, int version_id)
> > qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> > s->tick_offset = s->tick_offset_vmstate - delta;
> >
> > + goldfish_rtc_set_alarm(s);
> > +
> > return 0;
> > }
> >
> >
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 6/7] goldfish_rtc: re-arm the alarm after migration
@ 2021-01-25 23:44 ` Alistair Francis
0 siblings, 0 replies; 24+ messages in thread
From: Alistair Francis @ 2021-01-25 23:44 UTC (permalink / raw)
To: Laurent Vivier
Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, Alistair Francis
On Sat, Jan 23, 2021 at 7:06 AM Laurent Vivier <laurent@vivier.eu> wrote:
>
> Is there someone to merge this?
Do you mean just this patch or the whole series?
Alistair
>
> Thanks,
> Laurent
>
> Le 20/12/2020 à 12:26, Laurent Vivier a écrit :
> > After a migration the clock offset is updated, but we also
> > need to re-arm the alarm if needed.
> >
> > Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> > Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> > ---
> > hw/rtc/goldfish_rtc.c | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
> > index 0f4e8185a796..e07ff0164e0c 100644
> > --- a/hw/rtc/goldfish_rtc.c
> > +++ b/hw/rtc/goldfish_rtc.c
> > @@ -211,6 +211,8 @@ static int goldfish_rtc_post_load(void *opaque, int version_id)
> > qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> > s->tick_offset = s->tick_offset_vmstate - delta;
> >
> > + goldfish_rtc_set_alarm(s);
> > +
> > return 0;
> > }
> >
> >
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 6/7] goldfish_rtc: re-arm the alarm after migration
2021-01-25 23:44 ` Alistair Francis
@ 2021-02-06 14:46 ` Laurent Vivier
-1 siblings, 0 replies; 24+ messages in thread
From: Laurent Vivier @ 2021-02-06 14:46 UTC (permalink / raw)
To: Alistair Francis
Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers
Le 26/01/2021 à 00:44, Alistair Francis a écrit :
> On Sat, Jan 23, 2021 at 7:06 AM Laurent Vivier <laurent@vivier.eu> wrote:
>>
>> Is there someone to merge this?
>
> Do you mean just this patch or the whole series?
Sorry, I missed your mail.
I mean only this patch.
Thanks,
Laurent
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 6/7] goldfish_rtc: re-arm the alarm after migration
@ 2021-02-06 14:46 ` Laurent Vivier
0 siblings, 0 replies; 24+ messages in thread
From: Laurent Vivier @ 2021-02-06 14:46 UTC (permalink / raw)
To: Alistair Francis
Cc: Alistair Francis, open list:RISC-V, qemu-devel@nongnu.org Developers
Le 26/01/2021 à 00:44, Alistair Francis a écrit :
> On Sat, Jan 23, 2021 at 7:06 AM Laurent Vivier <laurent@vivier.eu> wrote:
>>
>> Is there someone to merge this?
>
> Do you mean just this patch or the whole series?
Sorry, I missed your mail.
I mean only this patch.
Thanks,
Laurent
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 6/7] goldfish_rtc: re-arm the alarm after migration
2021-02-06 14:46 ` Laurent Vivier
@ 2021-02-09 1:49 ` Alistair Francis
-1 siblings, 0 replies; 24+ messages in thread
From: Alistair Francis @ 2021-02-09 1:49 UTC (permalink / raw)
To: Laurent Vivier
Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers
On Sat, Feb 6, 2021 at 6:46 AM Laurent Vivier <laurent@vivier.eu> wrote:
>
> Le 26/01/2021 à 00:44, Alistair Francis a écrit :
> > On Sat, Jan 23, 2021 at 7:06 AM Laurent Vivier <laurent@vivier.eu> wrote:
> >>
> >> Is there someone to merge this?
> >
> > Do you mean just this patch or the whole series?
>
> Sorry, I missed your mail.
>
> I mean only this patch.
Ok, I have applied it.
Thanks!
Applied to riscv-to-apply.next
Alistair
>
> Thanks,
> Laurent
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 6/7] goldfish_rtc: re-arm the alarm after migration
@ 2021-02-09 1:49 ` Alistair Francis
0 siblings, 0 replies; 24+ messages in thread
From: Alistair Francis @ 2021-02-09 1:49 UTC (permalink / raw)
To: Laurent Vivier
Cc: Alistair Francis, open list:RISC-V, qemu-devel@nongnu.org Developers
On Sat, Feb 6, 2021 at 6:46 AM Laurent Vivier <laurent@vivier.eu> wrote:
>
> Le 26/01/2021 à 00:44, Alistair Francis a écrit :
> > On Sat, Jan 23, 2021 at 7:06 AM Laurent Vivier <laurent@vivier.eu> wrote:
> >>
> >> Is there someone to merge this?
> >
> > Do you mean just this patch or the whole series?
>
> Sorry, I missed your mail.
>
> I mean only this patch.
Ok, I have applied it.
Thanks!
Applied to riscv-to-apply.next
Alistair
>
> Thanks,
> Laurent
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 6/7] goldfish_rtc: re-arm the alarm after migration
2020-12-20 11:26 ` [PATCH v2 6/7] goldfish_rtc: re-arm the alarm after migration Laurent Vivier
2021-01-23 15:05 ` Laurent Vivier
@ 2021-01-24 0:15 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 24+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-24 0:15 UTC (permalink / raw)
To: Laurent Vivier, qemu-devel; +Cc: Alistair Francis
On 12/20/20 12:26 PM, Laurent Vivier wrote:
> After a migration the clock offset is updated, but we also
> need to re-arm the alarm if needed.
>
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> hw/rtc/goldfish_rtc.c | 2 ++
> 1 file changed, 2 insertions(+)
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 7/7] m68k: add Virtual M68k Machine
2020-12-20 11:26 [PATCH v2 0/7] m68k: add Virtual M68k Machine Laurent Vivier
` (5 preceding siblings ...)
2020-12-20 11:26 ` [PATCH v2 6/7] goldfish_rtc: re-arm the alarm after migration Laurent Vivier
@ 2020-12-20 11:26 ` Laurent Vivier
2021-01-24 0:18 ` Philippe Mathieu-Daudé
6 siblings, 1 reply; 24+ messages in thread
From: Laurent Vivier @ 2020-12-20 11:26 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 | 18 +
hw/m68k/virt.c | 312 ++++++++++++++++++
MAINTAINERS | 9 +
hw/m68k/Kconfig | 10 +
hw/m68k/meson.build | 1 +
6 files changed, 351 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..81be1e092497
--- /dev/null
+++ b/include/standard-headers/asm-m68k/bootinfo-virt.h
@@ -0,0 +1,18 @@
+/* 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 BI_VIRT_CTRL_BASE 0x8005
+
+#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..8d9825a68df6
--- /dev/null
+++ b/hw/m68k/virt.c
@@ -0,0 +1,312 @@
+/*
+ * 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/intc/m68k_irqc.h"
+#include "hw/misc/m68k_virt_ctrl.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 #6
+ * 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 */
+#define VIRT_GF_PIC_NB 6
+
+/* 2 goldfish-rtc (and timer) */
+#define VIRT_GF_RTC_MMIO_BASE 0xff006000 /* MMIO: 0xff006000 - 0xff007fff */
+#define VIRT_GF_RTC_IRQ_BASE PIC_IRQ(6, 1) /* PIC: #6, IRQ: #1 */
+#define VIRT_GF_RTC_NB 2
+
+/* 1 goldfish-tty */
+#define VIRT_GF_TTY_MMIO_BASE 0xff008000 /* MMIO: 0xff008000 - 0xff008fff */
+#define VIRT_GF_TTY_IRQ_BASE PIC_IRQ(1, 32) /* PIC: #1, IRQ: #32 */
+
+/* 1 m68k-virt-ctrl */
+#define VIRT_M68K_CTRL_MMIO_BASE 0xff009000 /* MMIO: 0xff009000 - 0xff009fff */
+#define VIRT_M68K_CTRL_IRQ_BASE PIC_IRQ(1, 1) /* PIC: #1, IRQ: #1 */
+
+/*
+ * 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 */
+
+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 *irqc_dev;
+ DeviceState *pic_dev[VIRT_GF_PIC_NB];
+ 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 Controller */
+
+ irqc_dev = qdev_new(TYPE_M68K_IRQC);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(irqc_dev), &error_fatal);
+
+ /*
+ * 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 < VIRT_GF_PIC_NB; 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, qdev_get_gpio_in(irqc_dev, i));
+
+ io_base += 0x1000;
+ }
+
+ /* goldfish-rtc */
+ io_base = VIRT_GF_RTC_MMIO_BASE;
+ for (i = 0; i < VIRT_GF_RTC_NB; i++) {
+ dev = qdev_new(TYPE_GOLDFISH_RTC);
+ sysbus = SYS_BUS_DEVICE(dev);
+ sysbus_realize_and_unref(sysbus, &error_fatal);
+ sysbus_mmio_map(sysbus, 0, io_base);
+ sysbus_connect_irq(sysbus, 0, PIC_GPIO(VIRT_GF_RTC_IRQ_BASE + i));
+
+ io_base += 0x1000;
+ }
+
+ /* 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));
+
+ /* M68K virt controller */
+ dev = qdev_new(TYPE_M68K_VIRT_CTRL);
+ sysbus = SYS_BUS_DEVICE(dev);
+ sysbus_realize_and_unref(sysbus, &error_fatal);
+ sysbus_mmio_map(sysbus, 0, VIRT_M68K_CTRL_MMIO_BASE);
+ sysbus_connect_irq(sysbus, 0, PIC_GPIO(VIRT_M68K_CTRL_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_MINOR << 16) |
+ (QEMU_VERSION_MICRO << 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_CTRL_BASE,
+ VIRT_M68K_CTRL_MMIO_BASE, VIRT_M68K_CTRL_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 = "QEMU M68K Virtual Machine";
+ mc->init = virt_init;
+ mc->default_cpu_type = M68K_CPU_TYPE_NAME("m68040");
+ mc->max_cpus = 1;
+ mc->no_floppy = 1;
+ mc->no_parallel = 1;
+ mc->default_ram_id = "m68k_virt.ram";
+}
+
+static const TypeInfo virt_machine_info = {
+ .name = MACHINE_TYPE_NAME("virt"),
+ .parent = TYPE_MACHINE,
+ .abstract = true,
+ .class_init = virt_machine_class_init,
+};
+
+static void virt_machine_register_types(void)
+{
+ type_register_static(&virt_machine_info);
+}
+
+type_init(virt_machine_register_types)
+
+#define DEFINE_VIRT_MACHINE(major, minor, latest) \
+ static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
+ void *data) \
+ { \
+ MachineClass *mc = MACHINE_CLASS(oc); \
+ virt_machine_##major##_##minor##_options(mc); \
+ mc->desc = "QEMU " # major "." # minor " M68K Virtual Machine"; \
+ if (latest) { \
+ mc->alias = "virt"; \
+ } \
+ } \
+ static const TypeInfo machvirt_##major##_##minor##_info = { \
+ .name = MACHINE_TYPE_NAME("virt-" # major "." # minor), \
+ .parent = MACHINE_TYPE_NAME("virt"), \
+ .class_init = virt_##major##_##minor##_class_init, \
+ }; \
+ static void machvirt_machine_##major##_##minor##_init(void) \
+ { \
+ type_register_static(&machvirt_##major##_##minor##_info); \
+ } \
+ type_init(machvirt_machine_##major##_##minor##_init);
+
+static void virt_machine_5_2_options(MachineClass *mc)
+{
+}
+DEFINE_VIRT_MACHINE(5, 2, true)
diff --git a/MAINTAINERS b/MAINTAINERS
index 7640dfb5f0fc..5a290151cdec 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1105,6 +1105,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 60d7bcfb8f2b..f90d06d1cab7 100644
--- a/hw/m68k/Kconfig
+++ b/hw/m68k/Kconfig
@@ -23,3 +23,13 @@ config Q800
select ESP
select DP8393X
select OR_IRQ
+
+config M68K_VIRT
+ bool
+ select M68K_IRQC
+ select M68K_VIRT_CTRL
+ 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.29.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v2 7/7] m68k: add Virtual M68k Machine
2020-12-20 11:26 ` [PATCH v2 7/7] m68k: add Virtual M68k Machine Laurent Vivier
@ 2021-01-24 0:18 ` Philippe Mathieu-Daudé
2021-01-24 10:58 ` Laurent Vivier
0 siblings, 1 reply; 24+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-24 0:18 UTC (permalink / raw)
To: Laurent Vivier, qemu-devel
On 12/20/20 12:26 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 | 18 +
> hw/m68k/virt.c | 312 ++++++++++++++++++
> MAINTAINERS | 9 +
> hw/m68k/Kconfig | 10 +
> hw/m68k/meson.build | 1 +
> 6 files changed, 351 insertions(+)
> create mode 100644 include/standard-headers/asm-m68k/bootinfo-virt.h
> create mode 100644 hw/m68k/virt.c
...
> 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..81be1e092497
> --- /dev/null
> +++ b/include/standard-headers/asm-m68k/bootinfo-virt.h
> @@ -0,0 +1,18 @@
> +/* 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 BI_VIRT_CTRL_BASE 0x8005
> +
> +#define VIRT_BOOTI_VERSION MK_BI_VERSION(2, 0)
> +
> +#endif /* _UAPI_ASM_M68K_BOOTINFO_MAC_H */
Doesn't this belong to patch #1?
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 7/7] m68k: add Virtual M68k Machine
2021-01-24 0:18 ` Philippe Mathieu-Daudé
@ 2021-01-24 10:58 ` Laurent Vivier
0 siblings, 0 replies; 24+ messages in thread
From: Laurent Vivier @ 2021-01-24 10:58 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Le 24/01/2021 à 01:18, Philippe Mathieu-Daudé a écrit :
> On 12/20/20 12:26 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 | 18 +
>> hw/m68k/virt.c | 312 ++++++++++++++++++
>> MAINTAINERS | 9 +
>> hw/m68k/Kconfig | 10 +
>> hw/m68k/meson.build | 1 +
>> 6 files changed, 351 insertions(+)
>> create mode 100644 include/standard-headers/asm-m68k/bootinfo-virt.h
>> create mode 100644 hw/m68k/virt.c
> ...
>
>> 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..81be1e092497
>> --- /dev/null
>> +++ b/include/standard-headers/asm-m68k/bootinfo-virt.h
>> @@ -0,0 +1,18 @@
>> +/* 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 BI_VIRT_CTRL_BASE 0x8005
>> +
>> +#define VIRT_BOOTI_VERSION MK_BI_VERSION(2, 0)
>> +
>> +#endif /* _UAPI_ASM_M68K_BOOTINFO_MAC_H */
>
> Doesn't this belong to patch #1?
>
No, because in PATCH #1 the m68k-virt machine doesn't exist.
PATCH #1 can be merged outside of this series, it's a generic patch.
Thanks,
Laurent
^ permalink raw reply [flat|nested] 24+ messages in thread