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:
commit
997eba28a3
5
configure
vendored
5
configure
vendored
@ -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"
|
||||
|
1
default-configs/aarch64_be-linux-user.mak
Normal file
1
default-configs/aarch64_be-linux-user.mak
Normal file
@ -0,0 +1 @@
|
||||
# Default configuration for aarch64_be-linux-user
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 = {
|
||||
|
@ -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);
|
||||
|
210
hw/net/imx_fec.c
210
hw/net/imx_fec.c
@ -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(),
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
;;
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user