target-arm queue:

* hw/arm/virt: add DT property /secure-chosen/stdout-path indicating secure UART
  * target/arm: Fix aarch64_sve_change_el wrt EL0
  * target/arm: Define fields of ISAR registers
  * target/arm: Align cortex-r5 id_isar0
  * target/arm: Fix cortex-a7 id_isar0
  * net/cadence_gem: Fix various bugs, add support for new
    features that will be used by the Xilinx Versal board
  * target-arm: powerctl: Enable HVC when starting CPUs to EL2
  * target/arm: Add the Cortex-A72
  * target/arm: Mark PMINTENCLR and PMINTENCLR_EL1 accesses as possibly doing IO
  * target/arm: Mask PMOVSR writes based on supported counters
  * target/arm: Initialize ARMMMUFaultInfo in v7m_stack_read/write
  * coccinelle: new inplace-byteswaps.cocci to remove inplace-byteswapping calls
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABCAAGBQJbxhTZAAoJEDwlJe0UNgzeksAP/iHi7Oo9FMWIrGcAC2BTkwNZ
 GVGKNg2tIf4BBfuGyYpNt5s9frzQl/hRPXp323Bc6ryLwqnVsAVPhRfyLcoEoAeU
 qMA2oeCiKWacE2KbK/E2i17Mr0zynlIURVoondBzR1W2/Vdt5mRcY5+qsGhcwqUA
 Ib9SO5viWHNR/VPJjT28/kPRtBOcLkyi+/sS5q8uXBy53xxcz8iaEKMtlhMuunv8
 ar9PVuVDZ25dBkgOX5NRrxxfpV0L49sweJVWjyv7G84s/xFvbz1ZaoNrq5w5oYY/
 FmiT+kAPSEUzRHEBJwew6+QKsHWALs/0Z9ZgF6TvwJ5KFBvowMEraHbLiWcS9eCb
 h89fpftPso3TiqIZyUliDRZxIKBzRBPfRYwfuy4WxMH9O6aoJhO4UpfYwI9I2AKj
 YxuXUCtf9B6C5HRlXTdQXQSMxS04AvKs0OxM4NIO4pgazopnAaaUQuzhaZLo9VJO
 HLRZmgitOyJspxl7QeDreMK5Tb1lzLuXVSU80Tgedkx03Z2vhoIM5DcOIk5VBW8k
 KPzN0jgHHS1R2NfJ1GwaHYWtskMm3AuWQ8YDxv0bUs9f2uQQBwfiYckp5LnGd0Sz
 oAXJgb3keQBiXsCpolx665DA9NFEOF581ufup6wp4J1tBwtH0UYkFkqxPqjpWQyX
 hCUmXQQkuskpLUvRbWT9
 =T/np
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20181016-1' into staging

target-arm queue:
 * hw/arm/virt: add DT property /secure-chosen/stdout-path indicating secure UART
 * target/arm: Fix aarch64_sve_change_el wrt EL0
 * target/arm: Define fields of ISAR registers
 * target/arm: Align cortex-r5 id_isar0
 * target/arm: Fix cortex-a7 id_isar0
 * net/cadence_gem: Fix various bugs, add support for new
   features that will be used by the Xilinx Versal board
 * target-arm: powerctl: Enable HVC when starting CPUs to EL2
 * target/arm: Add the Cortex-A72
 * target/arm: Mark PMINTENCLR and PMINTENCLR_EL1 accesses as possibly doing IO
 * target/arm: Mask PMOVSR writes based on supported counters
 * target/arm: Initialize ARMMMUFaultInfo in v7m_stack_read/write
 * coccinelle: new inplace-byteswaps.cocci to remove inplace-byteswapping calls

# gpg: Signature made Tue 16 Oct 2018 17:42:01 BST
# gpg:                using RSA key 3C2525ED14360CDE
# 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-20181016-1:
  coccinelle: new inplace-byteswaps.cocci to remove inplace-byteswapping calls
  target/arm: Initialize ARMMMUFaultInfo in v7m_stack_read/write
  target/arm: Mask PMOVSR writes based on supported counters
  target/arm: Mark PMINTENCLR and PMINTENCLR_EL1 accesses as possibly doing IO
  target/arm: Add the Cortex-A72
  target-arm: powerctl: Enable HVC when starting CPUs to EL2
  net: cadence_gem: Implement support for 64bit descriptor addresses
  net: cadence_gem: Add support for selecting the DMA MemoryRegion
  net: cadence_gem: Add support for extended descriptors
  net: cadence_gem: Add macro with max number of descriptor words
  net: cadence_gem: Use uint32_t for 32bit descriptor words
  net: cadence_gem: Disable TSU feature bit
  target/arm: Fix cortex-a7 id_isar0
  target/arm: Align cortex-r5 id_isar0
  target/arm: Define fields of ISAR registers
  target/arm: Fix aarch64_sve_change_el wrt EL0
  hw/arm/virt: add DT property /secure-chosen/stdout-path indicating secure UART

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2018-10-16 17:42:56 +01:00
commit 09558375a6
10 changed files with 402 additions and 70 deletions

View file

