Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pal/baremetal/base/include/pal_common_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ void pal_warn_not_implemented(const char *api_name);

/* TYPE 0/1 Cmn Cfg reg offsets and mask*/
#define TYPE01_CPR 0x34
#define TYPE01_CPR_MASK 0xff
#define TYPE01_CPR_MASK 0xfc
#define COMMAND_REG_OFFSET 0x04
#define REG_ACC_DATA 0x7

Expand Down Expand Up @@ -137,7 +137,7 @@ void pal_warn_not_implemented(const char *api_name);
#define PCIE_CIDR_MASK 0xff
#define PCIE_NCPR_MASK 0xff
#define PCIE_ECAP_CIDR_MASK 0xffff
#define PCIE_ECAP_NCPR_MASK 0xfff
#define PCIE_ECAP_NCPR_MASK 0xffc

#define PCIE_ECAP_START 0x100

Expand Down
2 changes: 2 additions & 0 deletions pal/uefi_acpi/include/pal_uefi.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,12 @@ typedef struct {
**/
typedef struct {
UINT64 ttbr0; ///< Translation Table Base Register 0
UINT64 ttbr1; ///< Translation Table Base Register 1
UINT64 tcr; ///< Translation Control Register
UINT64 mair; ///< Memory Attribute Indirection Register
UINT64 sctlr; ///< System Control Register
UINT32 current_el; ///< Current Exception Level (1 or 2)
UINT32 reserved; ///< Reserved for alignment
} PE_MMU_CONFIG;

/**
Expand Down
27 changes: 21 additions & 6 deletions pal/uefi_acpi/src/AArch64/ModuleEntryPoint.S
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ ASM_PFX(StackSize): .8byte 0x100

// PE_MMU_CONFIG structure offsets
.equ MMU_CFG_TTBR0, 0
.equ MMU_CFG_TCR, 8
.equ MMU_CFG_MAIR, 16
.equ MMU_CFG_SCTLR, 24
.equ MMU_CFG_EL, 32
.equ MMU_CFG_TTBR1, 8
.equ MMU_CFG_TCR, 16
.equ MMU_CFG_MAIR, 24
.equ MMU_CFG_SCTLR, 32
.equ MMU_CFG_EL, 40

// SCTLR bits
.equ SCTLR_M_BIT, (1 << 0) // MMU enable
Expand Down Expand Up @@ -77,14 +78,21 @@ _SetupMmuEl1:
dsb sy
isb

// Set MAIR, TCR, TTBR0 for EL1
// Set MAIR, TCR, TTBR0, TTBR1 for EL1
msr mair_el1, x14
isb
msr tcr_el1, x13
isb
msr ttbr0_el1, x12
isb

// Program TTBR1 only if TCR.EPD1 (bit[23]) enables TTBR1 walks
tbnz x13, #23, _SkipTtbr1El1
ldr x18, [x11, #MMU_CFG_TTBR1]
msr ttbr1_el1, x18
isb
_SkipTtbr1El1:

// Enable MMU and caches for EL1
// Use the same SCTLR value as primary PE (which has M, C, I bits set)
msr sctlr_el1, x15
Expand All @@ -97,14 +105,21 @@ _SetupMmuEl2:
dsb sy
isb

// Set MAIR, TCR, TTBR0 for EL2
// Set MAIR, TCR, TTBR0, TTBR1 for EL2
msr mair_el2, x14
isb
msr tcr_el2, x13
isb
msr ttbr0_el2, x12
isb

// Program TTBR1 only if TCR.EPD1 (bit[23]) enables TTBR1 walks
tbnz x13, #23, _SkipTtbr1El2
ldr x18, [x11, #MMU_CFG_TTBR1]
msr ttbr1_el2, x18
isb
_SkipTtbr1El2:

// Enable MMU and caches for EL2
// Use the same SCTLR value as primary PE (which has M, C, I bits set)
msr sctlr_el2, x15
Expand Down
19 changes: 17 additions & 2 deletions pal/uefi_acpi/src/pal_pe.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ static PE_MMU_CONFIG gMmuConfig __attribute__((aligned(64)));
UINT64 AA64ReadCurrentEL(VOID);
UINT64 AA64ReadTtbr0El1(VOID);
UINT64 AA64ReadTtbr0El2(VOID);
UINT64 AA64ReadTtbr1El1(VOID);
UINT64 AA64ReadTtbr1El2(VOID);
UINT64 AA64ReadTcr1(VOID);
UINT64 AA64ReadTcr2(VOID);
UINT64 AA64ReadMair1(VOID);
Expand All @@ -57,6 +59,7 @@ UINT64 AA64ReadSctlr2(VOID);

#define ENABLED_BIT(flags) (flags & 0x1)
#define ONLINE_CAP_BIT(flags) ((flags > 3) & 0x1)
#define TCR_EPD1_BIT 23U

UINT64
pal_get_madt_ptr();
Expand Down Expand Up @@ -224,7 +227,7 @@ PalGetMaxMpidr()

/**
@brief Captures the primary PE's MMU configuration for use by secondary PEs.
This function reads TTBR0, TCR, MAIR, and SCTLR from the current EL
This function reads TTBR0, TTBR1, TCR, MAIR, and SCTLR from the current EL
and stores them in a global structure that secondary PEs can access.

@param None
Expand All @@ -235,6 +238,7 @@ VOID
PalCaptureMmuConfig(VOID)
{
UINT64 CurrentEl;
UINT32 SkipTtbr1;

/* Read current exception level */
CurrentEl = (AA64ReadCurrentEL() >> 2) & 0x3;
Expand All @@ -246,20 +250,31 @@ PalCaptureMmuConfig(VOID)
gMmuConfig.tcr = AA64ReadTcr2();
gMmuConfig.mair = AA64ReadMair2();
gMmuConfig.sctlr = AA64ReadSctlr2();
/* Read TTBR1_EL2 only if TCR_EL2 allows translation via TTBR1 (EPD1 bit[23]) */
SkipTtbr1 = (gMmuConfig.tcr >> TCR_EPD1_BIT) & 0x1;
if (!SkipTtbr1)
gMmuConfig.ttbr1 = AA64ReadTtbr1El2();
} else {
/* Assume EL1 */
gMmuConfig.ttbr0 = AA64ReadTtbr0El1();
gMmuConfig.tcr = AA64ReadTcr1();
gMmuConfig.mair = AA64ReadMair1();
gMmuConfig.sctlr = AA64ReadSctlr1();
/* Read TTBR1_EL1 only if TCR_EL1 allows translation via TTBR1 (EPD1 bit[23]) */
SkipTtbr1 = (gMmuConfig.tcr >> TCR_EPD1_BIT) & 0x1;
if (!SkipTtbr1)
gMmuConfig.ttbr1 = AA64ReadTtbr1El1();
}

