From nobody Thu Apr 25 20:51:34 2024 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 1486762527110410.4787108056139; Fri, 10 Feb 2017 13:35:27 -0800 (PST) Received: from localhost ([::1]:46054 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ccIqj-0003Lp-Gu for importer@patchew.org; Fri, 10 Feb 2017 16:35:25 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37282) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ccIRb-0003ru-9D for qemu-devel@nongnu.org; Fri, 10 Feb 2017 16:09:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ccIRZ-0001kh-JJ for qemu-devel@nongnu.org; Fri, 10 Feb 2017 16:09:27 -0500 Received: from mail-wm0-x243.google.com ([2a00:1450:400c:c09::243]:36222) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ccIRS-0001jq-LL; Fri, 10 Feb 2017 16:09:18 -0500 Received: by mail-wm0-x243.google.com with SMTP id r18so9101513wmd.3; Fri, 10 Feb 2017 13:09:18 -0800 (PST) Received: from localhost.localdomain (cbv156.neoplus.adsl.tpnet.pl. [83.30.119.156]) by smtp.gmail.com with ESMTPSA id z10sm1113090wmg.31.2017.02.10.13.09.15 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 10 Feb 2017 13:09:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=agpweTcIBAmWsLk20KlX4MP6a9k6qJ8WlCFbaQpCP+0=; b=UsVWDT1OZC/fwsETaebDSNf9gMPfJ7Q0byWMC7XC0YeTxx4VKWPGYLI2uZSiBTcU3F /YR6xdWSLbZCa0kKMszosNLgIwmf+BZJ9W3I8Mw1+KSFpLKaDEDuFe8DI0H6ObmFBqxJ mln1c5MjOwL0oJ+mF6+qtsNeuPFgXrOvBzO/uEUtouUXQiEnI6cbWtaybaBEzFA8Ij6v JpaXKXRK/aVdb0RQtwL37f2g3nBoyC0dQ8JVecDo9jih5QtgQ+mxza9Ll/5BGcktrkHU KSIjXZ1n0NWFGQ5NfHfHNu/ZJmNwFJ1aMq6Zv8ZBuvWW8LkSQrsjFOvOkpqXuzcQVgyf pwJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=agpweTcIBAmWsLk20KlX4MP6a9k6qJ8WlCFbaQpCP+0=; b=q9vaMrwZePrmharh+DXru9+5u3VAwH65rpXlAbMBUs93qHh1QPNrqbcCXhzWv+xRxK 9oTfluWb8/8evlzUA3ZLLOJFpsw80Hk6qnFDLH5EJBs82ZQAGZnt5bx5u3cEu/CE26ld alNOamt0PAqCOb9/dM+j6EqVNR8j6vpwOonKBU3Y1KQ5fGWNgkt1Ba+bNbQhB/truE3u Az/bieAwRcw7W0xuWbrAhVKCx281ezmZ4sQLcbopzwXGQYFNrIazNKjywgvlZrf+PtaO xVFCBUFNa3Sge4JcFLH8uqSoP+u/t+EZ7DgPNkmdkCP6oVT5CYwzTnhN1DmiSwD4918d MAIQ== X-Gm-Message-State: AMke39m8y9t8HCrHE0SqqfJYwAyrXPNjQijy2oLyCONIF0O1nU8zcLkkvl6KbjDdc99SmA== X-Received: by 10.28.61.136 with SMTP id k130mr8885031wma.128.1486760957314; Fri, 10 Feb 2017 13:09:17 -0800 (PST) From: Marcin Chojnacki To: qemu-arm@nongnu.org Date: Fri, 10 Feb 2017 22:08:57 +0100 Message-Id: <20170210210857.47893-1-marcinch7@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::243 X-Mailman-Approved-At: Fri, 10 Feb 2017 16:33:57 -0500 Subject: [Qemu-devel] [PATCH v2] target-arm: Implement BCM2835 hardware RNG 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: peter.maydell@linaro.org, qemu-devel@nongnu.org, Marcin Chojnacki Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Recent vanilla Raspberry Pi kernels started to make use of the hardware random number generator in BCM2835 SoC. As a result, those kernels wouldn't work anymore under QEMU but rather just freeze during the boot process. This patch implements a trivial BCM2835 compatible RNG, and adds it as a peripheral to BCM2835 platform, which allows to boot a vanilla Raspberry Pi kernel under Qemu. Changes since v1: * Prevented guest from writing [31..20] bits in rng_status * Removed redundant minimum_version_id_old * Added field entries for the state * Changed realize function to reset Signed-off-by: Marcin Chojnacki --- hw/arm/bcm2835_peripherals.c | 15 +++++ hw/misc/Makefile.objs | 1 + hw/misc/bcm2835_rng.c | 124 +++++++++++++++++++++++++++++++= ++++ include/hw/arm/bcm2835_peripherals.h | 2 + include/hw/misc/bcm2835_rng.h | 27 ++++++++ 5 files changed, 169 insertions(+) create mode 100644 hw/misc/bcm2835_rng.c create mode 100644 include/hw/misc/bcm2835_rng.h diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c index 2e641a3..9ed22d5 100644 --- a/hw/arm/bcm2835_peripherals.c +++ b/hw/arm/bcm2835_peripherals.c @@ -86,6 +86,11 @@ static void bcm2835_peripherals_init(Object *obj) object_property_add_const_link(OBJECT(&s->property), "dma-mr", OBJECT(&s->gpu_bus_mr), &error_abort); =20 + /* Random Number Generator */ + object_initialize(&s->rng, sizeof(s->rng), TYPE_BCM2835_RNG); + object_property_add_child(obj, "rng", OBJECT(&s->rng), NULL); + qdev_set_parent_bus(DEVICE(&s->rng), sysbus_get_default()); + /* Extended Mass Media Controller */ object_initialize(&s->sdhci, sizeof(s->sdhci), TYPE_SYSBUS_SDHCI); object_property_add_child(obj, "sdhci", OBJECT(&s->sdhci), NULL); @@ -226,6 +231,16 @@ static void bcm2835_peripherals_realize(DeviceState *d= ev, Error **errp) sysbus_connect_irq(SYS_BUS_DEVICE(&s->property), 0, qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_PROPE= RTY)); =20 + /* Random Number Generator */ + object_property_set_bool(OBJECT(&s->rng), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + + memory_region_add_subregion(&s->peri_mr, RNG_OFFSET, + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->rng), 0)); + /* Extended Mass Media Controller */ object_property_set_int(OBJECT(&s->sdhci), BCM2835_SDHC_CAPAREG, "capa= reg", &err); diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index 898e4cc..57a4406 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -42,6 +42,7 @@ obj-$(CONFIG_OMAP) +=3D omap_sdrc.o obj-$(CONFIG_OMAP) +=3D omap_tap.o obj-$(CONFIG_RASPI) +=3D bcm2835_mbox.o obj-$(CONFIG_RASPI) +=3D bcm2835_property.o +obj-$(CONFIG_RASPI) +=3D bcm2835_rng.o obj-$(CONFIG_SLAVIO) +=3D slavio_misc.o obj-$(CONFIG_ZYNQ) +=3D zynq_slcr.o obj-$(CONFIG_ZYNQ) +=3D zynq-xadc.o diff --git a/hw/misc/bcm2835_rng.c b/hw/misc/bcm2835_rng.c new file mode 100644 index 0000000..d9a5acf --- /dev/null +++ b/hw/misc/bcm2835_rng.c @@ -0,0 +1,124 @@ +/* + * BCM2835 Random Number Generator emulation + * + * Copyright (C) 2017 Marcin Chojnacki + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "hw/misc/bcm2835_rng.h" + +static uint64_t bcm2835_rng_read(void *opaque, hwaddr offset, + unsigned size) +{ + BCM2835RngState *s =3D (BCM2835RngState *)opaque; + uint32_t res =3D 0; + + assert(size =3D=3D 4); + + switch (offset) { + case 0x0: /* rng_ctrl */ + res =3D s->rng_ctrl; + break; + case 0x4: /* rng_status */ + res =3D s->rng_status | (1 << 24); + break; + case 0x8: /* rng_data */ + res =3D rand(); + break; + + default: + qemu_log_mask(LOG_GUEST_ERROR, + "bcm2835_rng_read: Bad offset %x\n", + (int)offset); + res =3D 0; + break; + } + + return res; +} + +static void bcm2835_rng_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + BCM2835RngState *s =3D (BCM2835RngState *)opaque; + + assert(size =3D=3D 4); + + switch (offset) { + case 0x0: /* rng_ctrl */ + s->rng_ctrl =3D value; + break; + case 0x4: /* rng_status */ + /* we shouldn't let the guest write to bits [31..20] */ + s->rng_status &=3D ~0xFFFFF; /* clear 20 lower bits */ + s->rng_status |=3D value & 0xFFFFF; /* set them to new value */ + break; + + default: + qemu_log_mask(LOG_GUEST_ERROR, + "bcm2835_rng_write: Bad offset %x\n", + (int)offset); + break; + } +} + +static const MemoryRegionOps bcm2835_rng_ops =3D { + .read =3D bcm2835_rng_read, + .write =3D bcm2835_rng_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, +}; + +static const VMStateDescription vmstate_bcm2835_rng =3D { + .name =3D TYPE_BCM2835_RNG, + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (VMStateField[]) { + VMSTATE_UINT32(rng_ctrl, BCM2835RngState), + VMSTATE_UINT32(rng_status, BCM2835RngState), + VMSTATE_END_OF_LIST() + } +}; + +static void bcm2835_rng_init(Object *obj) +{ + BCM2835RngState *s =3D BCM2835_RNG(obj); + + memory_region_init_io(&s->iomem, obj, &bcm2835_rng_ops, s, + TYPE_BCM2835_RNG, 0x10); + sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem); +} + +static void bcm2835_rng_reset(DeviceState *dev) +{ + BCM2835RngState *s =3D BCM2835_RNG(dev); + + s->rng_ctrl =3D 0; + s->rng_status =3D 0; +} + +static void bcm2835_rng_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->reset =3D bcm2835_rng_reset; + dc->vmsd =3D &vmstate_bcm2835_rng; +} + +static TypeInfo bcm2835_rng_info =3D { + .name =3D TYPE_BCM2835_RNG, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(BCM2835RngState), + .class_init =3D bcm2835_rng_class_init, + .instance_init =3D bcm2835_rng_init, +}; + +static void bcm2835_rng_register_types(void) +{ + type_register_static(&bcm2835_rng_info); +} + +type_init(bcm2835_rng_register_types) diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_= peripherals.h index e12ae37..31241c7 100644 --- a/include/hw/arm/bcm2835_peripherals.h +++ b/include/hw/arm/bcm2835_peripherals.h @@ -19,6 +19,7 @@ #include "hw/dma/bcm2835_dma.h" #include "hw/intc/bcm2835_ic.h" #include "hw/misc/bcm2835_property.h" +#include "hw/misc/bcm2835_rng.h" #include "hw/misc/bcm2835_mbox.h" #include "hw/sd/sdhci.h" =20 @@ -41,6 +42,7 @@ typedef struct BCM2835PeripheralState { BCM2835DMAState dma; BCM2835ICState ic; BCM2835PropertyState property; + BCM2835RngState rng; BCM2835MboxState mboxes; SDHCIState sdhci; } BCM2835PeripheralState; diff --git a/include/hw/misc/bcm2835_rng.h b/include/hw/misc/bcm2835_rng.h new file mode 100644 index 0000000..41a531b --- /dev/null +++ b/include/hw/misc/bcm2835_rng.h @@ -0,0 +1,27 @@ +/* + * BCM2835 Random Number Generator emulation + * + * Copyright (C) 2017 Marcin Chojnacki + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef BCM2835_RNG_H +#define BCM2835_RNG_H + +#include "hw/sysbus.h" + +#define TYPE_BCM2835_RNG "bcm2835-rng" +#define BCM2835_RNG(obj) \ + OBJECT_CHECK(BCM2835RngState, (obj), TYPE_BCM2835_RNG) + +typedef struct { + SysBusDevice busdev; + MemoryRegion iomem; + + uint32_t rng_ctrl; + uint32_t rng_status; +} BCM2835RngState; + +#endif --=20 2.10.1 (Apple Git-78)