diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-07-18 10:35:06 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-07-18 10:35:06 +0100 |
commit | 6c4591566d6f1257683d2ccc94b9360ee8315474 (patch) | |
tree | c75449f19abce8e4fc2828ff4e83d998525c9529 /include | |
parent | a778cd5610b40eec037417565671d2717bc49def (diff) | |
parent | e5a6a6e64e82a132cebef023d867085b0a2993d7 (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.h | 29 | ||||
-rw-r--r-- | include/hw/char/cmsdk-apb-uart.h | 78 | ||||
-rw-r--r-- | include/hw/misc/mps2-scc.h | 43 | ||||
-rw-r--r-- | include/hw/qdev-core.h | 10 | ||||
-rw-r--r-- | include/hw/qdev-properties.h | 21 | ||||
-rw-r--r-- | include/hw/timer/cmsdk-apb-timer.h | 59 |
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 |