aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-07-18 10:35:06 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-07-18 10:35:06 +0100
commit6c4591566d6f1257683d2ccc94b9360ee8315474 (patch)
treec75449f19abce8e4fc2828ff4e83d998525c9529 /include
parenta778cd5610b40eec037417565671d2717bc49def (diff)
parente5a6a6e64e82a132cebef023d867085b0a2993d7 (diff)
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20170717' into staging
target-arm queue: * new model of the ARM MPS2/MPS2+ FPGA based development board * clean up DISAS_* exit conditions and fix various regressions since commits e75449a346 8a6b28c7b5 (in particular including ones which broke OP-TEE guests) * make Cortex-M3 and M4 correctly default to 8 PMSA regions # gpg: Signature made Mon 17 Jul 2017 13:43:45 BST # gpg: using RSA key 0x3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20170717: MAINTAINERS: Add entries for MPS2 board hw/arm/mps2: Add ethernet hw/arm/mps2: Add SCC hw/misc/mps2_scc: Implement MPS2 Serial Communication Controller hw/arm/mps2: Add timers hw/char/cmsdk-apb-timer: Implement CMSDK APB timer device hw/arm/mps2: Add UARTs hw/char/cmsdk-apb-uart.c: Implement CMSDK APB UART hw/arm/mps2: Implement skeleton mps2-an385 and mps2-an511 board models target/arm: use DISAS_EXIT for eret handling target/arm: use gen_goto_tb for ISB handling target/arm/translate: ensure gen_goto_tb sets exit flags target/arm/translate.h: expand comment on DISAS_EXIT target/arm/translate: make DISAS_UPDATE match declared semantics include/exec/exec-all: document common exit conditions target/arm: Make Cortex-M3 and M4 default to 8 PMSA regions qdev: support properties which don't set a default value qdev-properties.h: Explicitly set the default value for arraylen properties Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'include')
-rw-r--r--include/exec/exec-all.h29
-rw-r--r--include/hw/char/cmsdk-apb-uart.h78
-rw-r--r--include/hw/misc/mps2-scc.h43
-rw-r--r--include/hw/qdev-core.h10
-rw-r--r--include/hw/qdev-properties.h21
-rw-r--r--include/hw/timer/cmsdk-apb-timer.h59
6 files changed, 237 insertions, 3 deletions
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index c09b365716..87b1b74e3b 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -35,11 +35,34 @@ typedef abi_ulong tb_page_addr_t;
typedef ram_addr_t tb_page_addr_t;
#endif
-/* is_jmp field values */
+/* DisasContext is_jmp field values
+ *
+ * is_jmp starts as DISAS_NEXT. The translator will keep processing
+ * instructions until an exit condition is reached. If we reach the
+ * exit condition and is_jmp is still DISAS_NEXT (because of some
+ * other condition) we simply "jump" to the next address.
+ * The remaining exit cases are:
+ *
+ * DISAS_JUMP - Only the PC was modified dynamically (e.g computed)
+ * DISAS_TB_JUMP - Only the PC was modified statically (e.g. branch)
+ *
+ * In these cases as long as the PC is updated we can chain to the
+ * next TB either by exiting the loop or looking up the next TB via
+ * the loookup helper.
+ *
+ * DISAS_UPDATE - CPU State was modified dynamically
+ *
+ * This covers any other CPU state which necessities us exiting the
+ * TCG code to the main run-loop. Typically this includes anything
+ * that might change the interrupt state.
+ *
+ * Individual translators may define additional exit cases to deal
+ * with per-target special conditions.
+ */
#define DISAS_NEXT 0 /* next instruction can be analyzed */
#define DISAS_JUMP 1 /* only pc was modified dynamically */
-#define DISAS_UPDATE 2 /* cpu state was modified dynamically */
-#define DISAS_TB_JUMP 3 /* only pc was modified statically */
+#define DISAS_TB_JUMP 2 /* only pc was modified statically */
+#define DISAS_UPDATE 3 /* cpu state was modified dynamically */
#include "qemu/log.h"
diff --git a/include/hw/char/cmsdk-apb-uart.h b/include/hw/char/cmsdk-apb-uart.h
new file mode 100644
index 0000000000..c41fba9a27
--- /dev/null
+++ b/include/hw/char/cmsdk-apb-uart.h
@@ -0,0 +1,78 @@
+/*
+ * ARM CMSDK APB UART emulation
+ *
+ * Copyright (c) 2017 Linaro Limited
+ * Written by Peter Maydell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 or
+ * (at your option) any later version.
+ */
+
+#ifndef CMSDK_APB_UART_H
+#define CMSDK_APB_UART_H
+
+#include "hw/sysbus.h"
+#include "chardev/char-fe.h"
+
+#define TYPE_CMSDK_APB_UART "cmsdk-apb-uart"
+#define CMSDK_APB_UART(obj) OBJECT_CHECK(CMSDKAPBUART, (obj), \
+ TYPE_CMSDK_APB_UART)
+
+typedef struct {
+ /*< private >*/
+ SysBusDevice parent_obj;
+
+ /*< public >*/
+ MemoryRegion iomem;
+ CharBackend chr;
+ qemu_irq txint;
+ qemu_irq rxint;
+ qemu_irq txovrint;
+ qemu_irq rxovrint;
+ qemu_irq uartint;
+ guint watch_tag;
+ uint32_t pclk_frq;
+
+ uint32_t state;
+ uint32_t ctrl;
+ uint32_t intstatus;
+ uint32_t bauddiv;
+ /* This UART has no FIFO, only a 1-character buffer for each of Tx and Rx */
+ uint8_t txbuf;
+ uint8_t rxbuf;
+} CMSDKAPBUART;
+
+/**
+ * cmsdk_apb_uart_create - convenience function to create TYPE_CMSDK_APB_UART
+ * @addr: location in system memory to map registers
+ * @chr: Chardev backend to connect UART to, or NULL if no backend
+ * @pclk_frq: frequency in Hz of the PCLK clock (used for calculating baud rate)
+ */
+static inline DeviceState *cmsdk_apb_uart_create(hwaddr addr,
+ qemu_irq txint,
+ qemu_irq rxint,
+ qemu_irq txovrint,
+ qemu_irq rxovrint,
+ qemu_irq uartint,
+ Chardev *chr,
+ uint32_t pclk_frq)
+{
+ DeviceState *dev;
+ SysBusDevice *s;
+
+ dev = qdev_create(NULL, TYPE_CMSDK_APB_UART);
+ s = SYS_BUS_DEVICE(dev);
+ qdev_prop_set_chr(dev, "chardev", chr);
+ qdev_prop_set_uint32(dev, "pclk-frq", pclk_frq);
+ qdev_init_nofail(dev);
+ sysbus_mmio_map(s, 0, addr);
+ sysbus_connect_irq(s, 0, txint);
+ sysbus_connect_irq(s, 1, rxint);
+ sysbus_connect_irq(s, 2, txovrint);
+ sysbus_connect_irq(s, 3, rxovrint);
+ sysbus_connect_irq(s, 4, uartint);
+ return dev;
+}
+
+#endif
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
new file mode 100644
index 0000000000..7045473788
--- /dev/null
+++ b/include/hw/misc/mps2-scc.h
@@ -0,0 +1,43 @@
+/*
+ * ARM MPS2 SCC emulation
+ *
+ * Copyright (c) 2017 Linaro Limited
+ * Written by Peter Maydell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 or
+ * (at your option) any later version.
+ */
+
+#ifndef MPS2_SCC_H
+#define MPS2_SCC_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_MPS2_SCC "mps2-scc"
+#define MPS2_SCC(obj) OBJECT_CHECK(MPS2SCC, (obj), TYPE_MPS2_SCC)
+
+#define NUM_OSCCLK 3
+
+typedef struct {
+ /*< private >*/
+ SysBusDevice parent_obj;
+
+ /*< public >*/
+ MemoryRegion iomem;
+
+ uint32_t cfg0;
+ uint32_t cfg1;
+ uint32_t cfg4;
+ uint32_t cfgdata_rtn;
+ uint32_t cfgdata_out;
+ uint32_t cfgctrl;
+ uint32_t cfgstat;
+ uint32_t dll;
+ uint32_t aid;
+ uint32_t id;
+ uint32_t oscclk[NUM_OSCCLK];
+ uint32_t oscclk_reset[NUM_OSCCLK];
+} MPS2SCC;
+
+#endif
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 53488153fd..ae317286a4 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -221,11 +221,21 @@ struct BusState {
QLIST_ENTRY(BusState) sibling;
};
+/**
+ * Property:
+ * @set_default: true if the default value should be set from @defval,
+ * in which case @info->set_default_value must not be NULL
+ * (if false then no default value is set by the property system
+ * and the field retains whatever value it was given by instance_init).
+ * @defval: default value for the property. This is used only if @set_default
+ * is true.
+ */
struct Property {
const char *name;
const PropertyInfo *info;
ptrdiff_t offset;
uint8_t bitnr;
+ bool set_default;
union {
int64_t i;
uint64_t u;
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index f6692d5dc3..39297961f3 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -44,15 +44,24 @@ extern const PropertyInfo qdev_prop_link;
.info = &(_prop), \
.offset = offsetof(_state, _field) \
+ type_check(_type,typeof_field(_state, _field)), \
+ .set_default = true, \
.defval.i = (_type)_defval, \
}
+#define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) { \
+ .name = (_name), \
+ .info = &(_prop), \
+ .offset = offsetof(_state, _field) \
+ + type_check(_type, typeof_field(_state, _field)), \
+ }
+
#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) { \
.name = (_name), \
.info = &(qdev_prop_bit), \
.bitnr = (_bit), \
.offset = offsetof(_state, _field) \
+ type_check(uint32_t,typeof_field(_state, _field)), \
+ .set_default = true, \
.defval.u = (bool)_defval, \
}
@@ -61,15 +70,24 @@ extern const PropertyInfo qdev_prop_link;
.info = &(_prop), \
.offset = offsetof(_state, _field) \
+ type_check(_type, typeof_field(_state, _field)), \
+ .set_default = true, \
.defval.u = (_type)_defval, \
}
+#define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, _type) { \
+ .name = (_name), \
+ .info = &(_prop), \
+ .offset = offsetof(_state, _field) \
+ + type_check(_type, typeof_field(_state, _field)), \
+ }
+
#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) { \
.name = (_name), \
.info = &(qdev_prop_bit64), \
.bitnr = (_bit), \
.offset = offsetof(_state, _field) \
+ type_check(uint64_t, typeof_field(_state, _field)), \
+ .set_default = true, \
.defval.u = (bool)_defval, \
}
@@ -78,6 +96,7 @@ extern const PropertyInfo qdev_prop_link;
.info = &(qdev_prop_bool), \
.offset = offsetof(_state, _field) \
+ type_check(bool, typeof_field(_state, _field)), \
+ .set_default = true, \
.defval.u = (bool)_defval, \
}
@@ -111,6 +130,8 @@ extern const PropertyInfo qdev_prop_link;
_arrayfield, _arrayprop, _arraytype) { \
.name = (PROP_ARRAY_LEN_PREFIX _name), \
.info = &(qdev_prop_arraylen), \
+ .set_default = true, \
+ .defval.u = 0, \
.offset = offsetof(_state, _field) \
+ type_check(uint32_t, typeof_field(_state, _field)), \
.arrayinfo = &(_arrayprop), \
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
new file mode 100644
index 0000000000..f21686d26b
--- /dev/null
+++ b/include/hw/timer/cmsdk-apb-timer.h
@@ -0,0 +1,59 @@
+/*
+ * ARM CMSDK APB timer emulation
+ *
+ * Copyright (c) 2017 Linaro Limited
+ * Written by Peter Maydell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 or
+ * (at your option) any later version.
+ */
+
+#ifndef CMSDK_APB_TIMER_H
+#define CMSDK_APB_TIMER_H
+
+#include "hw/sysbus.h"
+#include "hw/ptimer.h"
+
+#define TYPE_CMSDK_APB_TIMER "cmsdk-apb-timer"
+#define CMSDK_APB_TIMER(obj) OBJECT_CHECK(CMSDKAPBTIMER, (obj), \
+ TYPE_CMSDK_APB_TIMER)
+
+typedef struct {
+ /*< private >*/
+ SysBusDevice parent_obj;
+
+ /*< public >*/
+ MemoryRegion iomem;
+ qemu_irq timerint;
+ uint32_t pclk_frq;
+ struct ptimer_state *timer;
+
+ uint32_t ctrl;
+ uint32_t value;
+ uint32_t reload;
+ uint32_t intstatus;
+} CMSDKAPBTIMER;
+
+/**
+ * cmsdk_apb_timer_create - convenience function to create TYPE_CMSDK_APB_TIMER
+ * @addr: location in system memory to map registers
+ * @pclk_frq: frequency in Hz of the PCLK clock (used for calculating baud rate)
+ */
+static inline DeviceState *cmsdk_apb_timer_create(hwaddr addr,
+ qemu_irq timerint,
+ uint32_t pclk_frq)
+{
+ DeviceState *dev;
+ SysBusDevice *s;
+
+ dev = qdev_create(NULL, TYPE_CMSDK_APB_TIMER);
+ s = SYS_BUS_DEVICE(dev);
+ qdev_prop_set_uint32(dev, "pclk-frq", pclk_frq);
+ qdev_init_nofail(dev);
+ sysbus_mmio_map(s, 0, addr);
+ sysbus_connect_irq(s, 0, timerint);
+ return dev;
+}
+
+#endif