acs_print(ACS_PRINT_INFO, L" MMU Config captured at EL%d\n", gMmuConfig.current_el);
acs_print(ACS_PRINT_DEBUG, L" MMU Config captured at EL%d\n", gMmuConfig.current_el);
acs_print(ACS_PRINT_DEBUG, L" TTBR0: 0x%lx\n", gMmuConfig.ttbr0);
acs_print(ACS_PRINT_DEBUG, L" TCR: 0x%lx\n", gMmuConfig.tcr);
acs_print(ACS_PRINT_DEBUG, L" MAIR: 0x%lx\n", gMmuConfig.mair);
acs_print(ACS_PRINT_DEBUG, L" SCTLR: 0x%lx\n", gMmuConfig.sctlr);

if (!SkipTtbr1)
acs_print(ACS_PRINT_DEBUG, L" TTBR1: 0x%lx\n", gMmuConfig.ttbr1);

/* Clean cache to ensure secondary PEs see the config */
pal_pe_data_cache_ops_by_va((UINT64)&gMmuConfig, CLEAN_AND_INVALIDATE);
}
Expand Down
2 changes: 2 additions & 0 deletions pal/uefi_dt/include/pal_uefi.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,12 @@ typedef struct {
**/
typedef struct {
UINT64 ttbr0; ///< Translation Table Base Register 0
UINT64 ttbr1; ///< Translation Table Base Register 1
UINT64 tcr; ///< Translation Control Register
UINT64 mair; ///< Memory Attribute Indirection Register
UINT64 sctlr; ///< System Control Register
UINT32 current_el; ///< Current Exception Level (1 or 2)
UINT32 reserved; ///< Reserved for alignment
} PE_MMU_CONFIG;

/**
Expand Down
27 changes: 21 additions & 6 deletions pal/uefi_dt/src/AArch64/ModuleEntryPoint.S
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ ASM_PFX(StackSize): .8byte 0x100

// PE_MMU_CONFIG structure offsets
.equ MMU_CFG_TTBR0, 0
.equ MMU_CFG_TCR, 8
.equ MMU_CFG_MAIR, 16
.equ MMU_CFG_SCTLR, 24
.equ MMU_CFG_EL, 32
.equ MMU_CFG_TTBR1, 8
.equ MMU_CFG_TCR, 16
.equ MMU_CFG_MAIR, 24
.equ MMU_CFG_SCTLR, 32
.equ MMU_CFG_EL, 40

// SCTLR bits
.equ SCTLR_M_BIT, (1 << 0) // MMU enable
Expand Down Expand Up @@ -77,14 +78,21 @@ _SetupMmuEl1:
dsb sy
isb

// Set MAIR, TCR, TTBR0 for EL1
// Set MAIR, TCR, TTBR0, TTBR1 for EL1
msr mair_el1, x14
isb
msr tcr_el1, x13
isb
msr ttbr0_el1, x12
isb

// Program TTBR1 only if TCR.EPD1 (bit[23]) enables TTBR1 walks
tbnz x13, #23, _SkipTtbr1El1
ldr x18, [x11, #MMU_CFG_TTBR1]
msr ttbr1_el1, x18
isb
_SkipTtbr1El1:

// Enable MMU and caches for EL1
// Use the same SCTLR value as primary PE (which has M, C, I bits set)
msr sctlr_el1, x15
Expand All @@ -97,14 +105,21 @@ _SetupMmuEl2:
dsb sy
isb

// Set MAIR, TCR, TTBR0 for EL2
// Set MAIR, TCR, TTBR0, TTBR1 for EL2
msr mair_el2, x14
isb
msr tcr_el2, x13
isb
msr ttbr0_el2, x12
isb

// Program TTBR1 only if TCR.EPD1 (bit[23]) enables TTBR1 walks
tbnz x13, #23, _SkipTtbr1El2
ldr x18, [x11, #MMU_CFG_TTBR1]
msr ttbr1_el2, x18
isb
_SkipTtbr1El2:

// Enable MMU and caches for EL2
// Use the same SCTLR value as primary PE (which has M, C, I bits set)
msr sctlr_el2, x15
Expand Down
20 changes: 18 additions & 2 deletions pal/uefi_dt/src/pal_pe.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ static PE_MMU_CONFIG gMmuConfig __attribute__((aligned(64)));
UINT64 AA64ReadCurrentEL(VOID);
UINT64 AA64ReadTtbr0El1(VOID);
UINT64 AA64ReadTtbr0El2(VOID);
UINT64 AA64ReadTtbr1El1(VOID);
UINT64 AA64ReadTtbr1El2(VOID);
UINT64 AA64ReadTcr1(VOID);
UINT64 AA64ReadTcr2(VOID);
UINT64 AA64ReadMair1(VOID);
Expand Down Expand Up @@ -88,6 +90,8 @@ static char psci_dt_arr[][PSCI_COMPATIBLE_STR_LEN] = {
#define SIZE_STACK_SECONDARY_PE 0x100 //256 bytes per core
#define UPDATE_AFF_MAX(src,dest,mask) ((dest & mask) > (src & mask) ? (dest & mask) : (src & mask))

#define TCR_EPD1_BIT 23U

UINT64
pal_get_madt_ptr();

Expand Down Expand Up @@ -266,7 +270,7 @@ PalGetMaxMpidr()

/**
@brief Captures the primary PE's MMU configuration for use by secondary PEs.
This function reads TTBR0, TCR, MAIR, and SCTLR from the current EL
This function reads TTBR0, TTBR1, TCR, MAIR, and SCTLR from the current EL
and stores them in a global structure that secondary PEs can access.

@param None
Expand All @@ -277,6 +281,7 @@ VOID
PalCaptureMmuConfig(VOID)
{
UINT64 CurrentEl;
UINT32 SkipTtbr1;

/* Read current exception level */
CurrentEl = (AA64ReadCurrentEL() >> 2) & 0x3;
Expand All @@ -288,20 +293,31 @@ PalCaptureMmuConfig(VOID)
gMmuConfig.tcr = AA64ReadTcr2();
gMmuConfig.mair = AA64ReadMair2();
gMmuConfig.sctlr = AA64ReadSctlr2();
/* Read TTBR1_EL2 only if TCR_EL2 allows translation via TTBR1 (EPD1 bit[23]) */
SkipTtbr1 = (gMmuConfig.tcr >> TCR_EPD1_BIT) & 0x1;
if (!SkipTtbr1)
gMmuConfig.ttbr1 = AA64ReadTtbr1El2();
} else {
/* Assume EL1 */
gMmuConfig.ttbr0 = AA64ReadTtbr0El1();
gMmuConfig.tcr = AA64ReadTcr1();
gMmuConfig.mair = AA64ReadMair1();
gMmuConfig.sctlr = AA64ReadSctlr1();
/* Read TTBR1_EL1 only if TCR_EL1 allows translation via TTBR1 (EPD1 bit[23]) */
SkipTtbr1 = (gMmuConfig.tcr >> TCR_EPD1_BIT) & 0x1;
if (!SkipTtbr1)
gMmuConfig.ttbr1 = AA64ReadTtbr1El1();
}

