[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 02/10] hw/arm_sysctl: Handle SYS_CFGCTRL in a more s
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PATCH 02/10] hw/arm_sysctl: Handle SYS_CFGCTRL in a more structured way |
Date: |
Mon, 4 Feb 2013 13:44:28 +0000 |
The SYS_CFGCTRL register consists of separate fields
for DCC, function, site, position and device, as well
as a read/write bit. Refactor the code handling SYS_CFGCTRL
writes to make it easier to add support for functions
like SYS_CFG_OSC which support multiple device fields.
We also pull the handling out into its own function for
clarity, as there are potentially a lot of implementable
subfunctions.
Signed-off-by: Peter Maydell <address@hidden>
---
hw/arm_sysctl.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 132 insertions(+), 11 deletions(-)
diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
index 7ecb7da..64e9ad5 100644
--- a/hw/arm_sysctl.c
+++ b/hw/arm_sysctl.c
@@ -9,6 +9,7 @@
#include "hw.h"
#include "qemu/timer.h"
+#include "qemu/bitops.h"
#include "sysbus.h"
#include "primecell.h"
#include "sysemu/sysemu.h"
@@ -191,6 +192,110 @@ static uint64_t arm_sysctl_read(void *opaque, hwaddr
offset,
}
}
+/* SYS_CFGCTRL functions */
+#define SYS_CFG_OSC 1
+#define SYS_CFG_VOLT 2
+#define SYS_CFG_AMP 3
+#define SYS_CFG_TEMP 4
+#define SYS_CFG_RESET 5
+#define SYS_CFG_SCC 6
+#define SYS_CFG_MUXFPGA 7
+#define SYS_CFG_SHUTDOWN 8
+#define SYS_CFG_REBOOT 9
+#define SYS_CFG_DVIMODE 11
+#define SYS_CFG_POWER 12
+#define SYS_CFG_ENERGY 13
+
+/* SYS_CFGCTRL site field values */
+#define SYS_CFG_SITE_MB 0
+#define SYS_CFG_SITE_DB1 1
+#define SYS_CFG_SITE_DB2 2
+
+/**
+ * vexpress_cfgctrl_read:
+ * @s: arm_sysctl_state pointer
+ * @dcc, @function, @site, @position, @device: split out values from
+ * SYS_CFGCTRL register
+ * @val: pointer to where to put the read data on success
+ *
+ * Handle a VExpress SYS_CFGCTRL register read. On success, return true and
+ * write the read value to *val. On failure, return false (and val may
+ * or may not be written to).
+ */
+static bool vexpress_cfgctrl_read(arm_sysctl_state *s, unsigned int dcc,
+ unsigned int function, unsigned int site,
+ unsigned int position, unsigned int device,
+ uint32_t *val)
+{
+ /* We don't support anything other than DCC 0, board stack position 0
+ * or sites other than motherboard/daughterboard:
+ */
+ if (dcc != 0 || position != 0 ||
+ (site != SYS_CFG_SITE_MB && site != SYS_CFG_SITE_DB1)) {
+ goto cfgctrl_unimp;
+ }
+
+ switch (function) {
+ default:
+ break;
+ }
+
+cfgctrl_unimp:
+ qemu_log_mask(LOG_UNIMP,
+ "arm_sysctl: Unimplemented SYS_CFGCTRL read of function "
+ "0x%x DCC 0x%x site 0x%x position 0x%x device 0x%x\n",
+ function, dcc, site, position, device);
+ return false;
+}
+
+/**
+ * vexpress_cfgctrl_write:
+ * @s: arm_sysctl_state pointer
+ * @dcc, @function, @site, @position, @device: split out values from
+ * SYS_CFGCTRL register
+ * @val: data to write
+ *
+ * Handle a VExpress SYS_CFGCTRL register write. On success, return true.
+ * On failure, return false.
+ */
+static bool vexpress_cfgctrl_write(arm_sysctl_state *s, unsigned int dcc,
+ unsigned int function, unsigned int site,
+ unsigned int position, unsigned int device,
+ uint32_t val)
+{
+ /* We don't support anything other than DCC 0, board stack position 0
+ * or sites other than motherboard/daughterboard:
+ */
+ if (dcc != 0 || position != 0 ||
+ (site != SYS_CFG_SITE_MB && site != SYS_CFG_SITE_DB1)) {
+ goto cfgctrl_unimp;
+ }
+
+ switch (function) {
+ case SYS_CFG_SHUTDOWN:
+ if (site == SYS_CFG_SITE_MB && device == 0) {
+ qemu_system_shutdown_request();
+ return true;
+ }
+ break;
+ case SYS_CFG_REBOOT:
+ if (site == SYS_CFG_SITE_MB && device == 0) {
+ qemu_system_reset_request();
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
+cfgctrl_unimp:
+ qemu_log_mask(LOG_UNIMP,
+ "arm_sysctl: Unimplemented SYS_CFGCTRL write of function "
+ "0x%x DCC 0x%x site 0x%x position 0x%x device 0x%x\n",
+ function, dcc, site, position, device);
+ return false;
+}
+
static void arm_sysctl_write(void *opaque, hwaddr offset,
uint64_t val, unsigned size)
{
@@ -322,17 +427,33 @@ static void arm_sysctl_write(void *opaque, hwaddr offset,
if (board_id(s) != BOARD_ID_VEXPRESS) {
goto bad_reg;
}
- s->sys_cfgctrl = val & ~(3 << 18);
- s->sys_cfgstat = 1; /* complete */
- switch (s->sys_cfgctrl) {
- case 0xc0800000: /* SYS_CFG_SHUTDOWN to motherboard */
- qemu_system_shutdown_request();
- break;
- case 0xc0900000: /* SYS_CFG_REBOOT to motherboard */
- qemu_system_reset_request();
- break;
- default:
- s->sys_cfgstat |= 2; /* error */
+ /* Undefined bits [19:18] are RAZ/WI, and writing to
+ * the start bit just triggers the action; it always reads
+ * as zero.
+ */
+ s->sys_cfgctrl = val & ~((3 << 18) | (1 << 31));
+ if (val & (1 << 31)) {
+ /* Start bit set -- actually do something */
+ unsigned int dcc = extract32(s->sys_cfgctrl, 26, 4);
+ unsigned int function = extract32(s->sys_cfgctrl, 20, 6);
+ unsigned int site = extract32(s->sys_cfgctrl, 16, 2);
+ unsigned int position = extract32(s->sys_cfgctrl, 12, 4);
+ unsigned int device = extract32(s->sys_cfgctrl, 0, 12);
+ s->sys_cfgstat = 1; /* complete */
+ if (s->sys_cfgctrl & (1 << 30)) {
+ if (!vexpress_cfgctrl_write(s, dcc, function, site, position,
+ device, s->sys_cfgdata)) {
+ s->sys_cfgstat |= 2; /* error */
+ }
+ } else {
+ uint32_t val;
+ if (!vexpress_cfgctrl_read(s, dcc, function, site, position,
+ device, &val)) {
+ s->sys_cfgstat |= 2; /* error */
+ } else {
+ s->sys_cfgdata = val;
+ }
+ }
}
s->sys_cfgctrl &= ~(1 << 31);
return;
--
1.7.9.5
- [Qemu-devel] [PATCH 05/10] hw/arm_sysctl: Convert from qdev init to instance_init, (continued)
- [Qemu-devel] [PATCH 05/10] hw/arm_sysctl: Convert from qdev init to instance_init, Peter Maydell, 2013/02/04
- [Qemu-devel] [PATCH 06/10] qdev: Implement (variable length) array properties, Peter Maydell, 2013/02/04
- [Qemu-devel] [PATCH 07/10] hw/arm_sysctl: Implement SYS_CFG_VOLT, Peter Maydell, 2013/02/04
- [Qemu-devel] [PATCH 09/10] hw/arm_sysctl: Implement SYS_CFG_OSC function, Peter Maydell, 2013/02/04
- [Qemu-devel] [PATCH 03/10] hw/arm_sysctl: Implement SYS_CFG_MUXFPGA writes as a no-op, Peter Maydell, 2013/02/04
- [Qemu-devel] [PATCH 01/10] hw/vexpress: Pass proc_id via VEDBoardInfo, Peter Maydell, 2013/02/04
- [Qemu-devel] [PATCH 10/10] hw/vexpress: Set reset values for daughterboard oscillators, Peter Maydell, 2013/02/04
- [Qemu-devel] [PATCH 02/10] hw/arm_sysctl: Handle SYS_CFGCTRL in a more structured way,
Peter Maydell <=
- [Qemu-devel] [PATCH 08/10] hw/vexpress: Pass voltage sensor properties to sysctl device, Peter Maydell, 2013/02/04
- [Qemu-devel] [PATCH 04/10] hw/arm_sysctl: Implement SYS_CFG_DVIMODE as a no-op, Peter Maydell, 2013/02/04