target-arm queue:

* add aarch64_be linux-user target
  * Virt: ACPI: fix qemu assert due to re-assigned table data address
  * imx_fec: various bug fixes and cleanups
  * hw/timer/pxa2xx_timer: replace hw_error() -> qemu_log_mask()
  * hw/sd/pxa2xx_mmci: add read/write() trace events
  * linux-user/arm/nwfpe: Check coprocessor number for FPA emulation
  * target/arm: Make disas_thumb2_insn() generate its own UNDEF exceptions
  * hw/intc/arm_gicv3: Make reserved register addresses RAZ/WI
  * hw/intc/arm_gic: reserved register addresses are RAZ/WI
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABCAAGBQJaV2iVAAoJEDwlJe0UNgzeLmEQAJ3A9m42/ZI6z3zSjnu27q13
 8UvLlXimJuABK9cav5EvqXz6j+LwqBs7psJ6tvNXV3L2A+lBPYPHsTqnS7T0BSts
 36r1IepRA1Gw8nIdKDpK4ZwNQ2EkkipairtWq7OV4Q3Ouh5TRuVX2Sm8iKdz0tm5
 cd6LAQjynPfe4oeZXgJU6TlulSaWxSrUhhc0VGsv6Q9L5tZR4C1lFYP8Ijv3xPfh
 5pKWccTJktywahrFrdr0mWOWnRgkZ3Fm63r0JeyoHeT7olLLp91zk/d+C7+QYoEn
 vkJwvPrhYru349Inq8T7X7jg3aWdh28Ivajm11EQ9l+uFjwdbR/jbVUHCQn3QXzE
 +SN1Kmk3U8IiAPoc9hjTjHnYG6OSKEBgJautgmxQZjWaMm7RvwVPvJTULyZTQi27
 0NxHl9Uh2dlc8Msj6DfGfd0XOdf1crqtAGERKfJBsyrN0whiugH9Hn+AEnjf17zt
 M6lJbkwF8P8oG0DmnbZcxvh9QIHv0eaAW5ksR5wwnPIHsvSLQv/wgiwRdTjNh/JM
 KNH/F4+H2O7bbK2Dh/Y20RGiip0XhpelRFfoN507Uh4YgE+NEmV1CnN1gbk/P+y6
 f1PJ5Dt+H3m3dSyzyUsie4foO5BVTxhPE6dQKz2nsTWjNJRbIRLJx82A5GSF2Cip
 ZDCn6DGcMXtbAoseeu9l
 =imOw
 -----END PGP SIGNATURE-----

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

target-arm queue:
 * add aarch64_be linux-user target
 * Virt: ACPI: fix qemu assert due to re-assigned table data address
 * imx_fec: various bug fixes and cleanups
 * hw/timer/pxa2xx_timer: replace hw_error() -> qemu_log_mask()
 * hw/sd/pxa2xx_mmci: add read/write() trace events
 * linux-user/arm/nwfpe: Check coprocessor number for FPA emulation
 * target/arm: Make disas_thumb2_insn() generate its own UNDEF exceptions
 * hw/intc/arm_gicv3: Make reserved register addresses RAZ/WI
 * hw/intc/arm_gic: reserved register addresses are RAZ/WI

# gpg: Signature made Thu 11 Jan 2018 13:37:25 GMT
# 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-20180111: (26 commits)
  hw/intc/arm_gic: reserved register addresses are RAZ/WI
  hw/intc/arm_gicv3: Make reserved register addresses RAZ/WI
  target/arm: Make disas_thumb2_insn() generate its own UNDEF exceptions
  linux-user/arm/nwfpe: Check coprocessor number for FPA emulation
  hw/sd/pxa2xx_mmci: add read/write() trace events
  hw/timer/pxa2xx_timer: replace hw_error() -> qemu_log_mask()
  imx_fec: Reserve full FSL_IMX25_FEC_SIZE page for the register file
  imx_fec: Fix a typo in imx_enet_receive()
  imx_fec: Use correct length for packet size
  imx_fec: Add support for multiple Tx DMA rings
  imx_fec: Emulate SHIFT16 in ENETx_RACC
  imx_fec: Use MIN instead of explicit ternary operator
  imx_fec: Use ENET_FTRL to determine truncation length
  imx_fec: Move Tx frame buffer away from the stack
  imx_fec: Change queue flushing heuristics
  imx_fec: Refactor imx_eth_enable_rx()
  imx_fec: Do not link to netdev
  Virt: ACPI: fix qemu assert due to re-assigned table data address
  target/arm: Fix stlxp for aarch64_be
  linux-user: Activate armeb handler registration
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2018-01-11 14:34:41 +00:00
commit 997eba28a3
21 changed files with 356 additions and 119 deletions

5
configure vendored
View File

@ -6439,7 +6439,7 @@ target_name=$(echo $target | cut -d '-' -f 1)
target_bigendian="no"
case "$target_name" in
armeb|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
target_bigendian=yes
;;
esac
@ -6494,7 +6494,8 @@ case "$target_name" in
mttcg="yes"
gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
;;
aarch64)
aarch64|aarch64_be)
TARGET_ARCH=aarch64
TARGET_BASE_ARCH=arm
bflt="yes"
mttcg="yes"

View File

@ -0,0 +1 @@
# Default configuration for aarch64_be-linux-user

