Commit graph

202 commits

Author SHA1 Message Date
Peter Crosthwaite e5cfcc3221
target-arm: implement SCTLR.EE
Implement SCTLR.EE bit which controls data endianess for exceptions
and page table translations. SCTLR.EE is mirrored to the CPSR.E bit
on exception entry.

Backports commit 73462dddf670c32c45c8ea359658092b0365b2d4 from qemu
2018-02-21 02:14:56 -05:00
Paolo Bonzini ec15ee10d0
target-arm: implement SCTLR.B, drop bswap_code
bswap_code is a CPU property of sorts ("is the iside endianness the
opposite way round to TARGET_WORDS_BIGENDIAN?") but it is not the
actual CPU state involved here which is SCTLR.B (set for BE32
binaries, clear for BE8).

Replace bswap_code with SCTLR.B, and pass that to arm_ld*_code.
The next patches will make data fetches honor both SCTLR.B and
CPSR.E appropriately.

Backports commit f9fd40ebe4f55e0048e002925b8d65e66d56e7a7 from qemu
2018-02-21 02:08:05 -05:00
Peter Maydell 64a9bec68a
target-arm: Correct handling of writes to CPSR mode bits from gdb in usermode
In helper.c the expression
(env->uncached_cpsr & CPSR_M) != CPSR_USER
is always true; the right hand side was supposed to be ARM_CPU_MODE_USR
(an error in commit cb01d391).

Since the incorrect expression was always true, this just meant that
commit cb01d391 had no effect.

However simply changing the RHS here would reveal a logic error: if
the mode is USR we wish to completely ignore the attempt to set the
mode bits, which means that we must clear the CPSR_M bits from mask
to avoid the uncached_cpsr bits being updated at the end of the
function.

Move the condition into the correct place in the code, fix its RHS
constant, and add a comment about the fact that we must be doing a
gdbstub write if we're in user mode.

Backports commit 8c4f0eb94cc65ee32a12feba88d0b32e3665d5ea from qemu
2018-02-21 01:57:34 -05:00
Peter Maydell 20712bcb9a
target-arm: Make reserved ranges in ID_AA64* spaces RAZ, not UNDEF
The v8 ARM ARM defines that unused spaces in the ID_AA64* system
register ranges are Reserved and must RAZ, rather than being UNDEF.
Implement this.

In particular, ARM v8.2 adds a new feature register ID_AA64MMFR2,
and newer versions of the Linux kernel will attempt to read this,
which causes them not to boot up on versions of QEMU missing this fix.

Since the encoding .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6
is actually defined in ARMv8 (as ID_MMFR4), we give it an entry in
the ARMCPU struct so CPUs can override it, though since none do
this too will just RAZ.

Backports commit e20d84c1407d43d5a2e2ac95dbb46db3b0af8f9f from qemu
2018-02-20 22:49:43 -05:00
Edgar E. Iglesias 66c4bd02eb
target-arm: Mark CNTHP_TVAL_EL2 as ARM_CP_NO_RAW
Mark CNTHP_TVAL_EL2 as ARM_CP_NO_RAW due to the register not
having any underlying state. This fixes an issue with booting
KVM enabled kernels when EL2 is on.

Backports commit d44ec156300a149b386a14d3ab349d3b83b66b8c from qemu
2018-02-20 22:30:44 -05:00
Peter Maydell eb02f0e818
target-arm: Implement MDCR_EL3.TPM and MDCR_EL2.TPM traps
Implement the performance monitor register traps controlled
by MDCR_EL3.TPM and MDCR_EL2.TPM. Most of the performance
registers already have an access function to deal with the
user-enable bit, and the TPM checks can be added there. We
also need a new access function which only implements the
TPM checks for use by the few not-EL0-accessible registers
and by PMUSERENR_EL0 (which is always EL0-readable).

Backports commit 1fce1ba985d9c5c96e5b9709e1356d1814b8fa9e from qemu
2018-02-20 22:29:26 -05:00
Peter Maydell ece364e7cc
target-arm: Fix handling of SDCR for 32-bit code
Fix two issues with our implementation of the SDCR:
* it is only present from ARMv8 onwards
* it does not contain several of the trap bits present in its 64-bit
counterpart the MDCR_EL3

Put the register description in the right place so that it does not
get enabled for ARMv7 and earlier, and give it a write function so that
we can mask out the bits which should not be allowed to have an effect
if EL3 is 32-bit.

Backports commit a8d64e735182cbbb5dcc98f41656b118c45e57cc from qemu
2018-02-20 22:26:58 -05:00
Peter Maydell 8477ed6389
target-arm: Make Monitor->NS PL1 mode changes illegal if HCR.TGE is 1
If HCR.TGE is 1 then mode changes via CPS and MSR from Monitor to
NonSecure PL1 modes are illegal mode changes. Implement this check
in bad_mode_switch().

(We don't currently implement HCR.TGE, but this is the only missing
check from the v8 ARM ARM G1.9.3 and so it's worth adding now; the
rest of the HCR.TGE checks can be added later as necessary.)

Backports commit 10eacda787ac9990dc22d4437b289200c819712c from qemu
2018-02-20 22:24:19 -05:00
Peter Maydell 8bfdc63424
target-arm: Make mode switches from Hyp via CPS and MRS illegal
Mode switches from Hyp to any other mode via the CPS and MRS
instructions are illegal mode switches (though obviously switching
via exception return is valid). Add this check to bad_mode_switch().

Backports commit af393ffc6da116b9dd4c70901bad1f4cafb1773d from qemu
2018-02-20 22:23:23 -05:00
Peter Maydell 00d06bf20e
target-arm: In v8, make illegal AArch32 mode changes set PSTATE.IL
In v8, the illegal mode changes which are UNPREDICTABLE in v7 are
given architected behaviour:
* the mode field is unchanged
* PSTATE.IL is set (so any subsequent instructions will UNDEF)
* any other CPSR fields are written to as normal

This is pretty much the same behaviour we picked for our
UNPREDICTABLE handling, with the exception that for v8 we
need to set the IL bit.

Backports commit 81907a582901671c15be36a63b5063f88f3487e2 from qemu
2018-02-20 22:22:01 -05:00
Peter Maydell 2296fb5915
target-arm: Forbid mode switch to Mon from Secure EL1
In v8 trying to switch mode to Mon from Secure EL1 is an
illegal mode switch. (In v7 this is impossible as all secure
modes except User are at EL3.) We can handle this case by
making a switch to Mon valid only if the current EL is 3,
which then gives the correct answer whether EL3 is AArch32
or AArch64.

Backports commit 58ae2d1f037fae1d90eed4522053a85d79edfbec from qemu
2018-02-20 22:21:10 -05:00
Peter Maydell 4919c7287c
target-arm: Add Hyp mode checks to bad_mode_switch()
We don't actually support Hyp mode yet, but add the correct
checks for it to the bad_mode_switch() function for completeness.

Backports commit e6c8fc07b4fce0729bb747770756835f4b0ca7f4 from qemu
2018-02-20 22:20:19 -05:00
Peter Maydell 339e3e340e
target-arm: Add comment about not implementing NSACR.RFR
QEMU doesn't implement the NSACR.RFR bit, which is a permitted
IMPDEF in choice in ARMv7 and the only permitted choice in ARMv8.
Add a comment to bad_mode_switch() to note that this is why
FIQ is always a valid mode regardless of the CPU's Secure state.

Backports commit 52ff951b4f63a29593650a15efdf82f63d6d962d from qemu
2018-02-20 22:19:38 -05:00
Peter Maydell a468baff61
target-arm: In cpsr_write() ignore mode switches from User mode
The only case where we can attempt a cpsr_write() mode switch from
User is from the gdbstub; all other cases are handled in the
calling code (notably translate.c). Architecturally attempts to
alter the mode bits from user mode are simply ignored (and not
treated as a bad mode switch, which in v8 sets CPSR.IL). Make
mode switches from User ignored in cpsr_write() as well, for
consistency.

Backports commit cb01d3912c8b000ed26d5fe95f6c194b3e3ba7a6 from qemu
2018-02-20 22:18:48 -05:00
Peter Maydell 553e230088
target-arm: Raw CPSR writes should skip checks and bank switching
Raw CPSR writes should skip the architectural checks for whether
we're allowed to set the A or F bits and should also not do
the switching of register banks if the mode changes. Handle
this inside cpsr_write(), which allows us to drop the "manually
set the mode bits to avoid the bank switch" code from all the
callsites which are using CPSRWriteRaw.

This fixes a bug in 32-bit KVM handling where we had forgotten
the "manually set the mode bits" part and could thus potentially
trash the register state if the mode from the last exit to userspace
differed from the mode on this exit.

Backports commit f8c88bbcda76d5674e4bb125471371b41d330df8 from qemu
2018-02-20 22:17:48 -05:00
Peter Maydell 611d4dad4b
target-arm: Add write_type argument to cpsr_write()
Add an argument to cpsr_write() to indicate what kind of CPSR
write is being requested, since the exact behaviour should
differ for the different cases.

Backports commit 50866ba5a2cfe922aaf3edb79f6eac5b0653477a from qemu
2018-02-20 22:15:53 -05:00
Alistair Francis a8807cd3b9
target-arm: Add PMUSERENR_EL0 register
The Linux kernel accesses this register early in its setup.

Backports commit 8a83ffc2dafad3499b87a736b17ab1b203fdb00b from qemu
2018-02-20 15:36:31 -05:00
Lioncash b29e024f56
target-arm: Correct bad VBAR patch merge 2018-02-20 15:34:32 -05:00
Alistair Francis 2945893f40
target-arm: Add the pmovsclr_el0 and pmintenclr_el1 registers
Backports commit 978364f12adebb4b8d90fdeb71242cb3c1405740 from qemu
2018-02-20 15:27:50 -05:00
Alistair Francis c31856e34e
target-arm: Add the pmceid0 and pmceid1 registers
Backports commit 4054bfa9e7986c9b7d2bf70f9e10af9647e376fc from qemu
2018-02-20 15:22:41 -05:00
Peter Maydell 3d4f8b2d8f
target-arm: Move get/set_r13_banked() to op_helper.c
Move get/set_r13_banked() from helper.c to op_helper.c. This will
let us add exception-raising code to them, and also puts them
in the same file as get/set_user_reg(), which makes some conceptual
sense.

(The original reason for the helper.c/op_helper.c split was that
only op_helper.c had access to the CPU env pointer; this distinction
has not been true for a long time, though, and so the split is
now rather arbitrary.)

Backports commit 72309cee482868d6c4711931c3f7e02ab9dec229 from qemu

target-arm: Move bank_number() into internals.h

Move bank_number()'s implementation into internals.h, so
it's available in the user-mode-only compile as well.

Backports commit c766568d3604082c6fd45cbabe42c48e4861a13f from qemu
2018-02-20 15:09:07 -05:00
Peter Maydell 56a88557db
target-arm: Report correct syndrome for FPEXC32_EL2 traps
If access to FPEXC32_EL2 is trapped by CPTR_EL2.TFP or CPTR_EL3.TFP,
this should be reported with a syndrome register indicating an
FP access trap, not one indicating a system register access trap.

Backports commit f2cae6092767aaf418778eada15be444c23883be from qemu
2018-02-20 15:00:32 -05:00
Peter Maydell 425db8c149
target-arm: Implement MDCR_EL3.TDA and MDCR_EL2.TDA traps
Implement the debug register traps controlled by MDCR_EL2.TDA
and MDCR_EL3.TDA.

Backports commit d6c8cf815171e35e0b1ef4e0cff602ab3d575747 from qemu
2018-02-20 14:58:52 -05:00
Peter Maydell 7295676caf
target-arm: Implement MDCR_EL2.TDRA traps
Implement trapping of the "debug ROM" registers, which are controlled
by MDCR_EL2.TDRA for EL2 but by the more general MDCR_EL3.TDA for EL3.

Backports commit 91b0a23865558e2ce9c2e7042d404e8bf2e4b817 from qemu
2018-02-20 14:54:53 -05:00
Peter Maydell 537ff96e34
target-arm: Implement MDCR_EL3.TDOSA and MDCR_EL2.TDOSA traps
Implement the traps to EL2 and EL3 controlled by the bits
MDCR_EL2.TDOSA MDCR_EL3.TDOSA. These can configurably trap
accesses to the "powerdown debug" registers.

Backports commit 187f678d5c28251dba2b44127e59966b14518ef7 from qemu
2018-02-20 14:52:47 -05:00
Peter Maydell 7b503db3c6
target-arm: correct CNTFRQ access rights
Correct some corner cases we were getting wrong for
CNTFRQ access rights:
* should UNDEF from 32-bit Secure EL1
* only writable from the highest implemented exception level,
which might not be EL1 now

To clarify the code, provide a new utility function
arm_highest_el() which returns the highest implemented
exception level.

Backports commit 755026728abb19fba70e6b4396a27fa2e7550d74 from qemu
2018-02-20 14:49:28 -05:00
Peter Maydell aecf7b05dc
target-arm: Implement NSACR trapping behaviour
Implement some corner cases of the behaviour of the NSACR
register on ARMv8:
* if EL3 is AArch64 then accessing the NSACR from Secure EL1
with AArch32 should trap to EL3
* if EL3 is not present or is AArch64 then reads from NS EL1 and
NS EL2 return constant 0xc00

It would in theory be possible to implement all these with
a single reginfo definition, but for clarity we use three
separate definitions for the three cases and install the
right one based on the CPU feature flags.

Backports commit 2f027fc52d4b444a47cb05a9c96697372a6b57d2 from qemu
2018-02-20 11:29:29 -05:00
Peter Maydell 6dbc781ce3
target-arm: Add isread parameter to CPAccessFns
System registers might have access requirements which need to
be described via a CPAccessFn and which differ for reads and
writes. For this to be possible we need to pass the access
function a parameter to tell it whether the access being checked
is a read or a write.

Backports commit 3f208fd76bcc91a8506681bb8472f2398fe6f487 from qemu
2018-02-20 11:24:17 -05:00
Peter Maydell 4552444928
target-arm: Use access_trap_aa32s_el1() for SCR and MVBAR
The registers MVBAR and SCR should have the behaviour of trapping to
EL3 if accessed from Secure EL1, but we were incorrectly implementing
them to UNDEF (which would trap to EL1). Fix this by using the new
access_trap_aa32s_el1() access function.

Backports commit efe4a274083f61484a8f1478d93f229d43aa8095 from qemu
2018-02-20 11:10:38 -05:00
Peter Maydell c0411e5422
target-arm: Implement MDCR_EL3 and SDCR
Implement the MDCR_EL3 register (which is SDCR for AArch32).
For the moment we implement it as reads-as-written.

Backports commit 5513c3abed8e5fabe116830c63f0d3fe1f94bd21 from qemu
2018-02-20 11:08:15 -05:00
Edgar E. Iglesias 3ea1b2a84c
target-arm: Implement the S2 MMU inputsize > pamax check
Implement the inputsize > pamax check for Stage 2 translations.
This is CONSTRAINED UNPREDICTABLE and we choose to fault.

Backports commit 3526423e867765568ad95b8094ae8b4042cac215 from qemu
2018-02-19 01:22:00 -05:00
Edgar E. Iglesias 71f370d549
target-arm: Rename check_s2_startlevel to check_s2_mmu_setup
Rename check_s2_startlevel to check_s2_mmu_setup in preparation
for additional checks.

Backports commit a0e966c93a0968d29ef51447d08a6b7be6f4d757 from qemu
2018-02-19 01:16:11 -05:00
Edgar E. Iglesias bab59f6b18
target-arm: Apply S2 MMU startlevel table size check to AArch64
The S2 starting level table size check applies to both AArch32
and AArch64. Move it to common code.

Backports commit 98d68ec289750139258d9cd9ab3f6d7dd10bb762 from qemu
2018-02-19 01:13:35 -05:00
Peter Maydell d3e5003e53
target-arm: Make various system registers visible to EL3
The AArch64 system registers DACR32_EL2, IFSR32_EL2, SPSR_IRQ,
SPSR_ABT, SPSR_UND and SPSR_FIQ are visible and fully functional from
EL3 even if the CPU has no EL2 (unlike some others which are RES0
from EL3 in that configuration). Move them from el2_cp_reginfo[] to
v8_cp_reginfo[] so they are always present.

Backports commit 6a43e0b6e1f6bcd6b11656967422f4217258200a from qemu
2018-02-19 01:11:40 -05:00
Peter Maydell 22dadac875
target-arm: Implement FPEXC32_EL2 system register
The AArch64 FPEXC32_EL2 system register is visible at EL2 and EL3,
and allows those exception levels to read and write the FPEXC
register for a lower exception level that is using AArch32.

Backports commit 03fbf20f4da58f41998dc10ec7542f65d37ba759 from qemu
2018-02-18 22:52:54 -05:00
Peter Maydell 2ffb545ec3
target-arm: Handle exception return from AArch64 to non-EL0 AArch32
Remove the assumptions that the AArch64 exception return code was
making about a return to AArch32 always being a return to EL0.
This includes pulling out the illegal-SPSR checks so we can apply
them for return to 32 bit as well as return to 64-bit.

Backports commit 3809951bf61605974b91578c582de4da28f8ed07 from qemu
2018-02-18 22:46:50 -05:00
Peter Maydell 134eeeeacc
target-arm: Fix wrong AArch64 entry offset for EL2/EL3 target
The entry offset when taking an exception to AArch64 from a lower
exception level may be 0x400 or 0x600. 0x400 is used if the
implemented exception level immediately lower than the target level
is using AArch64, and 0x600 if it is using AArch32. We were
incorrectly implementing this as checking the exception level
that the exception was taken from. (The two can be different if
for example we take an exception from EL0 to AArch64 EL3; we should
in this case be checking EL2 if EL2 is implemented, and EL1 if
EL2 is not implemented.)

Backports commit 3d6f761713745dfed7d2ccfe98077d213a6a6eba from qemu
2018-02-18 22:43:52 -05:00
Peter Maydell d7c3ba6fa0
target-arm: Pull semihosting handling out to arm_cpu_do_interrupt()
Handling of semihosting calls should depend on the register width
of the calling code, not on that of any higher exception level,
so we need to identify and handle semihosting calls before we
decide whether to deliver the exception as an entry to AArch32
or AArch64. (EXCP_SEMIHOST is also an "internal exception" so
it has no target exception level in the first place.)

This will allow AArch32 EL1 code to use semihosting calls when
running under an AArch64 EL3.

Backports commit 904c04de2e1b425e7bc8c4ce2fae3d652eeed242 from qemu
2018-02-18 22:41:58 -05:00
Peter Maydell 4d0bdc61b6
target-arm: Use a single entry point for AArch64 and AArch32 exceptions
If EL2 or EL3 is present on an AArch64 CPU, then exceptions can be
taken to an exception level which is running AArch32 (if only EL0
and EL1 are present then EL1 must be AArch64 and all exceptions are
taken to AArch64). To support this we need to have a single
implementation of the CPU do_interrupt() method which can handle both
32 and 64 bit exception entry.

Pull the common parts of aarch64_cpu_do_interrupt() and
arm_cpu_do_interrupt() out into a new function which calls
either the AArch32 or AArch64 specific entry code once it has
worked out which one is needed.

We temporarily special-case the handling of EXCP_SEMIHOST to
avoid an assertion in arm_el_is_aa64(); the next patch will
pull all the semihosting handling out to the arm_cpu_do_interrupt()
level (since semihosting semantics depend on the register width
of the calling code, not on that of any higher EL).

Backports commit 966f758c49ff478c4757efa5970ce649161bff92 from qemu
2018-02-18 22:34:31 -05:00
Peter Maydell e1925bb5fb
target-arm: Move aarch64_cpu_do_interrupt() to helper.c
Move the aarch64_cpu_do_interrupt() function to helper.c. We want
to be able to call this from code that isn't AArch64-only, and
the move allows us to avoid awkward #ifdeffery at the callsite.

Backports commit f3a9b6945cbbb23f3a70da14e9ffdf1e60c580a8 from qemu
2018-02-18 22:23:06 -05:00
Lioncash f1f3ff39eb
target-arm: Support multiple address spaces in page table walks
If we have a secure address space, use it in page table walks:
when doing the physical accesses to read descriptors, make them
through the correct address space.

(The descriptor reads are the only direct physical accesses
made in target-arm/ for CPUs which might have TrustZone.)

Backports commit 5ce4ff6502fc6ae01a30c3917996c6c41be1d176 from qemu
2018-02-18 22:18:28 -05:00
Peter Maydell d3eb5fb710
target-arm: Implement cpu_get_phys_page_attrs_debug
Implement cpu_get_phys_page_attrs_debug instead of cpu_get_phys_page_debug.

Backports commit 0faea0c7e6b729c64035b3591b184eeeeef6f1d4 from qemu
2018-02-18 22:15:50 -05:00
Peter Maydell cd5c4037ac
target-arm: Clean up includes
Clean up includes so that osdep.h is included first and headers
which it implies are not included manually.

This commit was created with scripts/clean-includes.

Backports commit 74c21bd07491739c6e56bcb1f962e4df730e77f3 from qemu
2018-02-17 21:09:32 -05:00
Alvise Rigo 1e3e75fa44
target-arm: Use the right MMU index in arm_regime_using_lpae_format
arm_regime_using_lpae_format checks whether the LPAE extension is used
for stage 1 translation regimes. MMU indexes not exclusively of a stage 1
regime won't work with this method.

In case of ARMMMUIdx_S12NSE0 or ARMMMUIdx_S12NSE1, offset these values
by ARMMMUIdx_S1NSE0 to get the right index indicating a stage 1
translation regime.

Rename also the function to arm_s1_regime_using_lpae_format and update
the comments to reflect the change.

Backports commit deb2db996cbb9470b39ae1e383791ef34c4eb3c2 from qemu
2018-02-17 20:56:32 -05:00
Andrew Baumann e1701b069f
target-arm: raise exception on misaligned LDREX operands
Qemu does not generally perform alignment checks. However, the ARM ARM
requires implementation of alignment exceptions for a number of cases
including LDREX, and Windows-on-ARM relies on this.

This change adds plumbing to enable alignment checks on loads using
MO_ALIGN, a do_unaligned_access hook to raise the exception (data
abort), and uses the new aligned loads in LDREX (for all but
single-byte loads).

Backports commit 30901475b91ef1f46304404ab4bfe89097f61b96 from qemu
2018-02-17 19:29:29 -05:00
Peter Maydell 386e398c56
target-arm: Don't mask out bits [47:40] in LPAE descriptors for v8
In an LPAE format descriptor in ARMv8 the address field extends
up to bit 47, not just bit 39. Correct the masking so we don't
give incorrect results if the output address size is greater
than 40 bits, as it can be for AArch64.

(Note that we don't yet support the new-in-v8 Address Size fault which
should be generated if any translation table entry or TTBR contains
an address with non-zero bits above the most significant bit of the
maximum output address size.)

Backports commit 6109769a8b42bd0c3d5b1601c9b35fe7ea6a603e from qemu
2018-02-17 18:55:32 -05:00
Soren Brinkmann 3f4efdd95e
target-arm: Add and use symbolic names for register banks
Add BANK_<cpumode> #defines to index banked registers.

Backports commit 99a99c1fc8e9bfec1656ac5916c53977a93d3581 from qemu
2018-02-17 18:14:14 -05:00
Edgar E. Iglesias 942c18ead7
target-arm: Add support for S1 + S2 MMU translations
Backports commit 9b539263faa5c1b7fce2551092b5c7b6eea92081 from qemu
2018-02-17 15:24:10 -05:00
Edgar E. Iglesias f779375656
target-arm: Add S2 translation to 32bit S1 PTWs
Add support for applying S2 translation to 32bit S1
page-table walks.

Backports commit a614e69854a2e601716ee44dfe15c09b8b88f620 from qemu
2018-02-17 15:24:10 -05:00
Edgar E. Iglesias 085a94faac
target-arm: Add S2 translation to 64bit S1 PTWs
Add support for applying S2 translation to 64bit S1
page-table walks.

Backports commit 37785977627295162bff58b1f8777d94e20f4c5b from qemu
2018-02-17 15:24:09 -05:00