acs_print(ACS_PRINT_INFO, L" MMU Config captured at EL%d\n", gMmuConfig.current_el);
acs_print(ACS_PRINT_DEBUG, L" MMU Config captured at EL%d\n", gMmuConfig.current_el);
acs_print(ACS_PRINT_DEBUG, L" TTBR0: 0x%lx\n", gMmuConfig.ttbr0);
acs_print(ACS_PRINT_DEBUG, L" TCR: 0x%lx\n", gMmuConfig.tcr);
acs_print(ACS_PRINT_DEBUG, L" MAIR: 0x%lx\n", gMmuConfig.mair);
acs_print(ACS_PRINT_DEBUG, L" SCTLR: 0x%lx\n", gMmuConfig.sctlr);

if (!SkipTtbr1)
acs_print(ACS_PRINT_DEBUG, L" TTBR1: 0x%lx\n", gMmuConfig.ttbr1);

/* Clean cache to ensure secondary PEs see the config */
pal_pe_data_cache_ops_by_va((UINT64)&gMmuConfig, CLEAN_AND_INVALIDATE);
}
Expand Down
10 changes: 10 additions & 0 deletions test_pool/pcie/p002.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,16 @@ payload(void)
while (next_offset)
{
val_pcie_read_cfg(bdf, next_offset, &data);

/* if data read from next ECAP offset is 0xFFFF-FFFF, report failure */
if (data == PCIE_UNKNOWN_RESPONSE) {
val_print(ACS_PRINT_ERR,
"\n Invalid data read from ECAP offset 0x%x", next_offset);
val_memory_set(skip_rid_list, sizeof(uint32_t) * MAX_VFS, 0);
val_set_status(index, RESULT_FAIL(TEST_NUM, 03));
return;
}

curr_offset = next_offset;
next_offset = ((data >> PCIE_ECAP_NCPR_SHIFT) & PCIE_ECAP_NCPR_MASK);
}
Expand Down
4 changes: 2 additions & 2 deletions val/include/acs_pcie_spec.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
#define TYPE01_CCR_SHIFT 8
#define TYPE01_CCR_MASK 0xffffff
#define TYPE01_CPR_SHIFT 0
#define TYPE01_CPR_MASK 0xff
#define TYPE01_CPR_MASK 0xfc
#define TYPE01_HTR_SHIFT 16
#define TYPE01_HTR_MASK 0xff
#define TYPE01_IPR_SHIFT 8
Expand Down Expand Up @@ -184,7 +184,7 @@
#define PCIE_CIDR_MASK 0xff
#define PCIE_NCPR_MASK 0xff
#define PCIE_ECAP_CIDR_MASK 0xffff
#define PCIE_ECAP_NCPR_MASK 0xfff
#define PCIE_ECAP_NCPR_MASK 0xffc