View File

@ -385,6 +385,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
spi_table[i].irq));
}
qdev_set_nic_properties(DEVICE(&s->eth), &nd_table[0]);
object_property_set_bool(OBJECT(&s->eth), true, "realized", &err);
if (err) {
error_propagate(errp, err);

View File

@ -453,6 +453,7 @@ build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
AcpiSerialPortConsoleRedirection *spcr;
const MemMapEntry *uart_memmap = &vms->memmap[VIRT_UART];
int irq = vms->irqmap[VIRT_UART] + ARM_SPI_BASE;
int spcr_start = table_data->len;
spcr = acpi_data_push(table_data, sizeof(*spcr));
@ -476,8 +477,8 @@ build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
spcr->pci_device_id = 0xffff; /* PCI Device ID: not a PCI device */
spcr->pci_vendor_id = 0xffff; /* PCI Vendor ID: not a PCI device */
build_header(linker, table_data, (void *)spcr, "SPCR", sizeof(*spcr), 2,
NULL, NULL);
build_header(linker, table_data, (void *)(table_data->data + spcr_start),
"SPCR", table_data->len - spcr_start, 2, NULL, NULL);
}
static void
@ -512,8 +513,8 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
mem_base += numa_info[i].node_mem;
}
build_header(linker, table_data, (void *)srat, "SRAT",
table_data->len - srat_start, 3, NULL, NULL);
build_header(linker, table_data, (void *)(table_data->data + srat_start),
"SRAT", table_data->len - srat_start, 3, NULL, NULL);
}
static void
@ -522,6 +523,7 @@ build_mcfg(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
AcpiTableMcfg *mcfg;
const MemMapEntry *memmap = vms->memmap;
int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
int mcfg_start = table_data->len;
mcfg = acpi_data_push(table_data, len);
mcfg->allocation[0].address = cpu_to_le64(memmap[VIRT_PCIE_ECAM].base);
@ -532,7 +534,8 @@ build_mcfg(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
mcfg->allocation[0].end_bus_number = (memmap[VIRT_PCIE_ECAM].size
/ PCIE_MMCFG_SIZE_MIN) - 1;
build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, NULL);
build_header(linker, table_data, (void *)(table_data->data + mcfg_start),
"MCFG", table_data->len - mcfg_start, 1, NULL, NULL);
}
/* GTDT */
@ -651,6 +654,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
static void build_fadt(GArray *table_data, BIOSLinker *linker,
VirtMachineState *vms, unsigned dsdt_tbl_offset)
{
int fadt_start = table_data->len;
AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
unsigned xdsdt_entry_offset = (char *)&fadt->x_dsdt - table_data->data;
uint16_t bootflags;
@ -681,8 +685,8 @@ static void build_fadt(GArray *table_data, BIOSLinker *linker,
ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, sizeof(fadt->x_dsdt),
ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
build_header(linker, table_data,
(void *)fadt, "FACP", sizeof(*fadt), 5, NULL, NULL);
build_header(linker, table_data, (void *)(table_data->data + fadt_start),
"FACP", table_data->len - fadt_start, 5, NULL, NULL);
}
/* DSDT */

View File

@ -1261,7 +1261,8 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
default:
qemu_log_mask(LOG_GUEST_ERROR,
"gic_cpu_read: Bad offset %x\n", (int)offset);
return MEMTX_ERROR;
*data = 0;
break;
}
return MEMTX_OK;
}
@ -1329,7 +1330,7 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
default:
qemu_log_mask(LOG_GUEST_ERROR,
"gic_cpu_write: Bad offset %x\n", (int)offset);
return MEMTX_ERROR;
return MEMTX_OK;
}
gic_update(s);
return MEMTX_OK;

View File

@ -817,6 +817,13 @@ MemTxResult gicv3_dist_read(void *opaque, hwaddr offset, uint64_t *data,
"%s: invalid guest read at offset " TARGET_FMT_plx
"size %u\n", __func__, offset, size);
trace_gicv3_dist_badread(offset, size, attrs.secure);
/* The spec requires that reserved registers are RAZ/WI;
* so use MEMTX_ERROR returns from leaf functions as a way to
* trigger the guest-error logging but don't return it to
* the caller, or we'll cause a spurious guest data abort.
*/
r = MEMTX_OK;
*data = 0;
} else {
trace_gicv3_dist_read(offset, *data, size, attrs.secure);
}
@ -852,6 +859,12 @@ MemTxResult gicv3_dist_write(void *opaque, hwaddr offset, uint64_t data,
"%s: invalid guest write at offset " TARGET_FMT_plx
"size %u\n", __func__, offset, size);
trace_gicv3_dist_badwrite(offset, data, size, attrs.secure);
/* The spec requires that reserved registers are RAZ/WI;
* so use MEMTX_ERROR returns from leaf functions as a way to
* trigger the guest-error logging but don't return it to
* the caller, or we'll cause a spurious guest data abort.
*/
r = MEMTX_OK;
} else {
trace_gicv3_dist_write(offset, data, size, attrs.secure);
}

View File

