qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PULL 25/43] target/arm: Provide fault type enum and FSR conversion functions
Date: Wed, 13 Dec 2017 18:12:23 +0000	[thread overview]
Message-ID: <1513188761-20784-26-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1513188761-20784-1-git-send-email-peter.maydell@linaro.org>

Currently get_phys_addr() and its various subfunctions return
a hard-coded fault status register value for translation
failures. This is awkward because FSR values these days may
be either long-descriptor format or short-descriptor format.
Worse, the right FSR type to use doesn't depend only on the
translation table being walked -- some cases, like fault
info reported to AArch32 EL2 for some kinds of ATS operation,
must be in long-descriptor format even if the translation
table being walked was short format. We can't get those cases
right with our current approach.

Provide fields in the ARMMMUFaultInfo struct which allow
get_phys_addr() to provide sufficient information for a caller to
construct an FSR value themselves, and utility functions which do
this for both long and short format FSR values, as a first step in
switching get_phys_addr() and its children to only returning the
failure cause in the ARMMMUFaultInfo struct.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
Message-id: 1512503192-2239-2-git-send-email-peter.maydell@linaro.org
---
 target/arm/internals.h | 185 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 185 insertions(+)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index aa9c91b..67b9a52 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -488,7 +488,39 @@ static inline void arm_clear_exclusive(CPUARMState *env)
 }
 
 /**
+ * ARMFaultType: type of an ARM MMU fault
+ * This corresponds to the v8A pseudocode's Fault enumeration,
+ * with extensions for QEMU internal conditions.
+ */
+typedef enum ARMFaultType {
+    ARMFault_None,
+    ARMFault_AccessFlag,
+    ARMFault_Alignment,
+    ARMFault_Background,
+    ARMFault_Domain,
+    ARMFault_Permission,
+    ARMFault_Translation,
+    ARMFault_AddressSize,
+    ARMFault_SyncExternal,
+    ARMFault_SyncExternalOnWalk,
+    ARMFault_SyncParity,
+    ARMFault_SyncParityOnWalk,
+    ARMFault_AsyncParity,
+    ARMFault_AsyncExternal,
+    ARMFault_Debug,
+    ARMFault_TLBConflict,
+    ARMFault_Lockdown,
+    ARMFault_Exclusive,
+    ARMFault_ICacheMaint,
+    ARMFault_QEMU_NSCExec, /* v8M: NS executing in S&NSC memory */
+    ARMFault_QEMU_SFault, /* v8M: SecureFault INVTRAN, INVEP or AUVIOL */
+} ARMFaultType;
+
+/**
  * ARMMMUFaultInfo: Information describing an ARM MMU Fault
+ * @type: Type of fault
+ * @level: Table walk level (for translation, access flag and permission faults)
+ * @domain: Domain of the fault address (for non-LPAE CPUs only)
  * @s2addr: Address that caused a fault at stage 2
  * @stage2: True if we faulted at stage 2
  * @s1ptw: True if we faulted at stage 2 while doing a stage 1 page-table walk
@@ -496,12 +528,165 @@ static inline void arm_clear_exclusive(CPUARMState *env)
  */
 typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
 struct ARMMMUFaultInfo {
+    ARMFaultType type;
     target_ulong s2addr;
+    int level;
+    int domain;
     bool stage2;
     bool s1ptw;
     bool ea;
 };
 