#define PCIE_CAP_START 0x40
#define PCIE_CAP_END 0xFC
Expand Down
2 changes: 1 addition & 1 deletion val/include/val_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
set for wakeup and wd tests*/
#define WAKEUP_WD_PASS_TIMEOUT_MAX_THRESHOLD 2000000 /*minimum timeout that can be
set for wakeup and wd tests*/
#define WAKEUP_WD_FAILSAFE_TIMEOUT_MULTIPLIER 2 /*fail safe timeout multipler
#define WAKEUP_WD_FAILSAFE_TIMEOUT_MULTIPLIER 100 /*fail safe timeout multipler
multiplied to timeout of ISR
under test*/
#define WAKEUP_WD_PASS_TIMEOUT_DEFAULT 1000 /*minimum timeout set
Expand Down
12 changes: 12 additions & 0 deletions val/src/AArch64/PeRegSysSupport.S
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,8 @@ GCC_ASM_EXPORT (AA64WriteTcr1)
GCC_ASM_EXPORT (AA64WriteTcr2)
GCC_ASM_EXPORT (AA64WriteTtbr0El1)
GCC_ASM_EXPORT (AA64WriteTtbr0El2)
GCC_ASM_EXPORT (AA64WriteTtbr1El1)
GCC_ASM_EXPORT (AA64WriteTtbr1El2)
GCC_ASM_EXPORT (AA64WriteSctlr1)
GCC_ASM_EXPORT (AA64WriteSctlr2)
GCC_ASM_EXPORT (AA64TlbiVmalle1)
Expand Down Expand Up @@ -779,6 +781,16 @@ ASM_PFX(AA64WriteTtbr0El2):
isb
ret

