[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 19/44] Add RNG200 timer
From: |
Sergey Kambalin |
Subject: |
[PATCH 19/44] Add RNG200 timer |
Date: |
Wed, 26 Jul 2023 16:24:47 +0300 |
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
---
hw/arm/bcm2838_peripherals.c | 14 ++++
hw/arm/raspi4b.c | 1 -
hw/misc/bcm2838_rng200.c | 105 ++++++++++++++++++++++++---
include/hw/arm/bcm2838_peripherals.h | 2 +
4 files changed, 111 insertions(+), 11 deletions(-)
diff --git a/hw/arm/bcm2838_peripherals.c b/hw/arm/bcm2838_peripherals.c
index 41b321b254..df97953bbe 100644
--- a/hw/arm/bcm2838_peripherals.c
+++ b/hw/arm/bcm2838_peripherals.c
@@ -34,6 +34,9 @@ static void bcm2838_peripherals_init(Object *obj)
bc->peri_low_size);
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->peri_low_mr);
+ /* Random Number Generator */
+ object_initialize_child(obj, "rng200", &s->rng200, TYPE_BCM2838_RNG200);
+
/* PCIe Host Bridge */
object_initialize_child(obj, "pcie-host", &s->pcie_host,
TYPE_BCM2838_PCIE_HOST);
@@ -84,6 +87,17 @@ static void bcm2838_peripherals_realize(DeviceState *dev,
Error **errp)
BCM2838_VC_PERI_LOW_BASE,
&s->peri_low_mr_alias, 1);
+ /* Random Number Generator */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->rng200), errp)) {
+ return;
+ }
+ memory_region_add_subregion(
+ &s_base->peri_mr, RNG_OFFSET,
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->rng200), 0));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->rng200), 0,
+ qdev_get_gpio_in_named(DEVICE(&s_base->ic), BCM2835_IC_GPU_IRQ,
+ INTERRUPT_RNG));
+
/* Extended Mass Media Controller 2 */
object_property_set_uint(OBJECT(&s->emmc2), "sd-spec-version", 3,
&error_abort);
diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c
index 115359e451..82b6b48d3c 100644
--- a/hw/arm/raspi4b.c
+++ b/hw/arm/raspi4b.c
@@ -66,7 +66,6 @@ static void raspi4_modify_dtb(const struct arm_boot_info
*info, void *fdt)
/* Temporary disable following devices until they are implemented*/
const char *to_be_removed_from_dt_as_wa[] = {
- "brcm,bcm2711-rng200",
"brcm,bcm2711-thermal",
"brcm,bcm2711-genet-v5",
};
diff --git a/hw/misc/bcm2838_rng200.c b/hw/misc/bcm2838_rng200.c
index bfc40658e2..face1e9579 100644
--- a/hw/misc/bcm2838_rng200.c
+++ b/hw/misc/bcm2838_rng200.c
@@ -9,6 +9,7 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
+#include "qom/object_interfaces.h"
#include "qapi/error.h"
#include "hw/qdev-properties.h"
#include "hw/misc/bcm2838_rng200.h"
@@ -35,6 +36,15 @@ static void bcm2838_rng200_update_irq(BCM2838Rng200State
*state)
& state->rng_int_status.value));
}
+static void bcm2838_rng200_update_rbg_period(void *opaque, ClockEvent event)
+{
+ BCM2838Rng200State *s = (BCM2838Rng200State *)opaque;
+
+ ptimer_transaction_begin(s->ptimer);
+ ptimer_set_period_from_clock(s->ptimer, s->clock, s->rng_fifo_cap * 8);
+ ptimer_transaction_commit(s->ptimer);
+}
+
static void bcm2838_rng200_update_fifo(void *opaque, const void *buf,
size_t size)
{
@@ -62,10 +72,11 @@ static void bcm2838_rng200_update_fifo(void *opaque, const
void *buf,
if ((num == 0) && (num_bits > 0)) {
num = 1;
}
- if (num > 0) {
+ if (!state->use_timer || (num > 0)) {
fifo8_push_all(fifo, buf, num);
- if (fifo8_num_used(fifo) > state->rng_fifo_count.thld) {
+ if (!state->use_timer
+ || (fifo8_num_used(fifo) > state->rng_fifo_count.thld)) {
state->rng_int_status.total_bits_count_irq = 1;
}
}
@@ -82,10 +93,14 @@ static void bcm2838_rng200_fill_fifo(BCM2838Rng200State
*state)
bcm2838_rng200_update_fifo, state);
}
-/* state is temporary unused */
-static void bcm2838_rng200_disable_rbg(BCM2838Rng200State *state
- __attribute__((unused)))
+static void bcm2838_rng200_disable_rbg(BCM2838Rng200State *state)
{
+ if (state->use_timer) {
+ ptimer_transaction_begin(state->ptimer);
+ ptimer_stop(state->ptimer);
+ ptimer_transaction_commit(state->ptimer);
+ }
+
trace_bcm2838_rng200_disable_rbg();
}
@@ -93,11 +108,38 @@ static void bcm2838_rng200_enable_rbg(BCM2838Rng200State
*state)
{
state->rng_total_bit_count = RNG_WARM_UP_PERIOD_ELAPSED;
- bcm2838_rng200_fill_fifo(state);
+ if (state->use_timer) {
+ uint32_t div = state->rng_ctrl.div + 1;
+
+ ptimer_transaction_begin(state->ptimer);
+ ptimer_set_limit(state->ptimer, div, 1);
+ ptimer_set_count(state->ptimer, div);
+ ptimer_run(state->ptimer, 0);
+ ptimer_transaction_commit(state->ptimer);
+ } else {
+ bcm2838_rng200_fill_fifo(state);
+ }
trace_bcm2838_rng200_enable_rbg();
}
+static void bcm2838_rng200_ptimer_cb(void *arg)
+{
+ BCM2838Rng200State *state = (BCM2838Rng200State *)arg;
+ Fifo8 *fifo = &state->fifo;
+ size_t size = fifo8_num_free(fifo);
+
+ assert(state->rng_ctrl.rbg_enable);
+
+ if (size > 0) {
+ rng_backend_request_entropy(state->rng, size,
+ bcm2838_rng200_update_fifo, state);
+ } else {
+ ptimer_stop(state->ptimer);
+ trace_bcm2838_rng200_fifo_full();
+ }
+}
+
static void bcm2838_rng200_rng_reset(BCM2838Rng200State *state)
{
state->rng_ctrl.value = 0;
@@ -129,6 +171,12 @@ static uint32_t
bcm2838_rng200_read_fifo_data(BCM2838Rng200State *state)
buf = fifo8_pop_buf(fifo, max, &num);
if ((buf != NULL) && (num > 0)) {
memcpy(&ret, buf, num);
+
+ if (state->rng_ctrl.rbg_enable && state->use_timer) {
+ ptimer_transaction_begin(state->ptimer);
+ ptimer_run(state->ptimer, 0);
+ ptimer_transaction_commit(state->ptimer);
+ }
}
} else {
qemu_log_mask(
@@ -138,7 +186,10 @@ static uint32_t
bcm2838_rng200_read_fifo_data(BCM2838Rng200State *state)
}
state->rng_fifo_count.count = fifo8_num_used(fifo) >> 2;
- bcm2838_rng200_fill_fifo(state);
+
+ if (!state->use_timer) {
+ bcm2838_rng200_fill_fifo(state);
+ }
return ret;
}
@@ -237,7 +288,11 @@ static void bcm2838_rng200_write(void *opaque, hwaddr
offset,
break;
case RNG_TOTAL_BIT_COUNT_THRESHOLD_OFFSET:
s->rng_bit_count_threshold = value;
- s->rng_total_bit_count = value + 1;
+ if (s->use_timer) {
+ s->rng_total_bit_count = 0;
+ } else {
+ s->rng_total_bit_count = value + 1;
+ }
break;
default:
qemu_log_mask(
@@ -253,15 +308,39 @@ static const MemoryRegionOps bcm2838_rng200_ops = {
.read = bcm2838_rng200_read,
.write = bcm2838_rng200_write,
.endianness = DEVICE_NATIVE_ENDIAN,
+ .impl = {
+ .max_access_size = 4,
+ .min_access_size = 4,
+ },
+ .valid = {
+ .max_access_size = 4,
+ .min_access_size = 4
+ },
};
static void bcm2838_rng200_realize(DeviceState *dev, Error **errp)
{
BCM2838Rng200State *s = BCM2838_RNG200(dev);
+ if (s->use_timer) {
+ s->ptimer = ptimer_init(bcm2838_rng200_ptimer_cb, s,
+ BCM2838_RNG200_PTIMER_POLICY);
+ if (s->ptimer == NULL) {
+ error_setg(&error_fatal, "Failed to init RBG timer");
+ return;
+ }
+ }
+
if (s->rng == NULL) {
Object *default_backend = object_new(TYPE_RNG_BUILTIN);
+ if (!user_creatable_complete(USER_CREATABLE(default_backend),
+ errp)) {
+ object_unref(default_backend);
+ error_setg(errp, "Failed to create user creatable RNG backend");
+ return;
+ }
+
object_property_add_child(OBJECT(dev), "default-backend",
default_backend);
object_unref(default_backend);
@@ -270,6 +349,12 @@ static void bcm2838_rng200_realize(DeviceState *dev, Error
**errp)
errp);
}
+ if (s->use_timer && !clock_has_source(s->clock)) {
+ ptimer_transaction_begin(s->ptimer);
+ ptimer_set_period(s->ptimer, s->rbg_period * s->rng_fifo_cap * 8);
+ ptimer_transaction_commit(s->ptimer);
+ }
+
fifo8_create(&s->fifo, s->rng_fifo_cap);
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
}
@@ -280,7 +365,7 @@ static void bcm2838_rng200_init(Object *obj)
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
s->clock = qdev_init_clock_in(DEVICE(s), "rbg-clock",
- NULL, s,
+ bcm2838_rng200_update_rbg_period, s,
ClockPreUpdate);
if (s->clock == NULL) {
error_setg(&error_fatal, "Failed to init RBG clock");
@@ -305,7 +390,7 @@ static Property bcm2838_rng200_properties[] = {
DEFINE_PROP_UINT32("rng-fifo-cap", BCM2838Rng200State, rng_fifo_cap, 128),
DEFINE_PROP_LINK("rng", BCM2838Rng200State, rng,
TYPE_RNG_BACKEND, RngBackend *),
- DEFINE_PROP_BOOL("use-timer", BCM2838Rng200State, use_timer, false),
+ DEFINE_PROP_BOOL("use-timer", BCM2838Rng200State, use_timer, true),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/include/hw/arm/bcm2838_peripherals.h
b/include/hw/arm/bcm2838_peripherals.h
index d3e3449b2b..d52617f3bd 100644
--- a/include/hw/arm/bcm2838_peripherals.h
+++ b/include/hw/arm/bcm2838_peripherals.h
@@ -10,6 +10,7 @@
#define BCM2838_PERIPHERALS_H
#include "hw/arm/bcm2835_peripherals.h"
+#include "hw/misc/bcm2838_rng200.h"
#include "hw/arm/bcm2838_pcie.h"
#include "hw/sd/sdhci.h"
#include "hw/gpio/bcm2838_gpio.h"
@@ -67,6 +68,7 @@ struct BCM2838PeripheralState {
MemoryRegion mphi_mr_alias;
MemoryRegion pcie_mmio_alias;
+ BCM2838Rng200State rng200;
SDHCIState emmc2;
BCM2838PcieHostState pcie_host;
BCM2838GpioState gpio;
--
2.34.1
- [PATCH 14/44] Add BCM2838 PCIE Root Complex, (continued)
- [PATCH 14/44] Add BCM2838 PCIE Root Complex, Sergey Kambalin, 2023/07/26
- [PATCH 15/44] Add BCM2838 PCIE host, Sergey Kambalin, 2023/07/26
- [PATCH 21/44] Add clock_isp stub, Sergey Kambalin, 2023/07/26
- [PATCH 24/44] Add GENET register structs. Part 2, Sergey Kambalin, 2023/07/26
- [PATCH 09/44] Add GPIO and SD to BCM2838 periph, Sergey Kambalin, 2023/07/26
- [PATCH 11/44] Introduce Raspberry PI 4 machine, Sergey Kambalin, 2023/07/26
- [PATCH 29/44] Impl GENET MDIO, Sergey Kambalin, 2023/07/26
- [PATCH 35/44] Add mailbox test stub, Sergey Kambalin, 2023/07/26
- [PATCH 38/44] Add mailbox tests tags. Part 2, Sergey Kambalin, 2023/07/26
- [PATCH 26/44] Add GENET register structs. Part 4, Sergey Kambalin, 2023/07/26
- [PATCH 19/44] Add RNG200 timer,
Sergey Kambalin <=
- [PATCH 28/44] Impl GENET register ops., Sergey Kambalin, 2023/07/26
- [PATCH 32/44] Enable BCM2838 GENET controller, Sergey Kambalin, 2023/07/26
- [PATCH 31/44] Impl GENET RX path, Sergey Kambalin, 2023/07/26
- [PATCH 33/44] Connect RNG200, PCIE and GENET to GIC, Sergey Kambalin, 2023/07/26
- [PATCH 37/44] Add mailbox tests tags. Part 1, Sergey Kambalin, 2023/07/26
- [PATCH 36/44] Add mailbox test constants, Sergey Kambalin, 2023/07/26
- [PATCH 39/44] Add mailbox tests tags. Part 3, Sergey Kambalin, 2023/07/26
- [PATCH 40/44] Add mailbox property tests. Part 1, Sergey Kambalin, 2023/07/26
- [PATCH 41/44] Add mailbox property tests. Part 2, Sergey Kambalin, 2023/07/26
- [PATCH 42/44] Add mailbox property tests. Part 3, Sergey Kambalin, 2023/07/26