@ -67,7 +67,8 @@ static MemTxResult gicv3_its_trans_read(void *opaque, hwaddr offset,
MemTxAttrs attrs)
{
qemu_log_mask(LOG_GUEST_ERROR, "ITS read at offset 0x%"PRIx64"\n", offset);
return MEMTX_ERROR;
*data = 0;
return MEMTX_OK;
}
static MemTxResult gicv3_its_trans_write(void *opaque, hwaddr offset,
@ -82,15 +83,12 @@ static MemTxResult gicv3_its_trans_write(void *opaque, hwaddr offset,
if (ret <= 0) {
qemu_log_mask(LOG_GUEST_ERROR,
"ITS: Error sending MSI: %s\n", strerror(-ret));
return MEMTX_DECODE_ERROR;
}
return MEMTX_OK;
} else {
qemu_log_mask(LOG_GUEST_ERROR,
"ITS write at bad offset 0x%"PRIx64"\n", offset);
return MEMTX_DECODE_ERROR;
}
return MEMTX_OK;
}
static const MemoryRegionOps gicv3_its_trans_ops = {

View File

@ -455,6 +455,13 @@ MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
"size %u\n", __func__, offset, size);
trace_gicv3_redist_badread(gicv3_redist_affid(cs), offset,
size, attrs.secure);
/* The spec requires that reserved registers are RAZ/WI;
* so use MEMTX_ERROR returns from leaf functions as a way to
* trigger the guest-error logging but don't return it to
* the caller, or we'll cause a spurious guest data abort.
*/
r = MEMTX_OK;
*data = 0;
} else {
trace_gicv3_redist_read(gicv3_redist_affid(cs), offset, *data,
size, attrs.secure);
@ -505,6 +512,12 @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
"size %u\n", __func__, offset, size);
trace_gicv3_redist_badwrite(gicv3_redist_affid(cs), offset, data,
size, attrs.secure);
/* The spec requires that reserved registers are RAZ/WI;
* so use MEMTX_ERROR returns from leaf functions as a way to
* trigger the guest-error logging but don't return it to
* the caller, or we'll cause a spurious guest data abort.
*/
r = MEMTX_OK;
} else {
trace_gicv3_redist_write(gicv3_redist_affid(cs), offset, data,
size, attrs.secure);

View File

@ -196,6 +196,31 @@ static const char *imx_eth_reg_name(IMXFECState *s, uint32_t index)
}
}
/*
* Versions of this device with more than one TX descriptor save the
* 2nd and 3rd descriptors in a subsection, to maintain migration
* compatibility with previous versions of the device that only
* supported a single descriptor.
*/
static bool imx_eth_is_multi_tx_ring(void *opaque)
{
IMXFECState *s = IMX_FEC(opaque);
return s->tx_ring_num > 1;
}
static const VMStateDescription vmstate_imx_eth_txdescs = {
.name = "imx.fec/txdescs",
.version_id = 1,
.minimum_version_id = 1,
.needed = imx_eth_is_multi_tx_ring,
.fields = (VMStateField[]) {
VMSTATE_UINT32(tx_descriptor[1], IMXFECState),
VMSTATE_UINT32(tx_descriptor[2], IMXFECState),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_imx_eth = {
.name = TYPE_IMX_FEC,
.version_id = 2,
@ -203,15 +228,18 @@ static const VMStateDescription vmstate_imx_eth = {
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
VMSTATE_UINT32(rx_descriptor, IMXFECState),
VMSTATE_UINT32(tx_descriptor, IMXFECState),
VMSTATE_UINT32(tx_descriptor[0], IMXFECState),
VMSTATE_UINT32(phy_status, IMXFECState),
VMSTATE_UINT32(phy_control, IMXFECState),
VMSTATE_UINT32(phy_advertise, IMXFECState),
VMSTATE_UINT32(phy_int, IMXFECState),
VMSTATE_UINT32(phy_int_mask, IMXFECState),
VMSTATE_END_OF_LIST()
}
},
.subsections = (const VMStateDescription * []) {
&vmstate_imx_eth_txdescs,
NULL
},
};
#define PHY_INT_ENERGYON (1 << 7)
@ -405,9 +433,8 @@ static void imx_eth_update(IMXFECState *s)
static void imx_fec_do_tx(IMXFECState *s)
{
int frame_size = 0, descnt = 0;
uint8_t frame[ENET_MAX_FRAME_SIZE];
uint8_t *ptr = frame;
uint32_t addr = s->tx_descriptor;
uint8_t *ptr = s->frame;
uint32_t addr = s->tx_descriptor[0];
while (descnt++ < IMX_MAX_DESC) {
IMXFECBufDesc bd;
@ -431,8 +458,8 @@ static void imx_fec_do_tx(IMXFECState *s)
frame_size += len;
if (bd.flags & ENET_BD_L) {
/* Last buffer in frame. */
qemu_send_packet(qemu_get_queue(s->nic), frame, frame_size);
ptr = frame;
qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
ptr = s->frame;
frame_size = 0;
s->regs[ENET_EIR] |= ENET_INT_TXF;
}
@ -448,17 +475,47 @@ static void imx_fec_do_tx(IMXFECState *s)
}
}
s->tx_descriptor = addr;
s->tx_descriptor[0] = addr;
imx_eth_update(s);
}
static void imx_enet_do_tx(IMXFECState *s)
static void imx_enet_do_tx(IMXFECState *s, uint32_t index)
{
int frame_size = 0, descnt = 0;
uint8_t frame[ENET_MAX_FRAME_SIZE];
uint8_t *ptr = frame;
uint32_t addr = s->tx_descriptor;
uint8_t *ptr = s->frame;
uint32_t addr, int_txb, int_txf, tdsr;
size_t ring;
switch (index) {
case ENET_TDAR:
ring = 0;
int_txb = ENET_INT_TXB;
int_txf = ENET_INT_TXF;
tdsr = ENET_TDSR;
break;
case ENET_TDAR1:
ring = 1;
int_txb = ENET_INT_TXB1;
int_txf = ENET_INT_TXF1;
tdsr = ENET_TDSR1;
break;
case ENET_TDAR2:
ring = 2;
int_txb = ENET_INT_TXB2;
int_txf = ENET_INT_TXF2;
tdsr = ENET_TDSR2;
break;
default:
qemu_log_mask(LOG_GUEST_ERROR,
"%s: bogus value for index %x\n",
__func__, index);
abort();
break;
}
addr = s->tx_descriptor[ring];
while (descnt++ < IMX_MAX_DESC) {
IMXENETBufDesc bd;
@ -482,13 +539,13 @@ static void imx_enet_do_tx(IMXFECState *s)
frame_size += len;
if (bd.flags & ENET_BD_L) {
if (bd.option & ENET_BD_PINS) {
struct ip_header *ip_hd = PKT_GET_IP_HDR(frame);
struct ip_header *ip_hd = PKT_GET_IP_HDR(s->frame);
if (IP_HEADER_VERSION(ip_hd) == 4) {
net_checksum_calculate(frame, frame_size);
net_checksum_calculate(s->frame, frame_size);
}
}
if (bd.option & ENET_BD_IINS) {
struct ip_header *ip_hd = PKT_GET_IP_HDR(frame);
struct ip_header *ip_hd = PKT_GET_IP_HDR(s->frame);
/* We compute checksum only for IPv4 frames */
if (IP_HEADER_VERSION(ip_hd) == 4) {
uint16_t csum;
@ -498,57 +555,59 @@ static void imx_enet_do_tx(IMXFECState *s)
}
}
/* Last buffer in frame. */
qemu_send_packet(qemu_get_queue(s->nic), frame, len);
ptr = frame;
qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
ptr = s->frame;
frame_size = 0;
if (bd.option & ENET_BD_TX_INT) {
s->regs[ENET_EIR] |= ENET_INT_TXF;
s->regs[ENET_EIR] |= int_txf;
}
}
if (bd.option & ENET_BD_TX_INT) {
s->regs[ENET_EIR] |= ENET_INT_TXB;
s->regs[ENET_EIR] |= int_txb;
}
bd.flags &= ~ENET_BD_R;
/* Write back the modified descriptor. */
imx_enet_write_bd(&bd, addr);
/* Advance to the next descriptor. */
if ((bd.flags & ENET_BD_W) != 0) {
addr = s->regs[ENET_TDSR];
addr = s->regs[tdsr];
} else {
addr += sizeof(bd);
}
}
s->tx_descriptor = addr;
s->tx_descriptor[ring] = addr;
imx_eth_update(s);
}
static void imx_eth_do_tx(IMXFECState *s)
static void imx_eth_do_tx(IMXFECState *s, uint32_t index)
{
if (!s->is_fec && (s->regs[ENET_ECR] & ENET_ECR_EN1588)) {
imx_enet_do_tx(s);
imx_enet_do_tx(s, index);
} else {
imx_fec_do_tx(s);
}
}
static void imx_eth_enable_rx(IMXFECState *s)
static void imx_eth_enable_rx(IMXFECState *s, bool flush)
{
IMXFECBufDesc bd;
bool tmp;
bool rx_ring_full;
imx_fec_read_bd(&bd, s->rx_descriptor);
tmp = ((bd.flags & ENET_BD_E) != 0);
rx_ring_full = !(bd.flags & ENET_BD_E);
if (!tmp) {
if (rx_ring_full) {
FEC_PRINTF("RX buffer full\n");
} else if (!s->regs[ENET_RDAR]) {
} else if (flush) {
qemu_flush_queued_packets(qemu_get_queue(s->nic));
}
s->regs[ENET_RDAR] = tmp ? ENET_RDAR_RDAR : 0;
s->regs[ENET_RDAR] = rx_ring_full ? 0 : ENET_RDAR_RDAR;
}
static void imx_eth_reset(DeviceState *d)
@ -585,7 +644,7 @@ static void imx_eth_reset(DeviceState *d)
}
s->rx_descriptor = 0;
s->tx_descriptor = 0;
memset(s->tx_descriptor, 0, sizeof(s->tx_descriptor));
/* We also reset the PHY */
phy_reset(s);
@ -791,6 +850,7 @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
unsigned size)
{
IMXFECState *s = IMX_FEC(opaque);
const bool single_tx_ring = !imx_eth_is_multi_tx_ring(s);
uint32_t index = offset >> 2;
FEC_PRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx_eth_reg_name(s, index),
@ -807,16 +867,24 @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
if (!s->regs[index]) {
s->regs[index] = ENET_RDAR_RDAR;
imx_eth_enable_rx(s);
imx_eth_enable_rx(s, true);
}
} else {
s->regs[index] = 0;
}
break;
case ENET_TDAR:
case ENET_TDAR1: /* FALLTHROUGH */
case ENET_TDAR2: /* FALLTHROUGH */
if (unlikely(single_tx_ring)) {
qemu_log_mask(LOG_GUEST_ERROR,
"[%s]%s: trying to access TDAR2 or TDAR1\n",
TYPE_IMX_FEC, __func__);
return;
}
case ENET_TDAR: /* FALLTHROUGH */
if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
s->regs[index] = ENET_TDAR_TDAR;
imx_eth_do_tx(s);
imx_eth_do_tx(s, index);
}
s->regs[index] = 0;
break;
@ -828,8 +896,12 @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
if ((s->regs[index] & ENET_ECR_ETHEREN) == 0) {
s->regs[ENET_RDAR] = 0;
s->rx_descriptor = s->regs[ENET_RDSR];
s->regs[ENET_TDAR] = 0;
s->tx_descriptor = s->regs[ENET_TDSR];
s->regs[ENET_TDAR] = 0;
s->regs[ENET_TDAR1] = 0;
s->regs[ENET_TDAR2] = 0;
s->tx_descriptor[0] = s->regs[ENET_TDSR];
s->tx_descriptor[1] = s->regs[ENET_TDSR1];
s->tx_descriptor[2] = s->regs[ENET_TDSR2];
}
break;
case ENET_MMFR:
@ -907,7 +979,29 @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
} else {
s->regs[index] = value & ~7;
}
s->tx_descriptor = s->regs[index];
s->tx_descriptor[0] = s->regs[index];
break;
case ENET_TDSR1:
if (unlikely(single_tx_ring)) {
qemu_log_mask(LOG_GUEST_ERROR,
"[%s]%s: trying to access TDSR1\n",
TYPE_IMX_FEC, __func__);
return;
}
s->regs[index] = value & ~7;
s->tx_descriptor[1] = s->regs[index];
break;
case ENET_TDSR2:
if (unlikely(single_tx_ring)) {
qemu_log_mask(LOG_GUEST_ERROR,
"[%s]%s: trying to access TDSR2\n",
TYPE_IMX_FEC, __func__);
return;
}
s->regs[index] = value & ~7;
s->tx_descriptor[2] = s->regs[index];
break;
case ENET_MRBR:
s->regs[index] = value & 0x00003ff0;
@ -930,7 +1024,7 @@ static int imx_eth_can_receive(NetClientState *nc)
FEC_PRINTF("\n");
return s->regs[ENET_RDAR] ? 1 : 0;
return !!s->regs[ENET_RDAR];
}
static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
@ -1020,7 +1114,7 @@ static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
}
}
s->rx_descriptor = addr;
imx_eth_enable_rx(s);
imx_eth_enable_rx(s, false);
imx_eth_update(s);
return len;
}
@ -1037,6 +1131,7 @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
uint8_t *crc_ptr;
unsigned int buf_len;
size_t size = len;
bool shift16 = s->regs[ENET_RACC] & ENET_RACC_SHIFT16;
FEC_PRINTF("len %d\n", (int)size);
@ -1051,9 +1146,13 @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
crc = cpu_to_be32(crc32(~0, buf, size));
crc_ptr = (uint8_t *) &crc;
/* Huge frames are truncted. */
if (size > ENET_MAX_FRAME_SIZE) {
size = ENET_MAX_FRAME_SIZE;
if (shift16) {
size += 2;
}
/* Huge frames are truncated. */
if (size > s->regs[ENET_FTRL]) {
size = s->regs[ENET_FTRL];
flags |= ENET_BD_TR | ENET_BD_LG;
}
@ -1076,7 +1175,7 @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
TYPE_IMX_FEC, __func__);
break;
}
buf_len = (size <= s->regs[ENET_MRBR]) ? size : s->regs[ENET_MRBR];
buf_len = MIN(size, s->regs[ENET_MRBR]);
bd.length = buf_len;
size -= buf_len;
@ -1087,6 +1186,24 @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
buf_len += size - 4;
}
buf_addr = bd.data;
if (shift16) {
/*
* If SHIFT16 bit of ENETx_RACC register is set we need to
* align the payload to 4-byte boundary.
*/
const uint8_t zeros[2] = { 0 };
dma_memory_write(&address_space_memory, buf_addr,
zeros, sizeof(zeros));
buf_addr += sizeof(zeros);
buf_len -= sizeof(zeros);
/* We only do this once per Ethernet frame */
shift16 = false;
}
dma_memory_write(&address_space_memory, buf_addr, buf, buf_len);
buf += buf_len;
if (size < 4) {
@ -1116,7 +1233,7 @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
}
}
s->rx_descriptor = addr;
imx_eth_enable_rx(s);
imx_eth_enable_rx(s, false);
imx_eth_update(s);
return len;
}
@ -1164,15 +1281,13 @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
memory_region_init_io(&s->iomem, OBJECT(dev), &imx_eth_ops, s,
TYPE_IMX_FEC, 0x400);
TYPE_IMX_FEC, FSL_IMX25_FEC_SIZE);
sysbus_init_mmio(sbd, &s->iomem);
sysbus_init_irq(sbd, &s->irq[0]);
sysbus_init_irq(sbd, &s->irq[1]);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->conf.peers.ncs[0] = nd_table[0].netdev;
s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,
object_get_typename(OBJECT(dev)),
DEVICE(dev)->id, s);
@ -1182,6 +1297,7 @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
static Property imx_eth_properties[] = {
DEFINE_NIC_PROPERTIES(IMXFECState, conf),
DEFINE_PROP_UINT32("tx-ring-num", IMXFECState, tx_ring_num, 1),
DEFINE_PROP_END_OF_LIST(),
};

