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:
commit
09558375a6
|
@ -712,6 +712,10 @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
|
||||||
/* Mark as not usable by the normal world */
|
/* Mark as not usable by the normal world */
|
||||||
qemu_fdt_setprop_string(vms->fdt, nodename, "status", "disabled");
|
qemu_fdt_setprop_string(vms->fdt, nodename, "status", "disabled");
|
||||||
qemu_fdt_setprop_string(vms->fdt, nodename, "secure-status", "okay");
|
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);
|
g_free(nodename);
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "hw/net/cadence_gem.h"
|
#include "hw/net/cadence_gem.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
|
#include "sysemu/dma.h"
|
||||||
#include "net/checksum.h"
|
#include "net/checksum.h"
|
||||||
|
|
||||||
#ifdef CADENCE_GEM_ERR_DEBUG
|
#ifdef CADENCE_GEM_ERR_DEBUG
|
||||||
|
@ -152,6 +153,9 @@
|
||||||
#define GEM_RECEIVE_Q1_PTR (0x00000480 / 4)
|
#define GEM_RECEIVE_Q1_PTR (0x00000480 / 4)
|
||||||
#define GEM_RECEIVE_Q7_PTR (GEM_RECEIVE_Q1_PTR + 6)
|
#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_Q1_ENABLE (0x00000600 / 4)
|
||||||
#define GEM_INT_Q7_ENABLE (GEM_INT_Q1_ENABLE + 6)
|
#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_BCAST_REJ 0x00000020 /* Reject broadcast packets */
|
||||||
#define GEM_NWCFG_PROMISC 0x00000010 /* Accept all 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_M 0x00FF0000 /* DMA RX Buffer Size mask */
|
||||||
#define GEM_DMACFG_RBUFSZ_S 16 /* DMA RX Buffer Size shift */
|
#define GEM_DMACFG_RBUFSZ_S 16 /* DMA RX Buffer Size shift */
|
||||||
#define GEM_DMACFG_RBUFSZ_MUL 64 /* DMA RX Buffer Size multiplier */
|
#define GEM_DMACFG_RBUFSZ_MUL 64 /* DMA RX Buffer Size multiplier */
|
||||||
|
@ -302,42 +309,47 @@
|
||||||
|
|
||||||
#define GEM_MODID_VALUE 0x00020118
|
#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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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("TXDESC (queue %" PRId8 "):\n", queue);
|
||||||
DB_PRINT("bufaddr: 0x%08x\n", *desc);
|
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));
|
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;
|
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;
|
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;
|
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;
|
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;
|
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] &= ~DESC_1_LENGTH;
|
||||||
desc[1] |= len;
|
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;
|
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;
|
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;
|
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,
|
desc[1] = deposit32(desc[1], R_DESC_1_RX_SAR_SHIFT, R_DESC_1_RX_SAR_LENGTH,
|
||||||
sar_idx);
|
sar_idx);
|
||||||
|
@ -419,7 +452,7 @@ static void gem_init_register_masks(CadenceGEMState *s)
|
||||||
memset(&s->regs_ro[0], 0, sizeof(s->regs_ro));
|
memset(&s->regs_ro[0], 0, sizeof(s->regs_ro));
|
||||||
s->regs_ro[GEM_NWCTRL] = 0xFFF80000;
|
s->regs_ro[GEM_NWCTRL] = 0xFFF80000;
|
||||||
s->regs_ro[GEM_NWSTATUS] = 0xFFFFFFFF;
|
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_TXSTATUS] = 0xFFFFFE08;
|
||||||
s->regs_ro[GEM_RXQBASE] = 0x00000003;
|
s->regs_ro[GEM_RXQBASE] = 0x00000003;
|
||||||
s->regs_ro[GEM_TXQBASE] = 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;
|
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)
|
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 */
|
/* read current descriptor */
|
||||||
cpu_physical_memory_read(s->rx_desc_addr[q],
|
address_space_read(&s->dma_as, desc_addr, MEMTXATTRS_UNSPECIFIED,
|
||||||
(uint8_t *)s->rx_desc[q], sizeof(s->rx_desc[q]));
|
(uint8_t *)s->rx_desc[q],
|
||||||
|
sizeof(uint32_t) * gem_get_desc_len(s, true));
|
||||||
|
|
||||||
/* Descriptor owned by software ? */
|
/* Descriptor owned by software ? */
|
||||||
if (rx_desc_get_ownership(s->rx_desc[q]) == 1) {
|
if (rx_desc_get_ownership(s->rx_desc[q]) == 1) {
|
||||||
DB_PRINT("descriptor 0x%x owned by sw.\n",
|
DB_PRINT("descriptor 0x%" HWADDR_PRIx " owned by sw.\n", desc_addr);
|
||||||
(unsigned)s->rx_desc_addr[q]);
|
|
||||||
s->regs[GEM_RXSTATUS] |= GEM_RXSTATUS_NOBUF;
|
s->regs[GEM_RXSTATUS] |= GEM_RXSTATUS_NOBUF;
|
||||||
s->regs[GEM_ISR] |= GEM_INT_RXUSED & ~(s->regs[GEM_IMR]);
|
s->regs[GEM_ISR] |= GEM_INT_RXUSED & ~(s->regs[GEM_IMR]);
|
||||||
/* Handle interrupt consequences */
|
/* 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);
|
q = get_queue_from_screen(s, rxbuf_ptr, rxbufsize);
|
||||||
|
|
||||||
while (bytes_to_copy) {
|
while (bytes_to_copy) {
|
||||||
|
hwaddr desc_addr;
|
||||||
|
|
||||||
/* Do nothing if receive is not enabled. */
|
/* Do nothing if receive is not enabled. */
|
||||||
if (!gem_can_receive(nc)) {
|
if (!gem_can_receive(nc)) {
|
||||||
assert(!first_desc);
|
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]));
|
rx_desc_get_buffer(s->rx_desc[q]));
|
||||||
|
|
||||||
/* Copy packet data to emulated DMA buffer */
|
/* Copy packet data to emulated DMA buffer */
|
||||||
cpu_physical_memory_write(rx_desc_get_buffer(s->rx_desc[q]) +
|
address_space_write(&s->dma_as, rx_desc_get_buffer(s, s->rx_desc[q]) +
|
||||||
rxbuf_offset,
|
rxbuf_offset,
|
||||||
rxbuf_ptr, MIN(bytes_to_copy, rxbufsize));
|
MEMTXATTRS_UNSPECIFIED, rxbuf_ptr,
|
||||||
|
MIN(bytes_to_copy, rxbufsize));
|
||||||
rxbuf_ptr += MIN(bytes_to_copy, rxbufsize);
|
rxbuf_ptr += MIN(bytes_to_copy, rxbufsize);
|
||||||
bytes_to_copy -= 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. */
|
/* Descriptor write-back. */
|
||||||
cpu_physical_memory_write(s->rx_desc_addr[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],
|
(uint8_t *)s->rx_desc[q],
|
||||||
sizeof(s->rx_desc[q]));
|
sizeof(uint32_t) * gem_get_desc_len(s, true));
|
||||||
|
|
||||||
/* Next descriptor */
|
/* Next descriptor */
|
||||||
if (rx_desc_get_wrap(s->rx_desc[q])) {
|
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];
|
s->rx_desc_addr[q] = s->regs[GEM_RXQBASE];
|
||||||
} else {
|
} else {
|
||||||
DB_PRINT("incrementing RX descriptor list\n");
|
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);
|
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)
|
static void gem_transmit(CadenceGEMState *s)
|
||||||
{
|
{
|
||||||
unsigned desc[2];
|
uint32_t desc[DESC_MAX_NUM_WORDS];
|
||||||
hwaddr packet_desc_addr;
|
hwaddr packet_desc_addr;
|
||||||
uint8_t tx_packet[2048];
|
uint8_t tx_packet[2048];
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
|
@ -1065,11 +1128,12 @@ static void gem_transmit(CadenceGEMState *s)
|
||||||
|
|
||||||
for (q = s->num_priority_queues - 1; q >= 0; q--) {
|
for (q = s->num_priority_queues - 1; q >= 0; q--) {
|
||||||
/* read current descriptor */
|
/* 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);
|
DB_PRINT("read descriptor 0x%" HWADDR_PRIx "\n", packet_desc_addr);
|
||||||
cpu_physical_memory_read(packet_desc_addr,
|
address_space_read(&s->dma_as, packet_desc_addr,
|
||||||
(uint8_t *)desc, sizeof(desc));
|
MEMTXATTRS_UNSPECIFIED, (uint8_t *)desc,
|
||||||
|
sizeof(uint32_t) * gem_get_desc_len(s, false));
|
||||||
/* Handle all descriptors owned by hardware */
|
/* Handle all descriptors owned by hardware */
|
||||||
while (tx_desc_get_used(desc) == 0) {
|
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).
|
/* The real hardware would eat this (and possibly crash).
|
||||||
* For QEMU let's lend a helping hand.
|
* 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)) {
|
(tx_desc_get_length(desc) == 0)) {
|
||||||
DB_PRINT("Invalid TX descriptor @ 0x%x\n",
|
DB_PRINT("Invalid TX descriptor @ 0x%x\n",
|
||||||
(unsigned)packet_desc_addr);
|
(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
|
/* Gather this fragment of the packet from "dma memory" to our
|
||||||
* contig buffer.
|
* contig buffer.
|
||||||
*/
|
*/
|
||||||
cpu_physical_memory_read(tx_desc_get_buffer(desc), p,
|
address_space_read(&s->dma_as, tx_desc_get_buffer(s, desc),
|
||||||
tx_desc_get_length(desc));
|
MEMTXATTRS_UNSPECIFIED,
|
||||||
|
p, tx_desc_get_length(desc));
|
||||||
p += tx_desc_get_length(desc);
|
p += tx_desc_get_length(desc);
|
||||||
total_bytes += tx_desc_get_length(desc);
|
total_bytes += tx_desc_get_length(desc);
|
||||||
|
|
||||||
/* Last descriptor for this packet; hand the whole thing off */
|
/* Last descriptor for this packet; hand the whole thing off */
|
||||||
if (tx_desc_get_last(desc)) {
|
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
|
/* Modify the 1st descriptor of this packet to be owned by
|
||||||
* the processor.
|
* the processor.
|
||||||
*/
|
*/
|
||||||
cpu_physical_memory_read(s->tx_desc_addr[q],
|
address_space_read(&s->dma_as, desc_addr,
|
||||||
|
MEMTXATTRS_UNSPECIFIED,
|
||||||
(uint8_t *)desc_first,
|
(uint8_t *)desc_first,
|
||||||
sizeof(desc_first));
|
sizeof(desc_first));
|
||||||
tx_desc_set_used(desc_first);
|
tx_desc_set_used(desc_first);
|
||||||
cpu_physical_memory_write(s->tx_desc_addr[q],
|
address_space_write(&s->dma_as, desc_addr,
|
||||||
|
MEMTXATTRS_UNSPECIFIED,
|
||||||
(uint8_t *)desc_first,
|
(uint8_t *)desc_first,
|
||||||
sizeof(desc_first));
|
sizeof(desc_first));
|
||||||
/* Advance the hardware current descriptor past this packet */
|
/* Advance the hardware current descriptor past this packet */
|
||||||
if (tx_desc_get_wrap(desc)) {
|
if (tx_desc_get_wrap(desc)) {
|
||||||
s->tx_desc_addr[q] = s->regs[GEM_TXQBASE];
|
s->tx_desc_addr[q] = s->regs[GEM_TXQBASE];
|
||||||
} else {
|
} 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]);
|
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);
|
tx_desc_set_last(desc);
|
||||||
packet_desc_addr = s->regs[GEM_TXQBASE];
|
packet_desc_addr = s->regs[GEM_TXQBASE];
|
||||||
} else {
|
} 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);
|
DB_PRINT("read descriptor 0x%" HWADDR_PRIx "\n", packet_desc_addr);
|
||||||
cpu_physical_memory_read(packet_desc_addr,
|
address_space_read(&s->dma_as, packet_desc_addr,
|
||||||
(uint8_t *)desc, sizeof(desc));
|
MEMTXATTRS_UNSPECIFIED, (uint8_t *)desc,
|
||||||
|
sizeof(uint32_t) * gem_get_desc_len(s, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tx_desc_get_used(desc)) {
|
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_MODID] = s->revision;
|
||||||
s->regs[GEM_DESCONF] = 0x02500111;
|
s->regs[GEM_DESCONF] = 0x02500111;
|
||||||
s->regs[GEM_DESCONF2] = 0x2ab13fff;
|
s->regs[GEM_DESCONF2] = 0x2ab13fff;
|
||||||
s->regs[GEM_DESCONF5] = 0x002f2145;
|
s->regs[GEM_DESCONF5] = 0x002f2045;
|
||||||
s->regs[GEM_DESCONF6] = 0x00000200;
|
s->regs[GEM_DESCONF6] = 0x00000200;
|
||||||
|
|
||||||
/* Set MAC address */
|
/* Set MAC address */
|
||||||
|
@ -1463,6 +1533,9 @@ static void gem_realize(DeviceState *dev, Error **errp)
|
||||||
CadenceGEMState *s = CADENCE_GEM(dev);
|
CadenceGEMState *s = CADENCE_GEM(dev);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
address_space_init(&s->dma_as,
|
||||||
|
s->dma_mr ? s->dma_mr : get_system_memory(), "dma");
|
||||||
|
|
||||||
if (s->num_priority_queues == 0 ||
|
if (s->num_priority_queues == 0 ||
|
||||||
s->num_priority_queues > MAX_PRIORITY_QUEUES) {
|
s->num_priority_queues > MAX_PRIORITY_QUEUES) {
|
||||||
error_setg(errp, "Invalid num-priority-queues value: %" PRIx8,
|
error_setg(errp, "Invalid num-priority-queues value: %" PRIx8,
|
||||||
|
@ -1500,6 +1573,12 @@ static void gem_init(Object *obj)
|
||||||
"enet", sizeof(s->regs));
|
"enet", sizeof(s->regs));
|
||||||
|
|
||||||
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
|
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 = {
|
static const VMStateDescription vmstate_cadence_gem = {
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
|
|
||||||
#define CADENCE_GEM_MAXREG (0x00000800 / 4) /* Last valid GEM address */
|
#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_PRIORITY_QUEUES 8
|
||||||
#define MAX_TYPE1_SCREENERS 16
|
#define MAX_TYPE1_SCREENERS 16
|
||||||
#define MAX_TYPE2_SCREENERS 16
|
#define MAX_TYPE2_SCREENERS 16
|
||||||
|
@ -42,6 +45,8 @@ typedef struct CadenceGEMState {
|
||||||
|
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
MemoryRegion iomem;
|
MemoryRegion iomem;
|
||||||
|
MemoryRegion *dma_mr;
|
||||||
|
AddressSpace dma_as;
|
||||||
NICState *nic;
|
NICState *nic;
|
||||||
NICConf conf;
|
NICConf conf;
|
||||||
qemu_irq irq[MAX_PRIORITY_QUEUES];
|
qemu_irq irq[MAX_PRIORITY_QUEUES];
|
||||||
|
@ -74,7 +79,7 @@ typedef struct CadenceGEMState {
|
||||||
|
|
||||||
uint8_t can_rx_state; /* Debug only */
|
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];
|
bool sar_active[4];
|
||||||
} CadenceGEMState;
|
} CadenceGEMState;
|
||||||
|
|
65
scripts/coccinelle/inplace-byteswaps.cocci
Normal file
65
scripts/coccinelle/inplace-byteswaps.cocci
Normal 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);
|
|
@ -103,6 +103,16 @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
|
||||||
} else {
|
} else {
|
||||||
/* Processor is not in secure mode */
|
/* Processor is not in secure mode */
|
||||||
target_cpu->env.cp15.scr_el3 |= SCR_NS;
|
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 */
|
/* We check if the started CPU is now at the correct level */
|
||||||
|
|
|
@ -1397,7 +1397,7 @@ static void cortex_r5_initfn(Object *obj)
|
||||||
cpu->id_mmfr1 = 0x00000000;
|
cpu->id_mmfr1 = 0x00000000;
|
||||||
cpu->id_mmfr2 = 0x01200000;
|
cpu->id_mmfr2 = 0x01200000;
|
||||||
cpu->id_mmfr3 = 0x0211;
|
cpu->id_mmfr3 = 0x0211;
|
||||||
cpu->id_isar0 = 0x2101111;
|
cpu->id_isar0 = 0x02101111;
|
||||||
cpu->id_isar1 = 0x13112111;
|
cpu->id_isar1 = 0x13112111;
|
||||||
cpu->id_isar2 = 0x21232141;
|
cpu->id_isar2 = 0x21232141;
|
||||||
cpu->id_isar3 = 0x01112131;
|
cpu->id_isar3 = 0x01112131;
|
||||||
|
@ -1587,7 +1587,10 @@ static void cortex_a7_initfn(Object *obj)
|
||||||
cpu->id_mmfr1 = 0x40000000;
|
cpu->id_mmfr1 = 0x40000000;
|
||||||
cpu->id_mmfr2 = 0x01240000;
|
cpu->id_mmfr2 = 0x01240000;
|
||||||
cpu->id_mmfr3 = 0x02102211;
|
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_isar1 = 0x13112111;
|
||||||
cpu->id_isar2 = 0x21232041;
|
cpu->id_isar2 = 0x21232041;
|
||||||
cpu->id_isar3 = 0x11112131;
|
cpu->id_isar3 = 0x11112131;
|
||||||
|
|
|
@ -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_read_register(CPUState *cpu, uint8_t *buf, int reg);
|
||||||
int aarch64_cpu_gdb_write_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_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
|
#else
|
||||||
static inline void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq) { }
|
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
|
#endif
|
||||||
|
|
||||||
target_ulong do_arm_semihosting(CPUARMState *env);
|
target_ulong do_arm_semihosting(CPUARMState *env);
|
||||||
|
@ -1440,6 +1443,94 @@ FIELD(V7M_CSSELR, LEVEL, 1, 3)
|
||||||
*/
|
*/
|
||||||
FIELD(V7M_CSSELR, INDEX, 0, 4)
|
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);
|
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
|
/* If adding a feature bit which corresponds to a Linux ELF
|
||||||
|
|
|
@ -51,7 +51,7 @@ static uint64_t a57_a53_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const ARMCPRegInfo cortex_a57_a53_cp_reginfo[] = {
|
static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
{ .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64,
|
{ .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2,
|
.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_num_lrs = 4;
|
||||||
cpu->gic_vpribits = 5;
|
cpu->gic_vpribits = 5;
|
||||||
cpu->gic_vprebits = 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)
|
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_num_lrs = 4;
|
||||||
cpu->gic_vpribits = 5;
|
cpu->gic_vpribits = 5;
|
||||||
cpu->gic_vprebits = 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,
|
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[] = {
|
static const ARMCPUInfo aarch64_cpus[] = {
|
||||||
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
|
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
|
||||||
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
|
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
|
||||||
|
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
|
||||||
{ .name = "max", .initfn = aarch64_max_initfn },
|
{ .name = "max", .initfn = aarch64_max_initfn },
|
||||||
{ .name = NULL }
|
{ .name = NULL }
|
||||||
};
|
};
|
||||||
|
|
|
@ -1179,6 +1179,7 @@ static void pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
uint64_t value)
|
uint64_t value)
|
||||||
{
|
{
|
||||||
|
value &= pmu_counter_mask(env);
|
||||||
env->cp15.c9_pmovsr &= ~value;
|
env->cp15.c9_pmovsr &= ~value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1423,12 +1424,14 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
|
||||||
.writefn = pmintenset_write, .raw_writefn = raw_write,
|
.writefn = pmintenset_write, .raw_writefn = raw_write,
|
||||||
.resetvalue = 0x0 },
|
.resetvalue = 0x0 },
|
||||||
{ .name = "PMINTENCLR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 2,
|
{ .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),
|
.fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
|
||||||
.writefn = pmintenclr_write, },
|
.writefn = pmintenclr_write, },
|
||||||
{ .name = "PMINTENCLR_EL1", .state = ARM_CP_STATE_AA64,
|
{ .name = "PMINTENCLR_EL1", .state = ARM_CP_STATE_AA64,
|
||||||
.opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 2,
|
.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),
|
.fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
|
||||||
.writefn = pmintenclr_write },
|
.writefn = pmintenclr_write },
|
||||||
{ .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
|
{ .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;
|
target_ulong page_size;
|
||||||
hwaddr physaddr;
|
hwaddr physaddr;
|
||||||
int prot;
|
int prot;
|
||||||
ARMMMUFaultInfo fi;
|
ARMMMUFaultInfo fi = {};
|
||||||
bool secure = mmu_idx & ARM_MMU_IDX_M_S;
|
bool secure = mmu_idx & ARM_MMU_IDX_M_S;
|
||||||
int exc;
|
int exc;
|
||||||
bool exc_secure;
|
bool exc_secure;
|
||||||
|
@ -6531,7 +6534,7 @@ static bool v7m_stack_read(ARMCPU *cpu, uint32_t *dest, uint32_t addr,
|
||||||
target_ulong page_size;
|
target_ulong page_size;
|
||||||
hwaddr physaddr;
|
hwaddr physaddr;
|
||||||
int prot;
|
int prot;
|
||||||
ARMMMUFaultInfo fi;
|
ARMMMUFaultInfo fi = {};
|
||||||
bool secure = mmu_idx & ARM_MMU_IDX_M_S;
|
bool secure = mmu_idx & ARM_MMU_IDX_M_S;
|
||||||
int exc;
|
int exc;
|
||||||
bool exc_secure;
|
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 new_mode = aarch64_pstate_mode(new_el, true);
|
||||||
unsigned int cur_el = arm_current_el(env);
|
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) {
|
if (cur_el < new_el) {
|
||||||
/* Entry vector offset depends on whether the implemented 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.
|
* 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;
|
int old_len, new_len;
|
||||||
|
bool old_a64, new_a64;
|
||||||
|
|
||||||
/* Nothing to do if no SVE. */
|
/* Nothing to do if no SVE. */
|
||||||
if (!arm_feature(env, ARM_FEATURE_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
|
* we already have the correct register contents when encountering the
|
||||||
* vq0->vq0 transition between EL0->EL1.
|
* 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);
|
? 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);
|
? sve_zcr_len_for_el(env, new_el) : 0);
|
||||||
|
|
||||||
/* When changing vector length, clear inaccessible state. */
|
/* When changing vector length, clear inaccessible state. */
|
||||||
|
|
|
@ -1101,7 +1101,11 @@ void HELPER(exception_return)(CPUARMState *env)
|
||||||
"AArch64 EL%d PC 0x%" PRIx64 "\n",
|
"AArch64 EL%d PC 0x%" PRIx64 "\n",
|
||||||
cur_el, new_el, env->pc);
|
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();
|
qemu_mutex_lock_iothread();
|
||||||
arm_call_el_change_hook(arm_env_get_cpu(env));
|
arm_call_el_change_hook(arm_env_get_cpu(env));
|
||||||
|
|
Loading…
Reference in a new issue