* [Qemu-devel] [PATCH v2] target-arm: Extract some external ARM CPU API
@ 2015-10-26 7:46 Pavel Fedin
2015-10-26 16:39 ` Peter Crosthwaite
0 siblings, 1 reply; 10+ messages in thread
From: Pavel Fedin @ 2015-10-26 7:46 UTC (permalink / raw)
To: qemu-devel
Cc: 'Peter Maydell', 'Shlomo Pongratz',
'Shlomo Pongratz'
Includes, which reside in target-arm, are very problematic to use from code
which is considered target-independent by the build system (for example,
hw/intc/something.c). It happens because they depend on config-target.h,
which is unreachable in this case. This creates problems for example for
GICv3 implementation, which needs to call define_arm_cp_regs_with_opaque()
in order to add system registers to the processor model, as well as play
with affinity IDs.
This patch solves the problem by extracting some self-sufficient
definitions into public area (include/hw/cpu).
Signed-off-by: Pavel Fedin <p.fedin@samsung.com>
---
v1 => v2:
- mp-affinity property addition left out, now a pure code move
- Move some more useful definitions (REGINFO_SENTINEL) and NOP accessors.
---
include/hw/cpu/arm.h | 308 +++++++++++++++++++++++++++++++++++++++++++++++++++
target-arm/cpu-qom.h | 40 +------
target-arm/cpu.h | 239 +--------------------------------------
3 files changed, 311 insertions(+), 276 deletions(-)
create mode 100644 include/hw/cpu/arm.h
diff --git a/include/hw/cpu/arm.h b/include/hw/cpu/arm.h
new file mode 100644
index 0000000..de7bec7
--- /dev/null
+++ b/include/hw/cpu/arm.h
@@ -0,0 +1,308 @@
+/*
+ * QEMU ARM CPU
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ * Copyright (c) 2015 Samsung Electronics Co. Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
+ */
+
+#ifndef HW_CPU_ARM_H
+#define HW_CPU_ARM_H
+
+#include "qom/cpu.h"
+
+#define TYPE_ARM_CPU "arm-cpu"
+
+#define ARM_CPU_CLASS(klass) \
+ OBJECT_CLASS_CHECK(ARMCPUClass, (klass), TYPE_ARM_CPU)
+#define ARM_CPU(obj) \
+ OBJECT_CHECK(ARMCPU, (obj), TYPE_ARM_CPU)
+#define ARM_CPU_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(ARMCPUClass, (obj), TYPE_ARM_CPU)
+
+/**
+ * ARMCPUClass:
+ * @parent_realize: The parent class' realize handler.
+ * @parent_reset: The parent class' reset handler.
+ *
+ * An ARM CPU model.
+ */
+typedef struct ARMCPUClass {
+ /*< private >*/
+ CPUClass parent_class;
+ /*< public >*/
+
+ DeviceRealize parent_realize;
+ void (*parent_reset)(CPUState *cpu);
+} ARMCPUClass;
+
+/* These two are black boxes for us */
+typedef struct ARMCPU ARMCPU;
+typedef struct CPUARMState CPUARMState;
+
+/* ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
+ * special-behaviour cp reg and bits [15..8] indicate what behaviour
+ * it has. Otherwise it is a simple cp reg, where CONST indicates that
+ * TCG can assume the value to be constant (ie load at translate time)
+ * and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END
+ * indicates that the TB should not be ended after a write to this register
+ * (the default is that the TB ends after cp writes). OVERRIDE permits
+ * a register definition to override a previous definition for the
+ * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the
+ * old must have the OVERRIDE bit set.
+ * ALIAS indicates that this register is an alias view of some underlying
+ * state which is also visible via another register, and that the other
+ * register is handling migration and reset; registers marked ALIAS will not be
+ * migrated but may have their state set by syncing of register state from KVM.
+ * NO_RAW indicates that this register has no underlying state and does not
+ * support raw access for state saving/loading; it will not be used for either
+ * migration or KVM state synchronization. (Typically this is for "registers"
+ * which are actually used as instructions for cache maintenance and so on.)
+ * IO indicates that this register does I/O and therefore its accesses
+ * need to be surrounded by gen_io_start()/gen_io_end(). In particular,
+ * registers which implement clocks or timers require this.
+ */
+#define ARM_CP_SPECIAL 1
+#define ARM_CP_CONST 2
+#define ARM_CP_64BIT 4
+#define ARM_CP_SUPPRESS_TB_END 8
+#define ARM_CP_OVERRIDE 16
+#define ARM_CP_ALIAS 32
+#define ARM_CP_IO 64
+#define ARM_CP_NO_RAW 128
+#define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8))
+#define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8))
+#define ARM_CP_NZCV (ARM_CP_SPECIAL | (3 << 8))
+#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8))
+#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | (5 << 8))
+#define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
+/* Used only as a terminator for ARMCPRegInfo lists */
+#define ARM_CP_SENTINEL 0xffff
+/* Mask of only the flag bits in a type field */
+#define ARM_CP_FLAG_MASK 0xff
+
+/* Valid values for ARMCPRegInfo state field, indicating which of
+ * the AArch32 and AArch64 execution states this register is visible in.
+ * If the reginfo doesn't explicitly specify then it is AArch32 only.
+ * If the reginfo is declared to be visible in both states then a second
+ * reginfo is synthesised for the AArch32 view of the AArch64 register,
+ * such that the AArch32 view is the lower 32 bits of the AArch64 one.
+ * Note that we rely on the values of these enums as we iterate through
+ * the various states in some places.
+ */
+enum {
+ ARM_CP_STATE_AA32 = 0,
+ ARM_CP_STATE_AA64 = 1,
+ ARM_CP_STATE_BOTH = 2,
+};
+
+/* ARM CP register secure state flags. These flags identify security state
+ * attributes for a given CP register entry.
+ * The existence of both or neither secure and non-secure flags indicates that
+ * the register has both a secure and non-secure hash entry. A single one of
+ * these flags causes the register to only be hashed for the specified
+ * security state.
+ * Although definitions may have any combination of the S/NS bits, each
+ * registered entry will only have one to identify whether the entry is secure
+ * or non-secure.
+ */
+enum {
+ ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */
+ ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
+};
+
+typedef struct ARMCPRegInfo ARMCPRegInfo;
+
+typedef enum CPAccessResult {
+ /* Access is permitted */
+ CP_ACCESS_OK = 0,
+ /* Access fails due to a configurable trap or enable which would
+ * result in a categorized exception syndrome giving information about
+ * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
+ * 0xc or 0x18). The exception is taken to the usual target EL (EL1 or
+ * PL1 if in EL0, otherwise to the current EL).
+ */
+ CP_ACCESS_TRAP = 1,
+ /* Access fails and results in an exception syndrome 0x0 ("uncategorized").
+ * Note that this is not a catch-all case -- the set of cases which may
+ * result in this failure is specifically defined by the architecture.
+ */
+ CP_ACCESS_TRAP_UNCATEGORIZED = 2,
+ /* As CP_ACCESS_TRAP, but for traps directly to EL2 or EL3 */
+ CP_ACCESS_TRAP_EL2 = 3,
+ CP_ACCESS_TRAP_EL3 = 4,
+ /* As CP_ACCESS_UNCATEGORIZED, but for traps directly to EL2 or EL3 */
+ CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = 5,
+ CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = 6,
+} CPAccessResult;
+
+/* Access functions for coprocessor registers. These cannot fail and
+ * may not raise exceptions.
+ */
+typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque);
+typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
+ uint64_t value);
+/* Access permission check functions for coprocessor registers. */
+typedef CPAccessResult CPAccessFn(CPUARMState *env, const ARMCPRegInfo *opaque);
+/* Hook function for register reset */
+typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
+
+#define CP_ANY 0xff
+
+/* Definition of an ARM coprocessor register */
+struct ARMCPRegInfo {
+ /* Name of register (useful mainly for debugging, need not be unique) */
+ const char *name;
+ /* Location of register: coprocessor number and (crn,crm,opc1,opc2)
+ * tuple. Any of crm, opc1 and opc2 may be CP_ANY to indicate a
+ * 'wildcard' field -- any value of that field in the MRC/MCR insn
+ * will be decoded to this register. The register read and write
+ * callbacks will be passed an ARMCPRegInfo with the crn/crm/opc1/opc2
+ * used by the program, so it is possible to register a wildcard and
+ * then behave differently on read/write if necessary.
+ * For 64 bit registers, only crm and opc1 are relevant; crn and opc2
+ * must both be zero.
+ * For AArch64-visible registers, opc0 is also used.
+ * Since there are no "coprocessors" in AArch64, cp is purely used as a
+ * way to distinguish (for KVM's benefit) guest-visible system registers
+ * from demuxed ones provided to preserve the "no side effects on
+ * KVM register read/write from QEMU" semantics. cp==0x13 is guest
+ * visible (to match KVM's encoding); cp==0 will be converted to
+ * cp==0x13 when the ARMCPRegInfo is registered, for convenience.
+ */
+ uint8_t cp;
+ uint8_t crn;
+ uint8_t crm;
+ uint8_t opc0;
+ uint8_t opc1;
+ uint8_t opc2;
+ /* Execution state in which this register is visible: ARM_CP_STATE_* */
+ int state;
+ /* Register type: ARM_CP_* bits/values */
+ int type;
+ /* Access rights: PL*_[RW] */
+ int access;
+ /* Security state: ARM_CP_SECSTATE_* bits/values */
+ int secure;
+ /* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
+ * this register was defined: can be used to hand data through to the
+ * register read/write functions, since they are passed the ARMCPRegInfo*.
+ */
+ void *opaque;
+ /* Value of this register, if it is ARM_CP_CONST. Otherwise, if
+ * fieldoffset is non-zero, the reset value of the register.
+ */
+ uint64_t resetvalue;
+ /* Offset of the field in CPUARMState for this register.
+ *
+ * This is not needed if either:
+ * 1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs
+ * 2. both readfn and writefn are specified
+ */
+ ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
+
+ /* Offsets of the secure and non-secure fields in CPUARMState for the
+ * register if it is banked. These fields are only used during the static
+ * registration of a register. During hashing the bank associated
+ * with a given security state is copied to fieldoffset which is used from
+ * there on out.
+ *
+ * It is expected that register definitions use either fieldoffset or
+ * bank_fieldoffsets in the definition but not both. It is also expected
+ * that both bank offsets are set when defining a banked register. This
+ * use indicates that a register is banked.
+ */
+ ptrdiff_t bank_fieldoffsets[2];
+
+ /* Function for making any access checks for this register in addition to
+ * those specified by the 'access' permissions bits. If NULL, no extra
+ * checks required. The access check is performed at runtime, not at
+ * translate time.
+ */
+ CPAccessFn *accessfn;
+ /* Function for handling reads of this register. If NULL, then reads
+ * will be done by loading from the offset into CPUARMState specified
+ * by fieldoffset.
+ */
+ CPReadFn *readfn;
+ /* Function for handling writes of this register. If NULL, then writes
+ * will be done by writing to the offset into CPUARMState specified
+ * by fieldoffset.
+ */
+ CPWriteFn *writefn;
+ /* Function for doing a "raw" read; used when we need to copy
+ * coprocessor state to the kernel for KVM or out for
+ * migration. This only needs to be provided if there is also a
+ * readfn and it has side effects (for instance clear-on-read bits).
+ */
+ CPReadFn *raw_readfn;
+ /* Function for doing a "raw" write; used when we need to copy KVM
+ * kernel coprocessor state into userspace, or for inbound
+ * migration. This only needs to be provided if there is also a
+ * writefn and it masks out "unwritable" bits or has write-one-to-clear
+ * or similar behaviour.
+ */
+ CPWriteFn *raw_writefn;
+ /* Function for resetting the register. If NULL, then reset will be done
+ * by writing resetvalue to the field specified in fieldoffset. If
+ * fieldoffset is 0 then no reset will be done.
+ */
+ CPResetFn *resetfn;
+};
+
+#define REGINFO_SENTINEL { .type = ARM_CP_SENTINEL }
+
+void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
+ const ARMCPRegInfo *regs, void *opaque);
+void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
+ const ARMCPRegInfo *regs, void *opaque);
+static inline void define_arm_cp_regs(ARMCPU *cpu, const ARMCPRegInfo *regs)
+{
+ define_arm_cp_regs_with_opaque(cpu, regs, NULL);
+}
+static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
+{
+ define_one_arm_cp_reg_with_opaque(cpu, regs, NULL);
+}
+
+/* CPWriteFn that can be used to implement writes-ignored behaviour */
+void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value);
+/* CPReadFn that can be used for read-as-zero behaviour */
+uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri);
+
+/* CPResetFn that does nothing, for use if no reset is required even
+ * if fieldoffset is non zero.
+ */
+void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque);
+
+/* Affinity ID composition */
+
+#define ARM_AFF0_SHIFT 0
+#define ARM_AFF0_MASK (0xFFULL << ARM_AFF0_SHIFT)
+#define ARM_AFF1_SHIFT 8
+#define ARM_AFF1_MASK (0xFFULL << ARM_AFF1_SHIFT)
+#define ARM_AFF2_SHIFT 16
+#define ARM_AFF2_MASK (0xFFULL << ARM_AFF2_SHIFT)
+#define ARM_AFF3_SHIFT 32
+#define ARM_AFF3_MASK (0xFFULL << ARM_AFF3_SHIFT)
+
+#define ARM32_AFFINITY_MASK (ARM_AFF0_MASK|ARM_AFF1_MASK|ARM_AFF2_MASK)
+#define ARM64_AFFINITY_MASK \
+ (ARM_AFF0_MASK|ARM_AFF1_MASK|ARM_AFF2_MASK|ARM_AFF3_MASK)
+
+#endif
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index 25fb1ce..38e0b94 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -20,32 +20,7 @@
#ifndef QEMU_ARM_CPU_QOM_H
#define QEMU_ARM_CPU_QOM_H
-#include "qom/cpu.h"
-
-#define TYPE_ARM_CPU "arm-cpu"
-
-#define ARM_CPU_CLASS(klass) \
- OBJECT_CLASS_CHECK(ARMCPUClass, (klass), TYPE_ARM_CPU)
-#define ARM_CPU(obj) \
- OBJECT_CHECK(ARMCPU, (obj), TYPE_ARM_CPU)
-#define ARM_CPU_GET_CLASS(obj) \
- OBJECT_GET_CLASS(ARMCPUClass, (obj), TYPE_ARM_CPU)
-
-/**
- * ARMCPUClass:
- * @parent_realize: The parent class' realize handler.
- * @parent_reset: The parent class' reset handler.
- *
- * An ARM CPU model.
- */
-typedef struct ARMCPUClass {
- /*< private >*/
- CPUClass parent_class;
- /*< public >*/
-
- DeviceRealize parent_realize;
- void (*parent_reset)(CPUState *cpu);
-} ARMCPUClass;
+#include "hw/cpu/arm.h"
/**
* ARMCPU:
@@ -227,19 +202,6 @@ void arm_gt_vtimer_cb(void *opaque);
void arm_gt_htimer_cb(void *opaque);
void arm_gt_stimer_cb(void *opaque);
-#define ARM_AFF0_SHIFT 0
-#define ARM_AFF0_MASK (0xFFULL << ARM_AFF0_SHIFT)
-#define ARM_AFF1_SHIFT 8
-#define ARM_AFF1_MASK (0xFFULL << ARM_AFF1_SHIFT)
-#define ARM_AFF2_SHIFT 16
-#define ARM_AFF2_MASK (0xFFULL << ARM_AFF2_SHIFT)
-#define ARM_AFF3_SHIFT 32
-#define ARM_AFF3_MASK (0xFFULL << ARM_AFF3_SHIFT)
-
-#define ARM32_AFFINITY_MASK (ARM_AFF0_MASK|ARM_AFF1_MASK|ARM_AFF2_MASK)
-#define ARM64_AFFINITY_MASK \
- (ARM_AFF0_MASK|ARM_AFF1_MASK|ARM_AFF2_MASK|ARM_AFF3_MASK)
-
#ifdef TARGET_AARCH64
int aarch64_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 35339aa..bef2322 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -123,7 +123,7 @@ typedef struct {
uint32_t base_mask;
} TCR;
-typedef struct CPUARMState {
+struct CPUARMState {
/* Regs for current mode. */
uint32_t regs[16];
@@ -507,7 +507,7 @@ typedef struct CPUARMState {
*/
DeviceState *irqchip;
const struct arm_boot_info *boot_info;
-} CPUARMState;
+};
#include "cpu-qom.h"
@@ -1138,77 +1138,6 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
return kvmid;
}
-/* ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
- * special-behaviour cp reg and bits [15..8] indicate what behaviour
- * it has. Otherwise it is a simple cp reg, where CONST indicates that
- * TCG can assume the value to be constant (ie load at translate time)
- * and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END
- * indicates that the TB should not be ended after a write to this register
- * (the default is that the TB ends after cp writes). OVERRIDE permits
- * a register definition to override a previous definition for the
- * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the
- * old must have the OVERRIDE bit set.
- * ALIAS indicates that this register is an alias view of some underlying
- * state which is also visible via another register, and that the other
- * register is handling migration and reset; registers marked ALIAS will not be
- * migrated but may have their state set by syncing of register state from KVM.
- * NO_RAW indicates that this register has no underlying state and does not
- * support raw access for state saving/loading; it will not be used for either
- * migration or KVM state synchronization. (Typically this is for "registers"
- * which are actually used as instructions for cache maintenance and so on.)
- * IO indicates that this register does I/O and therefore its accesses
- * need to be surrounded by gen_io_start()/gen_io_end(). In particular,
- * registers which implement clocks or timers require this.
- */
-#define ARM_CP_SPECIAL 1
-#define ARM_CP_CONST 2
-#define ARM_CP_64BIT 4
-#define ARM_CP_SUPPRESS_TB_END 8
-#define ARM_CP_OVERRIDE 16
-#define ARM_CP_ALIAS 32
-#define ARM_CP_IO 64
-#define ARM_CP_NO_RAW 128
-#define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8))
-#define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8))
-#define ARM_CP_NZCV (ARM_CP_SPECIAL | (3 << 8))
-#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8))
-#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | (5 << 8))
-#define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
-/* Used only as a terminator for ARMCPRegInfo lists */
-#define ARM_CP_SENTINEL 0xffff
-/* Mask of only the flag bits in a type field */
-#define ARM_CP_FLAG_MASK 0xff
-
-/* Valid values for ARMCPRegInfo state field, indicating which of
- * the AArch32 and AArch64 execution states this register is visible in.
- * If the reginfo doesn't explicitly specify then it is AArch32 only.
- * If the reginfo is declared to be visible in both states then a second
- * reginfo is synthesised for the AArch32 view of the AArch64 register,
- * such that the AArch32 view is the lower 32 bits of the AArch64 one.
- * Note that we rely on the values of these enums as we iterate through
- * the various states in some places.
- */
-enum {
- ARM_CP_STATE_AA32 = 0,
- ARM_CP_STATE_AA64 = 1,
- ARM_CP_STATE_BOTH = 2,
-};
-
-/* ARM CP register secure state flags. These flags identify security state
- * attributes for a given CP register entry.
- * The existence of both or neither secure and non-secure flags indicates that
- * the register has both a secure and non-secure hash entry. A single one of
- * these flags causes the register to only be hashed for the specified
- * security state.
- * Although definitions may have any combination of the S/NS bits, each
- * registered entry will only have one to identify whether the entry is secure
- * or non-secure.
- */
-enum {
- ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */
- ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
-};
-
/* Return true if cptype is a valid type field. This is used to try to
* catch errors where the sentinel has been accidentally left off the end
* of a list of registers.
@@ -1283,145 +1212,6 @@ static inline int arm_current_el(CPUARMState *env)
}
}
-typedef struct ARMCPRegInfo ARMCPRegInfo;
-
-typedef enum CPAccessResult {
- /* Access is permitted */
- CP_ACCESS_OK = 0,
- /* Access fails due to a configurable trap or enable which would
- * result in a categorized exception syndrome giving information about
- * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
- * 0xc or 0x18). The exception is taken to the usual target EL (EL1 or
- * PL1 if in EL0, otherwise to the current EL).
- */
- CP_ACCESS_TRAP = 1,
- /* Access fails and results in an exception syndrome 0x0 ("uncategorized").
- * Note that this is not a catch-all case -- the set of cases which may
- * result in this failure is specifically defined by the architecture.
- */
- CP_ACCESS_TRAP_UNCATEGORIZED = 2,
- /* As CP_ACCESS_TRAP, but for traps directly to EL2 or EL3 */
- CP_ACCESS_TRAP_EL2 = 3,
- CP_ACCESS_TRAP_EL3 = 4,
- /* As CP_ACCESS_UNCATEGORIZED, but for traps directly to EL2 or EL3 */
- CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = 5,
- CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = 6,
-} CPAccessResult;
-
-/* Access functions for coprocessor registers. These cannot fail and
- * may not raise exceptions.
- */
-typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque);
-typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
- uint64_t value);
-/* Access permission check functions for coprocessor registers. */
-typedef CPAccessResult CPAccessFn(CPUARMState *env, const ARMCPRegInfo *opaque);
-/* Hook function for register reset */
-typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
-
-#define CP_ANY 0xff
-
-/* Definition of an ARM coprocessor register */
-struct ARMCPRegInfo {
- /* Name of register (useful mainly for debugging, need not be unique) */
- const char *name;
- /* Location of register: coprocessor number and (crn,crm,opc1,opc2)
- * tuple. Any of crm, opc1 and opc2 may be CP_ANY to indicate a
- * 'wildcard' field -- any value of that field in the MRC/MCR insn
- * will be decoded to this register. The register read and write
- * callbacks will be passed an ARMCPRegInfo with the crn/crm/opc1/opc2
- * used by the program, so it is possible to register a wildcard and
- * then behave differently on read/write if necessary.
- * For 64 bit registers, only crm and opc1 are relevant; crn and opc2
- * must both be zero.
- * For AArch64-visible registers, opc0 is also used.
- * Since there are no "coprocessors" in AArch64, cp is purely used as a
- * way to distinguish (for KVM's benefit) guest-visible system registers
- * from demuxed ones provided to preserve the "no side effects on
- * KVM register read/write from QEMU" semantics. cp==0x13 is guest
- * visible (to match KVM's encoding); cp==0 will be converted to
- * cp==0x13 when the ARMCPRegInfo is registered, for convenience.
- */
- uint8_t cp;
- uint8_t crn;
- uint8_t crm;
- uint8_t opc0;
- uint8_t opc1;
- uint8_t opc2;
- /* Execution state in which this register is visible: ARM_CP_STATE_* */
- int state;
- /* Register type: ARM_CP_* bits/values */
- int type;
- /* Access rights: PL*_[RW] */
- int access;
- /* Security state: ARM_CP_SECSTATE_* bits/values */
- int secure;
- /* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
- * this register was defined: can be used to hand data through to the
- * register read/write functions, since they are passed the ARMCPRegInfo*.
- */
- void *opaque;
- /* Value of this register, if it is ARM_CP_CONST. Otherwise, if
- * fieldoffset is non-zero, the reset value of the register.
- */
- uint64_t resetvalue;
- /* Offset of the field in CPUARMState for this register.
- *
- * This is not needed if either:
- * 1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs
- * 2. both readfn and writefn are specified
- */
- ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
-
- /* Offsets of the secure and non-secure fields in CPUARMState for the
- * register if it is banked. These fields are only used during the static
- * registration of a register. During hashing the bank associated
- * with a given security state is copied to fieldoffset which is used from
- * there on out.
- *
- * It is expected that register definitions use either fieldoffset or
- * bank_fieldoffsets in the definition but not both. It is also expected
- * that both bank offsets are set when defining a banked register. This
- * use indicates that a register is banked.
- */
- ptrdiff_t bank_fieldoffsets[2];
-
- /* Function for making any access checks for this register in addition to
- * those specified by the 'access' permissions bits. If NULL, no extra
- * checks required. The access check is performed at runtime, not at
- * translate time.
- */
- CPAccessFn *accessfn;
- /* Function for handling reads of this register. If NULL, then reads
- * will be done by loading from the offset into CPUARMState specified
- * by fieldoffset.
- */
- CPReadFn *readfn;
- /* Function for handling writes of this register. If NULL, then writes
- * will be done by writing to the offset into CPUARMState specified
- * by fieldoffset.
- */
- CPWriteFn *writefn;
- /* Function for doing a "raw" read; used when we need to copy
- * coprocessor state to the kernel for KVM or out for
- * migration. This only needs to be provided if there is also a
- * readfn and it has side effects (for instance clear-on-read bits).
- */
- CPReadFn *raw_readfn;
- /* Function for doing a "raw" write; used when we need to copy KVM
- * kernel coprocessor state into userspace, or for inbound
- * migration. This only needs to be provided if there is also a
- * writefn and it masks out "unwritable" bits or has write-one-to-clear
- * or similar behaviour.
- */
- CPWriteFn *raw_writefn;
- /* Function for resetting the register. If NULL, then reset will be done
- * by writing resetvalue to the field specified in fieldoffset. If
- * fieldoffset is 0 then no reset will be done.
- */
- CPResetFn *resetfn;
-};
-
/* Macros which are lvalues for the field in CPUARMState for the
* ARMCPRegInfo *ri.
*/
@@ -1430,33 +1220,8 @@ struct ARMCPRegInfo {
#define CPREG_FIELD64(env, ri) \
(*(uint64_t *)((char *)(env) + (ri)->fieldoffset))
-#define REGINFO_SENTINEL { .type = ARM_CP_SENTINEL }
-
-void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
- const ARMCPRegInfo *regs, void *opaque);
-void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
- const ARMCPRegInfo *regs, void *opaque);
-static inline void define_arm_cp_regs(ARMCPU *cpu, const ARMCPRegInfo *regs)
-{
- define_arm_cp_regs_with_opaque(cpu, regs, 0);
-}
-static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
-{
- define_one_arm_cp_reg_with_opaque(cpu, regs, 0);
-}
const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp);
-/* CPWriteFn that can be used to implement writes-ignored behaviour */
-void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value);
-/* CPReadFn that can be used for read-as-zero behaviour */
-uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri);
-
-/* CPResetFn that does nothing, for use if no reset is required even
- * if fieldoffset is non zero.
- */
-void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque);
-
/* Return true if this reginfo struct's field in the cpu state struct
* is 64 bits wide.
*/
--
1.9.5.msysgit.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH v2] target-arm: Extract some external ARM CPU API
2015-10-26 7:46 [Qemu-devel] [PATCH v2] target-arm: Extract some external ARM CPU API Pavel Fedin
@ 2015-10-26 16:39 ` Peter Crosthwaite
2015-10-27 12:02 ` Pavel Fedin
2015-10-27 12:03 ` Pavel Fedin
0 siblings, 2 replies; 10+ messages in thread
From: Peter Crosthwaite @ 2015-10-26 16:39 UTC (permalink / raw)
To: Pavel Fedin
Cc: Peter Maydell, Shlomo Pongratz, qemu-devel@nongnu.org Developers,
Shlomo Pongratz
On Mon, Oct 26, 2015 at 12:46 AM, Pavel Fedin <p.fedin@samsung.com> wrote:
> Includes, which reside in target-arm, are very problematic to use from code
> which is considered target-independent by the build system (for example,
> hw/intc/something.c). It happens because they depend on config-target.h,
> which is unreachable in this case. This creates problems for example for
> GICv3 implementation, which needs to call define_arm_cp_regs_with_opaque()
> in order to add system registers to the processor model, as well as play
> with affinity IDs.
>
> This patch solves the problem by extracting some self-sufficient
> definitions into public area (include/hw/cpu).
>
So this conflicts with multi-arch, which takes the approach of leaving
the includes in target-* and instead modifying them there in a way
that lets you include cpu.h from device land to get a minimal with
this kind of stuff.
We have plenty of precedent in tree for interrupt controllers being
compiled as arch-specific for reasons such as this. Can we just
promote GIC to an obj-y (much the same way the KVM GIC or V7MNVIC are
promoted)? You should them have access to cpu.h and the CP interface.
> Signed-off-by: Pavel Fedin <p.fedin@samsung.com>
> ---
> v1 => v2:
> - mp-affinity property addition left out, now a pure code move
> - Move some more useful definitions (REGINFO_SENTINEL) and NOP accessors.
> ---
> include/hw/cpu/arm.h | 308 +++++++++++++++++++++++++++++++++++++++++++++++++++
I think this would be hw/arm/cpu.h
Regards,
Peter
> target-arm/cpu-qom.h | 40 +------
> target-arm/cpu.h | 239 +--------------------------------------
> 3 files changed, 311 insertions(+), 276 deletions(-)
> create mode 100644 include/hw/cpu/arm.h
>
> diff --git a/include/hw/cpu/arm.h b/include/hw/cpu/arm.h
> new file mode 100644
> index 0000000..de7bec7
> --- /dev/null
> +++ b/include/hw/cpu/arm.h
> @@ -0,0 +1,308 @@
> +/*
> + * QEMU ARM CPU
> + *
> + * Copyright (c) 2003 Fabrice Bellard
> + * Copyright (c) 2012 SUSE LINUX Products GmbH
> + * Copyright (c) 2015 Samsung Electronics Co. Ltd.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, see
> + * <http://www.gnu.org/licenses/gpl-2.0.html>
> + */
> +
> +#ifndef HW_CPU_ARM_H
> +#define HW_CPU_ARM_H
> +
> +#include "qom/cpu.h"
> +
> +#define TYPE_ARM_CPU "arm-cpu"
> +
> +#define ARM_CPU_CLASS(klass) \
> + OBJECT_CLASS_CHECK(ARMCPUClass, (klass), TYPE_ARM_CPU)
> +#define ARM_CPU(obj) \
> + OBJECT_CHECK(ARMCPU, (obj), TYPE_ARM_CPU)
> +#define ARM_CPU_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(ARMCPUClass, (obj), TYPE_ARM_CPU)
> +
> +/**
> + * ARMCPUClass:
> + * @parent_realize: The parent class' realize handler.
> + * @parent_reset: The parent class' reset handler.
> + *
> + * An ARM CPU model.
> + */
> +typedef struct ARMCPUClass {
> + /*< private >*/
> + CPUClass parent_class;
> + /*< public >*/
> +
> + DeviceRealize parent_realize;
> + void (*parent_reset)(CPUState *cpu);
> +} ARMCPUClass;
> +
> +/* These two are black boxes for us */
> +typedef struct ARMCPU ARMCPU;
> +typedef struct CPUARMState CPUARMState;
> +
> +/* ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
> + * special-behaviour cp reg and bits [15..8] indicate what behaviour
> + * it has. Otherwise it is a simple cp reg, where CONST indicates that
> + * TCG can assume the value to be constant (ie load at translate time)
> + * and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END
> + * indicates that the TB should not be ended after a write to this register
> + * (the default is that the TB ends after cp writes). OVERRIDE permits
> + * a register definition to override a previous definition for the
> + * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the
> + * old must have the OVERRIDE bit set.
> + * ALIAS indicates that this register is an alias view of some underlying
> + * state which is also visible via another register, and that the other
> + * register is handling migration and reset; registers marked ALIAS will not be
> + * migrated but may have their state set by syncing of register state from KVM.
> + * NO_RAW indicates that this register has no underlying state and does not
> + * support raw access for state saving/loading; it will not be used for either
> + * migration or KVM state synchronization. (Typically this is for "registers"
> + * which are actually used as instructions for cache maintenance and so on.)
> + * IO indicates that this register does I/O and therefore its accesses
> + * need to be surrounded by gen_io_start()/gen_io_end(). In particular,
> + * registers which implement clocks or timers require this.
> + */
> +#define ARM_CP_SPECIAL 1
> +#define ARM_CP_CONST 2
> +#define ARM_CP_64BIT 4
> +#define ARM_CP_SUPPRESS_TB_END 8
> +#define ARM_CP_OVERRIDE 16
> +#define ARM_CP_ALIAS 32
> +#define ARM_CP_IO 64
> +#define ARM_CP_NO_RAW 128
> +#define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8))
> +#define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8))
> +#define ARM_CP_NZCV (ARM_CP_SPECIAL | (3 << 8))
> +#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8))
> +#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | (5 << 8))
> +#define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
> +/* Used only as a terminator for ARMCPRegInfo lists */
> +#define ARM_CP_SENTINEL 0xffff
> +/* Mask of only the flag bits in a type field */
> +#define ARM_CP_FLAG_MASK 0xff
> +
> +/* Valid values for ARMCPRegInfo state field, indicating which of
> + * the AArch32 and AArch64 execution states this register is visible in.
> + * If the reginfo doesn't explicitly specify then it is AArch32 only.
> + * If the reginfo is declared to be visible in both states then a second
> + * reginfo is synthesised for the AArch32 view of the AArch64 register,
> + * such that the AArch32 view is the lower 32 bits of the AArch64 one.
> + * Note that we rely on the values of these enums as we iterate through
> + * the various states in some places.
> + */
> +enum {
> + ARM_CP_STATE_AA32 = 0,
> + ARM_CP_STATE_AA64 = 1,
> + ARM_CP_STATE_BOTH = 2,
> +};
> +
> +/* ARM CP register secure state flags. These flags identify security state
> + * attributes for a given CP register entry.
> + * The existence of both or neither secure and non-secure flags indicates that
> + * the register has both a secure and non-secure hash entry. A single one of
> + * these flags causes the register to only be hashed for the specified
> + * security state.
> + * Although definitions may have any combination of the S/NS bits, each
> + * registered entry will only have one to identify whether the entry is secure
> + * or non-secure.
> + */
> +enum {
> + ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */
> + ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
> +};
> +
> +typedef struct ARMCPRegInfo ARMCPRegInfo;
> +
> +typedef enum CPAccessResult {
> + /* Access is permitted */
> + CP_ACCESS_OK = 0,
> + /* Access fails due to a configurable trap or enable which would
> + * result in a categorized exception syndrome giving information about
> + * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
> + * 0xc or 0x18). The exception is taken to the usual target EL (EL1 or
> + * PL1 if in EL0, otherwise to the current EL).
> + */
> + CP_ACCESS_TRAP = 1,
> + /* Access fails and results in an exception syndrome 0x0 ("uncategorized").
> + * Note that this is not a catch-all case -- the set of cases which may
> + * result in this failure is specifically defined by the architecture.
> + */
> + CP_ACCESS_TRAP_UNCATEGORIZED = 2,
> + /* As CP_ACCESS_TRAP, but for traps directly to EL2 or EL3 */
> + CP_ACCESS_TRAP_EL2 = 3,
> + CP_ACCESS_TRAP_EL3 = 4,
> + /* As CP_ACCESS_UNCATEGORIZED, but for traps directly to EL2 or EL3 */
> + CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = 5,
> + CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = 6,
> +} CPAccessResult;
> +
> +/* Access functions for coprocessor registers. These cannot fail and
> + * may not raise exceptions.
> + */
> +typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque);
> +typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
> + uint64_t value);
> +/* Access permission check functions for coprocessor registers. */
> +typedef CPAccessResult CPAccessFn(CPUARMState *env, const ARMCPRegInfo *opaque);
> +/* Hook function for register reset */
> +typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
> +
> +#define CP_ANY 0xff
> +
> +/* Definition of an ARM coprocessor register */
> +struct ARMCPRegInfo {
> + /* Name of register (useful mainly for debugging, need not be unique) */
> + const char *name;
> + /* Location of register: coprocessor number and (crn,crm,opc1,opc2)
> + * tuple. Any of crm, opc1 and opc2 may be CP_ANY to indicate a
> + * 'wildcard' field -- any value of that field in the MRC/MCR insn
> + * will be decoded to this register. The register read and write
> + * callbacks will be passed an ARMCPRegInfo with the crn/crm/opc1/opc2
> + * used by the program, so it is possible to register a wildcard and
> + * then behave differently on read/write if necessary.
> + * For 64 bit registers, only crm and opc1 are relevant; crn and opc2
> + * must both be zero.
> + * For AArch64-visible registers, opc0 is also used.
> + * Since there are no "coprocessors" in AArch64, cp is purely used as a
> + * way to distinguish (for KVM's benefit) guest-visible system registers
> + * from demuxed ones provided to preserve the "no side effects on
> + * KVM register read/write from QEMU" semantics. cp==0x13 is guest
> + * visible (to match KVM's encoding); cp==0 will be converted to
> + * cp==0x13 when the ARMCPRegInfo is registered, for convenience.
> + */
> + uint8_t cp;
> + uint8_t crn;
> + uint8_t crm;
> + uint8_t opc0;
> + uint8_t opc1;
> + uint8_t opc2;
> + /* Execution state in which this register is visible: ARM_CP_STATE_* */
> + int state;
> + /* Register type: ARM_CP_* bits/values */
> + int type;
> + /* Access rights: PL*_[RW] */
> + int access;
> + /* Security state: ARM_CP_SECSTATE_* bits/values */
> + int secure;
> + /* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
> + * this register was defined: can be used to hand data through to the
> + * register read/write functions, since they are passed the ARMCPRegInfo*.
> + */
> + void *opaque;
> + /* Value of this register, if it is ARM_CP_CONST. Otherwise, if
> + * fieldoffset is non-zero, the reset value of the register.
> + */
> + uint64_t resetvalue;
> + /* Offset of the field in CPUARMState for this register.
> + *
> + * This is not needed if either:
> + * 1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs
> + * 2. both readfn and writefn are specified
> + */
> + ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
> +
> + /* Offsets of the secure and non-secure fields in CPUARMState for the
> + * register if it is banked. These fields are only used during the static
> + * registration of a register. During hashing the bank associated
> + * with a given security state is copied to fieldoffset which is used from
> + * there on out.
> + *
> + * It is expected that register definitions use either fieldoffset or
> + * bank_fieldoffsets in the definition but not both. It is also expected
> + * that both bank offsets are set when defining a banked register. This
> + * use indicates that a register is banked.
> + */
> + ptrdiff_t bank_fieldoffsets[2];
> +
> + /* Function for making any access checks for this register in addition to
> + * those specified by the 'access' permissions bits. If NULL, no extra
> + * checks required. The access check is performed at runtime, not at
> + * translate time.
> + */
> + CPAccessFn *accessfn;
> + /* Function for handling reads of this register. If NULL, then reads
> + * will be done by loading from the offset into CPUARMState specified
> + * by fieldoffset.
> + */
> + CPReadFn *readfn;
> + /* Function for handling writes of this register. If NULL, then writes
> + * will be done by writing to the offset into CPUARMState specified
> + * by fieldoffset.
> + */
> + CPWriteFn *writefn;
> + /* Function for doing a "raw" read; used when we need to copy
> + * coprocessor state to the kernel for KVM or out for
> + * migration. This only needs to be provided if there is also a
> + * readfn and it has side effects (for instance clear-on-read bits).
> + */
> + CPReadFn *raw_readfn;
> + /* Function for doing a "raw" write; used when we need to copy KVM
> + * kernel coprocessor state into userspace, or for inbound
> + * migration. This only needs to be provided if there is also a
> + * writefn and it masks out "unwritable" bits or has write-one-to-clear
> + * or similar behaviour.
> + */
> + CPWriteFn *raw_writefn;
> + /* Function for resetting the register. If NULL, then reset will be done
> + * by writing resetvalue to the field specified in fieldoffset. If
> + * fieldoffset is 0 then no reset will be done.
> + */
> + CPResetFn *resetfn;
> +};
> +
> +#define REGINFO_SENTINEL { .type = ARM_CP_SENTINEL }
> +
> +void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
> + const ARMCPRegInfo *regs, void *opaque);
> +void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
> + const ARMCPRegInfo *regs, void *opaque);
> +static inline void define_arm_cp_regs(ARMCPU *cpu, const ARMCPRegInfo *regs)
> +{
> + define_arm_cp_regs_with_opaque(cpu, regs, NULL);
> +}
> +static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
> +{
> + define_one_arm_cp_reg_with_opaque(cpu, regs, NULL);
> +}
> +
> +/* CPWriteFn that can be used to implement writes-ignored behaviour */
> +void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
> + uint64_t value);
> +/* CPReadFn that can be used for read-as-zero behaviour */
> +uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri);
> +
> +/* CPResetFn that does nothing, for use if no reset is required even
> + * if fieldoffset is non zero.
> + */
> +void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque);
> +
> +/* Affinity ID composition */
> +
> +#define ARM_AFF0_SHIFT 0
> +#define ARM_AFF0_MASK (0xFFULL << ARM_AFF0_SHIFT)
> +#define ARM_AFF1_SHIFT 8
> +#define ARM_AFF1_MASK (0xFFULL << ARM_AFF1_SHIFT)
> +#define ARM_AFF2_SHIFT 16
> +#define ARM_AFF2_MASK (0xFFULL << ARM_AFF2_SHIFT)
> +#define ARM_AFF3_SHIFT 32
> +#define ARM_AFF3_MASK (0xFFULL << ARM_AFF3_SHIFT)
> +
> +#define ARM32_AFFINITY_MASK (ARM_AFF0_MASK|ARM_AFF1_MASK|ARM_AFF2_MASK)
> +#define ARM64_AFFINITY_MASK \
> + (ARM_AFF0_MASK|ARM_AFF1_MASK|ARM_AFF2_MASK|ARM_AFF3_MASK)
> +
> +#endif
> diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
> index 25fb1ce..38e0b94 100644
> --- a/target-arm/cpu-qom.h
> +++ b/target-arm/cpu-qom.h
> @@ -20,32 +20,7 @@
> #ifndef QEMU_ARM_CPU_QOM_H
> #define QEMU_ARM_CPU_QOM_H
>
> -#include "qom/cpu.h"
> -
> -#define TYPE_ARM_CPU "arm-cpu"
> -
> -#define ARM_CPU_CLASS(klass) \
> - OBJECT_CLASS_CHECK(ARMCPUClass, (klass), TYPE_ARM_CPU)
> -#define ARM_CPU(obj) \
> - OBJECT_CHECK(ARMCPU, (obj), TYPE_ARM_CPU)
> -#define ARM_CPU_GET_CLASS(obj) \
> - OBJECT_GET_CLASS(ARMCPUClass, (obj), TYPE_ARM_CPU)
> -
> -/**
> - * ARMCPUClass:
> - * @parent_realize: The parent class' realize handler.
> - * @parent_reset: The parent class' reset handler.
> - *
> - * An ARM CPU model.
> - */
> -typedef struct ARMCPUClass {
> - /*< private >*/
> - CPUClass parent_class;
> - /*< public >*/
> -
> - DeviceRealize parent_realize;
> - void (*parent_reset)(CPUState *cpu);
> -} ARMCPUClass;
> +#include "hw/cpu/arm.h"
>
> /**
> * ARMCPU:
> @@ -227,19 +202,6 @@ void arm_gt_vtimer_cb(void *opaque);
> void arm_gt_htimer_cb(void *opaque);
> void arm_gt_stimer_cb(void *opaque);
>
> -#define ARM_AFF0_SHIFT 0
> -#define ARM_AFF0_MASK (0xFFULL << ARM_AFF0_SHIFT)
> -#define ARM_AFF1_SHIFT 8
> -#define ARM_AFF1_MASK (0xFFULL << ARM_AFF1_SHIFT)
> -#define ARM_AFF2_SHIFT 16
> -#define ARM_AFF2_MASK (0xFFULL << ARM_AFF2_SHIFT)
> -#define ARM_AFF3_SHIFT 32
> -#define ARM_AFF3_MASK (0xFFULL << ARM_AFF3_SHIFT)
> -
> -#define ARM32_AFFINITY_MASK (ARM_AFF0_MASK|ARM_AFF1_MASK|ARM_AFF2_MASK)
> -#define ARM64_AFFINITY_MASK \
> - (ARM_AFF0_MASK|ARM_AFF1_MASK|ARM_AFF2_MASK|ARM_AFF3_MASK)
> -
> #ifdef TARGET_AARCH64
> int aarch64_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
> int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 35339aa..bef2322 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -123,7 +123,7 @@ typedef struct {
> uint32_t base_mask;
> } TCR;
>
> -typedef struct CPUARMState {
> +struct CPUARMState {
> /* Regs for current mode. */
> uint32_t regs[16];
>
> @@ -507,7 +507,7 @@ typedef struct CPUARMState {
> */
> DeviceState *irqchip;
> const struct arm_boot_info *boot_info;
> -} CPUARMState;
> +};
>
> #include "cpu-qom.h"
>
> @@ -1138,77 +1138,6 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
> return kvmid;
> }
>
> -/* ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
> - * special-behaviour cp reg and bits [15..8] indicate what behaviour
> - * it has. Otherwise it is a simple cp reg, where CONST indicates that
> - * TCG can assume the value to be constant (ie load at translate time)
> - * and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END
> - * indicates that the TB should not be ended after a write to this register
> - * (the default is that the TB ends after cp writes). OVERRIDE permits
> - * a register definition to override a previous definition for the
> - * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the
> - * old must have the OVERRIDE bit set.
> - * ALIAS indicates that this register is an alias view of some underlying
> - * state which is also visible via another register, and that the other
> - * register is handling migration and reset; registers marked ALIAS will not be
> - * migrated but may have their state set by syncing of register state from KVM.
> - * NO_RAW indicates that this register has no underlying state and does not
> - * support raw access for state saving/loading; it will not be used for either
> - * migration or KVM state synchronization. (Typically this is for "registers"
> - * which are actually used as instructions for cache maintenance and so on.)
> - * IO indicates that this register does I/O and therefore its accesses
> - * need to be surrounded by gen_io_start()/gen_io_end(). In particular,
> - * registers which implement clocks or timers require this.
> - */
> -#define ARM_CP_SPECIAL 1
> -#define ARM_CP_CONST 2
> -#define ARM_CP_64BIT 4
> -#define ARM_CP_SUPPRESS_TB_END 8
> -#define ARM_CP_OVERRIDE 16
> -#define ARM_CP_ALIAS 32
> -#define ARM_CP_IO 64
> -#define ARM_CP_NO_RAW 128
> -#define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8))
> -#define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8))
> -#define ARM_CP_NZCV (ARM_CP_SPECIAL | (3 << 8))
> -#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8))
> -#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | (5 << 8))
> -#define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
> -/* Used only as a terminator for ARMCPRegInfo lists */
> -#define ARM_CP_SENTINEL 0xffff
> -/* Mask of only the flag bits in a type field */
> -#define ARM_CP_FLAG_MASK 0xff
> -
> -/* Valid values for ARMCPRegInfo state field, indicating which of
> - * the AArch32 and AArch64 execution states this register is visible in.
> - * If the reginfo doesn't explicitly specify then it is AArch32 only.
> - * If the reginfo is declared to be visible in both states then a second
> - * reginfo is synthesised for the AArch32 view of the AArch64 register,
> - * such that the AArch32 view is the lower 32 bits of the AArch64 one.
> - * Note that we rely on the values of these enums as we iterate through
> - * the various states in some places.
> - */
> -enum {
> - ARM_CP_STATE_AA32 = 0,
> - ARM_CP_STATE_AA64 = 1,
> - ARM_CP_STATE_BOTH = 2,
> -};
> -
> -/* ARM CP register secure state flags. These flags identify security state
> - * attributes for a given CP register entry.
> - * The existence of both or neither secure and non-secure flags indicates that
> - * the register has both a secure and non-secure hash entry. A single one of
> - * these flags causes the register to only be hashed for the specified
> - * security state.
> - * Although definitions may have any combination of the S/NS bits, each
> - * registered entry will only have one to identify whether the entry is secure
> - * or non-secure.
> - */
> -enum {
> - ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */
> - ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
> -};
> -
> /* Return true if cptype is a valid type field. This is used to try to
> * catch errors where the sentinel has been accidentally left off the end
> * of a list of registers.
> @@ -1283,145 +1212,6 @@ static inline int arm_current_el(CPUARMState *env)
> }
> }
>
> -typedef struct ARMCPRegInfo ARMCPRegInfo;
> -
> -typedef enum CPAccessResult {
> - /* Access is permitted */
> - CP_ACCESS_OK = 0,
> - /* Access fails due to a configurable trap or enable which would
> - * result in a categorized exception syndrome giving information about
> - * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
> - * 0xc or 0x18). The exception is taken to the usual target EL (EL1 or
> - * PL1 if in EL0, otherwise to the current EL).
> - */
> - CP_ACCESS_TRAP = 1,
> - /* Access fails and results in an exception syndrome 0x0 ("uncategorized").
> - * Note that this is not a catch-all case -- the set of cases which may
> - * result in this failure is specifically defined by the architecture.
> - */
> - CP_ACCESS_TRAP_UNCATEGORIZED = 2,
> - /* As CP_ACCESS_TRAP, but for traps directly to EL2 or EL3 */
> - CP_ACCESS_TRAP_EL2 = 3,
> - CP_ACCESS_TRAP_EL3 = 4,
> - /* As CP_ACCESS_UNCATEGORIZED, but for traps directly to EL2 or EL3 */
> - CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = 5,
> - CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = 6,
> -} CPAccessResult;
> -
> -/* Access functions for coprocessor registers. These cannot fail and
> - * may not raise exceptions.
> - */
> -typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque);
> -typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
> - uint64_t value);
> -/* Access permission check functions for coprocessor registers. */
> -typedef CPAccessResult CPAccessFn(CPUARMState *env, const ARMCPRegInfo *opaque);
> -/* Hook function for register reset */
> -typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
> -
> -#define CP_ANY 0xff
> -
> -/* Definition of an ARM coprocessor register */
> -struct ARMCPRegInfo {
> - /* Name of register (useful mainly for debugging, need not be unique) */
> - const char *name;
> - /* Location of register: coprocessor number and (crn,crm,opc1,opc2)
> - * tuple. Any of crm, opc1 and opc2 may be CP_ANY to indicate a
> - * 'wildcard' field -- any value of that field in the MRC/MCR insn
> - * will be decoded to this register. The register read and write
> - * callbacks will be passed an ARMCPRegInfo with the crn/crm/opc1/opc2
> - * used by the program, so it is possible to register a wildcard and
> - * then behave differently on read/write if necessary.
> - * For 64 bit registers, only crm and opc1 are relevant; crn and opc2
> - * must both be zero.
> - * For AArch64-visible registers, opc0 is also used.
> - * Since there are no "coprocessors" in AArch64, cp is purely used as a
> - * way to distinguish (for KVM's benefit) guest-visible system registers
> - * from demuxed ones provided to preserve the "no side effects on
> - * KVM register read/write from QEMU" semantics. cp==0x13 is guest
> - * visible (to match KVM's encoding); cp==0 will be converted to
> - * cp==0x13 when the ARMCPRegInfo is registered, for convenience.
> - */
> - uint8_t cp;
> - uint8_t crn;
> - uint8_t crm;
> - uint8_t opc0;
> - uint8_t opc1;
> - uint8_t opc2;
> - /* Execution state in which this register is visible: ARM_CP_STATE_* */
> - int state;
> - /* Register type: ARM_CP_* bits/values */
> - int type;
> - /* Access rights: PL*_[RW] */
> - int access;
> - /* Security state: ARM_CP_SECSTATE_* bits/values */
> - int secure;
> - /* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
> - * this register was defined: can be used to hand data through to the
> - * register read/write functions, since they are passed the ARMCPRegInfo*.
> - */
> - void *opaque;
> - /* Value of this register, if it is ARM_CP_CONST. Otherwise, if
> - * fieldoffset is non-zero, the reset value of the register.
> - */
> - uint64_t resetvalue;
> - /* Offset of the field in CPUARMState for this register.
> - *
> - * This is not needed if either:
> - * 1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs
> - * 2. both readfn and writefn are specified
> - */
> - ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
> -
> - /* Offsets of the secure and non-secure fields in CPUARMState for the
> - * register if it is banked. These fields are only used during the static
> - * registration of a register. During hashing the bank associated
> - * with a given security state is copied to fieldoffset which is used from
> - * there on out.
> - *
> - * It is expected that register definitions use either fieldoffset or
> - * bank_fieldoffsets in the definition but not both. It is also expected
> - * that both bank offsets are set when defining a banked register. This
> - * use indicates that a register is banked.
> - */
> - ptrdiff_t bank_fieldoffsets[2];
> -
> - /* Function for making any access checks for this register in addition to
> - * those specified by the 'access' permissions bits. If NULL, no extra
> - * checks required. The access check is performed at runtime, not at
> - * translate time.
> - */
> - CPAccessFn *accessfn;
> - /* Function for handling reads of this register. If NULL, then reads
> - * will be done by loading from the offset into CPUARMState specified
> - * by fieldoffset.
> - */
> - CPReadFn *readfn;
> - /* Function for handling writes of this register. If NULL, then writes
> - * will be done by writing to the offset into CPUARMState specified
> - * by fieldoffset.
> - */
> - CPWriteFn *writefn;
> - /* Function for doing a "raw" read; used when we need to copy
> - * coprocessor state to the kernel for KVM or out for
> - * migration. This only needs to be provided if there is also a
> - * readfn and it has side effects (for instance clear-on-read bits).
> - */
> - CPReadFn *raw_readfn;
> - /* Function for doing a "raw" write; used when we need to copy KVM
> - * kernel coprocessor state into userspace, or for inbound
> - * migration. This only needs to be provided if there is also a
> - * writefn and it masks out "unwritable" bits or has write-one-to-clear
> - * or similar behaviour.
> - */
> - CPWriteFn *raw_writefn;
> - /* Function for resetting the register. If NULL, then reset will be done
> - * by writing resetvalue to the field specified in fieldoffset. If
> - * fieldoffset is 0 then no reset will be done.
> - */
> - CPResetFn *resetfn;
> -};
> -
> /* Macros which are lvalues for the field in CPUARMState for the
> * ARMCPRegInfo *ri.
> */
> @@ -1430,33 +1220,8 @@ struct ARMCPRegInfo {
> #define CPREG_FIELD64(env, ri) \
> (*(uint64_t *)((char *)(env) + (ri)->fieldoffset))
>
> -#define REGINFO_SENTINEL { .type = ARM_CP_SENTINEL }
> -
> -void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
> - const ARMCPRegInfo *regs, void *opaque);
> -void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
> - const ARMCPRegInfo *regs, void *opaque);
> -static inline void define_arm_cp_regs(ARMCPU *cpu, const ARMCPRegInfo *regs)
> -{
> - define_arm_cp_regs_with_opaque(cpu, regs, 0);
> -}
> -static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
> -{
> - define_one_arm_cp_reg_with_opaque(cpu, regs, 0);
> -}
> const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp);
>
> -/* CPWriteFn that can be used to implement writes-ignored behaviour */
> -void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
> - uint64_t value);
> -/* CPReadFn that can be used for read-as-zero behaviour */
> -uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri);
> -
> -/* CPResetFn that does nothing, for use if no reset is required even
> - * if fieldoffset is non zero.
> - */
> -void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque);
> -
> /* Return true if this reginfo struct's field in the cpu state struct
> * is 64 bits wide.
> */
> --
> 1.9.5.msysgit.0
>
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH v2] target-arm: Extract some external ARM CPU API
2015-10-26 16:39 ` Peter Crosthwaite
@ 2015-10-27 12:02 ` Pavel Fedin
2015-10-27 13:41 ` Peter Maydell
2015-10-27 12:03 ` Pavel Fedin
1 sibling, 1 reply; 10+ messages in thread
From: Pavel Fedin @ 2015-10-27 12:02 UTC (permalink / raw)
To: 'Peter Crosthwaite'
Cc: 'Peter Maydell', 'Shlomo Pongratz', qemu-devel,
'Shlomo Pongratz'
Hello!
> We have plenty of precedent in tree for interrupt controllers being
> compiled as arch-specific for reasons such as this. Can we just
> promote GIC to an obj-y (much the same way the KVM GIC or V7MNVIC are
> promoted)? You should them have access to cpu.h and the CP interface.
Huh, indeed, it's so simple... I failed to notice this.
Peter, what do you think, if we indeed simply move gicv3 implementation from common-obj-y to obj-y?
Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH v2] target-arm: Extract some external ARM CPU API
2015-10-26 16:39 ` Peter Crosthwaite
2015-10-27 12:02 ` Pavel Fedin
@ 2015-10-27 12:03 ` Pavel Fedin
1 sibling, 0 replies; 10+ messages in thread
From: Pavel Fedin @ 2015-10-27 12:03 UTC (permalink / raw)
To: 'Peter Crosthwaite'
Cc: 'Peter Maydell', 'Shlomo Pongratz', qemu-devel,
'Shlomo Pongratz'
Hello!
> > include/hw/cpu/arm.h | 308 +++++++++++++++++++++++++++++++++++++++++++++++++++
>
> I think this would be hw/arm/cpu.h
Sorry for split-reply, forgot to look at this...
include/hw/arm is for board classes, isn't it?
Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH v2] target-arm: Extract some external ARM CPU API
2015-10-27 12:02 ` Pavel Fedin
@ 2015-10-27 13:41 ` Peter Maydell
2015-10-27 14:18 ` Pavel Fedin
0 siblings, 1 reply; 10+ messages in thread
From: Peter Maydell @ 2015-10-27 13:41 UTC (permalink / raw)
To: Pavel Fedin
Cc: Shlomo Pongratz, Peter Crosthwaite, QEMU Developers,
Shlomo Pongratz
On 27 October 2015 at 12:02, Pavel Fedin <p.fedin@samsung.com> wrote:
>> We have plenty of precedent in tree for interrupt controllers being
>> compiled as arch-specific for reasons such as this. Can we just
>> promote GIC to an obj-y (much the same way the KVM GIC or V7MNVIC are
>> promoted)? You should them have access to cpu.h and the CP interface.
>
> Huh, indeed, it's so simple... I failed to notice this.
> Peter, what do you think, if we indeed simply move gicv3
> implementation from common-obj-y to obj-y?
I thought that we were trying to reduce the amount of obj-y code
in order to make life easier for multiarch (because eventually
it's going to have to be compile-once anyway). And being obj-y
and having the whole of cpu.h available makes it very easy to
accidentally use target-specific defines and so on.
But Peter C has a better grasp of the current status of
multiarch than I do, so if he prefers using obj-y then
I'm happy to take his recommendation.
thanks
-- PMM
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH v2] target-arm: Extract some external ARM CPU API
2015-10-27 13:41 ` Peter Maydell
@ 2015-10-27 14:18 ` Pavel Fedin
2015-10-27 20:17 ` Peter Crosthwaite
0 siblings, 1 reply; 10+ messages in thread
From: Pavel Fedin @ 2015-10-27 14:18 UTC (permalink / raw)
To: 'Peter Maydell'
Cc: 'Shlomo Pongratz', 'Peter Crosthwaite',
'QEMU Developers', 'Shlomo Pongratz'
Hello!
> But Peter C has a better grasp of the current status of
> multiarch than I do, so if he prefers using obj-y then
> I'm happy to take his recommendation.
I am neutral, and i will accept any solution. OTOH, he agreed with my proposal too, and even promised to pick it up into his patchsets, but suggested to change include pathname to include/hw/arm/cpu.h. And i have the last concern about it because hw/arm/ is a place where board-specific includes are placed.
Additionally, we already have three more specific ARM CPU files in include/hw/cpu/, so they just look nice together.
And you know... Theoretically... As far as i can understand, multi-arch is a way to enable emulation of heterogeneous systems, which combine different CPUs. Am i right about it? In this case, what if in future we have some heterogeneous HW, where e.g. ARM and x86 are interoperating using system registers? In this case, x86-targeted qemu code would probably have to talk to ARM-targeted one. And having this API separated from the inner CPU guts would only help.
Compared to this architectural improvement, obj-y looks like very simple way to ignore, but not to solve the problem. :)
So, Peter C, what is your final decision?
Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH v2] target-arm: Extract some external ARM CPU API
2015-10-27 14:18 ` Pavel Fedin
@ 2015-10-27 20:17 ` Peter Crosthwaite
2015-10-28 6:46 ` Pavel Fedin
0 siblings, 1 reply; 10+ messages in thread
From: Peter Crosthwaite @ 2015-10-27 20:17 UTC (permalink / raw)
To: Pavel Fedin, Paolo Bonzini
Cc: Peter Maydell, Shlomo Pongratz, QEMU Developers, Shlomo Pongratz
[-- Attachment #1: Type: text/plain, Size: 2941 bytes --]
On Tue, Oct 27, 2015 at 7:18 AM, Pavel Fedin <p.fedin@samsung.com> wrote:
> Hello!
>
> > But Peter C has a better grasp of the current status of
> > multiarch than I do, so if he prefers using obj-y then
> > I'm happy to take his recommendation.
>
> I am neutral, and i will accept any solution. OTOH, he agreed with my
> proposal too, and even promised to pick it up into his patchsets, but
> suggested to change include pathname to include/hw/arm/cpu.h. And i have
> the last concern about it because hw/arm/ is a place where board-specific
> includes are placed.
> Additionally, we already have three more specific ARM CPU files in
> include/hw/cpu/, so they just look nice together.
>
> And you know... Theoretically... As far as i can understand, multi-arch
> is a way to enable emulation of heterogeneous systems, which combine
> different CPUs. Am i right about it? In this case, what if in future we
> have some heterogeneous HW, where e.g. ARM and x86 are interoperating using
> system registers? In this case, x86-targeted qemu code would probably have
> to talk to ARM-targeted one. And having this API separated from the inner
> CPU guts would only help.
> Compared to this architectural improvement, obj-y looks like very simple
> way to ignore, but not to solve the problem. :)
>
> So, Peter C, what is your final decision?
>
>
If there are no dependent patches on list that are 2.5 candidate, I suggest
we just drop this one for the short term. Is there something on list?
I have no objection to the obj-y solution medium term, as there are already
multiple users of the ARM CP API using their obj-y privileges to access it.
Certainly don't wait on MA to send your patches. These obj-y's will need to
be converted en-masse so adding GIC to the list of TBDs is not a big issue
IMO. So I would just prepend the obj-y conversion as P1 of the series
implementing your GIC CP functionality.
Note that multi-arch does not multiple-compile obj-y for the MA build
itself. There is still only one compile of obj-y for the MA binary. The
basic guideline is:
common-obj-y -> Compiled only once absolutely
obj-y -> Multiple compiled per output binary
arch-obj-y -> Multiple compiled per output binary and multiple compiled per
CPU arch within multi-arch build
Ideally obj-y eventually evaporates. Genuinely CPU specific stuff and
performance sensitive stuff (like the TCG translate+execute) are converted
from obj-y to arch-obj-y. The current multi-arch work does this:
https://lists.gnu.org/archive/html/qemu-devel/2015-07/msg03929.html
Everything else should be common-obj-y. So the follow up is to remove the
(mostly false) deps of device land on CPU-target specifics. So we should do
what your patch is doing only, on a much bigger scale. But the obj-y
conversion won't inhibit multi-arch functionality.
Regards,
Peter
> Kind regards,
> Pavel Fedin
> Expert Engineer
> Samsung Electronics Research center Russia
>
>
>
[-- Attachment #2: Type: text/html, Size: 3840 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH v2] target-arm: Extract some external ARM CPU API
2015-10-27 20:17 ` Peter Crosthwaite
@ 2015-10-28 6:46 ` Pavel Fedin
2015-10-28 11:12 ` Pavel Fedin
0 siblings, 1 reply; 10+ messages in thread
From: Pavel Fedin @ 2015-10-28 6:46 UTC (permalink / raw)
To: 'Peter Crosthwaite', 'Paolo Bonzini'
Cc: 'Peter Maydell', 'Shlomo Pongratz',
'QEMU Developers', 'Shlomo Pongratz'
Hello!
> If there are no dependent patches on list that are 2.5 candidate, I suggest we just drop this one for the short term.
> Is there something on list?
For 2.5, AFAIK, no. Unless Shlomo suddenly comes up with clean GICv3 implementation which could be quickly accepted.
I wanted to upstream this now in order to forget about the problem and allow me and Shlomo to post cleaner series without the need to include preparations like this every time.
> I have no objection to the obj-y solution medium term, as there are already multiple users of the ARM CP API using
> their obj-y privileges to access it.
Ok, so decided. I will convert my code, test the build and send a small patch for this soon, perhaps today.
Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH v2] target-arm: Extract some external ARM CPU API
2015-10-28 6:46 ` Pavel Fedin
@ 2015-10-28 11:12 ` Pavel Fedin
2015-10-28 11:34 ` Shlomo Pongratz
0 siblings, 1 reply; 10+ messages in thread
From: Pavel Fedin @ 2015-10-28 11:12 UTC (permalink / raw)
To: 'Peter Crosthwaite', 'Paolo Bonzini'
Cc: 'Peter Maydell', 'Shlomo Pongratz',
'QEMU Developers', 'Shlomo Pongratz'
Hello!
> Ok, so decided. I will convert my code, test the build and send a small patch for this soon,
> perhaps today.
arm_gicv3_kvm.o is already in obj-y, and arm_gicv3_common.o does not use any of those definitions. So, nothing to move, there will be no patch.
So far, we have only this small leftover: http://lists.nongnu.org/archive/html/qemu-devel/2015-10/msg02349.html. Needed both by live migration and SW emulation of GICv3.
Shlomo: Just add your GICv3 code to obj-$(CONFIG_ARM_GIC), and you'll be able to include things you need.
Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH v2] target-arm: Extract some external ARM CPU API
2015-10-28 11:12 ` Pavel Fedin
@ 2015-10-28 11:34 ` Shlomo Pongratz
0 siblings, 0 replies; 10+ messages in thread
From: Shlomo Pongratz @ 2015-10-28 11:34 UTC (permalink / raw)
To: Pavel Fedin, 'Peter Crosthwaite', 'Paolo Bonzini'
Cc: 'Peter Maydell', 'Shlomo Pongratz',
'QEMU Developers'
-----Original Message-----
From: Pavel Fedin [mailto:p.fedin@samsung.com]
Sent: 2015年10月28日 19:13
To: 'Peter Crosthwaite'; 'Paolo Bonzini'
Cc: 'Peter Maydell'; 'Shlomo Pongratz'; 'QEMU Developers'; Shlomo Pongratz
Subject: RE: [Qemu-devel] [PATCH v2] target-arm: Extract some external ARM CPU API
Hello!
> Ok, so decided. I will convert my code, test the build and send a
> small patch for this soon, perhaps today.
arm_gicv3_kvm.o is already in obj-y, and arm_gicv3_common.o does not use any of those definitions. So, nothing to move, there will be no patch.
So far, we have only this small leftover: http://lists.nongnu.org/archive/html/qemu-devel/2015-10/msg02349.html. Needed both by live migration and SW emulation of GICv3.
Shlomo: Just add your GICv3 code to obj-$(CONFIG_ARM_GIC), and you'll be able to include things you need.
Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia
Hi Pavel,
Thanks, I'm currently in business trip to China.
I'll resume working on it in approx two weeks.
Also please excuse me for using outlook (if the mail is unreadable).
Best regards,
S.P.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2015-10-28 11:34 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-26 7:46 [Qemu-devel] [PATCH v2] target-arm: Extract some external ARM CPU API Pavel Fedin
2015-10-26 16:39 ` Peter Crosthwaite
2015-10-27 12:02 ` Pavel Fedin
2015-10-27 13:41 ` Peter Maydell
2015-10-27 14:18 ` Pavel Fedin
2015-10-27 20:17 ` Peter Crosthwaite
2015-10-28 6:46 ` Pavel Fedin
2015-10-28 11:12 ` Pavel Fedin
2015-10-28 11:34 ` Shlomo Pongratz
2015-10-27 12:03 ` Pavel Fedin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).