View File

@ -19,6 +19,8 @@
#include "hw/qdev.h"
#include "hw/qdev-properties.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "trace.h"
#define TYPE_PXA2XX_MMCI "pxa2xx-mmci"
#define PXA2XX_MMCI(obj) OBJECT_CHECK(PXA2xxMMCIState, (obj), TYPE_PXA2XX_MMCI)
@ -278,45 +280,56 @@ static void pxa2xx_mmci_wakequeues(PXA2xxMMCIState *s)
static uint64_t pxa2xx_mmci_read(void *opaque, hwaddr offset, unsigned size)
{
PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
uint32_t ret;
uint32_t ret = 0;
switch (offset) {
case MMC_STRPCL:
return 0;
break;
case MMC_STAT:
return s->status;
ret = s->status;
break;
case MMC_CLKRT:
return s->clkrt;
ret = s->clkrt;
break;
case MMC_SPI:
return s->spi;
ret = s->spi;
break;
case MMC_CMDAT:
return s->cmdat;
ret = s->cmdat;
break;
case MMC_RESTO:
return s->resp_tout;
ret = s->resp_tout;
break;
case MMC_RDTO:
return s->read_tout;
ret = s->read_tout;
break;
case MMC_BLKLEN:
return s->blklen;
ret = s->blklen;
break;
case MMC_NUMBLK:
return s->numblk;
ret = s->numblk;
break;
case MMC_PRTBUF:
return 0;
break;
case MMC_I_MASK:
return s->intmask;
ret = s->intmask;
break;
case MMC_I_REG:
return s->intreq;
ret = s->intreq;
break;
case MMC_CMD:
return s->cmd | 0x40;
ret = s->cmd | 0x40;
break;
case MMC_ARGH:
return s->arg >> 16;
ret = s->arg >> 16;
break;
case MMC_ARGL:
return s->arg & 0xffff;
ret = s->arg & 0xffff;
break;
case MMC_RES:
if (s->resp_len < 9)
return s->resp_fifo[s->resp_len ++];
return 0;
ret = (s->resp_len < 9) ? s->resp_fifo[s->resp_len++] : 0;
break;
case MMC_RXFIFO:
ret = 0;
while (size-- && s->rx_len) {
ret |= s->rx_fifo[s->rx_start++] << (size << 3);
s->rx_start &= 0x1f;
@ -324,16 +337,20 @@ static uint64_t pxa2xx_mmci_read(void *opaque, hwaddr offset, unsigned size)
}
s->intreq &= ~INT_RXFIFO_REQ;
pxa2xx_mmci_fifo_update(s);
return ret;
break;
case MMC_RDWAIT:
return 0;
break;
case MMC_BLKS_REM:
return s->numblk;
ret = s->numblk;
break;
default:
hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: incorrect register 0x%02" HWADDR_PRIx "\n",
__func__, offset);
}
trace_pxa2xx_mmci_read(size, offset, ret);
return 0;
return ret;
}
static void pxa2xx_mmci_write(void *opaque,
@ -341,6 +358,7 @@ static void pxa2xx_mmci_write(void *opaque,
{
PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
trace_pxa2xx_mmci_write(size, offset, value);
switch (offset) {
case MMC_STRPCL:
if (value & STRPCL_STRT_CLK) {
@ -368,8 +386,10 @@ static void pxa2xx_mmci_write(void *opaque,
case MMC_SPI:
s->spi = value & 0xf;
if (value & SPI_SPI_MODE)
printf("%s: attempted to use card in SPI mode\n", __FUNCTION__);
if (value & SPI_SPI_MODE) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: attempted to use card in SPI mode\n", __func__);
}
break;
case MMC_CMDAT:
@ -442,7 +462,9 @@ static void pxa2xx_mmci_write(void *opaque,
break;
default:
hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: incorrect reg 0x%02" HWADDR_PRIx " "
"(value 0x%08" PRIx64 ")\n", __func__, offset, value);
}
}

View File

@ -3,3 +3,7 @@
# hw/sd/milkymist-memcard.c
milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
# hw/sd/pxa2xx_mmci.c
pxa2xx_mmci_read(uint8_t size, uint32_t addr, uint32_t value) "size %d addr 0x%02x value 0x%08x"
pxa2xx_mmci_write(uint8_t size, uint32_t addr, uint32_t value) "size %d addr 0x%02x value 0x%08x"

View File

@ -13,6 +13,7 @@
#include "sysemu/sysemu.h"
#include "hw/arm/pxa.h"
#include "hw/sysbus.h"
#include "qemu/log.h"
#define OSMR0 0x00
#define OSMR1 0x04
@ -252,8 +253,14 @@ static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset,
case OSNR:
return s->snapshot;
default:
qemu_log_mask(LOG_UNIMP,
"%s: unknown register 0x%02" HWADDR_PRIx "\n",
__func__, offset);
break;
badreg:
hw_error("pxa2xx_timer_read: Bad offset " REG_FMT "\n", offset);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: incorrect register 0x%02" HWADDR_PRIx "\n",
__func__, offset);
}
return 0;
@ -377,8 +384,14 @@ static void pxa2xx_timer_write(void *opaque, hwaddr offset,
}
break;
default:
qemu_log_mask(LOG_UNIMP,
"%s: unknown register 0x%02" HWADDR_PRIx " "
"(value 0x%08" PRIx64 ")\n", __func__, offset, value);
break;
badreg:
hw_error("pxa2xx_timer_write: Bad offset " REG_FMT "\n", offset);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: incorrect register 0x%02" HWADDR_PRIx " "
"(value 0x%08" PRIx64 ")\n", __func__, offset, value);
}
}

