xen/arm: Move some of the functions to common file

regions.inc is added to hold the common earlyboot MPU regions configurations
between arm64 and arm32.

prepare_xen_region, fail_insufficient_regions() will be used by both arm32 and
arm64. Thus, they have been moved to regions.inc.

*_PRBAR are moved to arm64/sysregs.h.
*_PRLAR are moved to regions.inc as they are common between arm32 and arm64.

Introduce WRITE_SYSREG_ASM to write to the system registers from regions.inc.

Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
Reviewed-by: Luca Fancellu <luca.fancellu@arm.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
Tested-by: Luca Fancellu <luca.fancellu@arm.com>
This commit is contained in:
Ayan Kumar Halder authored and Michal Orzel committed 2025-04-16 08:35:32 +02:00
1 parent 38d0780979
commit a9445d1606
3 files changed
+93 -77

No files matched your search

+1 -77
View File
@@ -3,83 +3,7 @@
* Start-of-day code for an Armv8-R MPU system.
*/
#include <asm/early_printk.h>
#include <asm/mpu.h>
/* Backgroud region enable/disable */
#define SCTLR_ELx_BR BIT(17, UL)
#define REGION_TEXT_PRBAR 0x38 /* SH=11 AP=10 XN=00 */
#define REGION_RO_PRBAR 0x3A /* SH=11 AP=10 XN=10 */
#define REGION_DATA_PRBAR 0x32 /* SH=11 AP=00 XN=10 */
#define REGION_DEVICE_PRBAR 0x22 /* SH=10 AP=00 XN=10 */
#define REGION_NORMAL_PRLAR 0x0f /* NS=0 ATTR=111 EN=1 */
#define REGION_DEVICE_PRLAR 0x09 /* NS=0 ATTR=100 EN=1 */
/*
* Macro to prepare and set a EL2 MPU memory region.
* We will also create an according MPU memory region entry, which
* is a structure of pr_t, in table \prmap.
*
* sel: region selector
* base: reg storing base address
* limit: reg storing limit address
* prbar: store computed PRBAR_EL2 value
* prlar: store computed PRLAR_EL2 value
* maxcount: maximum number of EL2 regions supported
* attr_prbar: PRBAR_EL2-related memory attributes. If not specified it will be
* REGION_DATA_PRBAR
* attr_prlar: PRLAR_EL2-related memory attributes. If not specified it will be
* REGION_NORMAL_PRLAR
*
* Preserves \maxcount
* Output:
* \sel: Next available region selector index.
* Clobbers \base, \limit, \prbar, \prlar
*
* Note that all parameters using registers should be distinct.
*/
.macro prepare_xen_region, sel, base, limit, prbar, prlar, maxcount, attr_prbar=REGION_DATA_PRBAR, attr_prlar=REGION_NORMAL_PRLAR
/* Check if the region is empty */
cmp \base, \limit
beq 1f
/* Check if the number of regions exceeded the count specified in MPUIR_EL2 */
cmp \sel, \maxcount
bge fail_insufficient_regions
/* Prepare value for PRBAR_EL2 reg and preserve it in \prbar.*/
and \base, \base, #MPU_REGION_MASK
mov \prbar, #\attr_prbar
orr \prbar, \prbar, \base
/* Limit address should be inclusive */
sub \limit, \limit, #1
and \limit, \limit, #MPU_REGION_MASK
mov \prlar, #\attr_prlar
orr \prlar, \prlar, \limit
msr PRSELR_EL2, \sel
isb
msr PRBAR_EL2, \prbar
msr PRLAR_EL2, \prlar
dsb sy
isb
add \sel, \sel, #1
1:
.endm
/*
* Failure caused due to insufficient MPU regions.
*/
FUNC_LOCAL(fail_insufficient_regions)
PRINT("- Selected MPU region is above the implemented number in MPUIR_EL2 -\r\n")
1: wfe
b 1b
END(fail_insufficient_regions)
#include <asm/mpu/regions.inc>
/*
* Enable EL2 MPU and data cache
+13
View File
@@ -462,6 +462,17 @@
#define ZCR_ELx_LEN_SIZE 9
#define ZCR_ELx_LEN_MASK 0x1ff
#define REGION_TEXT_PRBAR 0x38 /* SH=11 AP=10 XN=00 */
#define REGION_RO_PRBAR 0x3A /* SH=11 AP=10 XN=10 */
#define REGION_DATA_PRBAR 0x32 /* SH=11 AP=00 XN=10 */
#define REGION_DEVICE_PRBAR 0x22 /* SH=10 AP=00 XN=10 */
#ifdef __ASSEMBLY__
#define WRITE_SYSREG_ASM(v, name) "msr " __stringify(name,) #v
#else /* __ASSEMBLY__ */
/* Access to system registers */
#define WRITE_SYSREG64(v, name) do { \
@@ -481,6 +492,8 @@
#define WRITE_SYSREG_LR(v, index) WRITE_SYSREG(v, ICH_LR_REG(index))
#define READ_SYSREG_LR(index) READ_SYSREG(ICH_LR_REG(index))
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_ARM_ARM64_SYSREGS_H */
/*
+79
View File
@@ -0,0 +1,79 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <asm/mpu.h>
#include <asm/sysregs.h>
/* Backgroud region enable/disable */
#define SCTLR_ELx_BR BIT(17, UL)
#define REGION_NORMAL_PRLAR 0x0f /* NS=0 ATTR=111 EN=1 */
#define REGION_DEVICE_PRLAR 0x09 /* NS=0 ATTR=100 EN=1 */
/*
* Macro to prepare and set a EL2 MPU memory region.
* We will also create an according MPU memory region entry, which
* is a structure of pr_t, in table \prmap.
*
* sel: region selector
* base: reg storing base address
* limit: reg storing limit address
* prbar: store computed PRBAR_EL2 value
* prlar: store computed PRLAR_EL2 value
* maxcount: maximum number of EL2 regions supported
* attr_prbar: PRBAR_EL2-related memory attributes. If not specified it will be
* REGION_DATA_PRBAR
* attr_prlar: PRLAR_EL2-related memory attributes. If not specified it will be
* REGION_NORMAL_PRLAR
*
* Preserves maxcount
* Output:
* sel: Next available region selector index.
* Clobbers base, limit, prbar, prlar
*
* Note that all parameters using registers should be distinct.
*/
.macro prepare_xen_region, sel, base, limit, prbar, prlar, maxcount, attr_prbar=REGION_DATA_PRBAR, attr_prlar=REGION_NORMAL_PRLAR
/* Check if the region is empty */
cmp \base, \limit
beq 1f
/* Check if the number of regions exceeded the count specified in MPUIR_EL2 */
cmp \sel, \maxcount
bge fail_insufficient_regions
/* Prepare value for PRBAR_EL2 reg and preserve it in \prbar.*/
and \base, \base, #MPU_REGION_MASK
mov \prbar, #\attr_prbar
orr \prbar, \prbar, \base
/* Limit address should be inclusive */
sub \limit, \limit, #1
and \limit, \limit, #MPU_REGION_MASK
mov \prlar, #\attr_prlar
orr \prlar, \prlar, \limit
WRITE_SYSREG_ASM(\sel, PRSELR_EL2)
isb
WRITE_SYSREG_ASM(\prbar, PRBAR_EL2)
WRITE_SYSREG_ASM(\prlar, PRLAR_EL2)
dsb sy
isb
add \sel, \sel, #1
1:
.endm
/* Failure caused due to insufficient MPU regions. */
FUNC_LOCAL(fail_insufficient_regions)
PRINT("- Selected MPU region is above the implemented number in MPUIR_EL2 -\r\n")
1: wfe
b 1b
END(fail_insufficient_regions)
/*
* Local variables:
* mode: ASM
* indent-tabs-mode: nil
* End:
*/
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.