diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2014-02-11 11:26:36 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-02-11 11:26:36 +0000 |
commit | 8fa7574904793396694fa88834751a93bcdf4e10 (patch) | |
tree | 71655e2417ee088da62743f4a90da736cbce1e4f /include | |
parent | 702f6df9602a445103c55ac21af11c7aaedb9b34 (diff) | |
parent | 69991d7dcbcf7f3fe38274bc67fcba3cbbfda0cf (diff) |
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20140208' into staging
target-arm queue:
* more A64 Neon instructions
* AArch32 VCVTB and VCVTT ARMv8 instructions
* fixes to inaccuracies in GIC emulation
* libvixl disassembler for A64
* Allwinner SoC ethernet controller
* zynq software system reset support
# gpg: Signature made Sat 08 Feb 2014 15:53:05 GMT using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"
* remotes/pmaydell/tags/pull-target-arm-20140208: (29 commits)
arm/zynq: Add software system reset via SCLR
hw/arm/allwinner-a10: initialize EMAC
hw/net: add support for Allwinner EMAC Fast Ethernet controller
util/fifo8: clear fifo head upon reset
util/fifo8: implement push/pop of multiple bytes
disas: Implement disassembly output for A64
disas/libvixl: Fix upstream libvixl compilation issues
disas: Add subset of libvixl sources for A64 disassembler
rules.mak: Link with C++ if we have a C++ compiler
rules.mak: Support .cc as a C++ source file suffix
arm_gic: Add GICC_APRn state to the GICState
vmstate: Add uint32 2D-array support
arm_gic: Support setting/getting binary point reg
arm_gic: Keep track of SGI sources
arm_gic: Fix GIC pending behavior
target-arm: Add support for AArch32 64bit VCVTB and VCVTT
target-arm: A64: Add FNEG and FABS to the SIMD 2-reg-misc group
target-arm: A64: Add 2-reg-misc REV* instructions
target-arm: A64: Add narrowing 2-reg-misc instructions
target-arm: A64: Implement 2-reg-misc CNT, NOT and RBIT
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/disas/bfd.h | 1 | ||||
-rw-r--r-- | include/hw/arm/allwinner-a10.h | 3 | ||||
-rw-r--r-- | include/hw/intc/arm_gic_common.h | 33 | ||||
-rw-r--r-- | include/hw/net/allwinner_emac.h | 210 | ||||
-rw-r--r-- | include/migration/vmstate.h | 6 | ||||
-rw-r--r-- | include/qemu/fifo8.h | 61 |
6 files changed, 314 insertions, 0 deletions
diff --git a/include/disas/bfd.h b/include/disas/bfd.h index 803b6efe41..8bd703cb1a 100644 --- a/include/disas/bfd.h +++ b/include/disas/bfd.h @@ -379,6 +379,7 @@ int print_insn_h8300 (bfd_vma, disassemble_info*); int print_insn_h8300h (bfd_vma, disassemble_info*); int print_insn_h8300s (bfd_vma, disassemble_info*); int print_insn_h8500 (bfd_vma, disassemble_info*); +int print_insn_arm_a64 (bfd_vma, disassemble_info*); int print_insn_alpha (bfd_vma, disassemble_info*); disassembler_ftype arc_get_disassembler (int, int); int print_insn_arm (bfd_vma, disassemble_info*); diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h index da36647f32..01a189bcdc 100644 --- a/include/hw/arm/allwinner-a10.h +++ b/include/hw/arm/allwinner-a10.h @@ -6,6 +6,7 @@ #include "hw/arm/arm.h" #include "hw/timer/allwinner-a10-pit.h" #include "hw/intc/allwinner-a10-pic.h" +#include "hw/net/allwinner_emac.h" #include "sysemu/sysemu.h" #include "exec/address-spaces.h" @@ -14,6 +15,7 @@ #define AW_A10_PIC_REG_BASE 0x01c20400 #define AW_A10_PIT_REG_BASE 0x01c20c00 #define AW_A10_UART0_REG_BASE 0x01c28000 +#define AW_A10_EMAC_BASE 0x01c0b000 #define AW_A10_SDRAM_BASE 0x40000000 @@ -29,6 +31,7 @@ typedef struct AwA10State { qemu_irq irq[AW_A10_PIC_INT_NR]; AwA10PITState timer; AwA10PICState intc; + AwEmacState emac; } AwA10State; #define ALLWINNER_H_ diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h index 8a2aa00cee..89384c2bb4 100644 --- a/include/hw/intc/arm_gic_common.h +++ b/include/hw/intc/arm_gic_common.h @@ -31,6 +31,9 @@ /* Maximum number of possible CPU interfaces, determined by GIC architecture */ #define GIC_NCPU 8 +#define MAX_NR_GROUP_PRIO 128 +#define GIC_NR_APRS (MAX_NR_GROUP_PRIO / 32) + typedef struct gic_irq_state { /* The enable bits are only banked for per-cpu interrupts. */ uint8_t enabled; @@ -55,12 +58,42 @@ typedef struct GICState { uint8_t priority1[GIC_INTERNAL][GIC_NCPU]; uint8_t priority2[GIC_MAXIRQ - GIC_INTERNAL]; uint16_t last_active[GIC_MAXIRQ][GIC_NCPU]; + /* For each SGI on the target CPU, we store 8 bits + * indicating which source CPUs have made this SGI + * pending on the target CPU. These correspond to + * the bytes in the GIC_SPENDSGIR* registers as + * read by the target CPU. + */ + uint8_t sgi_pending[GIC_NR_SGIS][GIC_NCPU]; uint16_t priority_mask[GIC_NCPU]; uint16_t running_irq[GIC_NCPU]; uint16_t running_priority[GIC_NCPU]; uint16_t current_pending[GIC_NCPU]; + /* We present the GICv2 without security extensions to a guest and + * therefore the guest can configure the GICC_CTLR to configure group 1 + * binary point in the abpr. + */ + uint8_t bpr[GIC_NCPU]; + uint8_t abpr[GIC_NCPU]; + + /* The APR is implementation defined, so we choose a layout identical to + * the KVM ABI layout for QEMU's implementation of the gic: + * If an interrupt for preemption level X is active, then + * APRn[X mod 32] == 0b1, where n = X / 32 + * otherwise the bit is clear. + * + * TODO: rewrite the interrupt acknowlege/complete routines to use + * the APR registers to track the necessary information to update + * s->running_priority[] on interrupt completion (ie completely remove + * last_active[][] and running_irq[]). This will be necessary if we ever + * want to support TCG<->KVM migration, or TCG guests which can + * do power management involving powering down and restarting + * the GIC. + */ + uint32_t apr[GIC_NR_APRS][GIC_NCPU]; + uint32_t num_cpu; MemoryRegion iomem; /* Distributor */ diff --git a/include/hw/net/allwinner_emac.h b/include/hw/net/allwinner_emac.h new file mode 100644 index 0000000000..a5e944af05 --- /dev/null +++ b/include/hw/net/allwinner_emac.h @@ -0,0 +1,210 @@ +/* + * Emulation of Allwinner EMAC Fast Ethernet controller and + * Realtek RTL8201CP PHY + * + * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com> + * + * Allwinner EMAC register definitions from Linux kernel are: + * Copyright 2012 Stefan Roese <sr@denx.de> + * Copyright 2013 Maxime Ripard <maxime.ripard@free-electrons.com> + * Copyright 1997 Sten Wang + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef AW_EMAC_H +#define AW_EMAC_H + +#include "net/net.h" +#include "qemu/fifo8.h" + +#define TYPE_AW_EMAC "allwinner-emac" +#define AW_EMAC(obj) OBJECT_CHECK(AwEmacState, (obj), TYPE_AW_EMAC) + +/* + * Allwinner EMAC register list + */ +#define EMAC_CTL_REG 0x00 + +#define EMAC_TX_MODE_REG 0x04 +#define EMAC_TX_FLOW_REG 0x08 +#define EMAC_TX_CTL0_REG 0x0C +#define EMAC_TX_CTL1_REG 0x10 +#define EMAC_TX_INS_REG 0x14 +#define EMAC_TX_PL0_REG 0x18 +#define EMAC_TX_PL1_REG 0x1C +#define EMAC_TX_STA_REG 0x20 +#define EMAC_TX_IO_DATA_REG 0x24 +#define EMAC_TX_IO_DATA1_REG 0x28 +#define EMAC_TX_TSVL0_REG 0x2C +#define EMAC_TX_TSVH0_REG 0x30 +#define EMAC_TX_TSVL1_REG 0x34 +#define EMAC_TX_TSVH1_REG 0x38 + +#define EMAC_RX_CTL_REG 0x3C +#define EMAC_RX_HASH0_REG 0x40 +#define EMAC_RX_HASH1_REG 0x44 +#define EMAC_RX_STA_REG 0x48 +#define EMAC_RX_IO_DATA_REG 0x4C +#define EMAC_RX_FBC_REG 0x50 + +#define EMAC_INT_CTL_REG 0x54 +#define EMAC_INT_STA_REG 0x58 + +#define EMAC_MAC_CTL0_REG 0x5C +#define EMAC_MAC_CTL1_REG 0x60 +#define EMAC_MAC_IPGT_REG 0x64 +#define EMAC_MAC_IPGR_REG 0x68 +#define EMAC_MAC_CLRT_REG 0x6C +#define EMAC_MAC_MAXF_REG 0x70 +#define EMAC_MAC_SUPP_REG 0x74 +#define EMAC_MAC_TEST_REG 0x78 +#define EMAC_MAC_MCFG_REG 0x7C +#define EMAC_MAC_MCMD_REG 0x80 +#define EMAC_MAC_MADR_REG 0x84 +#define EMAC_MAC_MWTD_REG 0x88 +#define EMAC_MAC_MRDD_REG 0x8C +#define EMAC_MAC_MIND_REG 0x90 +#define EMAC_MAC_SSRR_REG 0x94 +#define EMAC_MAC_A0_REG 0x98 +#define EMAC_MAC_A1_REG 0x9C +#define EMAC_MAC_A2_REG 0xA0 + +#define EMAC_SAFX_L_REG0 0xA4 +#define EMAC_SAFX_H_REG0 0xA8 +#define EMAC_SAFX_L_REG1 0xAC +#define EMAC_SAFX_H_REG1 0xB0 +#define EMAC_SAFX_L_REG2 0xB4 +#define EMAC_SAFX_H_REG2 0xB8 +#define EMAC_SAFX_L_REG3 0xBC +#define EMAC_SAFX_H_REG3 0xC0 + +/* CTL register fields */ +#define EMAC_CTL_RESET (1 << 0) +#define EMAC_CTL_TX_EN (1 << 1) +#define EMAC_CTL_RX_EN (1 << 2) + +/* TX MODE register fields */ +#define EMAC_TX_MODE_ABORTED_FRAME_EN (1 << 0) +#define EMAC_TX_MODE_DMA_EN (1 << 1) + +/* RX CTL register fields */ +#define EMAC_RX_CTL_AUTO_DRQ_EN (1 << 1) +#define EMAC_RX_CTL_DMA_EN (1 << 2) +#define EMAC_RX_CTL_PASS_ALL_EN (1 << 4) +#define EMAC_RX_CTL_PASS_CTL_EN (1 << 5) +#define EMAC_RX_CTL_PASS_CRC_ERR_EN (1 << 6) +#define EMAC_RX_CTL_PASS_LEN_ERR_EN (1 << 7) +#define EMAC_RX_CTL_PASS_LEN_OOR_EN (1 << 8) +#define EMAC_RX_CTL_ACCEPT_UNICAST_EN (1 << 16) +#define EMAC_RX_CTL_DA_FILTER_EN (1 << 17) +#define EMAC_RX_CTL_ACCEPT_MULTICAST_EN (1 << 20) +#define EMAC_RX_CTL_HASH_FILTER_EN (1 << 21) +#define EMAC_RX_CTL_ACCEPT_BROADCAST_EN (1 << 22) +#define EMAC_RX_CTL_SA_FILTER_EN (1 << 24) +#define EMAC_RX_CTL_SA_FILTER_INVERT_EN (1 << 25) + +/* RX IO DATA register fields */ +#define EMAC_RX_HEADER(len, status) (((len) & 0xffff) | ((status) << 16)) +#define EMAC_RX_IO_DATA_STATUS_CRC_ERR (1 << 4) +#define EMAC_RX_IO_DATA_STATUS_LEN_ERR (3 << 5) +#define EMAC_RX_IO_DATA_STATUS_OK (1 << 7) +#define EMAC_UNDOCUMENTED_MAGIC 0x0143414d /* header for RX frames */ + +/* PHY registers */ +#define MII_BMCR 0 +#define MII_BMSR 1 +#define MII_PHYID1 2 +#define MII_PHYID2 3 +#define MII_ANAR 4 +#define MII_ANLPAR 5 +#define MII_ANER 6 +#define MII_NSR 16 +#define MII_LBREMR 17 +#define MII_REC 18 +#define MII_SNRDR 19 +#define MII_TEST 25 + +/* PHY registers fields */ +#define MII_BMCR_RESET (1 << 15) +#define MII_BMCR_LOOPBACK (1 << 14) +#define MII_BMCR_SPEED (1 << 13) +#define MII_BMCR_AUTOEN (1 << 12) +#define MII_BMCR_FD (1 << 8) + +#define MII_BMSR_100TX_FD (1 << 14) +#define MII_BMSR_100TX_HD (1 << 13) +#define MII_BMSR_10T_FD (1 << 12) +#define MII_BMSR_10T_HD (1 << 11) +#define MII_BMSR_MFPS (1 << 6) +#define MII_BMSR_AUTONEG (1 << 3) +#define MII_BMSR_LINK_ST (1 << 2) + +#define MII_ANAR_TXFD (1 << 8) +#define MII_ANAR_TX (1 << 7) +#define MII_ANAR_10FD (1 << 6) +#define MII_ANAR_10 (1 << 5) +#define MII_ANAR_CSMACD (1 << 0) + +#define RTL8201CP_PHYID1 0x0000 +#define RTL8201CP_PHYID2 0x8201 + +/* INT CTL and INT STA registers fields */ +#define EMAC_INT_TX_CHAN(x) (1 << (x)) +#define EMAC_INT_RX (1 << 8) + +/* Due to lack of specifications, size of fifos is chosen arbitrarily */ +#define TX_FIFO_SIZE (4 * 1024) +#define RX_FIFO_SIZE (32 * 1024) + +#define NUM_TX_FIFOS 2 +#define RX_HDR_SIZE 8 +#define CRC_SIZE 4 + +#define PHY_REG_SHIFT 0 +#define PHY_ADDR_SHIFT 8 + +typedef struct RTL8201CPState { + uint16_t bmcr; + uint16_t bmsr; + uint16_t anar; + uint16_t anlpar; +} RTL8201CPState; + +typedef struct AwEmacState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + MemoryRegion iomem; + qemu_irq irq; + NICState *nic; + NICConf conf; + RTL8201CPState mii; + uint8_t phy_addr; + + uint32_t ctl; + uint32_t tx_mode; + uint32_t rx_ctl; + uint32_t int_ctl; + uint32_t int_sta; + uint32_t phy_target; + + Fifo8 rx_fifo; + uint32_t rx_num_packets; + uint32_t rx_packet_size; + uint32_t rx_packet_pos; + + Fifo8 tx_fifo[NUM_TX_FIFOS]; + uint32_t tx_length[NUM_TX_FIFOS]; + uint32_t tx_channel; +} AwEmacState; + +#endif diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index fbd16a03e6..ded8e2302f 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -656,9 +656,15 @@ extern const VMStateInfo vmstate_info_bitmap; #define VMSTATE_UINT32_ARRAY_V(_f, _s, _n, _v) \ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint32, uint32_t) +#define VMSTATE_UINT32_2DARRAY_V(_f, _s, _n1, _n2, _v) \ + VMSTATE_2DARRAY(_f, _s, _n1, _n2, _v, vmstate_info_uint32, uint32_t) + #define VMSTATE_UINT32_ARRAY(_f, _s, _n) \ VMSTATE_UINT32_ARRAY_V(_f, _s, _n, 0) +#define VMSTATE_UINT32_2DARRAY(_f, _s, _n1, _n2) \ + VMSTATE_UINT32_2DARRAY_V(_f, _s, _n1, _n2, 0) + #define VMSTATE_UINT64_ARRAY_V(_f, _s, _n, _v) \ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint64, uint64_t) diff --git a/include/qemu/fifo8.h b/include/qemu/fifo8.h index d318f71e11..8820780669 100644 --- a/include/qemu/fifo8.h +++ b/include/qemu/fifo8.h @@ -44,6 +44,19 @@ void fifo8_destroy(Fifo8 *fifo); void fifo8_push(Fifo8 *fifo, uint8_t data); /** + * fifo8_push_all: + * @fifo: FIFO to push to + * @data: data to push + * @size: number of bytes to push + * + * Push a byte array to the FIFO. Behaviour is undefined if the FIFO is full. + * Clients are responsible for checking the space left in the FIFO using + * fifo8_num_free(). + */ + +void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num); + +/** * fifo8_pop: * @fifo: fifo to pop from * @@ -56,6 +69,32 @@ void fifo8_push(Fifo8 *fifo, uint8_t data); uint8_t fifo8_pop(Fifo8 *fifo); /** + * fifo8_pop_buf: + * @fifo: FIFO to pop from + * @max: maximum number of bytes to pop + * @num: actual number of returned bytes + * + * Pop a number of elements from the FIFO up to a maximum of max. The buffer + * containing the popped data is returned. This buffer points directly into + * the FIFO backing store and data is invalidated once any of the fifo8_* APIs + * are called on the FIFO. + * + * The function may return fewer bytes than requested when the data wraps + * around in the ring buffer; in this case only a contiguous part of the data + * is returned. + * + * The number of valid bytes returned is populated in *num; will always return + * at least 1 byte. max must not be 0 or greater than the number of bytes in + * the FIFO. + * + * Clients are responsible for checking the availability of requested data + * using fifo8_num_used(). + * + * Returns: A pointer to popped data. + */ +const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *num); + +/** * fifo8_reset: * @fifo: FIFO to reset * @@ -86,6 +125,28 @@ bool fifo8_is_empty(Fifo8 *fifo); bool fifo8_is_full(Fifo8 *fifo); +/** + * fifo8_num_free: + * @fifo: FIFO to check + * + * Return the number of free bytes in the FIFO. + * + * Returns: Number of free bytes. + */ + +uint32_t fifo8_num_free(Fifo8 *fifo); + +/** + * fifo8_num_used: + * @fifo: FIFO to check + * + * Return the number of used bytes in the FIFO. + * + * Returns: Number of used bytes. + */ + +uint32_t fifo8_num_used(Fifo8 *fifo); + extern const VMStateDescription vmstate_fifo8; #define VMSTATE_FIFO8(_field, _state) { \ |