aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Stanley <joel@jms.id.au>2018-06-15 14:57:15 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-06-15 15:23:34 +0100
commitacd9575e59da1bfc21a1feccb00c5dddd45328f7 (patch)
tree38d5dfee59be8fcecd839cb8b85c7c55dc46680b
parent29b80469dc51ae4064e9ef9223967882d2610523 (diff)
downloadqemu-acd9575e59da1bfc21a1feccb00c5dddd45328f7.zip
qemu-acd9575e59da1bfc21a1feccb00c5dddd45328f7.tar.gz
qemu-acd9575e59da1bfc21a1feccb00c5dddd45328f7.tar.bz2
aspeed_scu: Implement RNG register
The ASPEED SoCs contain a single register that returns random data when read. This models that register so that guests can use it. The random number data register has a corresponding control register, however it returns data regardless of the state of the enabled bit, so the model follows this behaviour. When the qcrypto call fails we exit as the guest uses the random number device to feed it's entropy pool, which is used for cryptographic purposes. Reviewed-by: Cédric Le Goater <clg@kaod.org> Signed-off-by: Joel Stanley <joel@jms.id.au> Message-id: 20180613114836.9265-1-joel@jms.id.au Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/misc/aspeed_scu.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index 5e6d574..5931501 100644
--- a/hw/misc/aspeed_scu.c
+++ b/hw/misc/aspeed_scu.c
@@ -16,6 +16,7 @@
#include "qapi/visitor.h"
#include "qemu/bitops.h"
#include "qemu/log.h"
+#include "crypto/random.h"
#include "trace.h"
#define TO_REG(offset) ((offset) >> 2)
@@ -154,6 +155,19 @@ static const uint32_t ast2500_a1_resets[ASPEED_SCU_NR_REGS] = {
[BMC_DEV_ID] = 0x00002402U
};
+static uint32_t aspeed_scu_get_random(void)
+{
+ Error *err = NULL;
+ uint32_t num;
+
+ if (qcrypto_random_bytes((uint8_t *)&num, sizeof(num), &err)) {
+ error_report_err(err);
+ exit(1);
+ }
+
+ return num;
+}
+
static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
{
AspeedSCUState *s = ASPEED_SCU(opaque);
@@ -167,6 +181,12 @@ static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
}
switch (reg) {
+ case RNG_DATA:
+ /* On hardware, RNG_DATA works regardless of
+ * the state of the enable bit in RNG_CTRL
+ */
+ s->regs[RNG_DATA] = aspeed_scu_get_random();
+ break;
case WAKEUP_EN:
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Read of write-only offset 0x%" HWADDR_PRIx "\n",