View File

@ -192,7 +192,6 @@ typedef struct FslIMX25State {
#define FSL_IMX25_UART5_ADDR 0x5002C000
#define FSL_IMX25_UART5_SIZE 0x4000
#define FSL_IMX25_FEC_ADDR 0x50038000
#define FSL_IMX25_FEC_SIZE 0x4000
#define FSL_IMX25_CCM_ADDR 0x53F80000
#define FSL_IMX25_CCM_SIZE 0x4000
#define FSL_IMX25_GPT4_ADDR 0x53F84000

View File

@ -52,6 +52,8 @@
#define ENET_TFWR 81
#define ENET_FRBR 83
#define ENET_FRSR 84
#define ENET_TDSR1 89
#define ENET_TDSR2 92
#define ENET_RDSR 96
#define ENET_TDSR 97
#define ENET_MRBR 98
@ -66,6 +68,8 @@
#define ENET_FTRL 108
#define ENET_TACC 112
#define ENET_RACC 113
#define ENET_TDAR1 121
#define ENET_TDAR2 123
#define ENET_MIIGSK_CFGR 192
#define ENET_MIIGSK_ENR 194
#define ENET_ATCR 256
@ -86,7 +90,6 @@
#define ENET_TCCR3 393
#define ENET_MAX 400
#define ENET_MAX_FRAME_SIZE 2032
/* EIR and EIMR */
#define ENET_INT_HB (1 << 31)
@ -106,13 +109,18 @@
#define ENET_INT_WAKEUP (1 << 17)
#define ENET_INT_TS_AVAIL (1 << 16)
#define ENET_INT_TS_TIMER (1 << 15)
#define ENET_INT_TXF2 (1 << 7)
#define ENET_INT_TXB2 (1 << 6)
#define ENET_INT_TXF1 (1 << 3)
#define ENET_INT_TXB1 (1 << 2)
#define ENET_INT_MAC (ENET_INT_HB | ENET_INT_BABR | ENET_INT_BABT | \
ENET_INT_GRA | ENET_INT_TXF | ENET_INT_TXB | \
ENET_INT_RXF | ENET_INT_RXB | ENET_INT_MII | \
ENET_INT_EBERR | ENET_INT_LC | ENET_INT_RL | \
ENET_INT_UN | ENET_INT_PLR | ENET_INT_WAKEUP | \
ENET_INT_TS_AVAIL)
ENET_INT_TS_AVAIL | ENET_INT_TXF1 | \
ENET_INT_TXB1 | ENET_INT_TXF2 | ENET_INT_TXB2)
/* RDAR */
#define ENET_RDAR_RDAR (1 << 24)
@ -155,6 +163,8 @@
#define ENET_RCR_NLC (1 << 30)
#define ENET_RCR_GRS (1 << 31)
#define ENET_MAX_FRAME_SIZE (1 << ENET_RCR_MAX_FL_LENGTH)
/* TCR */
#define ENET_TCR_GTS (1 << 0)
#define ENET_TCR_FDEN (1 << 2)
@ -169,6 +179,8 @@
#define ENET_TWFR_TFWR_LENGTH (6)
#define ENET_TWFR_STRFWD (1 << 8)
#define ENET_RACC_SHIFT16 BIT(7)
/* Buffer Descriptor. */
typedef struct {
uint16_t length;
@ -231,6 +243,10 @@ typedef struct {
#define ENET_BD_BDU (1 << 31)
#define ENET_TX_RING_NUM 3
#define FSL_IMX25_FEC_SIZE 0x4000
typedef struct IMXFECState {
/*< private >*/
SysBusDevice parent_obj;
@ -243,7 +259,9 @@ typedef struct IMXFECState {
uint32_t regs[ENET_MAX];
uint32_t rx_descriptor;
uint32_t tx_descriptor;
uint32_t tx_descriptor[ENET_TX_RING_NUM];
uint32_t tx_ring_num;
uint32_t phy_status;
uint32_t phy_control;
@ -252,6 +270,9 @@ typedef struct IMXFECState {
uint32_t phy_int_mask;
bool is_fec;
/* Buffer used to assemble a Tx frame */
uint8_t frame[ENET_MAX_FRAME_SIZE];
} IMXFECState;
#endif

View File

@ -8,7 +8,11 @@ struct target_pt_regs {
uint64_t pstate;
};
#if defined(TARGET_WORDS_BIGENDIAN)
#define UNAME_MACHINE "aarch64_be"
#else
#define UNAME_MACHINE "aarch64"
#endif
#define UNAME_MINIMUM_RELEASE "3.8.0"
#define TARGET_CLONE_BACKWARDS
#define TARGET_MINSIGSTKSZ 2048

View File

@ -137,8 +137,17 @@ unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs)
unsigned int nRc = 0;
// unsigned long flags;
FPA11 *fpa11;
unsigned int cp;
// save_flags(flags); sti();
/* Check that this is really an FPA11 instruction: the coprocessor
* field in bits [11:8] must be 1 or 2.
*/
cp = (opcode >> 8) & 0xf;
if (cp != 1 && cp != 2) {
return 0;
}
qemufpa=qfpa;
user_registers=qregs;

View File

@ -4629,6 +4629,12 @@ int main(int argc, char **argv, char **envp)
}
env->pc = regs->pc;
env->xregs[31] = regs->sp;
#ifdef TARGET_WORDS_BIGENDIAN
env->cp15.sctlr_el[1] |= SCTLR_E0E;
for (i = 1; i < 4; ++i) {
env->cp15.sctlr_el[i] |= SCTLR_EE;
}
#endif
}
#elif defined(TARGET_ARM)
{

View File

@ -1599,9 +1599,13 @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
if (ka->sa_flags & TARGET_SA_RESTORER) {
return_addr = ka->sa_restorer;
} else {
/* mov x8,#__NR_rt_sigreturn; svc #0 */
__put_user(0xd2801168, &frame->tramp[0]);
__put_user(0xd4000001, &frame->tramp[1]);
/*
* mov x8,#__NR_rt_sigreturn; svc #0
* Since these are instructions they need to be put as little-endian
* regardless of target default or current CPU endianness.
*/
__put_user_e(0xd2801168, &frame->tramp[0], le);
__put_user_e(0xd4000001, &frame->tramp[1], le);
return_addr = frame_addr + offsetof(struct target_rt_sigframe, tramp);
}
env->xregs[0] = usig;

View File

@ -2,9 +2,9 @@
# enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390/HPPA
# program execution by the kernel
qemu_target_list="i386 i486 alpha arm sparc32plus ppc ppc64 ppc64le m68k \
qemu_target_list="i386 i486 alpha arm armeb sparc32plus ppc ppc64 ppc64le m68k \
mips mipsel mipsn32 mipsn32el mips64 mips64el \
sh4 sh4eb s390x aarch64 hppa"
sh4 sh4eb s390x aarch64 aarch64_be hppa"
i386_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00'
i386_mask='\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
@ -24,7 +24,7 @@ arm_family=arm
armeb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28'
armeb_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
armeb_family=arm
armeb_family=armeb
sparc_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02'
sparc_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
@ -92,6 +92,10 @@ aarch64_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x
aarch64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
aarch64_family=arm
aarch64_be_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7'
aarch64_be_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
aarch64_be_family=armeb
hppa_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x0f'
hppa_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
hppa_family=hppa
@ -111,9 +115,12 @@ qemu_get_family() {
ppc64el|ppc64le)
echo "ppcle"
;;
arm|armel|armhf|arm64|armv[4-9]*)
arm|armel|armhf|arm64|armv[4-9]*l|aarch64)
echo "arm"
;;
armeb|armv[4-9]*b|aarch64_be)
echo "armeb"
;;
sparc*)
echo "sparc"
;;