+/**
+ * arm_fi_to_sfsc: Convert fault info struct to short-format FSC
+ * Compare pseudocode EncodeSDFSC(), though unlike that function
+ * we set up a whole FSR-format code including domain field and
+ * putting the high bit of the FSC into bit 10.
+ */
+static inline uint32_t arm_fi_to_sfsc(ARMMMUFaultInfo *fi)
+{
+    uint32_t fsc;
+
+    switch (fi->type) {
+    case ARMFault_None:
+        return 0;
+    case ARMFault_AccessFlag:
+        fsc = fi->level == 1 ? 0x3 : 0x6;
+        break;
+    case ARMFault_Alignment:
+        fsc = 0x1;
+        break;
+    case ARMFault_Permission:
+        fsc = fi->level == 1 ? 0xd : 0xf;
+        break;
+    case ARMFault_Domain:
+        fsc = fi->level == 1 ? 0x9 : 0xb;
+        break;
+    case ARMFault_Translation:
+        fsc = fi->level == 1 ? 0x5 : 0x7;
+        break;
+    case ARMFault_SyncExternal:
+        fsc = 0x8 | (fi->ea << 12);
+        break;
+    case ARMFault_SyncExternalOnWalk:
+        fsc = fi->level == 1 ? 0xc : 0xe;
+        fsc |= (fi->ea << 12);
+        break;
+    case ARMFault_SyncParity:
+        fsc = 0x409;
+        break;
+    case ARMFault_SyncParityOnWalk:
+        fsc = fi->level == 1 ? 0x40c : 0x40e;
+        break;
+    case ARMFault_AsyncParity:
+        fsc = 0x408;
+        break;
+    case ARMFault_AsyncExternal:
+        fsc = 0x406 | (fi->ea << 12);
+        break;
+    case ARMFault_Debug:
+        fsc = 0x2;
+        break;
+    case ARMFault_TLBConflict:
+        fsc = 0x400;
+        break;
+    case ARMFault_Lockdown:
+        fsc = 0x404;
+        break;
+    case ARMFault_Exclusive:
+        fsc = 0x405;
+        break;
+    case ARMFault_ICacheMaint:
+        fsc = 0x4;
+        break;
+    case ARMFault_Background:
+        fsc = 0x0;
+        break;
+    case ARMFault_QEMU_NSCExec:
+        fsc = M_FAKE_FSR_NSC_EXEC;
+        break;
+    case ARMFault_QEMU_SFault:
+        fsc = M_FAKE_FSR_SFAULT;
+        break;
+    default:
+        /* Other faults can't occur in a context that requires a
+         * short-format status code.
+         */
+        g_assert_not_reached();
+    }
+
+    fsc |= (fi->domain << 4);
+    return fsc;
+}
+
+/**
+ * arm_fi_to_lfsc: Convert fault info struct to long-format FSC
+ * Compare pseudocode EncodeLDFSC(), though unlike that function
+ * we fill in also the LPAE bit 9 of a DFSR format.
+ */
+static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
+{
+    uint32_t fsc;
+
+    switch (fi->type) {
+    case ARMFault_None:
+        return 0;
+    case ARMFault_AddressSize:
+        fsc = fi->level & 3;
+        break;
+    case ARMFault_AccessFlag:
+        fsc = (fi->level & 3) | (0x2 << 2);
+        break;
+    case ARMFault_Permission:
+        fsc = (fi->level & 3) | (0x3 << 2);
+        break;
+    case ARMFault_Translation:
+        fsc = (fi->level & 3) | (0x1 << 2);
+        break;
+    case ARMFault_SyncExternal:
+        fsc = 0x10 | (fi->ea << 12);
+        break;
+    case ARMFault_SyncExternalOnWalk:
+        fsc = (fi->level & 3) | (0x5 << 2) | (fi->ea << 12);
+        break;
+    case ARMFault_SyncParity:
+        fsc = 0x18;
+        break;
+    case ARMFault_SyncParityOnWalk:
+        fsc = (fi->level & 3) | (0x7 << 2);
+        break;
+    case ARMFault_AsyncParity:
+        fsc = 0x19;
+        break;
+    case ARMFault_AsyncExternal:
+        fsc = 0x11 | (fi->ea << 12);
+        break;
+    case ARMFault_Alignment:
+        fsc = 0x21;
+        break;
+    case ARMFault_Debug:
+        fsc = 0x22;
+        break;
+    case ARMFault_TLBConflict:
+        fsc = 0x30;
+        break;
+    case ARMFault_Lockdown:
+        fsc = 0x34;
+        break;
+    case ARMFault_Exclusive:
+        fsc = 0x35;
+        break;
+    default:
+        /* Other faults can't occur in a context that requires a
+         * long-format status code.
+         */
+        g_assert_not_reached();
+    }
+
+    fsc |= 1 << 9;
+    return fsc;
+}
+
 /* Do a page table walk and add page to TLB if possible */
 bool arm_tlb_fill(CPUState *cpu, vaddr address,
                   MMUAccessType access_type, int mmu_idx,
-- 
2.7.4

  parent reply	other threads:[~2017-12-13 18:13 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-13 18:11 [Qemu-devel] [PULL 00/43] target-arm queue Peter Maydell
2017-12-13 18:11 ` [Qemu-devel] [PULL 01/43] m25p80: Add support for continuous read out of RDSR and READ_FSR Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 02/43] m25p80: Add support for SST READ ID 0x90/0xAB commands Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 03/43] m25p80: Add support for BRRD/BRWR and BULK_ERASE (0x60) Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 04/43] m25p80: Add support for n25q512a11 and n25q512a13 Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 05/43] xilinx_spips: Move FlashCMD, XilinxQSPIPS and XilinxSPIPSClass Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 06/43] xilinx_spips: Update striping to be big-endian bit order Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 07/43] xilinx_spips: Add support for RX discard and RX drain Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 08/43] xilinx_spips: Make tx/rx_data_bytes more generic and reusable Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 09/43] xilinx_spips: Add support for zero pumping Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 10/43] xilinx_spips: Add support for 4 byte addresses in the LQSPI Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 11/43] xilinx_spips: Don't set TX FIFO UNDERFLOW at cmd done Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 12/43] xilinx_spips: Add support for the ZynqMP Generic QSPI Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 13/43] xlnx-zcu102: Add support for the ZynqMP QSPI Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 14/43] hw/intc/arm_gicv3_its: Don't call post_load on reset Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 15/43] hw/intc/arm_gicv3_its: Implement a minimalist reset Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 16/43] linux-headers: update to 4.15-rc1 Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 17/43] hw/intc/arm_gicv3_its: Implement full reset Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 18/43] target/arm: Handle SPSEL and current stack being out of sync in MSP/PSP reads Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 19/43] target/arm: Allow explicit writes to CONTROL.SPSEL in Handler mode Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 20/43] target/arm: Add missing M profile case to regime_is_user() Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 21/43] target/arm: Split M profile MNegPri mmu index into user and priv Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 22/43] target/arm: Create new arm_v7m_mmu_idx_for_secstate_and_priv() Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 23/43] target/arm: Factor MPU lookup code out of get_phys_addr_pmsav8() Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 24/43] target/arm: Implement TT instruction Peter Maydell
2017-12-13 18:12 ` Peter Maydell [this message]
2017-12-13 18:12 ` [Qemu-devel] [PULL 26/43] target/arm: Remove fsr argument from arm_ld*_ptw() Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 27/43] target/arm: Convert get_phys_addr_v5() to not return FSC values Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 28/43] target/arm: Convert get_phys_addr_v6() " Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 29/43] target/arm: Convert get_phys_addr_lpae() " Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 30/43] target/arm: Convert get_phys_addr_pmsav5() " Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 31/43] target/arm: Convert get_phys_addr_pmsav7() " Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 32/43] target/arm: Convert get_phys_addr_pmsav8() " Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 33/43] target/arm: Use ARMMMUFaultInfo in deliver_fault() Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 34/43] target/arm: Ignore fsr from get_phys_addr() in do_ats_write() Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 35/43] target/arm: Remove fsr argument from get_phys_addr() and arm_tlb_fill() Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 36/43] target/arm: Extend PAR format determination Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 37/43] nvic: Make nvic_sysreg_ns_ops work with any MemoryRegion Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 38/43] nvic: Make systick banked Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 39/43] hw/display/tc6393xb: limit irq handler index to TC6393XB_GPIOS Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 40/43] MAINTAINERS: replace the unavailable email address Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 41/43] xilinx_spips: Update the QSPI Mod ID reset value Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 42/43] xilinx_spips: Set all of the reset values Peter Maydell
2017-12-13 18:12 ` [Qemu-devel] [PULL 43/43] xilinx_spips: Use memset instead of a for loop to zero registers Peter Maydell
2017-12-14 15:32 ` [Qemu-devel] [PULL 00/43] target-arm queue Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1513188761-20784-26-git-send-email-peter.maydell@linaro.org \
    --to=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).