From nobody Sat Jul 12 15:34:06 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1486016325131724.0190034402117; Wed, 1 Feb 2017 22:18:45 -0800 (PST) Received: from localhost ([::1]:54559 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cZAjD-0002kw-5m for importer@patchew.org; Thu, 02 Feb 2017 01:18:43 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51798) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cZ9jw-0007WL-PC for qemu-devel@nongnu.org; Thu, 02 Feb 2017 00:15:31 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cZ9jq-0003qG-64 for qemu-devel@nongnu.org; Thu, 02 Feb 2017 00:15:24 -0500 Received: from ozlabs.org ([2401:3900:2:1::2]:54527) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cZ9jp-0003li-Ba; Thu, 02 Feb 2017 00:15:18 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vDSqR5QgMz9s8N; Thu, 2 Feb 2017 16:14:58 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1486012499; bh=AC1TlmsD12/o5Nk+Qq5oNt5kAKdoK8JzkOgsPc1XPHc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=plQgXFTehT76+VE2I9iLq+XN+b0vb7qh5IjfaUtDg+k1GrLxcULt87IwrNy5a9wP9 IWzKeklMblorvv2GgiWnZh5gX6Ewwr4HA+OAG5/bvKvlvFX8Z7K7NtY/jeFojPYf9N TEjz/1gXE4RVMRnb6Po4sAn9QlWMqoyBohk2mV7c= From: David Gibson To: peter.maydell@linaro.org Date: Thu, 2 Feb 2017 16:13:46 +1100 Message-Id: <20170202051445.5735-49-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170202051445.5735-1-david@gibson.dropbear.id.au> References: <20170202051445.5735-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PULL 048/107] prep: add PReP System I/O X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, thuth@redhat.com, qemu-devel@nongnu.org, mdroth@linux.vnet.ibm.com, agraf@suse.de, aik@ozlabs.ru, qemu-ppc@nongnu.org, =?UTF-8?q?Herv=C3=A9=20Poussineau?= , David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Herv=C3=A9 Poussineau This device is a partial duplicate of System I/O device available in hw/ppc= /prep.c This new one doesn't have all the Motorola-specific registers. The old one should be deprecated and removed with the 'prep' machine. Partial documentation available at ftp://ftp.software.ibm.com/rs6000/technology/spec/srp1_1.exe section 6.1.5 (I/O Device Mapping) Signed-off-by: Herv=C3=A9 Poussineau Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/Makefile.objs | 1 + hw/ppc/prep_systemio.c | 303 +++++++++++++++++++++++++++++++++++++++++++++= ++++ hw/ppc/trace-events | 4 + 3 files changed, 308 insertions(+) create mode 100644 hw/ppc/prep_systemio.c diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs index 8025129..db72297 100644 --- a/hw/ppc/Makefile.objs +++ b/hw/ppc/Makefile.objs @@ -16,6 +16,7 @@ obj-y +=3D ppc405_boards.o ppc4xx_devs.o ppc405_uc.o ppc4= 40_bamboo.o obj-y +=3D ppc4xx_pci.o # PReP obj-$(CONFIG_PREP) +=3D prep.o +obj-$(CONFIG_PREP) +=3D prep_systemio.o # OldWorld PowerMac obj-$(CONFIG_MAC) +=3D mac_oldworld.o # NewWorld PowerMac diff --git a/hw/ppc/prep_systemio.c b/hw/ppc/prep_systemio.c new file mode 100644 index 0000000..50893ec --- /dev/null +++ b/hw/ppc/prep_systemio.c @@ -0,0 +1,303 @@ +/* + * QEMU PReP System I/O emulation + * + * Copyright (c) 2017 Herv=C3=A9 Poussineau + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), t= o deal + * in the Software without restriction, including without limitation the r= ights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OT= HER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING= FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS = IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "hw/isa/isa.h" +#include "exec/address-spaces.h" +#include "qemu/error-report.h" /* for error_report() */ +#include "sysemu/sysemu.h" /* for vm_stop() */ +#include "cpu.h" +#include "trace.h" + +#define TYPE_PREP_SYSTEMIO "prep-systemio" +#define PREP_SYSTEMIO(obj) \ + OBJECT_CHECK(PrepSystemIoState, (obj), TYPE_PREP_SYSTEMIO) + +/* Bit as defined in PowerPC Reference Plaform v1.1, sect. 6.1.5, p. 132 */ +#define PREP_BIT(n) (1 << (7 - (n))) + +typedef struct PrepSystemIoState { + ISADevice parent_obj; + MemoryRegion ppc_parity_mem; + + qemu_irq non_contiguous_io_map_irq; + uint8_t sreset; /* 0x0092 */ + uint8_t equipment; /* 0x080c */ + uint8_t system_control; /* 0x081c */ + uint8_t iomap_type; /* 0x0850 */ + uint8_t ibm_planar_id; /* 0x0852 */ + qemu_irq softreset_irq; + PortioList portio; +} PrepSystemIoState; + +/* PORT 0092 -- Special Port 92 (Read/Write) */ + +enum { + PORT0092_SOFTRESET =3D PREP_BIT(7), + PORT0092_LE_MODE =3D PREP_BIT(6), +}; + +static void prep_port0092_write(void *opaque, uint32_t addr, uint32_t val) +{ + PrepSystemIoState *s =3D opaque; + + trace_prep_systemio_write(addr, val); + + s->sreset =3D val & PORT0092_SOFTRESET; + qemu_set_irq(s->softreset_irq, s->sreset); + + if ((val & PORT0092_LE_MODE) !=3D 0) { + /* XXX Not supported yet */ + error_report("little-endian mode not supported"); + vm_stop(RUN_STATE_PAUSED); + } else { + /* Nothing to do */ + } +} + +static uint32_t prep_port0092_read(void *opaque, uint32_t addr) +{ + PrepSystemIoState *s =3D opaque; + trace_prep_systemio_read(addr, s->sreset); + return s->sreset; +} + +/* PORT 0808 -- Hardfile Light Register (Write Only) */ + +enum { + PORT0808_HARDFILE_LIGHT_ON =3D PREP_BIT(7), +}; + +static void prep_port0808_write(void *opaque, uint32_t addr, uint32_t val) +{ + trace_prep_systemio_write(addr, val); +} + +/* PORT 0810 -- Password Protect 1 Register (Write Only) */ + +/* reset by port 0x4D in the SIO */ +static void prep_port0810_write(void *opaque, uint32_t addr, uint32_t val) +{ + trace_prep_systemio_write(addr, val); +} + +/* PORT 0812 -- Password Protect 2 Register (Write Only) */ + +/* reset by port 0x4D in the SIO */ +static void prep_port0812_write(void *opaque, uint32_t addr, uint32_t val) +{ + trace_prep_systemio_write(addr, val); +} + +/* PORT 0814 -- L2 Invalidate Register (Write Only) */ + +static void prep_port0814_write(void *opaque, uint32_t addr, uint32_t val) +{ + trace_prep_systemio_write(addr, val); +} + +/* PORT 0818 -- Reserved for Keylock (Read Only) */ + +enum { + PORT0818_KEYLOCK_SIGNAL_HIGH =3D PREP_BIT(7), +}; + +static uint32_t prep_port0818_read(void *opaque, uint32_t addr) +{ + uint32_t val =3D 0; + trace_prep_systemio_read(addr, val); + return val; +} + +/* PORT 080C -- Equipment */ + +enum { + PORT080C_SCSIFUSE =3D PREP_BIT(1), + PORT080C_L2_COPYBACK =3D PREP_BIT(4), + PORT080C_L2_256 =3D PREP_BIT(5), + PORT080C_UPGRADE_CPU =3D PREP_BIT(6), + PORT080C_L2 =3D PREP_BIT(7), +}; + +static uint32_t prep_port080c_read(void *opaque, uint32_t addr) +{ + PrepSystemIoState *s =3D opaque; + trace_prep_systemio_read(addr, s->equipment); + return s->equipment; +} + +/* PORT 081C -- System Control Register (Read/Write) */ + +enum { + PORT081C_FLOPPY_MOTOR_INHIBIT =3D PREP_BIT(3), + PORT081C_MASK_TEA =3D PREP_BIT(2), + PORT081C_L2_UPDATE_INHIBIT =3D PREP_BIT(1), + PORT081C_L2_CACHEMISS_INHIBIT =3D PREP_BIT(0), +}; + +static void prep_port081c_write(void *opaque, uint32_t addr, uint32_t val) +{ + static const uint8_t mask =3D PORT081C_FLOPPY_MOTOR_INHIBIT | + PORT081C_MASK_TEA | + PORT081C_L2_UPDATE_INHIBIT | + PORT081C_L2_CACHEMISS_INHIBIT; + PrepSystemIoState *s =3D opaque; + trace_prep_systemio_write(addr, val); + s->system_control =3D val & mask; +} + +static uint32_t prep_port081c_read(void *opaque, uint32_t addr) +{ + PrepSystemIoState *s =3D opaque; + trace_prep_systemio_read(addr, s->system_control); + return s->system_control; +} + +/* System Board Identification */ + +static uint32_t prep_port0852_read(void *opaque, uint32_t addr) +{ + PrepSystemIoState *s =3D opaque; + trace_prep_systemio_read(addr, s->ibm_planar_id); + return s->ibm_planar_id; +} + +/* PORT 0850 -- I/O Map Type Register (Read/Write) */ + +enum { + PORT0850_IOMAP_NONCONTIGUOUS =3D PREP_BIT(7), +}; + +static uint32_t prep_port0850_read(void *opaque, uint32_t addr) +{ + PrepSystemIoState *s =3D opaque; + trace_prep_systemio_read(addr, s->iomap_type); + return s->iomap_type; +} + +static void prep_port0850_write(void *opaque, uint32_t addr, uint32_t val) +{ + PrepSystemIoState *s =3D opaque; + + trace_prep_systemio_write(addr, val); + qemu_set_irq(s->non_contiguous_io_map_irq, + val & PORT0850_IOMAP_NONCONTIGUOUS); + s->iomap_type =3D val & PORT0850_IOMAP_NONCONTIGUOUS; +} + +static const MemoryRegionPortio ppc_io800_port_list[] =3D { + { 0x092, 1, 1, .read =3D prep_port0092_read, + .write =3D prep_port0092_write, }, + { 0x808, 1, 1, .write =3D prep_port0808_write, }, + { 0x80c, 1, 1, .read =3D prep_port080c_read, }, + { 0x810, 1, 1, .write =3D prep_port0810_write, }, + { 0x812, 1, 1, .write =3D prep_port0812_write, }, + { 0x814, 1, 1, .write =3D prep_port0814_write, }, + { 0x818, 1, 1, .read =3D prep_port0818_read }, + { 0x81c, 1, 1, .read =3D prep_port081c_read, + .write =3D prep_port081c_write, }, + { 0x850, 1, 1, .read =3D prep_port0850_read, + .write =3D prep_port0850_write, }, + { 0x852, 1, 1, .read =3D prep_port0852_read, }, + PORTIO_END_OF_LIST() +}; + +static uint64_t ppc_parity_error_readl(void *opaque, hwaddr addr, + unsigned int size) +{ + uint32_t val =3D 0; + trace_prep_systemio_read((unsigned int)addr, val); + return val; +} + +static const MemoryRegionOps ppc_parity_error_ops =3D { + .read =3D ppc_parity_error_readl, + .valid =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + }, +}; + +static void prep_systemio_realize(DeviceState *dev, Error **errp) +{ + ISADevice *isa =3D ISA_DEVICE(dev); + PrepSystemIoState *s =3D PREP_SYSTEMIO(dev); + PowerPCCPU *cpu; + + qdev_init_gpio_out(dev, &s->non_contiguous_io_map_irq, 1); + s->iomap_type =3D PORT0850_IOMAP_NONCONTIGUOUS; + qemu_set_irq(s->non_contiguous_io_map_irq, + s->iomap_type & PORT0850_IOMAP_NONCONTIGUOUS); + cpu =3D POWERPC_CPU(first_cpu); + s->softreset_irq =3D cpu->env.irq_inputs[PPC6xx_INPUT_HRESET]; + + isa_register_portio_list(isa, &s->portio, 0x0, ppc_io800_port_list, s, + "systemio800"); + + memory_region_init_io(&s->ppc_parity_mem, OBJECT(dev), + &ppc_parity_error_ops, s, "ppc-parity", 0x4); + memory_region_add_subregion(get_system_memory(), 0xbfffeff0, + &s->ppc_parity_mem); +} + +static const VMStateDescription vmstate_prep_systemio =3D { + .name =3D "prep_systemio", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (VMStateField[]) { + VMSTATE_UINT8(sreset, PrepSystemIoState), + VMSTATE_UINT8(system_control, PrepSystemIoState), + VMSTATE_UINT8(iomap_type, PrepSystemIoState), + VMSTATE_END_OF_LIST() + }, +}; + +static Property prep_systemio_properties[] =3D { + DEFINE_PROP_UINT8("ibm-planar-id", PrepSystemIoState, ibm_planar_id, 0= ), + DEFINE_PROP_UINT8("equipment", PrepSystemIoState, equipment, 0), + DEFINE_PROP_END_OF_LIST() +}; + +static void prep_systemio_class_initfn(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->realize =3D prep_systemio_realize; + dc->vmsd =3D &vmstate_prep_systemio; + dc->props =3D prep_systemio_properties; +} + +static TypeInfo prep_systemio800_info =3D { + .name =3D TYPE_PREP_SYSTEMIO, + .parent =3D TYPE_ISA_DEVICE, + .instance_size =3D sizeof(PrepSystemIoState), + .class_init =3D prep_systemio_class_initfn, +}; + +static void prep_systemio_register_types(void) +{ + type_register_static(&prep_systemio800_info); +} + +type_init(prep_systemio_register_types) diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events index 2297ead..2ba6166 100644 --- a/hw/ppc/trace-events +++ b/hw/ppc/trace-events @@ -74,3 +74,7 @@ ppc_tb_adjust(uint64_t offs1, uint64_t offs2, int64_t dif= f, int64_t seconds) "ad # hw/ppc/prep.c prep_io_800_writeb(uint32_t addr, uint32_t val) "0x%08" PRIx32 " =3D> 0x%0= 2" PRIx32 prep_io_800_readb(uint32_t addr, uint32_t retval) "0x%08" PRIx32 " <=3D 0x= %02" PRIx32 + +# hw/ppc/prep_systemio.c +prep_systemio_read(uint32_t addr, uint32_t val) "read addr=3D%x val=3D%x" +prep_systemio_write(uint32_t addr, uint32_t val) "write addr=3D%x val=3D%x" --=20 2.9.3