ASM_PFX(AA64WriteTtbr1El1):
msr ttbr1_el1, x0 // write EL1 TTBR1
isb
ret

ASM_PFX(AA64WriteTtbr1El2):
msr ttbr1_el2, x0 // write EL2 TTBR1
isb
ret

ASM_PFX(AA64WriteSctlr1):
msr sctlr_el1, x0 // write EL1 SCTLR
isb
Expand Down
9 changes: 7 additions & 2 deletions val/src/acs_pcie.c
Original file line number Diff line number Diff line change
Expand Up @@ -961,7 +961,7 @@ val_pcie_find_capability(uint32_t bdf, uint32_t cid_type, uint32_t cid, uint32_t

if (cid_type == PCIE_CAP) {

/* Serach in PCIe configuration space */
/* Search in PCIe configuration space */
ret = val_pcie_read_cfg(bdf, TYPE01_CPR, &reg_value);
if (ret == PCIE_NO_MAPPING || reg_value == PCIE_UNKNOWN_RESPONSE)
return ret;
Expand All @@ -980,11 +980,16 @@ val_pcie_find_capability(uint32_t bdf, uint32_t cid_type, uint32_t cid, uint32_t
} else if (cid_type == PCIE_ECAP)
{

/* Serach in PCIe extended configuration space */
/* Search in PCIe extended configuration space */
next_cap_offset = PCIE_ECAP_START;
while (next_cap_offset)
{
val_pcie_read_cfg(bdf, next_cap_offset, &reg_value);

/* if data at next ECAP offset reads 0xFFFF-FFFF, exit with failure code */
if (reg_value == PCIE_UNKNOWN_RESPONSE)
return PCIE_UNKNOWN_RESPONSE;

if ((reg_value & PCIE_ECAP_CIDR_MASK) == cid)
{
*cid_offset = next_cap_offset;
Expand Down
Loading