View File

@ -506,8 +506,11 @@ static uint64_t do_paired_cmpxchg64_be(CPUARMState *env, uint64_t addr,
Int128 oldv, cmpv, newv;
bool success;
cmpv = int128_make128(env->exclusive_val, env->exclusive_high);
newv = int128_make128(new_lo, new_hi);
/* high and low need to be switched here because this is not actually a
* 128bit store but two doublewords stored consecutively
*/
cmpv = int128_make128(env->exclusive_high, env->exclusive_val);
newv = int128_make128(new_hi, new_lo);
if (parallel) {
#ifndef CONFIG_ATOMIC128

View File

@ -9775,9 +9775,8 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
return 0;
}
/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
is not legal. */
static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
/* Translate a 32-bit thumb instruction. */
static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
{
uint32_t imm, shift, offset;
uint32_t rd, rn, rm, rs;
@ -11016,16 +11015,16 @@ static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
/* UNPREDICTABLE, unallocated hint or
* PLD/PLDW/PLI (literal)
*/
return 0;
return;
}
if (op1 & 1) {
return 0; /* PLD/PLDW/PLI or unallocated hint */
return; /* PLD/PLDW/PLI or unallocated hint */
}
if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
return 0; /* PLD/PLDW/PLI or unallocated hint */
return; /* PLD/PLDW/PLI or unallocated hint */
}
/* UNDEF space, or an UNPREDICTABLE */
return 1;
goto illegal_op;
}
}
memidx = get_mem_index(s);
@ -11151,9 +11150,10 @@ static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
default:
goto illegal_op;
}
return 0;
return;
illegal_op:
return 1;
gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
default_exception_el(s));
}
static void disas_thumb_insn(DisasContext *s, uint32_t insn)
@ -12275,10 +12275,7 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
if (is_16bit) {
disas_thumb_insn(dc, insn);
} else {
if (disas_thumb2_insn(dc, insn)) {
gen_exception_insn(dc, 4, EXCP_UDEF, syn_uncategorized(),
default_exception_el(dc));
}
disas_thumb2_insn(dc, insn);
}
/* Advance the Thumb condexec condition. */