aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-02-11 11:26:36 +0000
committerPeter Maydell <peter.maydell@linaro.org>2014-02-11 11:26:36 +0000
commit8fa7574904793396694fa88834751a93bcdf4e10 (patch)
tree71655e2417ee088da62743f4a90da736cbce1e4f /include
parent702f6df9602a445103c55ac21af11c7aaedb9b34 (diff)
parent69991d7dcbcf7f3fe38274bc67fcba3cbbfda0cf (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.h1
-rw-r--r--include/hw/arm/allwinner-a10.h3
-rw-r--r--include/hw/intc/arm_gic_common.h33
-rw-r--r--include/hw/net/allwinner_emac.h210
-rw-r--r--include/migration/vmstate.h6
-rw-r--r--include/qemu/fifo8.h61
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) { \