@ -712,6 +712,10 @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
/* Mark as not usable by the normal world */
qemu_fdt_setprop_string(vms->fdt, nodename, "status", "disabled");
qemu_fdt_setprop_string(vms->fdt, nodename, "secure-status", "okay");
qemu_fdt_add_subnode(vms->fdt, "/secure-chosen");
qemu_fdt_setprop_string(vms->fdt, "/secure-chosen", "stdout-path",
nodename);
}
g_free(nodename);

View file

@ -28,6 +28,7 @@
#include "hw/net/cadence_gem.h"
#include "qapi/error.h"
#include "qemu/log.h"
#include "sysemu/dma.h"
#include "net/checksum.h"
#ifdef CADENCE_GEM_ERR_DEBUG
@ -152,6 +153,9 @@
#define GEM_RECEIVE_Q1_PTR (0x00000480 / 4)
#define GEM_RECEIVE_Q7_PTR (GEM_RECEIVE_Q1_PTR + 6)
#define GEM_TBQPH (0x000004C8 / 4)
#define GEM_RBQPH (0x000004D4 / 4)
#define GEM_INT_Q1_ENABLE (0x00000600 / 4)
#define GEM_INT_Q7_ENABLE (GEM_INT_Q1_ENABLE + 6)
@ -207,6 +211,9 @@
#define GEM_NWCFG_BCAST_REJ 0x00000020 /* Reject broadcast packets */
#define GEM_NWCFG_PROMISC 0x00000010 /* Accept all packets */
#define GEM_DMACFG_ADDR_64B (1U << 30)
#define GEM_DMACFG_TX_BD_EXT (1U << 29)
#define GEM_DMACFG_RX_BD_EXT (1U << 28)
#define GEM_DMACFG_RBUFSZ_M 0x00FF0000 /* DMA RX Buffer Size mask */
#define GEM_DMACFG_RBUFSZ_S 16 /* DMA RX Buffer Size shift */
#define GEM_DMACFG_RBUFSZ_MUL 64 /* DMA RX Buffer Size multiplier */
@ -302,42 +309,47 @@
#define GEM_MODID_VALUE 0x00020118
static inline unsigned tx_desc_get_buffer(unsigned *desc)
static inline uint64_t tx_desc_get_buffer(CadenceGEMState *s, uint32_t *desc)
{
return desc[0];
uint64_t ret = desc[0];
if (s->regs[GEM_DMACFG] & GEM_DMACFG_ADDR_64B) {
ret |= (uint64_t)desc[2] << 32;
}
return ret;
}
static inline unsigned tx_desc_get_used(unsigned *desc)
static inline unsigned tx_desc_get_used(uint32_t *desc)
{
return (desc[1] & DESC_1_USED) ? 1 : 0;
}
static inline void tx_desc_set_used(unsigned *desc)
static inline void tx_desc_set_used(uint32_t *desc)
{
desc[1] |= DESC_1_USED;
}
static inline unsigned tx_desc_get_wrap(unsigned *desc)
static inline unsigned tx_desc_get_wrap(uint32_t *desc)
{
return (desc[1] & DESC_1_TX_WRAP) ? 1 : 0;
}
static inline unsigned tx_desc_get_last(unsigned *desc)
static inline unsigned tx_desc_get_last(uint32_t *desc)
{
return (desc[1] & DESC_1_TX_LAST) ? 1 : 0;
}
static inline void tx_desc_set_last(unsigned *desc)
static inline void tx_desc_set_last(uint32_t *desc)
{
desc[1] |= DESC_1_TX_LAST;
}
static inline unsigned tx_desc_get_length(unsigned *desc)
static inline unsigned tx_desc_get_length(uint32_t *desc)
{
return desc[1] & DESC_1_LENGTH;
}
static inline void print_gem_tx_desc(unsigned *desc, uint8_t queue)
static inline void print_gem_tx_desc(uint32_t *desc, uint8_t queue)
{
DB_PRINT("TXDESC (queue %" PRId8 "):\n", queue);
DB_PRINT("bufaddr: 0x%08x\n", *desc);
@ -347,58 +359,79 @@ static inline void print_gem_tx_desc(unsigned *desc, uint8_t queue)
DB_PRINT("length: %d\n", tx_desc_get_length(desc));
}
static inline unsigned rx_desc_get_buffer(unsigned *desc)
static inline uint64_t rx_desc_get_buffer(CadenceGEMState *s, uint32_t *desc)
{
return desc[0] & ~0x3UL;
uint64_t ret = desc[0] & ~0x3UL;
if (s->regs[GEM_DMACFG] & GEM_DMACFG_ADDR_64B) {
ret |= (uint64_t)desc[2] << 32;
}
return ret;
}
static inline unsigned rx_desc_get_wrap(unsigned *desc)
static inline int gem_get_desc_len(CadenceGEMState *s, bool rx_n_tx)
{
int ret = 2;
if (s->regs[GEM_DMACFG] & GEM_DMACFG_ADDR_64B) {
ret += 2;
}
if (s->regs[GEM_DMACFG] & (rx_n_tx ? GEM_DMACFG_RX_BD_EXT
: GEM_DMACFG_TX_BD_EXT)) {
ret += 2;
}
assert(ret <= DESC_MAX_NUM_WORDS);
return ret;
}
static inline unsigned rx_desc_get_wrap(uint32_t *desc)
{
return desc[0] & DESC_0_RX_WRAP ? 1 : 0;
}
static inline unsigned rx_desc_get_ownership(unsigned *desc)
static inline unsigned rx_desc_get_ownership(uint32_t *desc)
{
return desc[0] & DESC_0_RX_OWNERSHIP ? 1 : 0;
}
static inline void rx_desc_set_ownership(unsigned *desc)
static inline void rx_desc_set_ownership(uint32_t *desc)
{
desc[0] |= DESC_0_RX_OWNERSHIP;
}
static inline void rx_desc_set_sof(unsigned *desc)
static inline void rx_desc_set_sof(uint32_t *desc)
{
desc[1] |= DESC_1_RX_SOF;
}
static inline void rx_desc_set_eof(unsigned *desc)
static inline void rx_desc_set_eof(uint32_t *desc)
{
desc[1] |= DESC_1_RX_EOF;
}
static inline void rx_desc_set_length(unsigned *desc, unsigned len)
static inline void rx_desc_set_length(uint32_t *desc, unsigned len)
{
desc[1] &= ~DESC_1_LENGTH;
desc[1] |= len;
}
static inline void rx_desc_set_broadcast(unsigned *desc)
static inline void rx_desc_set_broadcast(uint32_t *desc)
{
desc[1] |= R_DESC_1_RX_BROADCAST;
}
static inline void rx_desc_set_unicast_hash(unsigned *desc)
static inline void rx_desc_set_unicast_hash(uint32_t *desc)
{
desc[1] |= R_DESC_1_RX_UNICAST_HASH;
}
static inline void rx_desc_set_multicast_hash(unsigned *desc)
static inline void rx_desc_set_multicast_hash(uint32_t *desc)
{
desc[1] |= R_DESC_1_RX_MULTICAST_HASH;
}
static inline void rx_desc_set_sar(unsigned *desc, int sar_idx)
static inline void rx_desc_set_sar(uint32_t *desc, int sar_idx)
{
desc[1] = deposit32(desc[1], R_DESC_1_RX_SAR_SHIFT, R_DESC_1_RX_SAR_LENGTH,
sar_idx);
@ -419,7 +452,7 @@ static void gem_init_register_masks(CadenceGEMState *s)
memset(&s->regs_ro[0], 0, sizeof(s->regs_ro));
s->regs_ro[GEM_NWCTRL] = 0xFFF80000;
s->regs_ro[GEM_NWSTATUS] = 0xFFFFFFFF;
s->regs_ro[GEM_DMACFG] = 0xFE00F000;
s->regs_ro[GEM_DMACFG] = 0x8E00F000;
s->regs_ro[GEM_TXSTATUS] = 0xFFFFFE08;
s->regs_ro[GEM_RXQBASE] = 0x00000003;
s->regs_ro[GEM_TXQBASE] = 0x00000003;
@ -802,17 +835,42 @@ static int get_queue_from_screen(CadenceGEMState *s, uint8_t *rxbuf_ptr,
return 0;
}
static hwaddr gem_get_desc_addr(CadenceGEMState *s, bool tx, int q)
{
hwaddr desc_addr = 0;
if (s->regs[GEM_DMACFG] & GEM_DMACFG_ADDR_64B) {
desc_addr = s->regs[tx ? GEM_TBQPH : GEM_RBQPH];
}
desc_addr <<= 32;
desc_addr |= tx ? s->tx_desc_addr[q] : s->rx_desc_addr[q];
return desc_addr;
}
static hwaddr gem_get_tx_desc_addr(CadenceGEMState *s, int q)
{
return gem_get_desc_addr(s, true, q);
}
static hwaddr gem_get_rx_desc_addr(CadenceGEMState *s, int q)
{
return gem_get_desc_addr(s, false, q);
}
static void gem_get_rx_desc(CadenceGEMState *s, int q)
{
DB_PRINT("read descriptor 0x%x\n", (unsigned)s->rx_desc_addr[q]);
hwaddr desc_addr = gem_get_rx_desc_addr(s, q);
DB_PRINT("read descriptor 0x%" HWADDR_PRIx "\n", desc_addr);
/* read current descriptor */
cpu_physical_memory_read(s->rx_desc_addr[q],
(uint8_t *)s->rx_desc[q], sizeof(s->rx_desc[q]));
address_space_read(&s->dma_as, desc_addr, MEMTXATTRS_UNSPECIFIED,
(uint8_t *)s->rx_desc[q],
sizeof(uint32_t) * gem_get_desc_len(s, true));
/* Descriptor owned by software ? */
if (rx_desc_get_ownership(s->rx_desc[q]) == 1) {
DB_PRINT("descriptor 0x%x owned by sw.\n",
(unsigned)s->rx_desc_addr[q]);
DB_PRINT("descriptor 0x%" HWADDR_PRIx " owned by sw.\n", desc_addr);
s->regs[GEM_RXSTATUS] |= GEM_RXSTATUS_NOBUF;
s->regs[GEM_ISR] |= GEM_INT_RXUSED & ~(s->regs[GEM_IMR]);
/* Handle interrupt consequences */
@ -916,6 +974,8 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
q = get_queue_from_screen(s, rxbuf_ptr, rxbufsize);
while (bytes_to_copy) {
hwaddr desc_addr;
/* Do nothing if receive is not enabled. */
if (!gem_can_receive(nc)) {
assert(!first_desc);
@ -926,9 +986,10 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
rx_desc_get_buffer(s->rx_desc[q]));
/* Copy packet data to emulated DMA buffer */
cpu_physical_memory_write(rx_desc_get_buffer(s->rx_desc[q]) +
rxbuf_offset,
rxbuf_ptr, MIN(bytes_to_copy, rxbufsize));
address_space_write(&s->dma_as, rx_desc_get_buffer(s, s->rx_desc[q]) +
rxbuf_offset,
MEMTXATTRS_UNSPECIFIED, rxbuf_ptr,
MIN(bytes_to_copy, rxbufsize));
rxbuf_ptr += MIN(bytes_to_copy, rxbufsize);
bytes_to_copy -= MIN(bytes_to_copy, rxbufsize);
@ -962,9 +1023,11 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
}
/* Descriptor write-back. */
cpu_physical_memory_write(s->rx_desc_addr[q],
(uint8_t *)s->rx_desc[q],
sizeof(s->rx_desc[q]));
desc_addr = gem_get_rx_desc_addr(s, q);
address_space_write(&s->dma_as, desc_addr,
MEMTXATTRS_UNSPECIFIED,
(uint8_t *)s->rx_desc[q],
sizeof(uint32_t) * gem_get_desc_len(s, true));
/* Next descriptor */
if (rx_desc_get_wrap(s->rx_desc[q])) {
@ -972,7 +1035,7 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
s->rx_desc_addr[q] = s->regs[GEM_RXQBASE];
} else {
DB_PRINT("incrementing RX descriptor list\n");
s->rx_desc_addr[q] += 8;
s->rx_desc_addr[q] += 4 * gem_get_desc_len(s, true);
}
gem_get_rx_desc(s, q);
@ -1042,7 +1105,7 @@ static void gem_transmit_updatestats(CadenceGEMState *s, const uint8_t *packet,
*/
static void gem_transmit(CadenceGEMState *s)
{
unsigned desc[2];
uint32_t desc[DESC_MAX_NUM_WORDS];
hwaddr packet_desc_addr;
uint8_t tx_packet[2048];
uint8_t *p;
@ -1065,11 +1128,12 @@ static void gem_transmit(CadenceGEMState *s)
for (q = s->num_priority_queues - 1; q >= 0; q--) {
/* read current descriptor */
packet_desc_addr = s->tx_desc_addr[q];
packet_desc_addr = gem_get_tx_desc_addr(s, q);
DB_PRINT("read descriptor 0x%" HWADDR_PRIx "\n", packet_desc_addr);
cpu_physical_memory_read(packet_desc_addr,
(uint8_t *)desc, sizeof(desc));
address_space_read(&s->dma_as, packet_desc_addr,
MEMTXATTRS_UNSPECIFIED, (uint8_t *)desc,
sizeof(uint32_t) * gem_get_desc_len(s, false));
/* Handle all descriptors owned by hardware */
while (tx_desc_get_used(desc) == 0) {
@ -1082,7 +1146,7 @@ static void gem_transmit(CadenceGEMState *s)
/* The real hardware would eat this (and possibly crash).
* For QEMU let's lend a helping hand.
*/
if ((tx_desc_get_buffer(desc) == 0) ||
if ((tx_desc_get_buffer(s, desc) == 0) ||
(tx_desc_get_length(desc) == 0)) {
DB_PRINT("Invalid TX descriptor @ 0x%x\n",
(unsigned)packet_desc_addr);
@ -1101,30 +1165,35 @@ static void gem_transmit(CadenceGEMState *s)
/* Gather this fragment of the packet from "dma memory" to our
* contig buffer.
*/
cpu_physical_memory_read(tx_desc_get_buffer(desc), p,
tx_desc_get_length(desc));
address_space_read(&s->dma_as, tx_desc_get_buffer(s, desc),
MEMTXATTRS_UNSPECIFIED,
p, tx_desc_get_length(desc));
p += tx_desc_get_length(desc);
total_bytes += tx_desc_get_length(desc);
/* Last descriptor for this packet; hand the whole thing off */
if (tx_desc_get_last(desc)) {
unsigned desc_first[2];
uint32_t desc_first[DESC_MAX_NUM_WORDS];
hwaddr desc_addr = gem_get_tx_desc_addr(s, q);
/* Modify the 1st descriptor of this packet to be owned by
* the processor.
*/
cpu_physical_memory_read(s->tx_desc_addr[q],
(uint8_t *)desc_first,
sizeof(desc_first));
address_space_read(&s->dma_as, desc_addr,
MEMTXATTRS_UNSPECIFIED,
(uint8_t *)desc_first,
sizeof(desc_first));
tx_desc_set_used(desc_first);
cpu_physical_memory_write(s->tx_desc_addr[q],
(uint8_t *)desc_first,
sizeof(desc_first));
address_space_write(&s->dma_as, desc_addr,
MEMTXATTRS_UNSPECIFIED,
(uint8_t *)desc_first,
sizeof(desc_first));
/* Advance the hardware current descriptor past this packet */
if (tx_desc_get_wrap(desc)) {
s->tx_desc_addr[q] = s->regs[GEM_TXQBASE];
} else {
s->tx_desc_addr[q] = packet_desc_addr + 8;
s->tx_desc_addr[q] = packet_desc_addr +
4 * gem_get_desc_len(s, false);
}
DB_PRINT("TX descriptor next: 0x%08x\n", s->tx_desc_addr[q]);
@ -1168,11 +1237,12 @@ static void gem_transmit(CadenceGEMState *s)
tx_desc_set_last(desc);
packet_desc_addr = s->regs[GEM_TXQBASE];
} else {
packet_desc_addr += 8;
packet_desc_addr += 4 * gem_get_desc_len(s, false);
}
DB_PRINT("read descriptor 0x%" HWADDR_PRIx "\n", packet_desc_addr);
cpu_physical_memory_read(packet_desc_addr,
(uint8_t *)desc, sizeof(desc));
address_space_read(&s->dma_as, packet_desc_addr,
MEMTXATTRS_UNSPECIFIED, (uint8_t *)desc,
sizeof(uint32_t) * gem_get_desc_len(s, false));
}
if (tx_desc_get_used(desc)) {
@ -1228,7 +1298,7 @@ static void gem_reset(DeviceState *d)
s->regs[GEM_MODID] = s->revision;
s->regs[GEM_DESCONF] = 0x02500111;
s->regs[GEM_DESCONF2] = 0x2ab13fff;
s->regs[GEM_DESCONF5] = 0x002f2145;
s->regs[GEM_DESCONF5] = 0x002f2045;
s->regs[GEM_DESCONF6] = 0x00000200;
/* Set MAC address */
@ -1463,6 +1533,9 @@ static void gem_realize(DeviceState *dev, Error **errp)
CadenceGEMState *s = CADENCE_GEM(dev);
int i;
address_space_init(&s->dma_as,
s->dma_mr ? s->dma_mr : get_system_memory(), "dma");
if (s->num_priority_queues == 0 ||
s->num_priority_queues > MAX_PRIORITY_QUEUES) {
error_setg(errp, "Invalid num-priority-queues value: %" PRIx8,
@ -1500,6 +1573,12 @@ static void gem_init(Object *obj)
"enet", sizeof(s->regs));
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
(Object **)&s->dma_mr,
qdev_prop_allow_set_link_before_realize,
OBJ_PROP_LINK_STRONG,
&error_abort);
}
static const VMStateDescription vmstate_cadence_gem = {

View file

@ -32,6 +32,9 @@
#define CADENCE_GEM_MAXREG (0x00000800 / 4) /* Last valid GEM address */
/* Max number of words in a DMA descriptor. */
#define DESC_MAX_NUM_WORDS 6
#define MAX_PRIORITY_QUEUES 8
#define MAX_TYPE1_SCREENERS 16
#define MAX_TYPE2_SCREENERS 16
@ -42,6 +45,8 @@ typedef struct CadenceGEMState {
/*< public >*/
MemoryRegion iomem;
MemoryRegion *dma_mr;
AddressSpace dma_as;
NICState *nic;
NICConf conf;
qemu_irq irq[MAX_PRIORITY_QUEUES];
@ -74,7 +79,7 @@ typedef struct CadenceGEMState {
uint8_t can_rx_state; /* Debug only */
unsigned rx_desc[MAX_PRIORITY_QUEUES][2];
uint32_t rx_desc[MAX_PRIORITY_QUEUES][DESC_MAX_NUM_WORDS];
bool sar_active[4];
} CadenceGEMState;

View file

@ -0,0 +1,65 @@
// Replace uses of in-place byteswapping functions with calls to the
// equivalent not-in-place functions. This is necessary to avoid
// undefined behaviour if the expression being swapped is a field in a
// packed struct.
@@
expression E;
@@
-be16_to_cpus(&E);
+E = be16_to_cpu(E);
@@
expression E;
@@
-be32_to_cpus(&E);
+E = be32_to_cpu(E);
@@
expression E;
@@
-be64_to_cpus(&E);
+E = be64_to_cpu(E);
@@
expression E;
@@
-cpu_to_be16s(&E);
+E = cpu_to_be16(E);
@@
expression E;
@@
-cpu_to_be32s(&E);
+E = cpu_to_be32(E);
@@
expression E;
@@
-cpu_to_be64s(&E);
+E = cpu_to_be64(E);
@@
expression E;
@@
-le16_to_cpus(&E);
+E = le16_to_cpu(E);
@@
expression E;
@@
-le32_to_cpus(&E);
+E = le32_to_cpu(E);
@@
expression E;
@@
-le64_to_cpus(&E);
+E = le64_to_cpu(E);
@@
expression E;
@@
-cpu_to_le16s(&E);
+E = cpu_to_le16(E);
@@
expression E;
@@
-cpu_to_le32s(&E);
+E = cpu_to_le32(E);
@@
expression E;
@@
-cpu_to_le64s(&E);
+E = cpu_to_le64(E);

View file

@ -103,6 +103,16 @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
} else {
/* Processor is not in secure mode */
target_cpu->env.cp15.scr_el3 |= SCR_NS;
/*
* If QEMU is providing the equivalent of EL3 firmware, then we need
* to make sure a CPU targeting EL2 comes out of reset with a
* functional HVC insn.
*/
if (arm_feature(&target_cpu->env, ARM_FEATURE_EL3)
&& info->target_el == 2) {
target_cpu->env.cp15.scr_el3 |= SCR_HCE;
}
}
/* We check if the started CPU is now at the correct level */

View file

@ -1397,7 +1397,7 @@ static void cortex_r5_initfn(Object *obj)
cpu->id_mmfr1 = 0x00000000;
cpu->id_mmfr2 = 0x01200000;
cpu->id_mmfr3 = 0x0211;
cpu->id_isar0 = 0x2101111;
cpu->id_isar0 = 0x02101111;
cpu->id_isar1 = 0x13112111;
cpu->id_isar2 = 0x21232141;
cpu->id_isar3 = 0x01112131;
@ -1587,7 +1587,10 @@ static void cortex_a7_initfn(Object *obj)
cpu->id_mmfr1 = 0x40000000;
cpu->id_mmfr2 = 0x01240000;
cpu->id_mmfr3 = 0x02102211;
cpu->id_isar0 = 0x01101110;
/* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
* table 4-41 gives 0x02101110, which includes the arm div insns.
*/
cpu->id_isar0 = 0x02101110;
cpu->id_isar1 = 0x13112111;
cpu->id_isar2 = 0x21232041;
cpu->id_isar3 = 0x11112131;

View file

@ -911,10 +911,13 @@ int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
int aarch64_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq);
void aarch64_sve_change_el(CPUARMState *env, int old_el, int new_el);
void aarch64_sve_change_el(CPUARMState *env, int old_el,
int new_el, bool el0_a64);
#else
static inline void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq) { }
static inline void aarch64_sve_change_el(CPUARMState *env, int o, int n) { }
static inline void aarch64_sve_change_el(CPUARMState *env, int o,
int n, bool a)
{ }
#endif
target_ulong do_arm_semihosting(CPUARMState *env);
@ -1440,6 +1443,94 @@ FIELD(V7M_CSSELR, LEVEL, 1, 3)
*/
FIELD(V7M_CSSELR, INDEX, 0, 4)
/*
* System register ID fields.
*/
FIELD(ID_ISAR0, SWAP, 0, 4)
FIELD(ID_ISAR0, BITCOUNT, 4, 4)
FIELD(ID_ISAR0, BITFIELD, 8, 4)
FIELD(ID_ISAR0, CMPBRANCH, 12, 4)
FIELD(ID_ISAR0, COPROC, 16, 4)
FIELD(ID_ISAR0, DEBUG, 20, 4)
FIELD(ID_ISAR0, DIVIDE, 24, 4)
FIELD(ID_ISAR1, ENDIAN, 0, 4)
FIELD(ID_ISAR1, EXCEPT, 4, 4)
FIELD(ID_ISAR1, EXCEPT_AR, 8, 4)
FIELD(ID_ISAR1, EXTEND, 12, 4)
FIELD(ID_ISAR1, IFTHEN, 16, 4)
FIELD(ID_ISAR1, IMMEDIATE, 20, 4)
FIELD(ID_ISAR1, INTERWORK, 24, 4)
FIELD(ID_ISAR1, JAZELLE, 28, 4)
FIELD(ID_ISAR2, LOADSTORE, 0, 4)
FIELD(ID_ISAR2, MEMHINT, 4, 4)
FIELD(ID_ISAR2, MULTIACCESSINT, 8, 4)
FIELD(ID_ISAR2, MULT, 12, 4)
FIELD(ID_ISAR2, MULTS, 16, 4)
FIELD(ID_ISAR2, MULTU, 20, 4)
FIELD(ID_ISAR2, PSR_AR, 24, 4)
FIELD(ID_ISAR2, REVERSAL, 28, 4)
FIELD(ID_ISAR3, SATURATE, 0, 4)
FIELD(ID_ISAR3, SIMD, 4, 4)
FIELD(ID_ISAR3, SVC, 8, 4)
FIELD(ID_ISAR3, SYNCHPRIM, 12, 4)
FIELD(ID_ISAR3, TABBRANCH, 16, 4)
FIELD(ID_ISAR3, T32COPY, 20, 4)
FIELD(ID_ISAR3, TRUENOP, 24, 4)
FIELD(ID_ISAR3, T32EE, 28, 4)
FIELD(ID_ISAR4, UNPRIV, 0, 4)
FIELD(ID_ISAR4, WITHSHIFTS, 4, 4)
FIELD(ID_ISAR4, WRITEBACK, 8, 4)
FIELD(ID_ISAR4, SMC, 12, 4)
FIELD(ID_ISAR4, BARRIER, 16, 4)
FIELD(ID_ISAR4, SYNCHPRIM_FRAC, 20, 4)
FIELD(ID_ISAR4, PSR_M, 24, 4)
FIELD(ID_ISAR4, SWP_FRAC, 28, 4)
FIELD(ID_ISAR5, SEVL, 0, 4)
FIELD(ID_ISAR5, AES, 4, 4)
FIELD(ID_ISAR5, SHA1, 8, 4)
FIELD(ID_ISAR5, SHA2, 12, 4)
FIELD(ID_ISAR5, CRC32, 16, 4)
FIELD(ID_ISAR5, RDM, 24, 4)
FIELD(ID_ISAR5, VCMA, 28, 4)
FIELD(ID_ISAR6, JSCVT, 0, 4)
FIELD(ID_ISAR6, DP, 4, 4)
FIELD(ID_ISAR6, FHM, 8, 4)
FIELD(ID_ISAR6, SB, 12, 4)
FIELD(ID_ISAR6, SPECRES, 16, 4)
FIELD(ID_AA64ISAR0, AES, 4, 4)
FIELD(ID_AA64ISAR0, SHA1, 8, 4)
FIELD(ID_AA64ISAR0, SHA2, 12, 4)
FIELD(ID_AA64ISAR0, CRC32, 16, 4)
FIELD(ID_AA64ISAR0, ATOMIC, 20, 4)
FIELD(ID_AA64ISAR0, RDM, 28, 4)
FIELD(ID_AA64ISAR0, SHA3, 32, 4)
FIELD(ID_AA64ISAR0, SM3, 36, 4)
FIELD(ID_AA64ISAR0, SM4, 40, 4)
FIELD(ID_AA64ISAR0, DP, 44, 4)
FIELD(ID_AA64ISAR0, FHM, 48, 4)
FIELD(ID_AA64ISAR0, TS, 52, 4)
FIELD(ID_AA64ISAR0, TLB, 56, 4)
FIELD(ID_AA64ISAR0, RNDR, 60, 4)
FIELD(ID_AA64ISAR1, DPB, 0, 4)
FIELD(ID_AA64ISAR1, APA, 4, 4)
FIELD(ID_AA64ISAR1, API, 8, 4)
FIELD(ID_AA64ISAR1, JSCVT, 12, 4)
FIELD(ID_AA64ISAR1, FCMA, 16, 4)
FIELD(ID_AA64ISAR1, LRCPC, 20, 4)
FIELD(ID_AA64ISAR1, GPA, 24, 4)
FIELD(ID_AA64ISAR1, GPI, 28, 4)
FIELD(ID_AA64ISAR1, FRINTTS, 32, 4)
FIELD(ID_AA64ISAR1, SB, 36, 4)
FIELD(ID_AA64ISAR1, SPECRES, 40, 4)
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
/* If adding a feature bit which corresponds to a Linux ELF

View file

@ -51,7 +51,7 @@ static uint64_t a57_a53_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
}
#endif
static const ARMCPRegInfo cortex_a57_a53_cp_reginfo[] = {
static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
#ifndef CONFIG_USER_ONLY
{ .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2,
@ -156,7 +156,7 @@ static void aarch64_a57_initfn(Object *obj)
cpu->gic_num_lrs = 4;
cpu->gic_vpribits = 5;
cpu->gic_vprebits = 5;
define_arm_cp_regs(cpu, cortex_a57_a53_cp_reginfo);
define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
}
static void aarch64_a53_initfn(Object *obj)
@ -215,7 +215,66 @@ static void aarch64_a53_initfn(Object *obj)
cpu->gic_num_lrs = 4;
cpu->gic_vpribits = 5;
cpu->gic_vprebits = 5;
define_arm_cp_regs(cpu, cortex_a57_a53_cp_reginfo);
define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
}
static void aarch64_a72_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "arm,cortex-a72";
set_feature(&cpu->env, ARM_FEATURE_V8);
set_feature(&cpu->env, ARM_FEATURE_VFP4);
set_feature(&cpu->env, ARM_FEATURE_NEON);
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
set_feature(&cpu->env, ARM_FEATURE_V8_AES);
set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
set_feature(&cpu->env, ARM_FEATURE_CRC);
set_feature(&cpu->env, ARM_FEATURE_EL2);
set_feature(&cpu->env, ARM_FEATURE_EL3);
set_feature(&cpu->env, ARM_FEATURE_PMU);
cpu->midr = 0x410fd083;
cpu->revidr = 0x00000000;
cpu->reset_fpsid = 0x41034080;
cpu->mvfr0 = 0x10110222;
cpu->mvfr1 = 0x12111111;
cpu->mvfr2 = 0x00000043;
cpu->ctr = 0x8444c004;
cpu->reset_sctlr = 0x00c50838;
cpu->id_pfr0 = 0x00000131;
cpu->id_pfr1 = 0x00011011;
cpu->id_dfr0 = 0x03010066;
cpu->id_afr0 = 0x00000000;
cpu->id_mmfr0 = 0x10201105;
cpu->id_mmfr1 = 0x40000000;
cpu->id_mmfr2 = 0x01260000;
cpu->id_mmfr3 = 0x02102211;
cpu->id_isar0 = 0x02101110;
cpu->id_isar1 = 0x13112111;
cpu->id_isar2 = 0x21232042;
cpu->id_isar3 = 0x01112131;
cpu->id_isar4 = 0x00011142;
cpu->id_isar5 = 0x00011121;
cpu->id_aa64pfr0 = 0x00002222;
cpu->id_aa64dfr0 = 0x10305106;
cpu->pmceid0 = 0x00000000;
cpu->pmceid1 = 0x00000000;
cpu->id_aa64isar0 = 0x00011120;
cpu->id_aa64mmfr0 = 0x00001124;
cpu->dbgdidr = 0x3516d000;
cpu->clidr = 0x0a200023;
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
cpu->ccsidr[2] = 0x707fe07a; /* 1MB L2 cache */
cpu->dcz_blocksize = 4; /* 64 bytes */
cpu->gic_num_lrs = 4;
cpu->gic_vpribits = 5;
cpu->gic_vprebits = 5;
define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
}
static void cpu_max_get_sve_vq(Object *obj, Visitor *v, const char *name,
@ -293,6 +352,7 @@ typedef struct ARMCPUInfo {
static const ARMCPUInfo aarch64_cpus[] = {
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
{ .name = "max", .initfn = aarch64_max_initfn },
{ .name = NULL }
};

View file

@ -1179,6 +1179,7 @@ static void pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
value &= pmu_counter_mask(env);
env->cp15.c9_pmovsr &= ~value;
}
@ -1423,12 +1424,14 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
.writefn = pmintenset_write, .raw_writefn = raw_write,
.resetvalue = 0x0 },
{ .name = "PMINTENCLR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 2,
.access = PL1_RW, .accessfn = access_tpm, .type = ARM_CP_ALIAS,
.access = PL1_RW, .accessfn = access_tpm,
.type = ARM_CP_ALIAS | ARM_CP_IO,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
.writefn = pmintenclr_write, },
{ .name = "PMINTENCLR_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 2,
.access = PL1_RW, .accessfn = access_tpm, .type = ARM_CP_ALIAS,
.access = PL1_RW, .accessfn = access_tpm,
.type = ARM_CP_ALIAS | ARM_CP_IO,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
.writefn = pmintenclr_write },
{ .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
@ -6469,7 +6472,7 @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
target_ulong page_size;
hwaddr physaddr;
int prot;
ARMMMUFaultInfo fi;
ARMMMUFaultInfo fi = {};
bool secure = mmu_idx & ARM_MMU_IDX_M_S;
int exc;
bool exc_secure;
@ -6531,7 +6534,7 @@ static bool v7m_stack_read(ARMCPU *cpu, uint32_t *dest, uint32_t addr,
target_ulong page_size;
hwaddr physaddr;
int prot;
ARMMMUFaultInfo fi;
ARMMMUFaultInfo fi = {};
bool secure = mmu_idx & ARM_MMU_IDX_M_S;
int exc;
bool exc_secure;
@ -8374,7 +8377,11 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
unsigned int new_mode = aarch64_pstate_mode(new_el, true);
unsigned int cur_el = arm_current_el(env);
aarch64_sve_change_el(env, cur_el, new_el);
/*
* Note that new_el can never be 0. If cur_el is 0, then
* el0_a64 is is_a64(), else el0_a64 is ignored.
*/
aarch64_sve_change_el(env, cur_el, new_el, is_a64(env));
if (cur_el < new_el) {
/* Entry vector offset depends on whether the implemented EL
@ -12791,9 +12798,11 @@ void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq)
/*
* Notice a change in SVE vector size when changing EL.
*/
void aarch64_sve_change_el(CPUARMState *env, int old_el, int new_el)
void aarch64_sve_change_el(CPUARMState *env, int old_el,
int new_el, bool el0_a64)
{
int old_len, new_len;
bool old_a64, new_a64;
/* Nothing to do if no SVE. */
if (!arm_feature(env, ARM_FEATURE_SVE)) {
@ -12817,9 +12826,11 @@ void aarch64_sve_change_el(CPUARMState *env, int old_el, int new_el)
* we already have the correct register contents when encountering the
* vq0->vq0 transition between EL0->EL1.
*/
old_len = (arm_el_is_aa64(env, old_el) && !sve_exception_el(env, old_el)
old_a64 = old_el ? arm_el_is_aa64(env, old_el) : el0_a64;
old_len = (old_a64 && !sve_exception_el(env, old_el)
? sve_zcr_len_for_el(env, old_el) : 0);
new_len = (arm_el_is_aa64(env, new_el) && !sve_exception_el(env, new_el)
new_a64 = new_el ? arm_el_is_aa64(env, new_el) : el0_a64;
new_len = (new_a64 && !sve_exception_el(env, new_el)
? sve_zcr_len_for_el(env, new_el) : 0);
/* When changing vector length, clear inaccessible state. */

View file

@ -1101,7 +1101,11 @@ void HELPER(exception_return)(CPUARMState *env)
"AArch64 EL%d PC 0x%" PRIx64 "\n",
cur_el, new_el, env->pc);
}
aarch64_sve_change_el(env, cur_el, new_el);
/*
* Note that cur_el can never be 0. If new_el is 0, then
* el0_a64 is return_to_aa64, else el0_a64 is ignored.
*/
aarch64_sve_change_el(env, cur_el, new_el, return_to_aa64);
qemu_mutex_lock_iothread();
arm_call_el_change_hook(arm_env_get_cpu(env));