diff --git a/README.md b/README.md index 7d38a51c..9ee71f51 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ## Base System Architecture **Base System Architecture** (BSA) specification describes a hardware system architecture based on the Arm 64-bit architecture. System software such as operating systems, hypervisors, and firmware rely on this. It addresses PE features and key aspects of system architecture. -For more information, download the [BSA specification](https://developer.arm.com/documentation/den0094/latest) +For more information, see [BSA specification](https://developer.arm.com/documentation/den0094/latest) ## BSA - Architecture Compliance Suite @@ -16,35 +16,49 @@ A few tests are executed by running the BSA ACS Linux application which in turn ## Release details - - Code quality: v0.5 Alpha + - Code quality: v0.9 Beta - The tests are written for version 1.0 of the BSA specification. - The compliance suite is not a substitute for design verification. - To review the BSA ACS logs, Arm licensees can contact Arm directly through their partner managers. ## GitHub branch - - To pick up the release version of the code, checkout the coresponding tag from main branch. + - To pick up the release version of the code, checkout the corresponding tag from the main branch. - To get the latest version of the code with bug fixes and new features, use the main branch. ## Additional reading - - For information on the test scenarios currently implemented for IR, see [Scenario Document](docs/Arm_Base_System_Architecture_Scenario_IR.pdf). + - For information on the test scenarios currently implemented for platform using Device tree, see [Scenario Document](docs/Arm_Base_System_Architecture_Scenario_IR.pdf). + - For information on the test scenarios currently implemented for platform using ACPI table, see [Scenario Document](docs/Arm_Base_System_Architecture_Scenario_ES.pdf). ## ACS build steps - UEFI Shell application ### Prebuilt images Prebuilt images for each release are available in the prebuilt_images folder of the release branch. You can choose to use these images or build your own image by following the steps below. If you choose to use the prebuilt image, see the Test suite execution section below for details on how to run the application. -### Prerequisites +### 1. Building from source Before you start the ACS build, ensure that the following requirements are met. - Any mainstream Linux-based OS distribution running on a x86 or AArch64 machine. - git clone the edk2-stable202102 tag of [EDK2 tree](https://github.com/tianocore/edk2). - git clone the [EDK2 port of libc](https://github.com/tianocore/edk2-libc) to local . -- Install GCC 7.5 or a later toolchain for Linux from [here](https://releases.linaro.org/components/toolchain/binaries/). +- GCC 7.5 or a later toolchain for Linux from [here](https://releases.linaro.org/components/toolchain/binaries/). - Install the build prerequisite packages to build EDK2. Note: The details of the packages are beyond the scope of this document. -To start the ACS build for IR, perform the following steps: +#### 1.1 Target Platform +##### To start the ACS build for platform using ACPI table, perform the following steps: + +1. cd local_edk2_path +2. git submodule update --init --recursive +3. git clone https://github.com/ARM-software/bsa-acs.git ShellPkg/Application/bsa-acs +4. Add the following to the [LibraryClasses.common] section in ShellPkg/ShellPkg.dsc +> BsaValLib|ShellPkg/Application/bsa-acs/val/BsaValLib.inf +> BsaPalLib|ShellPkg/Application/bsa-acs/platform/pal_uefi_acpi/BsaPalLib.inf + +5. Add the following in the [components] section of ShellPkg/ShellPkg.dsc +> ShellPkg/Application/bsa-acs/uefi_app/BsaAcs.inf + +##### To start the ACS build for platform using Device tree, perform the following steps: 1. cd local_edk2_path 2. git submodule update --init --recursive @@ -64,25 +78,25 @@ To start the ACS build for IR, perform the following steps: > +//Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &gHiiConfigRouting); > +//ASSERT_EFI_ERROR (Status); -### Linux build environment -If the build environment is Linux, perform the following steps: +#### 1.2 Build environment +##### If the build environment is Linux, perform the following steps: 1. export GCC49_AARCH64_PREFIX= GCC7.5 toolchain path pointing to /bin/aarch64-linux-gnu- in case of x86 machine. For an AArch64 build it should point to /usr/bin/ 2. export PACKAGES_PATH= path pointing to edk2-libc 3. source edksetup.sh 4. make -C BaseTools/Source/C 5. source ShellPkg/Application/bsa-acs/tools/scripts/acsbuild.sh -### Build output +#### 1.3 Build output The EFI executable file is generated at /Build/Shell/DEBUG_GCC49/AARCH64/Bsa.efi -## Test suite execution +### 2. Test suite execution The execution of the compliance suite varies depending on the test environment. The below steps assume that the test suite is invoked through the ACS UEFI shell application. -### Prerequisites +#### Prerequisites - If the system supports LPIs (Interrupt ID > 8192) then Firmware should support installation of handler for LPI interrupts. - If you are using edk2, change the ArmGic driver in the ArmPkg to support installation of handler for LPIs. - Add the following in edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c @@ -92,7 +106,8 @@ The execution of the compliance suite varies depending on the test environment. > -mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase); > +mGicNumInterrupts = ARM_GIC_MAX_NUM_INTERRUPT; -### Silicon +#### 2.1 Silicon + On a system where a USB port is available and functional, perform the following steps: #### For IR Systems: @@ -111,12 +126,13 @@ On a system where a USB port is available and functional, perform the following 9. Copy the UART console output to a log file. Note: 'Shell.efi' is available in the [pebuilt_images/IR](prebuilt_images) -### Emulation environment with secondary storage +#### 2.2 Emulation environment with secondary storage On an emulation environment with secondary storage, perform the following steps: 1. Create an image file which contains the 'Bsa.efi' file. For example: - mkfs.vfat -C -n HD0 hda.img 2097152 - - sudo mount -o rw,loop=/dev/loop0,uid=`whoami`,gid=`whoami` hda.img /mnt/bsa + - sudo mount -o rw,loop=/dev/loop0,uid=\`whoami\`,gid=\`whoami\` hda.img /mnt/bsa + In case loop0 is busy, please specify the one that is free. - sudo cp "/Bsa.efi" /mnt/bsa/ - sudo umount /mnt/bsa 2. Load the image file to the secondary storage using a backdoor. The steps to load the image file are emulation environment-specific and beyond the scope of this document. @@ -126,8 +142,10 @@ On an emulation environment with secondary storage, perform the following steps: 6. To start the compliance tests, run the executable Bsa.efi with the appropriate parameters. 7. Copy the UART console output to a log file for analysis and certification. + - For information on the BSA uefi shell application parameters, see [User Guide](docs/Arm_Base_System_Architecture_Compliance_User_Guide.pdf). + -### Emulation environment without secondary storage +#### 2.3 Emulation environment without secondary storage On an emulation platform where secondary storage is not available, perform the following steps: @@ -139,81 +157,63 @@ On an emulation platform where secondary storage is not available, perform the f ## Linux OS-based tests -Certain Peripheral, PCIe and Memory map tests require Linux operating system with kernel version 5.10 or above. +Certain Peripheral, PCIe and Memory map tests require Linux operating system with kernel version 5.11 or above. This chapter provides information on executing tests from the Linux application. -### Build steps and environment setup +### 1. Build steps and environment setup This section lists the porting and build steps for the kernel module. -The patch for the kernel tree and the Linux PAL are hosted separately on [linux-acs](https://gitlab.arm.com/linux-arm/linux-acs) repo +The patch for the kernel tree and the Linux PAL are hosted separately on [linux-acs](https://git.gitlab.arm.com/linux-arm/linux-acs.git) repo -### Building the kernel module +### 1.1 Building the kernel module #### Prerequisites -- Linux kernel source version 5.10. +- Linux kernel source version 5.11. - Linaro GCC tool chain 7.5 or above. - Build environment for AArch64 Linux kernel. #### Porting steps for Linux kernel 1. git clone https://git.gitlab.arm.com/linux-arm/linux-acs.git bsa-acs-drv 2. git clone https://github.com/ARM-software/bsa-acs.git bsa-acs -3. git clone https://github.com/torvalds/linux.git -b v5.10 +3. git clone https://github.com/torvalds/linux.git -b v5.11 4. export CROSS_COMPILE= pointing to /bin/aarch64-linux-gnu- -5. git apply /bsa-acs-drv/kernel/src/0001-BSA-SBSA-ACS-Linux-5.10.patch to your kernel source tree. +5. git apply /bsa-acs-drv/kernel/src/0001-BSA-ACS-Linux-5.11.patch to your kernel source tree. 6. make ARCH=arm64 defconfig && make -j $(nproc) ARCH=arm64 -#### Build steps for BSA kernel module +#### 1.2 Build steps for BSA kernel module 1. cd /bsa-acs-drv/files 2. export CROSS_COMPILE=/bin/aarch64-linux-gnu- 3. export KERNEL_SRC= 4. ./setup.sh 5. ./linux_bsa_acs.sh -bsa_acs.ko file is generated. -#### BSA Linux application build +Successfull completion of above steps will generate bsa_acs.ko + +#### 1.3 BSA Linux application build 1. cd /linux_app/bsa-acs-app 2. export CROSS_COMPILE=/bin/aarch64-linux-gnu- 3. make -The executable file bsa is generated. - -## Linux application arguments -Run the Linux application with the following set of arguments -```sh -shell> bsa [--v ] [--skip ] -``` -| Argument | Description | -| ------ | ------ | -| v | Print level | -|| 1. INFO and above| -|| 2. DEBUG and above| -|| 3. TEST and above| -|| 4. WARN and ERROR| -|| 5. ERROR| -||| -| skip | Overrides the suite to skip the execution of a particular test. -|| For example, 53 skips test case with ID 53.| - -### Example -```sh -shell> bsa --v 3 --skip 53 -``` -This set of parameters tests for compliance against BSA with print verbosity set to 3, and skips test number 53. +Successfull completion of above steps will generate executable file bsa -### Loading the kernel module +### 2. Loading the kernel module Before the BSA ACS Linux application can be run, load the BSA ACS kernel module using the insmod command. ```sh shell> insmod bsa_acs.ko ``` -### Running BSA ACS +### 3. Running BSA ACS ```sh shell> ./bsa ``` + - For information on the BSA Linux application parameters, see [User Guide](docs/Arm_Base_System_Architecture_Compliance_User_Guide.pdf). ## Security implication The Arm System Ready ACS test suite may run at a higher privilege level. An attacker may utilize these tests to elevate the privilege which can potentially reveal the platform security assets. To prevent the leakage of secure information, Arm strongly recommends that you run the ACS test suite only on development platforms. If it is run on production systems, the system should be scrubbed after running the test suite. ## Limitations - No known limitations. + + - PCIE iEP rules are out of scope for current release. + - ITS rules are available only for systems that present firmware compliant to SBBR. + - Peripheral rules RB_PER_01,02,03 are not implemented in current release for systems that present firmware compliant to EBBR. ## License BSA ACS is distributed under Apache v2.0 License. diff --git a/changelog.txt b/changelog.txt index 48a4a258..b7a47531 100644 --- a/changelog.txt +++ b/changelog.txt @@ -6,3 +6,9 @@ v21.05_05_ALPHA * BSA: Provided documentations required to build and run BSA ACS on supported platforms. * BSA: Provided documentation on test scenarios. +v21.07_0.9_BETA + +* BSA: Increaed PCIe rules coverage +* BSA: Initial ITS tests for systems presenting firmware which is SBBR complaint +* BSA: Renamed pal_uefi to pal_uefi_acpi +* BSA: Bug Fixes on Alpha release diff --git a/docs/Arm_Base_System_Architecture_Compliance_User_Guide.pdf b/docs/Arm_Base_System_Architecture_Compliance_User_Guide.pdf index fa5e3390..682fc6d4 100644 Binary files a/docs/Arm_Base_System_Architecture_Compliance_User_Guide.pdf and b/docs/Arm_Base_System_Architecture_Compliance_User_Guide.pdf differ diff --git a/docs/Arm_Base_System_Architecture_Compliance_Validation_Methodology.pdf b/docs/Arm_Base_System_Architecture_Compliance_Validation_Methodology.pdf index 265ea56d..7cc25d86 100644 Binary files a/docs/Arm_Base_System_Architecture_Compliance_Validation_Methodology.pdf and b/docs/Arm_Base_System_Architecture_Compliance_Validation_Methodology.pdf differ diff --git a/docs/Arm_Base_System_Architecture_Scenario_ES.pdf b/docs/Arm_Base_System_Architecture_Scenario_ES.pdf new file mode 100644 index 00000000..6c4859d2 Binary files /dev/null and b/docs/Arm_Base_System_Architecture_Scenario_ES.pdf differ diff --git a/docs/Arm_Base_System_Architecture_Scenario_IR.pdf b/docs/Arm_Base_System_Architecture_Scenario_IR.pdf index 9ddbf598..d615f1c8 100644 Binary files a/docs/Arm_Base_System_Architecture_Scenario_IR.pdf and b/docs/Arm_Base_System_Architecture_Scenario_IR.pdf differ diff --git a/linux_app/bsa-acs-app/bsa_app_main.c b/linux_app/bsa-acs-app/bsa_app_main.c index 81876953..06ab8965 100644 --- a/linux_app/bsa-acs-app/bsa_app_main.c +++ b/linux_app/bsa-acs-app/bsa_app_main.c @@ -143,12 +143,12 @@ main (int argc, char **argv) return 0; } - printf("\n *** Starting Peripherals tests *** \n"); - execute_tests_peripheral(1, g_print_level); - printf("\n *** Starting Memory Map tests *** \n"); execute_tests_memory(1, g_print_level); + printf("\n *** Starting Peripherals tests *** \n"); + execute_tests_peripheral(1, g_print_level); + if (run_exerciser) { printf("\n *** PCIe Exerciser tests only runs on UEFI *** \n"); //execute_tests_exerciser(1, g_print_level); diff --git a/linux_app/bsa-acs-app/include/bsa_app.h b/linux_app/bsa-acs-app/include/bsa_app.h index b295918d..ac4711cc 100644 --- a/linux_app/bsa-acs-app/include/bsa_app.h +++ b/linux_app/bsa-acs-app/include/bsa_app.h @@ -21,7 +21,7 @@ #define BSA_APP_VERSION_MAJOR 0 -#define BSA_APP_VERSION_MINOR 5 +#define BSA_APP_VERSION_MINOR 9 #define G_SW_OS 0 #define G_SW_HYP 1 diff --git a/platform/pal_uefi/src_gic_its/bsa_gic_its.c b/platform/pal_uefi/src_gic_its/bsa_gic_its.c deleted file mode 100644 index edf067ae..00000000 --- a/platform/pal_uefi/src_gic_its/bsa_gic_its.c +++ /dev/null @@ -1,591 +0,0 @@ -/** @file - * Copyright (c) 2020, Arm Limited or its affiliates. All rights reserved. - * SPDX-License-Identifier : Apache-2.0 - - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -**/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Include/IndustryStandard/Acpi61.h" -#include -#include -#include - -#include "bsa_gic_its.h" -#include "include/pal_uefi.h" - -UINT64 ArmReadMpidr(VOID); - -extern GIC_ITS_INFO *g_gic_its_info; -static UINT32 *g_cwriter_ptr; -static UINT32 g_its_setup_done = 0; - -UINT64 -GetCurrentCpuRDBase ( - UINT64 mGicRedistributorBase, - UINT32 length - ) -{ - UINT64 Mpidr; - UINT32 Affinity, CpuAffinity; - UINT32 GicRedistributorGranularity; - UINT64 GicCpuRedistributorBase; - - Mpidr = ArmReadMpidr(); - - CpuAffinity = (Mpidr & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2)) | - ((Mpidr & ARM_CORE_AFF3) >> 8); - - GicRedistributorGranularity = ARM_GICR_CTLR_FRAME_SIZE - + ARM_GICR_SGI_PPI_FRAME_SIZE; - - GicCpuRedistributorBase = mGicRedistributorBase; - - /* If information is present in GICC Structure */ - if (length == 0) - { - Affinity = MmioRead32(GicCpuRedistributorBase + ARM_GICR_TYPER + NEXT_DW_OFFSET); - if (Affinity == CpuAffinity) { - return GicCpuRedistributorBase; - } - return 0; - } - - /* If information is present in GICR Structure */ - while (GicCpuRedistributorBase < (mGicRedistributorBase + length)) - { - Affinity = MmioRead32(GicCpuRedistributorBase + ARM_GICR_TYPER + NEXT_DW_OFFSET); - if (Affinity == CpuAffinity) { - return GicCpuRedistributorBase; - } - - /* Move to the next GIC Redistributor frame */ - GicCpuRedistributorBase += GicRedistributorGranularity; - } - - return 0; -} - -EFIAPI -UINT32 -ArmGICDSupportsLPIs ( - IN UINT64 GicDistributorBase - ) -{ - return (MmioRead32(GicDistributorBase + ARM_GICD_TYPER) & ARM_GICD_TYPER_LPIS); -} - -EFIAPI -UINT32 -ArmGICRSupportsLPIs ( - IN UINT64 GicRedistributorBase - ) -{ - return (MmioRead32(GicRedistributorBase + ARM_GICR_TYPER) & ARM_GICR_TYPER_PLPIS); -} - -EFIAPI -EFI_STATUS -ArmGicSetItsCommandQueueBase ( - IN UINT32 ItsIndex - ) -{ - /* Allocate Memory for Command queue. Set command queue base in GITS_CBASER. */ - EFI_PHYSICAL_ADDRESS Address; - UINT64 write_value; - UINT64 ItsBase; - - ItsBase = g_gic_its_info->GicIts[ItsIndex].Base; - - Address = (EFI_PHYSICAL_ADDRESS)AllocateAlignedPages(EFI_SIZE_TO_PAGES(NUM_PAGES_8 * SIZE_4KB), SIZE_64KB); - if (!Address) { - DEBUG ((DEBUG_ERROR, "\n ITS : Could Not Allocate Memory For Command Q. Test may not pass.")); - return EFI_OUT_OF_RESOURCES; - } - - ZeroMem((VOID *)Address, (NUM_PAGES_8*SIZE_4KB)); - - g_gic_its_info->GicIts[ItsIndex].CommandQBase = Address; - DEBUG((DEBUG_INFO, "%a Address Allocated : %x\n", __func__, Address)); - - write_value = MmioRead64(ItsBase + ARM_GITS_CBASER) & (~ARM_GITS_CBASER_PA_MASK); - write_value = write_value | (Address & ARM_GITS_CBASER_PA_MASK); - write_value = write_value | ARM_GITS_CBASER_VALID; - MmioWrite64(ItsBase + ARM_GITS_CBASER, write_value); - - return EFI_SUCCESS; -} - -EFIAPI -EFI_STATUS -ArmGicSetItsTables ( - IN UINT32 ItsIndex - ) -{ - UINT32 Pages; - UINT32 TableSize, entry_size; - UINT64 its_baser, its_typer; - UINT8 it, table_type; - UINT64 write_value; - UINT32 DevBits, CIDBits; - EFI_PHYSICAL_ADDRESS Address; - UINT64 ItsBase; - - ItsBase = g_gic_its_info->GicIts[ItsIndex].Base; - - /* Allocate Memory for Table Depending on the Type of the table in GITS_BASER. */ - for(it=0; itGicIts[ItsIndex].ITTBase = Address; - - return EFI_SUCCESS; -} - -EFIAPI -VOID -EnableITS ( - IN UINT64 GicItsBase - ) -{ - /* Set GITS_CTLR.Enable as 1 to enable the ITS */ - UINT32 value; - - value = MmioRead32(GicItsBase + ARM_GITS_CTLR); - MmioWrite32(GicItsBase + ARM_GITS_CTLR, (value | ARM_GITS_CTLR_ENABLE)); -} - -VOID -WriteCmdQMAPD ( - IN UINT32 ItsIndex, - IN UINT64 *CMDQ_BASE, - IN UINT64 DevID, - IN UINT64 ITT_BASE, - IN UINT32 Size, - IN UINT64 Valid - ) -{ - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex]), (UINT64)((DevID << ITS_CMD_SHIFT_DEVID) | ARM_ITS_CMD_MAPD)); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 1), (UINT64)(Size)); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 2), (UINT64)((Valid << ITS_CMD_SHIFT_VALID) | (ITT_BASE & ITT_PAR_MASK))); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 3), (UINT64)(0x0)); - g_cwriter_ptr[ItsIndex] = g_cwriter_ptr[ItsIndex] + ITS_NEXT_CMD_PTR; -} - -VOID -WriteCmdQMAPC ( - IN UINT32 ItsIndex, - IN UINT64 *CMDQ_BASE, - IN UINT32 DevID, - IN UINT32 Clctn_ID, - IN UINT32 RDBase, - IN UINT64 Valid - ) -{ - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] ), (UINT64)(ARM_ITS_CMD_MAPC)); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 1), (UINT64)(0x0)); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 2), (UINT64)((Valid << ITS_CMD_SHIFT_VALID) | RDBase | Clctn_ID)); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 3), (UINT64)(0x0)); - g_cwriter_ptr[ItsIndex] = g_cwriter_ptr[ItsIndex] + ITS_NEXT_CMD_PTR; -} - -VOID -WriteCmdQMAPI ( - IN UINT32 ItsIndex, - IN UINT64 *CMDQ_BASE, - IN UINT64 DevID, - IN UINT32 IntID, - IN UINT32 Clctn_ID - ) -{ - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex]), (UINT64)((DevID << ITS_CMD_SHIFT_DEVID) | ARM_ITS_CMD_MAPI)); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 1), (UINT64)(IntID)); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 2), (UINT64)(Clctn_ID)); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 3), (UINT64)(0x0)); - g_cwriter_ptr[ItsIndex] = g_cwriter_ptr[ItsIndex] + ITS_NEXT_CMD_PTR; -} - -VOID -WriteCmdQINV ( - IN UINT32 ItsIndex, - IN UINT64 *CMDQ_BASE, - IN UINT64 DevID, - IN UINT32 IntID - ) -{ - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex]), (UINT64)((DevID << ITS_CMD_SHIFT_DEVID) | ARM_ITS_CMD_INV)); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 1), (UINT64)(IntID)); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 2), (UINT64)(0x0)); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 3), (UINT64)(0x0)); - g_cwriter_ptr[ItsIndex] = g_cwriter_ptr[ItsIndex] + ITS_NEXT_CMD_PTR; -} - -VOID -WriteCmdQDISCARD ( - IN UINT32 ItsIndex, - IN UINT64 *CMDQ_BASE, - IN UINT64 DevID, - IN UINT32 IntID - ) -{ - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex]), (UINT64)((DevID << ITS_CMD_SHIFT_DEVID) | ARM_ITS_CMD_DISCARD)); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 1), (UINT64)(IntID)); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 2), (UINT64)(0x0)); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 3), (UINT64)(0x0)); - g_cwriter_ptr[ItsIndex] = g_cwriter_ptr[ItsIndex] + ITS_NEXT_CMD_PTR; -} - - -VOID -WriteCmdQSYNC ( - IN UINT32 ItsIndex, - IN UINT64 *CMDQ_BASE, - IN UINT32 RDBase - ) -{ - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex]), (UINT64)(ARM_ITS_CMD_SYNC)); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 1), (UINT64)(0x0)); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 2), (UINT64)(RDBase)); - MmioWrite64((UINT64)(CMDQ_BASE + g_cwriter_ptr[ItsIndex] + 3), (UINT64)(0x0)); - g_cwriter_ptr[ItsIndex] = g_cwriter_ptr[ItsIndex] + ITS_NEXT_CMD_PTR; -} - -VOID -PollTillCommandQueueDone ( - IN UINT32 ItsIndex - ) -{ - UINT32 count; - UINT64 creadr_value; - UINT64 stall_value; - UINT64 cwriter_value; - UINT64 ItsBase; - - count = 0; - ItsBase = g_gic_its_info->GicIts[ItsIndex].Base; - cwriter_value = MmioRead64(ItsBase + ARM_GITS_CWRITER); - creadr_value = MmioRead64(ItsBase + ARM_GITS_CREADR); - - while (creadr_value != cwriter_value) { - /* Check Stall Value */ - stall_value = creadr_value & ARM_GITS_CREADR_STALL; - - if (stall_value) { - /* Retry */ - MmioWrite64((ItsBase + ARM_GITS_CWRITER), - (cwriter_value | ARM_GITS_CWRITER_RETRY) - ); - } - - count++; - if (count > WAIT_ITS_COMMAND_DONE) { - DEBUG ((DEBUG_ERROR, "\n ITS : Command Queue READR not moving, Test may not pass.")); - break; - } - - creadr_value = MmioRead64(ItsBase + ARM_GITS_CREADR); - } - -} - -UINT64 -GetRDBaseFormat ( - IN UINT32 ItsIndex - ) -{ - UINT32 value; - UINT64 ItsBase; - - ItsBase = g_gic_its_info->GicIts[ItsIndex].Base; - - /* Check GITS_TYPER.PTA. - If PTA = 1 then RDBase = Physical Address, - Else RDBase = GICR_TYPER.Processor_Number - */ - value = MmioRead64(ItsBase + ARM_GITS_TYPER); - if (value & ARM_GITS_TYPER_PTA) { - return g_gic_its_info->GicRdBase; - } else { - value = MmioRead64(g_gic_its_info->GicRdBase + ARM_GICR_TYPER); - return (value & ARM_GICR_TYPER_PN_MASK); - } -} - -EFIAPI -VOID -ArmGicItsClearLpiMappings ( - IN UINT32 ItsIndex, - IN UINT32 DevID, - IN UINT32 IntID - ) -{ - UINT64 value; - UINT64 RDBase; - UINT64 ItsBase; - UINT64 ItsCommandBase; - - if (!g_its_setup_done) - return; - - ItsBase = g_gic_its_info->GicIts[ItsIndex].Base; - ItsCommandBase = g_gic_its_info->GicIts[ItsIndex].CommandQBase; - - /* Clear Config table for LPI=IntID */ - ClearConfigTable(IntID); - - /* Get RDBase Depending on GITS_TYPER.PTA */ - RDBase = GetRDBaseFormat(ItsIndex); - - /* Discard Mappings */ - WriteCmdQDISCARD(ItsIndex, (UINT64 *)(ItsCommandBase), DevID, IntID); - /* ITS SYNC Command */ - WriteCmdQSYNC(ItsIndex, (UINT64 *)(ItsCommandBase), RDBase); - - /* Update the CWRITER Register so that all the commands from Command queue gets executed.*/ - value = ((g_cwriter_ptr[ItsIndex] * NUM_BYTES_IN_DW)); - MmioWrite64((ItsBase + ARM_GITS_CWRITER), value); - - /* Check CREADR value which ensures Command Queue is processed */ - PollTillCommandQueueDone(ItsIndex); - -} - -EFIAPI -VOID -ArmGicItsCreateLpiMap ( - IN UINT32 ItsIndex, - IN UINT32 DevID, - IN UINT32 IntID, - IN UINT32 Priority - ) -{ - UINT64 value; - UINT64 RDBase; - UINT64 ItsBase; - UINT64 ItsCommandBase; - - if (!g_its_setup_done) - return; - - ItsBase = g_gic_its_info->GicIts[ItsIndex].Base; - ItsCommandBase = g_gic_its_info->GicIts[ItsIndex].CommandQBase; - - /* Set Config table with enable the LPI = IntID, Priority. */ - SetConfigTable(IntID, Priority); - - /* Enable Redistributor */ - EnableLPIsRD(g_gic_its_info->GicRdBase); - - /* Enable ITS */ - EnableITS(ItsBase); - - /* Get RDBase Depending on GITS_TYPER.PTA */ - RDBase = GetRDBaseFormat(ItsIndex); - - /* Map Device using MAPD */ - WriteCmdQMAPD(ItsIndex, (UINT64 *)(ItsCommandBase), DevID, - g_gic_its_info->GicIts[ItsIndex].ITTBase, - g_gic_its_info->GicIts[ItsIndex].IDBits, 0x1 /*Valid*/); - /* Map Collection using MAPC */ - WriteCmdQMAPC(ItsIndex, (UINT64 *)(ItsCommandBase), DevID, 0x1 /*Clctn_ID*/, RDBase, 0x1 /*Valid*/); - /* Map Interrupt using MAPI */ - WriteCmdQMAPI(ItsIndex, (UINT64 *)(ItsCommandBase), DevID, IntID, 0x1 /*Clctn_ID*/); - /* Invalid Entry */ - WriteCmdQINV(ItsIndex, (UINT64 *)(ItsCommandBase), DevID, IntID); - /* ITS SYNC Command */ - WriteCmdQSYNC(ItsIndex, (UINT64 *)(ItsCommandBase), RDBase); - - /* Update the CWRITER Register so that all the commands from Command queue gets executed.*/ - value = ((g_cwriter_ptr[ItsIndex] * NUM_BYTES_IN_DW)); - MmioWrite64((ItsBase + ARM_GITS_CWRITER), value); - - /* Check CREADR value which ensures Command Queue is processed */ - PollTillCommandQueueDone(ItsIndex); - -} - -EFIAPI -UINT32 -ArmGicItsGetMaxLpiID ( - ) -{ - UINT32 index; - UINT32 min_idbits = ARM_LPI_MAX_IDBITS; - - if ((g_gic_its_info == NULL) || (g_gic_its_info->GicNumIts == 0)) - return 0; - - if (!g_its_setup_done) - return 0; - - /* Return The Minimum IDBits supported in ITS */ - for (index=0; indexGicNumIts; index++) - { - min_idbits = (min_idbits < g_gic_its_info->GicIts[index].IDBits)? - (min_idbits): - (g_gic_its_info->GicIts[index].IDBits); - } - return ((1 << (min_idbits+1)) - 1); -} - -EFIAPI -UINT64 -ArmGicItsGetGITSTranslatorAddress ( - IN UINT32 ItsIndex - ) -{ - return (g_gic_its_info->GicIts[ItsIndex].Base + ARM_GITS_TRANSLATER); -} - -EFIAPI -EFI_STATUS -SetInitialConfiguration ( - UINT32 ItsIndex - ) -{ - /* Program GIC Redistributor with the Min ID bits supported. */ - UINT32 gicd_typer_idbits, gits_typer_bits; - UINT64 write_value; - UINT64 ItsBase; - - ItsBase = g_gic_its_info->GicIts[ItsIndex].Base; - - gicd_typer_idbits = ARM_GICD_TYPER_IDbits(MmioRead32(g_gic_its_info->GicDBase + ARM_GICD_TYPER)); - gits_typer_bits = ARM_GITS_TYPER_IDbits(MmioRead64(ItsBase + ARM_GITS_TYPER)); - - /* Check least bits implemented is 14 if LPIs are supported. */ - if (GET_MIN(gicd_typer_idbits, gits_typer_bits) < ARM_LPI_MIN_IDBITS) { - return EFI_UNSUPPORTED; - } - - write_value = MmioRead64(g_gic_its_info->GicRdBase + ARM_GICR_PROPBASER); - write_value |= GET_MIN(gicd_typer_idbits, gits_typer_bits); - - g_gic_its_info->GicIts[ItsIndex].IDBits = GET_MIN(gicd_typer_idbits, gits_typer_bits); - - MmioWrite64((g_gic_its_info->GicRdBase + ARM_GICR_PROPBASER), write_value); - - return EFI_SUCCESS; -} - -EFIAPI -EFI_STATUS -ArmGicItsConfiguration ( - ) -{ - EFI_STATUS Status; - UINT32 index; - - g_cwriter_ptr = AllocatePool(sizeof(UINT32) * (g_gic_its_info->GicNumIts)); - if (g_cwriter_ptr == NULL) { - DEBUG ((DEBUG_ERROR, "\n ITS : Could Not Allocate Memory CWriteR. Test may not pass.")); - return EFI_OUT_OF_RESOURCES; - } - for (index=0; indexGicNumIts; index++) - g_cwriter_ptr[index] = 0; - - for (index=0; indexGicNumIts; index++) - { - /* Set Initial configuration */ - Status = SetInitialConfiguration(index); - if (EFI_ERROR(Status)) { - return Status; - } - } - - /* Configure Redistributor For LPIs */ - Status = ArmGicRedistributorConfigurationForLPI(g_gic_its_info->GicDBase, g_gic_its_info->GicRdBase); - if (EFI_ERROR(Status)) { - return Status; - } - - for (index=0; indexGicNumIts; index++) - { - /* Set Command Queue Base */ - Status = ArmGicSetItsCommandQueueBase(index); - if (EFI_ERROR(Status)) { - return Status; - } - - /* Set Up the ITS tables */ - Status = ArmGicSetItsTables(index); - if (EFI_ERROR(Status)) { - return Status; - } - } - - g_its_setup_done = 1; - - DEBUG ((DEBUG_INFO, "\n ITS : Info Block ")); - for (index=0; indexGicNumIts; index++) - { - DEBUG ((DEBUG_INFO, "\nGIC ITS Index : %x", index)); - DEBUG ((DEBUG_INFO, "\nGIC ITS ID : %x", g_gic_its_info->GicIts[index].ID)); - DEBUG ((DEBUG_INFO, "\nGIC ITS Base : %x\n\n", g_gic_its_info->GicIts[index].Base)); - } - - return EFI_SUCCESS; -} diff --git a/platform/pal_uefi/src_gic_its/bsa_gic_redistributor.c b/platform/pal_uefi/src_gic_its/bsa_gic_redistributor.c deleted file mode 100644 index 2a735057..00000000 --- a/platform/pal_uefi/src_gic_its/bsa_gic_redistributor.c +++ /dev/null @@ -1,173 +0,0 @@ -/** @file - * Copyright (c) 2020, Arm Limited or its affiliates. All rights reserved. - * SPDX-License-Identifier : Apache-2.0 - - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -**/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Include/IndustryStandard/Acpi61.h" -#include -#include -#include - -#include "bsa_gic_its.h" - -static UINT64 ConfigBase; - -EFIAPI -EFI_STATUS -ArmGicSetItsConfigTableBase ( - IN UINT64 GicDistributorBase, - IN UINT64 GicRedistributorBase - ) -{ - /* Allocate Memory for Redistributor Configuration Table */ - /* Set GICR_PROPBASER with the Config table base */ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Address; - UINT32 Pages; - UINT32 ConfigTableSize; - UINT64 write_value; - UINT32 gicr_propbaser_idbits; - - /* Get Memory size by reading the GICR_PROPBASER.IDBits field */ - gicr_propbaser_idbits = ARM_GICR_PROPBASER_IDbits(MmioRead64(GicRedistributorBase + ARM_GICR_PROPBASER)); - ConfigTableSize = ((1 << (gicr_propbaser_idbits+1)) - ARM_LPI_MINID); - - Pages = EFI_SIZE_TO_PAGES (ConfigTableSize) + 1; - - Status = gBS->AllocatePages ( - AllocateAnyPages, - EfiBootServicesData, - Pages, - &Address - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "\n ITS : Could Not Allocate Memory For Config Table. Test may not pass.")); - return Status; - } - ZeroMem((VOID *)Address, EFI_PAGES_TO_SIZE(Pages)); - - write_value = MmioRead64(GicRedistributorBase + ARM_GICR_PROPBASER); - write_value = write_value & (~ARM_GICR_PROPBASER_PA_MASK); - write_value = write_value | (Address & ARM_GICR_PROPBASER_PA_MASK); - MmioWrite64(GicRedistributorBase + ARM_GICR_PROPBASER, write_value); - - ConfigBase = Address; - - return EFI_SUCCESS; -} - -EFIAPI -EFI_STATUS -ArmGicSetItsPendingTableBase ( - IN UINT64 GicDistributorBase, - IN UINT64 GicRedistributorBase - ) -{ - /* Allocate Memory for Pending Table for each Redistributor*/ - /* Set GICR_PENDBASER with the Config table base */ - EFI_PHYSICAL_ADDRESS Address; - UINT32 Pages; - UINT32 PendingTableSize; - UINT64 write_value; - UINT32 gicr_propbaser_idbits; - - /* Get Memory size by reading the GICD_TYPER.IDBits, GICR_PROPBASER.IDBits field */ - gicr_propbaser_idbits = ARM_GICR_PROPBASER_IDbits(MmioRead64(GicRedistributorBase + ARM_GICR_PROPBASER)); - PendingTableSize = ((1 << (gicr_propbaser_idbits+1))/8); - - Pages = EFI_SIZE_TO_PAGES (PendingTableSize) + 1; - - Address = (EFI_PHYSICAL_ADDRESS)AllocateAlignedPages(Pages, SIZE_64KB); - if (!Address) { - DEBUG ((DEBUG_ERROR, "\n ITS : Could Not Allocate Memory For Pending Table. Test may not pass.")); - return EFI_OUT_OF_RESOURCES; - } - - ZeroMem((VOID *)Address, EFI_PAGES_TO_SIZE(Pages)); - - write_value = MmioRead64(GicRedistributorBase + ARM_GICR_PENDBASER); - write_value = write_value & (~ARM_GICR_PENDBASER_PA_MASK); - write_value = write_value | (Address & ARM_GICR_PENDBASER_PA_MASK); - MmioWrite64(GicRedistributorBase + ARM_GICR_PENDBASER, write_value); - - return EFI_SUCCESS; -} - -EFIAPI -VOID -ClearConfigTable ( - IN UINT32 IntID - ) -{ - MmioWrite8(ConfigBase + (IntID - ARM_LPI_MINID), LPI_DISABLE); -} - -EFIAPI -VOID -SetConfigTable ( - IN UINT32 IntID, - IN UINT32 Priority - ) -{ - UINT8 value; - - value = (Priority & LPI_PRIORITY_MASK) | LPI_ENABLE; - MmioWrite8(ConfigBase + (IntID - ARM_LPI_MINID), value); -} - -EFIAPI -VOID -EnableLPIsRD ( - IN UINT64 GicRedistributorBase - ) -{ - UINT32 value; - value = MmioRead32(GicRedistributorBase + ARM_GICR_CTLR); - - MmioWrite32(GicRedistributorBase + ARM_GICR_CTLR, - (value | ARM_GICR_CTLR_ENABLE_LPIS)); -} - -EFIAPI -EFI_STATUS -ArmGicRedistributorConfigurationForLPI ( - IN UINT64 GicDistributorBase, - IN UINT64 GicRedistributorBase - ) -{ - EFI_STATUS Status; - /* Set Configuration Table Base */ - Status = ArmGicSetItsConfigTableBase(GicDistributorBase, GicRedistributorBase); - if (EFI_ERROR(Status)) { - return Status; - } - - /* Set Pending Table Base For Each Redistributor */ - Status = ArmGicSetItsPendingTableBase(GicDistributorBase, GicRedistributorBase); - if (EFI_ERROR(Status)) { - return Status; - } - - return Status; -} diff --git a/platform/pal_uefi/BsaPalLib.inf b/platform/pal_uefi_acpi/BsaPalLib.inf similarity index 96% rename from platform/pal_uefi/BsaPalLib.inf rename to platform/pal_uefi_acpi/BsaPalLib.inf index 0c6ffecf..5fcf8073 100644 --- a/platform/pal_uefi/BsaPalLib.inf +++ b/platform/pal_uefi_acpi/BsaPalLib.inf @@ -39,8 +39,6 @@ src/pal_peripherals.c src/pal_exerciser.c src/pal_smmu.c - src_gic_its/bsa_gic_its.c - src_gic_its/bsa_gic_redistributor.c [Packages] ArmPkg/ArmPkg.dec diff --git a/platform/pal_uefi/include/bsa_pcie_enum.h b/platform/pal_uefi_acpi/include/bsa_pcie_enum.h similarity index 100% rename from platform/pal_uefi/include/bsa_pcie_enum.h rename to platform/pal_uefi_acpi/include/bsa_pcie_enum.h diff --git a/platform/pal_uefi/include/pal_exerciser.h b/platform/pal_uefi_acpi/include/pal_exerciser.h similarity index 91% rename from platform/pal_uefi/include/pal_exerciser.h rename to platform/pal_uefi_acpi/include/pal_exerciser.h index 339aab16..9d2c5d51 100644 --- a/platform/pal_uefi/include/pal_exerciser.h +++ b/platform/pal_uefi_acpi/include/pal_exerciser.h @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2020, Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2016-2021, Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -200,11 +200,16 @@ typedef enum { EXERCISER_DATA_BAR0_SPACE = 0x2, } EXERCISER_DATA_TYPE; -UINT32 pal_exerciser_set_param(EXERCISER_PARAM_TYPE Type, UINT64 Value1, UINT64 Value2, UINT32 Bdf); -UINT32 pal_exerciser_get_param(EXERCISER_PARAM_TYPE Type, UINT64 *Value1, UINT64 *Value2, UINT32 Bdf); -UINT32 pal_exerciser_set_state(EXERCISER_STATE State, UINT64 *Value, UINT32 Bdf); +UINT32 pal_exerciser_set_param(EXERCISER_PARAM_TYPE Type, UINT64 Value1, + UINT64 Value2, UINT32 Bdf, UINT64 Ecam); +UINT32 pal_exerciser_get_param(EXERCISER_PARAM_TYPE Type, UINT64 *Value1, + UINT64 *Value2, UINT32 Bdf, UINT64 Ecam); +UINT32 pal_exerciser_set_state(EXERCISER_STATE State, UINT64 *Value, + UINT32 Bdf); UINT32 pal_exerciser_get_state(EXERCISER_STATE *State, UINT32 Bdf); -UINT32 pal_exerciser_ops(EXERCISER_OPS Ops, UINT64 Param, UINT32 Bdf); -UINT32 pal_exerciser_get_data(EXERCISER_DATA_TYPE Type, exerciser_data_t *Data, UINT32 Bdf, UINT64 Ecam); +UINT32 pal_exerciser_ops(EXERCISER_OPS Ops, UINT64 Param, UINT32 Bdf, + UINT64 Ecam); +UINT32 pal_exerciser_get_data(EXERCISER_DATA_TYPE Type, exerciser_data_t *Data, + UINT32 Bdf, UINT64 Ecam); #endif diff --git a/platform/pal_uefi/include/pal_iovirt.h b/platform/pal_uefi_acpi/include/pal_iovirt.h similarity index 100% rename from platform/pal_uefi/include/pal_iovirt.h rename to platform/pal_uefi_acpi/include/pal_iovirt.h diff --git a/platform/pal_uefi/include/pal_uefi.h b/platform/pal_uefi_acpi/include/pal_uefi.h similarity index 98% rename from platform/pal_uefi/include/pal_uefi.h rename to platform/pal_uefi_acpi/include/pal_uefi.h index 104fffdc..3563138b 100644 --- a/platform/pal_uefi/include/pal_uefi.h +++ b/platform/pal_uefi_acpi/include/pal_uefi.h @@ -316,6 +316,8 @@ typedef struct { UINT32 msi; ///< MSI Enabled UINT32 msix; ///< MSIX Enabled UINT32 max_pasids; + UINT32 baud_rate; + UINT32 interface_type; }PERIPHERAL_INFO_BLOCK; /** @@ -364,6 +366,9 @@ UINT32 pal_pcie_get_root_port_bdf(UINT32 *seg, UINT32 *bus, UINT32 *dev, UINT32 UINT32 pal_pcie_max_pasid_bits(UINT32 bdf); /* Memory INFO table */ + +#define MEM_INFO_TBL_MAX_ENTRY 500 /* Maximum entries to be added in Mem info table*/ + typedef enum { MEMORY_TYPE_DEVICE = 0x1000, MEMORY_TYPE_NORMAL, diff --git a/platform/pal_uefi/include/platform_override.h b/platform/pal_uefi_acpi/include/platform_override.h similarity index 100% rename from platform/pal_uefi/include/platform_override.h rename to platform/pal_uefi_acpi/include/platform_override.h diff --git a/platform/pal_uefi/src/AArch64/AcsTestInfra.S b/platform/pal_uefi_acpi/src/AArch64/AcsTestInfra.S similarity index 100% rename from platform/pal_uefi/src/AArch64/AcsTestInfra.S rename to platform/pal_uefi_acpi/src/AArch64/AcsTestInfra.S diff --git a/platform/pal_uefi/src/AArch64/ArmSmc.S b/platform/pal_uefi_acpi/src/AArch64/ArmSmc.S similarity index 100% rename from platform/pal_uefi/src/AArch64/ArmSmc.S rename to platform/pal_uefi_acpi/src/AArch64/ArmSmc.S diff --git a/platform/pal_uefi/src/AArch64/ModuleEntryPoint.S b/platform/pal_uefi_acpi/src/AArch64/ModuleEntryPoint.S similarity index 100% rename from platform/pal_uefi/src/AArch64/ModuleEntryPoint.S rename to platform/pal_uefi_acpi/src/AArch64/ModuleEntryPoint.S diff --git a/platform/pal_uefi/src/pal_acpi.c b/platform/pal_uefi_acpi/src/pal_acpi.c similarity index 92% rename from platform/pal_uefi/src/pal_acpi.c rename to platform/pal_uefi_acpi/src/pal_acpi.c index 0671cd61..28e31d95 100644 --- a/platform/pal_uefi/src/pal_acpi.c +++ b/platform/pal_uefi_acpi/src/pal_acpi.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2018, 2020 Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2016-2018, 2020, 2021 Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,15 +26,24 @@ #include "Include/IndustryStandard/Acpi61.h" #include "include/pal_uefi.h" + +VOID +pal_dump_dtb() +{ + bsa_print(ACS_PRINT_ERR, L"DTB dump not available for platform initialized" + " with ACPI table \n"); +} /** - @brief Checks if gic init and interrupt handlers ACS code is used + @brief Checks if System information is passed using Device Tree (DT) + This api is also used to check if GIC/Interrupt Init ACS Code + is used or not. In case of DT, ACS Code is used for INIT @param None @return True/False */ UINT32 -pal_bsa_gic_imp() +pal_target_is_dt() { return 0; } diff --git a/platform/pal_uefi/src/pal_exerciser.c b/platform/pal_uefi_acpi/src/pal_exerciser.c similarity index 91% rename from platform/pal_uefi/src/pal_exerciser.c rename to platform/pal_uefi_acpi/src/pal_exerciser.c index ed791dc4..f306a95a 100644 --- a/platform/pal_uefi/src/pal_exerciser.c +++ b/platform/pal_uefi_acpi/src/pal_exerciser.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2018-2020, Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2018-2021, Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -71,11 +71,11 @@ pal_increment_bus_dev( **/ UINT64 pal_exerciser_get_ecsr_base ( - UINT32 Bdf, + UINT64 EcsrBase, UINT32 BarIndex ) { - return palPcieGetBase(Bdf, BarIndex); + return pal_mmio_read(EcsrBase + BAR0_OFFSET + (BarIndex * 4)); } UINT64 @@ -96,7 +96,7 @@ pal_exerciser_get_pcie_config_offset(UINT32 Bdf) UINT32 pal_is_bdf_exerciser(UINT32 bdf) { - UINT32 Ecam; + UINT64 Ecam; UINT32 vendor_dev_id; Ecam = pal_pcie_get_mcfg_ecam(); @@ -151,7 +151,7 @@ pal_exerciser_find_pcie_capability ( UINT64 NxtPtr; UINT32 Data; UINT32 TempId; - UINT32 Ecam; + UINT64 Ecam; UINT32 IdMask; UINT32 PtrMask; UINT32 PtrOffset; @@ -196,14 +196,18 @@ UINT32 pal_exerciser_set_param ( EXERCISER_PARAM_TYPE Type, UINT64 Value1, UINT64 Value2, - UINT32 Bdf + UINT32 Bdf, + UINT64 Ecam ) { UINT32 Status; UINT32 Data; UINT64 Base; + UINT64 EcsrBase; /* Exerciser Base */ + + EcsrBase = (Ecam + pal_exerciser_get_pcie_config_offset(Bdf)); + Base = pal_exerciser_get_ecsr_base(EcsrBase, 0); /* BAR0 address */ - Base = pal_exerciser_get_ecsr_base(Bdf,0); switch (Type) { case SNOOP_ATTRIBUTES: @@ -263,14 +267,18 @@ pal_exerciser_get_param ( EXERCISER_PARAM_TYPE Type, UINT64 *Value1, UINT64 *Value2, - UINT32 Bdf + UINT32 Bdf, + UINT64 Ecam ) { UINT32 Status; UINT32 Temp; UINT64 Base; + UINT64 EcsrBase; /* Exerciser Base */ + + EcsrBase = (Ecam + pal_exerciser_get_pcie_config_offset(Bdf)); + Base = pal_exerciser_get_ecsr_base(EcsrBase, 0); /*BAR0 address */ - Base = pal_exerciser_get_ecsr_base(Bdf,0); switch (Type) { case SNOOP_ATTRIBUTES: @@ -341,16 +349,18 @@ UINT32 pal_exerciser_ops ( EXERCISER_OPS Ops, UINT64 Param, - UINT32 Bdf + UINT32 Bdf, + UINT64 Ecam ) { UINT64 Base; - UINT32 Ecam; UINT32 CapabilityOffset; UINT32 data; + UINT64 EcsrBase; /* Exerciser Base */ + + EcsrBase = (Ecam + pal_exerciser_get_pcie_config_offset(Bdf)); + Base = pal_exerciser_get_ecsr_base(EcsrBase, 0); /*BAR 0 address */ - Base = pal_exerciser_get_ecsr_base(Bdf,0); - Ecam = pal_pcie_get_mcfg_ecam(); // Getting the ECAM address switch(Ops){ case START_DMA: @@ -441,10 +451,11 @@ pal_exerciser_get_data ( ) { UINT32 Index; - UINT64 EcamBase; - UINT64 EcamBAR0; + UINT64 Base; + UINT64 EcsrBase; /* Exerciser Base */ - EcamBase = (Ecam + pal_exerciser_get_pcie_config_offset(Bdf)); + EcsrBase = (Ecam + pal_exerciser_get_pcie_config_offset(Bdf)); + Base = pal_exerciser_get_ecsr_base(EcsrBase, 0); /* BAR0 address */ //In the Latest version of BSA 6.0 this part of the test is obsolete hence filling the reg with same data UINT32 offset_table[TEST_REG_COUNT] = {0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08}; @@ -456,13 +467,13 @@ pal_exerciser_get_data ( for (Index = 0; Index < TEST_REG_COUNT; Index++) { Data->cfg_space.reg[Index].offset = (offset_table[Index] + pal_exerciser_get_pcie_config_offset (Bdf)); Data->cfg_space.reg[Index].attribute = attr_table[Index]; - Data->cfg_space.reg[Index].value = pal_mmio_read(EcamBase + offset_table[Index]); + Data->cfg_space.reg[Index].value = + pal_mmio_read(EcsrBase + offset_table[Index]); } return 0; case EXERCISER_DATA_BAR0_SPACE: - EcamBAR0 = pal_exerciser_get_ecsr_base(Bdf, 0); - Data->bar_space.base_addr = (void *)EcamBAR0; - if (((pal_exerciser_get_ecsr_base(Bdf,0) >> PREFETCHABLE_BIT_SHIFT) & MASK_BIT) == 0x1) + Data->bar_space.base_addr = (void *)Base; + if (((Base >> PREFETCHABLE_BIT_SHIFT) & MASK_BIT) == 0x1) Data->bar_space.type = MMIO_PREFETCHABLE; else Data->bar_space.type = MMIO_NON_PREFETCHABLE; diff --git a/platform/pal_uefi/src/pal_gic.c b/platform/pal_uefi_acpi/src/pal_gic.c similarity index 67% rename from platform/pal_uefi/src/pal_gic.c rename to platform/pal_uefi_acpi/src/pal_gic.c index 29eb5252..81c2cca6 100644 --- a/platform/pal_uefi/src/pal_gic.c +++ b/platform/pal_uefi_acpi/src/pal_gic.c @@ -27,7 +27,6 @@ #include "include/pal_uefi.h" #include "include/bsa_pcie_enum.h" -#include "src_gic_its/bsa_gic_its.h" static EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *gMadtHdr; @@ -37,9 +36,6 @@ EFI_HARDWARE_INTERRUPT2_PROTOCOL *gInterrupt2 = NULL; UINT64 pal_get_madt_ptr(); -GIC_INFO_ENTRY *g_gic_entry = NULL; -GIC_ITS_INFO *g_gic_its_info; - /** @brief Populate information about the GIC sub-system at the input address. In a UEFI-ACPI framework, this information is part of the MADT table. @@ -62,7 +58,6 @@ pal_gic_create_info_table(GIC_INFO_TABLE *GicTable) } GicEntry = GicTable->gic_info; - g_gic_entry = GicTable->gic_info; GicTable->header.gic_version = 0; GicTable->header.num_gicrd = 0; @@ -280,173 +275,3 @@ pal_gic_free_irq( { } - -UINT32 -pal_gic_its_configure( - ) -{ - /* - * This function configure the gic to have support for LPIs, - * If supported in the system. - */ - EFI_STATUS Status; - GIC_INFO_ENTRY *gic_entry = g_gic_entry; - - /* Allocate memory to store ITS info */ - g_gic_its_info = (GIC_ITS_INFO *) pal_mem_alloc(1024); - if (!g_gic_its_info) { - bsa_print(ACS_PRINT_DEBUG, L"GIC : ITS table memory allocation failed\n", 0); - goto its_fail; - } - - g_gic_its_info->GicNumIts = 0; - g_gic_its_info->GicRdBase = 0; - g_gic_its_info->GicDBase = 0; - - while (gic_entry->type != 0xFF) - { - if (gic_entry->type == ENTRY_TYPE_GICD) - { - g_gic_its_info->GicDBase = gic_entry->base; - } - else if ((gic_entry->type == ENTRY_TYPE_GICR_GICRD) - || (gic_entry->type == ENTRY_TYPE_GICC_GICRD)) - { - /* Calculate Current PE Redistributor Base Address */ - if (g_gic_its_info->GicRdBase == 0) - { - if (gic_entry->type == ENTRY_TYPE_GICR_GICRD) - g_gic_its_info->GicRdBase = GetCurrentCpuRDBase(gic_entry->base, gic_entry->length); - else - g_gic_its_info->GicRdBase = GetCurrentCpuRDBase(gic_entry->base, 0); - } - } - else if (gic_entry->type == ENTRY_TYPE_GICITS) - { - g_gic_its_info->GicIts[g_gic_its_info->GicNumIts].Base = gic_entry->base; - g_gic_its_info->GicIts[g_gic_its_info->GicNumIts++].ID = gic_entry->entry_id; - } - gic_entry++; - } - - /* Return if no ITS */ - if (g_gic_its_info->GicNumIts == 0) - { - bsa_print(ACS_PRINT_DEBUG, L"No ITS Found in the MADT.\n", 0); - goto its_fail; - } - - /* Base Address Check. */ - if ((g_gic_its_info->GicRdBase == 0) || (g_gic_its_info->GicDBase == 0)) - { - bsa_print(ACS_PRINT_DEBUG, L"Could not get GICD/GICRD Base.\n", 0); - goto its_fail; - } - - if (ArmGICDSupportsLPIs(g_gic_its_info->GicDBase) && ArmGICRSupportsLPIs(g_gic_its_info->GicRdBase)) - { - Status = ArmGicItsConfiguration(); - if (EFI_ERROR(Status)) - { - bsa_print(ACS_PRINT_DEBUG, L"Could Not Configure ITS.\n", 0); - goto its_fail; - } - } - else - { - bsa_print(ACS_PRINT_DEBUG, L"LPIs not supported in the system.\n", 0); - goto its_fail; - } - - return 0; - -its_fail: - bsa_print(ACS_PRINT_DEBUG, L"GIC ITS Initialization Failed.\n", 0); - bsa_print(ACS_PRINT_DEBUG, L"LPI Interrupt related test may not pass.\n", 0); - return 0xFFFFFFFF; -} - -UINT32 -pal_gic_get_max_lpi_id ( - ) -{ - return ArmGicItsGetMaxLpiID(); -} - -UINT32 -getItsIndex ( - IN UINT32 ItsID - ) -{ - UINT32 index; - - for (index=0; indexGicNumIts; index++) - { - if (ItsID == g_gic_its_info->GicIts[index].ID) - return index; - } - return 0xFFFFFFFF; -} - -UINT32 -pal_gic_request_msi ( - UINT32 ItsID, - UINT32 DevID, - UINT32 IntID, - UINT32 msi_index, - UINT32 *msi_addr, - UINT32 *msi_data - ) -{ - UINT32 ItsIndex; - - if ((g_gic_its_info == NULL) || (g_gic_its_info->GicNumIts == 0)) - return 0xFFFFFFFF; - - ItsIndex = getItsIndex(ItsID); - if (ItsIndex > g_gic_its_info->GicNumIts) { - bsa_print(ACS_PRINT_ERR, L"\n Could not find ITS block in MADT", 0); - return 0xFFFFFFFF; - } - - if ((g_gic_its_info->GicRdBase == 0) || (g_gic_its_info->GicDBase == 0)) - { - bsa_print(ACS_PRINT_DEBUG, L"GICD/GICRD Base Invalid value.\n", 0); - return 0xFFFFFFFF; - } - - ArmGicItsCreateLpiMap(ItsIndex, DevID, IntID, LPI_PRIORITY1); - - *msi_addr = ArmGicItsGetGITSTranslatorAddress(ItsIndex); - *msi_data = IntID; - - return 0; -} - -VOID -pal_gic_free_msi ( - UINT32 ItsID, - UINT32 DevID, - UINT32 IntID, - UINT32 msi_index - ) -{ - UINT32 ItsIndex; - - if ((g_gic_its_info == NULL) || (g_gic_its_info->GicNumIts == 0)) - return; - - ItsIndex = getItsIndex(ItsID); - if (ItsIndex > g_gic_its_info->GicNumIts) - { - bsa_print(ACS_PRINT_ERR, L"\n Could not find ITS block in MADT", 0); - return; - } - if ((g_gic_its_info->GicRdBase == 0) || (g_gic_its_info->GicDBase == 0)) - { - bsa_print(ACS_PRINT_DEBUG, L"GICD/GICRD Base Invalid value.\n", 0); - return; - } - - ArmGicItsClearLpiMappings(ItsIndex, DevID, IntID); -} diff --git a/platform/pal_uefi/src/pal_iovirt.c b/platform/pal_uefi_acpi/src/pal_iovirt.c similarity index 97% rename from platform/pal_uefi/src/pal_iovirt.c rename to platform/pal_uefi_acpi/src/pal_iovirt.c index b05adb4b..021f7b1c 100644 --- a/platform/pal_uefi/src/pal_iovirt.c +++ b/platform/pal_uefi_acpi/src/pal_iovirt.c @@ -53,16 +53,16 @@ dump_block(IOVIRT_BLOCK *block) { NODE_DATA_MAP *map = &block->data_map[0]; switch(block->type) { case IOVIRT_NODE_ITS_GROUP: - bsa_print(ACS_PRINT_INFO, L"\nITS Group:\n Num ITS:%d\n", (*map).id[0]); + bsa_print(ACS_PRINT_INFO, L"\nITS Group:\n Num ITS : %d", block->data.its_count); for(i = 0; i < block->data.its_count; i++) - bsa_print(ACS_PRINT_INFO, L"%d ", (*map).id[i]); + bsa_print(ACS_PRINT_INFO, L"\n ITS ID : %d", (*map).id[i]); bsa_print(ACS_PRINT_INFO, L"\n"); return; case IOVIRT_NODE_NAMED_COMPONENT: bsa_print(ACS_PRINT_INFO, L"\nNamed Component:\n Device Name:%a\n", block->data.name); break; case IOVIRT_NODE_PCI_ROOT_COMPLEX: - bsa_print(ACS_PRINT_INFO, L"\nRoot Complex:\n PCI segment number:%d\n", block->data.rc.segment); + bsa_print(ACS_PRINT_INFO, L"\nRoot Complex:\n Segment Num:%d\n", block->data.rc.segment); break; case IOVIRT_NODE_SMMU: case IOVIRT_NODE_SMMU_V3: @@ -74,7 +74,7 @@ dump_block(IOVIRT_BLOCK *block) { block->data.pmcg.base, block->data.pmcg.overflow_gsiv, block->data.pmcg.node_ref); break; } - bsa_print(ACS_PRINT_INFO, L"Number of ID Mappings:%d\n", block->num_data_map); + bsa_print(ACS_PRINT_INFO, L"\nNumber of ID Mappings:%d\n", block->num_data_map); for(i = 0; i < block->num_data_map; i++, map++) { bsa_print(ACS_PRINT_INFO, L"\n input_base:0x%x\n id_count:0x%x\n output_base:0x%x\n output ref:0x%x\n", (*map).map.input_base, (*map).map.id_count, diff --git a/platform/pal_uefi/src/pal_misc.c b/platform/pal_uefi_acpi/src/pal_misc.c similarity index 100% rename from platform/pal_uefi/src/pal_misc.c rename to platform/pal_uefi_acpi/src/pal_misc.c diff --git a/platform/pal_uefi/src/pal_pcie.c b/platform/pal_uefi_acpi/src/pal_pcie.c similarity index 96% rename from platform/pal_uefi/src/pal_pcie.c rename to platform/pal_uefi_acpi/src/pal_pcie.c index 24026ff5..e844e815 100644 --- a/platform/pal_uefi/src/pal_pcie.c +++ b/platform/pal_uefi_acpi/src/pal_pcie.c @@ -109,6 +109,11 @@ pal_pcie_create_info_table(PCIE_INFO_TABLE *PcieTable) PcieTable->block[i].segment_num = Entry->PciSegmentGroupNumber; PcieTable->block[i].start_bus_num = Entry->StartBusNumber; PcieTable->block[i].end_bus_num = Entry->EndBusNumber; + bsa_print(ACS_PRINT_INFO, L"\nEcam Index = %d", i); + bsa_print(ACS_PRINT_INFO, L"\n Base Address = 0x%llx", Entry->BaseAddress); + bsa_print(ACS_PRINT_INFO, L"\n Segment = 0x%llx", Entry->PciSegmentGroupNumber); + bsa_print(ACS_PRINT_INFO, L"\n Start Bus = 0x%llx", Entry->StartBusNumber); + bsa_print(ACS_PRINT_INFO, L"\n End Bus = 0x%llx", Entry->EndBusNumber); length += sizeof(EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE); Entry++; i++; @@ -294,7 +299,7 @@ pal_pcie_get_legacy_irq_map ( PERIPHERAL_IRQ_MAP *IrqMap ) { - return 1; + return 1; /* not implemented */ } /* Place holder function. Need to be diff --git a/platform/pal_uefi/src/pal_pcie_enumeration.c b/platform/pal_uefi_acpi/src/pal_pcie_enumeration.c similarity index 100% rename from platform/pal_uefi/src/pal_pcie_enumeration.c rename to platform/pal_uefi_acpi/src/pal_pcie_enumeration.c diff --git a/platform/pal_uefi/src/pal_pe.c b/platform/pal_uefi_acpi/src/pal_pe.c similarity index 98% rename from platform/pal_uefi/src/pal_pe.c rename to platform/pal_uefi_acpi/src/pal_pe.c index fd3a149c..c20a6261 100644 --- a/platform/pal_uefi/src/pal_pe.c +++ b/platform/pal_uefi_acpi/src/pal_pe.c @@ -158,7 +158,7 @@ pal_pe_create_info_table(PE_INFO_TABLE *PeTable) Ptr->pe_num = PeTable->header.num_of_pe; Ptr->pmu_gsiv = Entry->PerformanceInterruptGsiv; Ptr->gmain_gsiv = Entry->VGICMaintenanceInterrupt; - bsa_print(ACS_PRINT_DEBUG, L"MPIDR %x PE num %x \n", Ptr->mpidr, Ptr->pe_num); + bsa_print(ACS_PRINT_DEBUG, L" MPIDR %x PE num %x \n", Ptr->mpidr, Ptr->pe_num); pal_pe_data_cache_ops_by_va((UINT64)Ptr, CLEAN_AND_INVALIDATE); Ptr++; PeTable->header.num_of_pe++; diff --git a/platform/pal_uefi/src/pal_peripherals.c b/platform/pal_uefi_acpi/src/pal_peripherals.c similarity index 95% rename from platform/pal_uefi/src/pal_peripherals.c rename to platform/pal_uefi_acpi/src/pal_peripherals.c index c3d1cc55..5c81016f 100644 --- a/platform/pal_uefi/src/pal_peripherals.c +++ b/platform/pal_uefi_acpi/src/pal_peripherals.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2018, 2020 Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2016-2018, 2020-2021 Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -37,6 +37,7 @@ #define BAR1 1 #define BAR2 2 +UINT32 spcr_baudrate_id[] = {0, 0, 0, 9600, 19200, 0, 57600, 115200}; UINT64 pal_get_spcr_ptr(); @@ -109,6 +110,13 @@ pal_peripheral_create_info_table(PERIPHERAL_INFO_TABLE *peripheralInfoTable) per_info->base0 = spcr->BaseAddress.Address; per_info->irq = spcr->GlobalSystemInterrupt; per_info->type = PERIPHERAL_TYPE_UART; + + if (spcr->BaudRate < 8) + per_info->baud_rate = spcr_baudrate_id[spcr->BaudRate]; + else + per_info->baud_rate = 0; + + per_info->interface_type = spcr->InterfaceType; per_info++; } @@ -268,6 +276,10 @@ pal_memory_create_info_table(MEMORY_INFO_TABLE *memoryInfoTable) memoryInfoTable->info[i].virt_addr = MemoryMapPtr->VirtualStart; memoryInfoTable->info[i].size = (MemoryMapPtr->NumberOfPages * EFI_PAGE_SIZE); i++; + if (i >= MEM_INFO_TBL_MAX_ENTRY) { + bsa_print(ACS_PRINT_DEBUG, L"Memory Info tbl limit exceeded, Skipping remaining\n", 0); + break; + } MemoryMapPtr = (EFI_MEMORY_DESCRIPTOR*)((UINTN)MemoryMapPtr + DescriptorSize); } diff --git a/platform/pal_uefi/src/pal_smmu.c b/platform/pal_uefi_acpi/src/pal_smmu.c similarity index 100% rename from platform/pal_uefi/src/pal_smmu.c rename to platform/pal_uefi_acpi/src/pal_smmu.c diff --git a/platform/pal_uefi/src/pal_timer_wd.c b/platform/pal_uefi_acpi/src/pal_timer_wd.c similarity index 95% rename from platform/pal_uefi/src/pal_timer_wd.c rename to platform/pal_uefi_acpi/src/pal_timer_wd.c index 446d479e..050e1e15 100644 --- a/platform/pal_uefi/src/pal_timer_wd.c +++ b/platform/pal_uefi_acpi/src/pal_timer_wd.c @@ -107,7 +107,7 @@ pal_timer_create_info_table(TIMER_INFO_TABLE *TimerTable) GtEntry->type = TIMER_TYPE_SYS_TIMER; GtEntry->block_cntl_base = Entry->CntCtlBase; GtEntry->timer_count = Entry->GTBlockTimerCount; - bsa_print(ACS_PRINT_DEBUG, L"CNTCTLBase = %x \n", GtEntry->block_cntl_base); + bsa_print(ACS_PRINT_DEBUG, L" CNTCTLBase = %x \n", GtEntry->block_cntl_base); GtBlockTimer = (EFI_ACPI_6_1_GTDT_GT_BLOCK_TIMER_STRUCTURE *)(((UINT8 *)Entry) + Entry->GTBlockTimerOffset); for (i = 0; i < GtEntry->timer_count; i++) { bsa_print(ACS_PRINT_INFO, L"Found timer entry \n"); @@ -117,7 +117,8 @@ pal_timer_create_info_table(TIMER_INFO_TABLE *TimerTable) GtEntry->gsiv[i] = GtBlockTimer->GTxPhysicalTimerGSIV; GtEntry->virt_gsiv[i] = GtBlockTimer->GTxVirtualTimerGSIV; GtEntry->flags[i] = GtBlockTimer->GTxPhysicalTimerFlags | (GtBlockTimer->GTxVirtualTimerFlags << 8) | (GtBlockTimer->GTxCommonFlags << 16); - bsa_print(ACS_PRINT_DEBUG, L"CNTBaseN = %x for sys counter = %d\n", GtEntry->GtCntBase[i], i); + bsa_print(ACS_PRINT_DEBUG, L" CNTBaseN = %x for sys counter = %d\n", + GtEntry->GtCntBase[i], i); GtBlockTimer++; TimerTable->header.num_platform_timer++; } @@ -203,7 +204,8 @@ pal_wd_create_info_table(WD_INFO_TABLE *WdTable) WdEntry->wd_gsiv = Entry->WatchdogTimerGSIV; WdEntry->wd_flags = Entry->WatchdogTimerFlags; WdTable->header.num_wd++; - bsa_print(ACS_PRINT_DEBUG, L"Watchdog base = 0x%x INTID = 0x%x \n", WdEntry->wd_ctrl_base, WdEntry->wd_gsiv); + bsa_print(ACS_PRINT_DEBUG, L" Watchdog base = 0x%x INTID = 0x%x \n", + WdEntry->wd_ctrl_base, WdEntry->wd_gsiv); WdEntry++; } Entry = (EFI_ACPI_6_1_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE *) ((UINT8 *)Entry + (Entry->Length)); diff --git a/platform/pal_uefi_dt/BsaPalLib.inf b/platform/pal_uefi_dt/BsaPalLib.inf index cf6cb6f2..b813a593 100644 --- a/platform/pal_uefi_dt/BsaPalLib.inf +++ b/platform/pal_uefi_dt/BsaPalLib.inf @@ -41,8 +41,6 @@ src/pal_smmu.c src/pal_dt.c src/pal_dt_debug.c - src_gic_its/bsa_gic_its.c - src_gic_its/bsa_gic_redistributor.c [Packages] ArmPkg/ArmPkg.dec diff --git a/platform/pal_uefi_dt/include/pal_dt.h b/platform/pal_uefi_dt/include/pal_dt.h index 1b79e4c8..16a1558c 100644 --- a/platform/pal_uefi_dt/include/pal_dt.h +++ b/platform/pal_uefi_dt/include/pal_dt.h @@ -18,6 +18,8 @@ #ifndef __PAL_DT_H__ #define __PAL_DT_H__ +extern VOID *g_dtb_log_file_handle; + UINT64 pal_get_dt_ptr(); diff --git a/platform/pal_uefi_dt/include/pal_dt_spec.h b/platform/pal_uefi_dt/include/pal_dt_spec.h index eeac4f4d..dcca4496 100644 --- a/platform/pal_uefi_dt/include/pal_dt_spec.h +++ b/platform/pal_uefi_dt/include/pal_dt_spec.h @@ -21,6 +21,12 @@ #define PPI_OFFSET 16 #define SPI_OFFSET 32 +#define INTERRUPT_CELLS_MAX 4 +#define INTERRUPT_CELLS_MIN 1 + +#define INTERRUPT_TYPE_SPI 0 +#define INTERRUPT_TYPE_PPI 1 + /* PE related */ #define PROPERTY_MASK_PE_AFF3 0xFF /* Affinity bits 3 mask MPIDR_EL1[39:32] */ #define PROPERTY_MASK_PE_AFF0_AFF2 0xFFFFFF /* Affinity bits 0, 1, 2 mask MPIDR_EL1[23:0] */ @@ -68,4 +74,11 @@ /* PCI related */ #define PCI_COMPATIBLE_STR_LEN 26 +/* Peripheral Related */ +#define COMPATIBLE_FULL_16550 0x0 +#define COMPATIBLE_SUBSET_16550 0x1 +#define ARM_PL011_UART 0x3 +#define ARM_SBSA_GENERIC_UART 0xE +#define COMPATIBLE_GENERIC_16550 0x12 + #endif diff --git a/platform/pal_uefi_dt/include/pal_exerciser.h b/platform/pal_uefi_dt/include/pal_exerciser.h index 339aab16..9d2c5d51 100644 --- a/platform/pal_uefi_dt/include/pal_exerciser.h +++ b/platform/pal_uefi_dt/include/pal_exerciser.h @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2020, Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2016-2021, Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -200,11 +200,16 @@ typedef enum { EXERCISER_DATA_BAR0_SPACE = 0x2, } EXERCISER_DATA_TYPE; -UINT32 pal_exerciser_set_param(EXERCISER_PARAM_TYPE Type, UINT64 Value1, UINT64 Value2, UINT32 Bdf); -UINT32 pal_exerciser_get_param(EXERCISER_PARAM_TYPE Type, UINT64 *Value1, UINT64 *Value2, UINT32 Bdf); -UINT32 pal_exerciser_set_state(EXERCISER_STATE State, UINT64 *Value, UINT32 Bdf); +UINT32 pal_exerciser_set_param(EXERCISER_PARAM_TYPE Type, UINT64 Value1, + UINT64 Value2, UINT32 Bdf, UINT64 Ecam); +UINT32 pal_exerciser_get_param(EXERCISER_PARAM_TYPE Type, UINT64 *Value1, + UINT64 *Value2, UINT32 Bdf, UINT64 Ecam); +UINT32 pal_exerciser_set_state(EXERCISER_STATE State, UINT64 *Value, + UINT32 Bdf); UINT32 pal_exerciser_get_state(EXERCISER_STATE *State, UINT32 Bdf); -UINT32 pal_exerciser_ops(EXERCISER_OPS Ops, UINT64 Param, UINT32 Bdf); -UINT32 pal_exerciser_get_data(EXERCISER_DATA_TYPE Type, exerciser_data_t *Data, UINT32 Bdf, UINT64 Ecam); +UINT32 pal_exerciser_ops(EXERCISER_OPS Ops, UINT64 Param, UINT32 Bdf, + UINT64 Ecam); +UINT32 pal_exerciser_get_data(EXERCISER_DATA_TYPE Type, exerciser_data_t *Data, + UINT32 Bdf, UINT64 Ecam); #endif diff --git a/platform/pal_uefi_dt/include/pal_uefi.h b/platform/pal_uefi_dt/include/pal_uefi.h index 8107aa8f..07b66b19 100644 --- a/platform/pal_uefi_dt/include/pal_uefi.h +++ b/platform/pal_uefi_dt/include/pal_uefi.h @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2020, Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2016-2021, Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -105,7 +105,7 @@ typedef enum { typedef struct { UINT32 type; UINT64 base; - UINT32 its_id; /* This its_id is only used in case of ITS Type entry */ + UINT32 entry_id; /* This entry_id is only used in case of ITS Type entry */ UINT64 length; /* This length is only used in case of Re-Distributor Range Address length */ UINT32 flags; UINT32 spi_count; @@ -317,6 +317,8 @@ typedef struct { UINT32 msi; ///< MSI Enabled UINT32 msix; ///< MSIX Enabled UINT32 max_pasids; + UINT32 baud_rate; + UINT32 interface_type; }PERIPHERAL_INFO_BLOCK; /** @@ -365,6 +367,9 @@ UINT32 pal_pcie_get_root_port_bdf(UINT32 *seg, UINT32 *bus, UINT32 *dev, UINT32 UINT32 pal_pcie_max_pasid_bits(UINT32 bdf); /* Memory INFO table */ + +#define MEM_INFO_TBL_MAX_ENTRY 500 /* Maximum entries to be added in Mem info table*/ + typedef enum { MEMORY_TYPE_DEVICE = 0x1000, MEMORY_TYPE_NORMAL, diff --git a/platform/pal_uefi_dt/src/pal_dt.c b/platform/pal_uefi_dt/src/pal_dt.c index ee5d1c5e..e06d5f95 100644 --- a/platform/pal_uefi_dt/src/pal_dt.c +++ b/platform/pal_uefi_dt/src/pal_dt.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -30,14 +31,16 @@ #include "include/pal_uefi.h" #include "include/pal_dt.h" /** - @brief Checks if gic init and interrupt handlers ACS code is used + @brief Checks if System information is passed using Device Tree (DT) + This api is also used to check if GIC/Interrupt Init ACS Code + is used or not. In case of DT, ACS Code is used for INIT @param None @return True/False */ UINT32 -pal_bsa_gic_imp() +pal_target_is_dt() { return 1; } @@ -160,3 +163,33 @@ int fdt_node_offset_by_prop_name(const void *fdt, int startoffset, const char *p } return offset; } + +/** + @brief Dump DTB to file + + @param None + + @return None +**/ +VOID +pal_dump_dtb() +{ + if (g_dtb_log_file_handle) + { + UINT64 dtb = pal_get_dt_ptr(); + UINTN BufferSize; + EFI_STATUS Status; + + if (!dtb) + return; + + BufferSize = fdt_totalsize(dtb); + if (!BufferSize) { + bsa_print(ACS_PRINT_ERR, L"dtb size 0\n"); + return; + } + Status = ShellWriteFile(g_dtb_log_file_handle, &BufferSize, (VOID *)dtb); + if (EFI_ERROR(Status)) + bsa_print(ACS_PRINT_ERR, L"Error in writing to dtb log file\n"); + } +} diff --git a/platform/pal_uefi_dt/src/pal_dt_debug.c b/platform/pal_uefi_dt/src/pal_dt_debug.c index a6f1d9ef..2e190710 100644 --- a/platform/pal_uefi_dt/src/pal_dt_debug.c +++ b/platform/pal_uefi_dt/src/pal_dt_debug.c @@ -77,7 +77,7 @@ dt_dump_gic_table(GIC_INFO_TABLE *GicTable) bsa_print(ACS_PRINT_DEBUG, L" GIC TYPE :%x\n", GicTable->gic_info[Index].type); bsa_print(ACS_PRINT_DEBUG, L" BASE :%x\n", GicTable->gic_info[Index].base); bsa_print(ACS_PRINT_DEBUG, L" LEN :%x\n", GicTable->gic_info[Index].length); -// bsa_print(ACS_PRINT_DEBUG, L" ITS ID :%x\n", GicTable->gic_info[Index].its_id); +// bsa_print(ACS_PRINT_DEBUG, L" ITS ID :%x\n", GicTable->gic_info[Index].entry_id); Index++; } bsa_print(ACS_PRINT_DEBUG, L"************************************* \n\n"); diff --git a/platform/pal_uefi_dt/src/pal_exerciser.c b/platform/pal_uefi_dt/src/pal_exerciser.c index ed791dc4..f306a95a 100644 --- a/platform/pal_uefi_dt/src/pal_exerciser.c +++ b/platform/pal_uefi_dt/src/pal_exerciser.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2018-2020, Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2018-2021, Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -71,11 +71,11 @@ pal_increment_bus_dev( **/ UINT64 pal_exerciser_get_ecsr_base ( - UINT32 Bdf, + UINT64 EcsrBase, UINT32 BarIndex ) { - return palPcieGetBase(Bdf, BarIndex); + return pal_mmio_read(EcsrBase + BAR0_OFFSET + (BarIndex * 4)); } UINT64 @@ -96,7 +96,7 @@ pal_exerciser_get_pcie_config_offset(UINT32 Bdf) UINT32 pal_is_bdf_exerciser(UINT32 bdf) { - UINT32 Ecam; + UINT64 Ecam; UINT32 vendor_dev_id; Ecam = pal_pcie_get_mcfg_ecam(); @@ -151,7 +151,7 @@ pal_exerciser_find_pcie_capability ( UINT64 NxtPtr; UINT32 Data; UINT32 TempId; - UINT32 Ecam; + UINT64 Ecam; UINT32 IdMask; UINT32 PtrMask; UINT32 PtrOffset; @@ -196,14 +196,18 @@ UINT32 pal_exerciser_set_param ( EXERCISER_PARAM_TYPE Type, UINT64 Value1, UINT64 Value2, - UINT32 Bdf + UINT32 Bdf, + UINT64 Ecam ) { UINT32 Status; UINT32 Data; UINT64 Base; + UINT64 EcsrBase; /* Exerciser Base */ + + EcsrBase = (Ecam + pal_exerciser_get_pcie_config_offset(Bdf)); + Base = pal_exerciser_get_ecsr_base(EcsrBase, 0); /* BAR0 address */ - Base = pal_exerciser_get_ecsr_base(Bdf,0); switch (Type) { case SNOOP_ATTRIBUTES: @@ -263,14 +267,18 @@ pal_exerciser_get_param ( EXERCISER_PARAM_TYPE Type, UINT64 *Value1, UINT64 *Value2, - UINT32 Bdf + UINT32 Bdf, + UINT64 Ecam ) { UINT32 Status; UINT32 Temp; UINT64 Base; + UINT64 EcsrBase; /* Exerciser Base */ + + EcsrBase = (Ecam + pal_exerciser_get_pcie_config_offset(Bdf)); + Base = pal_exerciser_get_ecsr_base(EcsrBase, 0); /*BAR0 address */ - Base = pal_exerciser_get_ecsr_base(Bdf,0); switch (Type) { case SNOOP_ATTRIBUTES: @@ -341,16 +349,18 @@ UINT32 pal_exerciser_ops ( EXERCISER_OPS Ops, UINT64 Param, - UINT32 Bdf + UINT32 Bdf, + UINT64 Ecam ) { UINT64 Base; - UINT32 Ecam; UINT32 CapabilityOffset; UINT32 data; + UINT64 EcsrBase; /* Exerciser Base */ + + EcsrBase = (Ecam + pal_exerciser_get_pcie_config_offset(Bdf)); + Base = pal_exerciser_get_ecsr_base(EcsrBase, 0); /*BAR 0 address */ - Base = pal_exerciser_get_ecsr_base(Bdf,0); - Ecam = pal_pcie_get_mcfg_ecam(); // Getting the ECAM address switch(Ops){ case START_DMA: @@ -441,10 +451,11 @@ pal_exerciser_get_data ( ) { UINT32 Index; - UINT64 EcamBase; - UINT64 EcamBAR0; + UINT64 Base; + UINT64 EcsrBase; /* Exerciser Base */ - EcamBase = (Ecam + pal_exerciser_get_pcie_config_offset(Bdf)); + EcsrBase = (Ecam + pal_exerciser_get_pcie_config_offset(Bdf)); + Base = pal_exerciser_get_ecsr_base(EcsrBase, 0); /* BAR0 address */ //In the Latest version of BSA 6.0 this part of the test is obsolete hence filling the reg with same data UINT32 offset_table[TEST_REG_COUNT] = {0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08}; @@ -456,13 +467,13 @@ pal_exerciser_get_data ( for (Index = 0; Index < TEST_REG_COUNT; Index++) { Data->cfg_space.reg[Index].offset = (offset_table[Index] + pal_exerciser_get_pcie_config_offset (Bdf)); Data->cfg_space.reg[Index].attribute = attr_table[Index]; - Data->cfg_space.reg[Index].value = pal_mmio_read(EcamBase + offset_table[Index]); + Data->cfg_space.reg[Index].value = + pal_mmio_read(EcsrBase + offset_table[Index]); } return 0; case EXERCISER_DATA_BAR0_SPACE: - EcamBAR0 = pal_exerciser_get_ecsr_base(Bdf, 0); - Data->bar_space.base_addr = (void *)EcamBAR0; - if (((pal_exerciser_get_ecsr_base(Bdf,0) >> PREFETCHABLE_BIT_SHIFT) & MASK_BIT) == 0x1) + Data->bar_space.base_addr = (void *)Base; + if (((Base >> PREFETCHABLE_BIT_SHIFT) & MASK_BIT) == 0x1) Data->bar_space.type = MMIO_PREFETCHABLE; else Data->bar_space.type = MMIO_NON_PREFETCHABLE; diff --git a/platform/pal_uefi_dt/src/pal_gic.c b/platform/pal_uefi_dt/src/pal_gic.c index 601e0633..243d72ba 100644 --- a/platform/pal_uefi_dt/src/pal_gic.c +++ b/platform/pal_uefi_dt/src/pal_gic.c @@ -28,7 +28,6 @@ #include "include/pal_uefi.h" #include "include/bsa_pcie_enum.h" -#include "src_gic_its/bsa_gic_its.h" #include "include/pal_dt.h" #include "include/pal_dt_spec.h" @@ -64,9 +63,6 @@ EFI_HARDWARE_INTERRUPT2_PROTOCOL *gInterrupt2 = NULL; UINT64 pal_get_madt_ptr(); -GIC_INFO_ENTRY *g_gic_entry = NULL; -GIC_ITS_INFO *g_gic_its_info; - /** @brief This API fills in the PE_INFO_TABLE with information about GIC maintenance interrupt in the system. This is achieved by parsing the DT. @@ -98,7 +94,7 @@ pal_pe_info_table_gmaint_gsiv_dt(PE_INFO_TABLE *PeTable) /* Search for GICv3 nodes*/ offset = fdt_node_offset_by_compatible((const void *)dt_ptr, -1, gicv3_dt_arr[i]); if (offset < 0) { - bsa_print(ACS_PRINT_DEBUG, L"GICv3 compatible value not found for index : %d\n", i); + bsa_print(ACS_PRINT_DEBUG, L" GICv3 compatible value not found for index : %d\n", i); continue; /* Search for next compatible item*/ } else { @@ -112,7 +108,7 @@ pal_pe_info_table_gmaint_gsiv_dt(PE_INFO_TABLE *PeTable) /* Search for GICv2 nodes*/ offset = fdt_node_offset_by_compatible((const void *)dt_ptr, -1, gicv2_dt_arr[i]); if (offset < 0) { - bsa_print(ACS_PRINT_DEBUG, L"GICv2 compatible value not found for index : %d\n", i); + bsa_print(ACS_PRINT_DEBUG, L" GICv2 compatible value not found for index : %d\n", i); continue; /* Search for next compatible item*/ } else { @@ -136,13 +132,13 @@ pal_pe_info_table_gmaint_gsiv_dt(PE_INFO_TABLE *PeTable) interrupt_cell = fdt_interrupt_cells((const void *)dt_ptr, offset); bsa_print(ACS_PRINT_DEBUG, L" interrupt_cell %d\n", interrupt_cell); - if (interrupt_cell < 1 || interrupt_cell > 3) { + if (interrupt_cell < INTERRUPT_CELLS_MIN || interrupt_cell > INTERRUPT_CELLS_MAX) { bsa_print(ACS_PRINT_ERR, L" Invalid interrupt cell : %d \n", interrupt_cell); return; } for (i = 0; i < PeTable->header.num_of_pe; i++) { - if (interrupt_cell == 3) { + if ((interrupt_cell == 3) || (interrupt_cell == 4)) { if (Pintr[0]) Ptr->gmain_gsiv = fdt32_to_cpu(Pintr[1]) + PPI_OFFSET; else @@ -176,7 +172,6 @@ pal_gic_create_info_table(GIC_INFO_TABLE *GicTable) } GicEntry = GicTable->gic_info; - g_gic_entry = GicTable->gic_info; GicTable->header.gic_version = 0; GicTable->header.num_gicrd = 0; GicTable->header.num_gicd = 0; @@ -205,7 +200,7 @@ pal_gic_create_info_table(GIC_INFO_TABLE *GicTable) if (Entry->PhysicalBaseAddress != 0) { GicEntry->type = ENTRY_TYPE_CPUIF; GicEntry->base = Entry->PhysicalBaseAddress; - bsa_print(ACS_PRINT_INFO, L"GIC CPUIF base %x \n", GicEntry->base); + bsa_print(ACS_PRINT_INFO, L" GIC CPUIF base %x \n", GicEntry->base); GicEntry++; } @@ -213,7 +208,7 @@ pal_gic_create_info_table(GIC_INFO_TABLE *GicTable) GicEntry->type = ENTRY_TYPE_GICC_GICRD; GicEntry->base = Entry->GICRBaseAddress; GicEntry->length = 0; - bsa_print(ACS_PRINT_INFO, L"GIC RD base %x \n", GicEntry->base); + bsa_print(ACS_PRINT_INFO, L" GIC RD base %x \n", GicEntry->base); GicTable->header.num_gicrd++; GicEntry++; } @@ -223,7 +218,7 @@ pal_gic_create_info_table(GIC_INFO_TABLE *GicTable) GicEntry->type = ENTRY_TYPE_GICD; GicEntry->base = ((EFI_ACPI_6_1_GIC_DISTRIBUTOR_STRUCTURE *)Entry)->PhysicalBaseAddress; GicTable->header.gic_version = ((EFI_ACPI_6_1_GIC_DISTRIBUTOR_STRUCTURE *)Entry)->GicVersion; - bsa_print(ACS_PRINT_INFO, L"GIC DIS base %x \n", GicEntry->base); + bsa_print(ACS_PRINT_INFO, L" GIC DIS base %x \n", GicEntry->base); GicTable->header.num_gicd++; GicEntry++; } @@ -232,7 +227,7 @@ pal_gic_create_info_table(GIC_INFO_TABLE *GicTable) GicEntry->type = ENTRY_TYPE_GICR_GICRD; GicEntry->base = ((EFI_ACPI_6_1_GICR_STRUCTURE *)Entry)->DiscoveryRangeBaseAddress; GicEntry->length = ((EFI_ACPI_6_1_GICR_STRUCTURE *)Entry)->DiscoveryRangeLength; - bsa_print(ACS_PRINT_INFO, L"GIC RD base Structure %x \n", GicEntry->base); + bsa_print(ACS_PRINT_INFO, L" GIC RD base Structure %x \n", GicEntry->base); GicTable->header.num_gicrd++; GicEntry++; } @@ -240,9 +235,9 @@ pal_gic_create_info_table(GIC_INFO_TABLE *GicTable) if (Entry->Type == EFI_ACPI_6_1_GIC_ITS) { GicEntry->type = ENTRY_TYPE_GICITS; GicEntry->base = ((EFI_ACPI_6_1_GIC_ITS_STRUCTURE *)Entry)->PhysicalBaseAddress; - GicEntry->its_id = ((EFI_ACPI_6_1_GIC_ITS_STRUCTURE *)Entry)->GicItsId; - bsa_print(ACS_PRINT_INFO, L"GIC ITS base %x \n", GicEntry->base); - bsa_print(ACS_PRINT_INFO, L"GIC ITS ID%x \n", GicEntry->its_id); + GicEntry->entry_id = ((EFI_ACPI_6_1_GIC_ITS_STRUCTURE *)Entry)->GicItsId; + bsa_print(ACS_PRINT_INFO, L" GIC ITS base %x \n", GicEntry->base); + bsa_print(ACS_PRINT_INFO, L" GIC ITS ID%x \n", GicEntry->entry_id); GicTable->header.num_its++; GicEntry++; } @@ -374,174 +369,6 @@ pal_gic_free_irq ( } -UINT32 -pal_gic_its_configure ( - ) -{ - /* - * This function configure the gic to have support for LPIs, - * If supported in the system. - */ - EFI_STATUS Status; - - /* Allocate memory to store ITS info */ - g_gic_its_info = (GIC_ITS_INFO *) pal_mem_alloc(1024); - if (!g_gic_its_info) { - bsa_print(ACS_PRINT_DEBUG, L"GIC : ITS table memory allocation failed\n", 0); - goto its_fail; - } - - g_gic_its_info->GicNumIts = 0; - g_gic_its_info->GicRdBase = 0; - g_gic_its_info->GicDBase = 0; - - while (g_gic_entry->type != 0xFF) - { - if (g_gic_entry->type == ENTRY_TYPE_GICD) - { - g_gic_its_info->GicDBase = g_gic_entry->base; - } - else if ((g_gic_entry->type == ENTRY_TYPE_GICR_GICRD) || (g_gic_entry->type == ENTRY_TYPE_GICC_GICRD)) - { - /* Calculate Current PE Redistributor Base Address */ - if (g_gic_its_info->GicRdBase == 0) - { - if (g_gic_entry->type == ENTRY_TYPE_GICR_GICRD) - g_gic_its_info->GicRdBase = GetCurrentCpuRDBase(g_gic_entry->base, g_gic_entry->length); - else - g_gic_its_info->GicRdBase = GetCurrentCpuRDBase(g_gic_entry->base, 0); - } - } - else if (g_gic_entry->type == ENTRY_TYPE_GICITS) - { - g_gic_its_info->GicIts[g_gic_its_info->GicNumIts].Base = g_gic_entry->base; - g_gic_its_info->GicIts[g_gic_its_info->GicNumIts++].ID = g_gic_entry->its_id; - } - g_gic_entry++; - } - - /* Return if no ITS */ - if (g_gic_its_info->GicNumIts == 0) - { - bsa_print(ACS_PRINT_DEBUG, L"No ITS Found in the MADT.\n", 0); - goto its_fail; - } - - /* Base Address Check. */ - if ((g_gic_its_info->GicRdBase == 0) || (g_gic_its_info->GicDBase == 0)) - { - bsa_print(ACS_PRINT_DEBUG, L"Could not get GICD/GICRD Base.\n", 0); - goto its_fail; - } - - if (ArmGICDSupportsLPIs(g_gic_its_info->GicDBase) && ArmGICRSupportsLPIs(g_gic_its_info->GicRdBase)) - { - Status = ArmGicItsConfiguration(); - if (EFI_ERROR(Status)) - { - bsa_print(ACS_PRINT_DEBUG, L"Could Not Configure ITS.\n", 0); - goto its_fail; - } - } - else - { - bsa_print(ACS_PRINT_DEBUG, L"LPIs not supported in the system.\n", 0); - goto its_fail; - } - - return 0; - -its_fail: - bsa_print(ACS_PRINT_DEBUG, L"GIC ITS Initialization Failed.\n", 0); - bsa_print(ACS_PRINT_DEBUG, L"LPI Interrupt related test may not pass.\n", 0); - return 0xFFFFFFFF; -} - -UINT32 -pal_gic_get_max_lpi_id ( - ) -{ - return ArmGicItsGetMaxLpiID(); -} - -UINT32 -getItsIndex ( - IN UINT32 ItsID - ) -{ - UINT32 index; - - for (index=0; indexGicNumIts; index++) - { - if (ItsID == g_gic_its_info->GicIts[index].ID) - return index; - } - return 0xFFFFFFFF; -} - -UINT32 -pal_gic_request_msi ( - UINT32 ItsID, - UINT32 DevID, - UINT32 IntID, - UINT32 msi_index, - UINT32 *msi_addr, - UINT32 *msi_data - ) -{ - UINT32 ItsIndex; - - if ((g_gic_its_info == NULL) || (g_gic_its_info->GicNumIts == 0)) - return 0xFFFFFFFF; - - ItsIndex = getItsIndex(ItsID); - if (ItsIndex > g_gic_its_info->GicNumIts) { - bsa_print(ACS_PRINT_ERR, L"\n Could not find ITS block in MADT", 0); - return 0xFFFFFFFF; - } - - if ((g_gic_its_info->GicRdBase == 0) || (g_gic_its_info->GicDBase == 0)) - { - bsa_print(ACS_PRINT_DEBUG, L"GICD/GICRD Base Invalid value.\n", 0); - return 0xFFFFFFFF; - } - - ArmGicItsCreateLpiMap(ItsIndex, DevID, IntID, LPI_PRIORITY1); - - *msi_addr = ArmGicItsGetGITSTranslatorAddress(ItsIndex); - *msi_data = IntID; - - return 0; -} - -VOID -pal_gic_free_msi ( - UINT32 ItsID, - UINT32 DevID, - UINT32 IntID, - UINT32 msi_index - ) -{ - UINT32 ItsIndex; - - if ((g_gic_its_info == NULL) || (g_gic_its_info->GicNumIts == 0)) - return; - - ItsIndex = getItsIndex(ItsID); - if (ItsIndex > g_gic_its_info->GicNumIts) - { - bsa_print(ACS_PRINT_ERR, L"\n Could not find ITS block in MADT", 0); - return; - } - if ((g_gic_its_info->GicRdBase == 0) || (g_gic_its_info->GicDBase == 0)) - { - bsa_print(ACS_PRINT_DEBUG, L"GICD/GICRD Base Invalid value.\n", 0); - return; - } - - ArmGicItsClearLpiMappings(ItsIndex, DevID, IntID); -} - /** @brief This API fills in the GIC_INFO Table with information about the GIC in the system. This is achieved by parsing the DT blob. @@ -572,7 +399,7 @@ pal_gic_create_info_table_dt(GIC_INFO_TABLE *GicTable) /* Search for GICv3 nodes*/ offset = fdt_node_offset_by_compatible((const void *)dt_ptr, -1, gicv3_dt_arr[i]); if (offset < 0) { - bsa_print(ACS_PRINT_DEBUG, L"GICv3 compatible value not found for index : %d\n", i); + bsa_print(ACS_PRINT_DEBUG, L" GICv3 compatible value not found for index : %d\n", i); continue; /* Search for next compatible item*/ } else { @@ -583,12 +410,12 @@ pal_gic_create_info_table_dt(GIC_INFO_TABLE *GicTable) } if (offset < 0) { - bsa_print(ACS_PRINT_DEBUG, L"GIC v3 compatible node not found\n"); + bsa_print(ACS_PRINT_DEBUG, L" GIC v3 compatible node not found\n"); for (i = 0; i < (sizeof(gicv2_dt_arr)/GIC_COMPATIBLE_STR_LEN); i++) { /* Search for GICv2 nodes*/ offset = fdt_node_offset_by_compatible((const void *)dt_ptr, -1, gicv2_dt_arr[i]); if (offset < 0) { - bsa_print(ACS_PRINT_DEBUG, L"GICv2 compatible value not found for index : %d\n", i); + bsa_print(ACS_PRINT_DEBUG, L" GICv2 compatible value not found for index : %d\n", i); continue; /* Search for next compatible item*/ } else { @@ -600,7 +427,7 @@ pal_gic_create_info_table_dt(GIC_INFO_TABLE *GicTable) } if (offset < 0) { - bsa_print(ACS_PRINT_DEBUG, L"GIC v2 compatible node not found\n"); + bsa_print(ACS_PRINT_DEBUG, L" GIC v2 compatible node not found\n"); return; } diff --git a/platform/pal_uefi_dt/src/pal_misc.c b/platform/pal_uefi_dt/src/pal_misc.c index 038ed130..f923681e 100644 --- a/platform/pal_uefi_dt/src/pal_misc.c +++ b/platform/pal_uefi_dt/src/pal_misc.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2020, Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2016-2020, 2021 Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -346,7 +346,6 @@ pal_mem_alloc_cacheable ( ) { EFI_PHYSICAL_ADDRESS Address; - EFI_CPU_ARCH_PROTOCOL *Cpu; EFI_STATUS Status; Status = gBS->AllocatePages (AllocateAnyPages, @@ -358,23 +357,7 @@ pal_mem_alloc_cacheable ( return NULL; } - /* Check Whether Cpu architectural protocol is installed */ - Status = gBS->LocateProtocol ( &gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu); - if (EFI_ERROR(Status)) { - bsa_print(ACS_PRINT_ERR, L"Could not get Cpu Arch Protocol %x \n", Status); - return NULL; - } - - /* Set Memory Attributes */ - Status = Cpu->SetMemoryAttributes (Cpu, - Address, - Size, - EFI_MEMORY_WB); - if (EFI_ERROR (Status)) { - bsa_print(ACS_PRINT_ERR, L"Could not Set Memory Attribute %x \n", Status); - return NULL; - } - + /* As per EBBR spec, the memory allocated is cacheable */ *Pa = (VOID *)Address; return (VOID *)Address; } diff --git a/platform/pal_uefi_dt/src/pal_pcie.c b/platform/pal_uefi_dt/src/pal_pcie.c index 3f9b2ee7..a9da9765 100644 --- a/platform/pal_uefi_dt/src/pal_pcie.c +++ b/platform/pal_uefi_dt/src/pal_pcie.c @@ -296,7 +296,7 @@ pal_pcie_get_legacy_irq_map ( PERIPHERAL_IRQ_MAP *IrqMap ) { - return 1; + return 1; /* not implemented */ } /* Place holder function. Need to be diff --git a/platform/pal_uefi_dt/src/pal_pe.c b/platform/pal_uefi_dt/src/pal_pe.c index 0996cd99..28e24a7a 100644 --- a/platform/pal_uefi_dt/src/pal_pe.c +++ b/platform/pal_uefi_dt/src/pal_pe.c @@ -35,6 +35,11 @@ static UINT32 g_num_pe; static char pmu_dt_arr[][PMU_COMPATIBLE_STR_LEN] = { "arm,armv8-pmuv3", + "arm,cortex-a73-pmu", + "arm,cortex-a72-pmu", + "arm,cortex-a57-pmu", + "arm,cortex-a53-pmu", + "arm,cortex-a35-pmu", "arm,cortex-a17-pmu", "arm,cortex-a15-pmu", "arm,cortex-a12-pmu", @@ -363,7 +368,8 @@ pal_pe_info_table_pmu_gsiv_dt(PE_INFO_TABLE *PeTable) int index = 0; int interrupt_cell, interrupt_frame_count; PE_INFO_ENTRY *Ptr = NULL; - + int intr_type = 0; + int curr_pmu_intr_num = 0, prev_pmu_intr_num = 0; if (PeTable == NULL) return; @@ -381,7 +387,7 @@ pal_pe_info_table_pmu_gsiv_dt(PE_INFO_TABLE *PeTable) /* Search for pmu nodes*/ offset = fdt_node_offset_by_compatible((const void *)dt_ptr, -1, pmu_dt_arr[i]); if (offset < 0) { - bsa_print(ACS_PRINT_DEBUG, L"PMU compatible value not found for index:%d\n", i); + bsa_print(ACS_PRINT_DEBUG, L" PMU compatible value not found for index:%d\n", i); continue; /* Search for next compatible item*/ } @@ -397,7 +403,7 @@ pal_pe_info_table_pmu_gsiv_dt(PE_INFO_TABLE *PeTable) interrupt_cell = fdt_interrupt_cells((const void *)dt_ptr, offset); bsa_print(ACS_PRINT_DEBUG, L" interrupt_cell %d\n", interrupt_cell); - if (interrupt_cell < 1 || interrupt_cell > 3) { + if (interrupt_cell < INTERRUPT_CELLS_MIN || interrupt_cell > INTERRUPT_CELLS_MAX) { bsa_print(ACS_PRINT_ERR, L" Invalid interrupt cell : %d \n", interrupt_cell); return; } @@ -409,40 +415,56 @@ pal_pe_info_table_pmu_gsiv_dt(PE_INFO_TABLE *PeTable) bsa_print(ACS_PRINT_ERR, L" interrupt_frame_count is invalid\n"); return; } - /* Handle Single PMU node with Single PPI or SPI */ - if (interrupt_frame_count == 1) { - for (i = 0; i < PeTable->header.num_of_pe; i++) { - if (interrupt_cell == 3) { - if (Pintr[0]) - Ptr->pmu_gsiv = fdt32_to_cpu(Pintr[1]) + PPI_OFFSET; - else - Ptr->pmu_gsiv = fdt32_to_cpu(Pintr[1]) + SPI_OFFSET; - } - else - Ptr->pmu_gsiv = fdt32_to_cpu(Pintr[0]); - Ptr++; - } - return; - } - /* Handle Multiple PMU node with multiple SPI frames + index = 0; + /* Handle PMU node with multiple/single SPI/PPI frames * the pmu_gsiv should be in same order of CPU nodes */ for (i = 0; i < interrupt_frame_count; i++) { - if (interrupt_cell == 3) { - if (Pintr[index++]) - Ptr->pmu_gsiv = fdt32_to_cpu(Pintr[index++]) + PPI_OFFSET; - else - Ptr->pmu_gsiv = fdt32_to_cpu(Pintr[index++]) + SPI_OFFSET; - index++; /*Skip flag*/ - } else if (interrupt_cell == 2) { - Ptr->pmu_gsiv = fdt32_to_cpu(Pintr[index++]); - index++; /*Skip flag*/ - } else - Ptr->pmu_gsiv = fdt32_to_cpu(Pintr[index++]); - - Ptr++; - } + if ((interrupt_cell == 3) || (interrupt_cell == 4)) { + intr_type = fdt32_to_cpu(Pintr[index++]); + curr_pmu_intr_num = fdt32_to_cpu(Pintr[index++]); + index++; /*Skip flag*/ + if (interrupt_cell == 4) + index++; /*Skip CPU affinity */ + } else { + /* Skip PMU node , if interrupt type not mentioned*/ + Ptr = PeTable->pe_info; + for (i = 0; i < PeTable->header.num_of_pe; i++) { + Ptr->pmu_gsiv = 0; /* Set to zero*/ + Ptr++; + } + bsa_print(ACS_PRINT_WARN, L" PMU interrupt type not mentioned\n"); + return; + } + bsa_print(ACS_PRINT_DEBUG, L" intr_type : %d \n", intr_type); + bsa_print(ACS_PRINT_DEBUG, L" pmu_intr_num : %d \n", curr_pmu_intr_num); + + if (intr_type == INTERRUPT_TYPE_PPI) { + curr_pmu_intr_num += PPI_OFFSET; + if ((prev_pmu_intr_num != 0) && (curr_pmu_intr_num != prev_pmu_intr_num)) { + Ptr = PeTable->pe_info; + for (i = 0; i < PeTable->header.num_of_pe; i++) { + Ptr->pmu_gsiv = 0; /* Set to zero*/ + Ptr++; + } + bsa_print(ACS_PRINT_WARN, L" PMU interrupt number mismatch found\n"); + return; + } + if (prev_pmu_intr_num == 0) { /* Update table first time with same id*/ + for (i = 0; i < PeTable->header.num_of_pe; i++) { + Ptr->pmu_gsiv = curr_pmu_intr_num; + Ptr++; + } + } + prev_pmu_intr_num = curr_pmu_intr_num; + } + else { + curr_pmu_intr_num += SPI_OFFSET; + Ptr->pmu_gsiv = curr_pmu_intr_num; + Ptr++; + } + } offset = fdt_node_offset_by_compatible((const void *)dt_ptr, offset, pmu_dt_arr[i]); } diff --git a/platform/pal_uefi_dt/src/pal_peripherals.c b/platform/pal_uefi_dt/src/pal_peripherals.c index 2826a335..a1cc4984 100644 --- a/platform/pal_uefi_dt/src/pal_peripherals.c +++ b/platform/pal_uefi_dt/src/pal_peripherals.c @@ -58,7 +58,10 @@ static char sata_dt_compatible[][SATA_COMPATIBLE_STR_LEN] = { static char uart_dt_compatible[][UART_COMPATIBLE_STR_LEN] = { "arm,sbsa-uart", - "arm,pl011" + "arm,pl011", + "ns16550", + "ns16550a", + "ns8250", }; /** @@ -96,7 +99,7 @@ pal_peripheral_usb_create_info_table_dt(PERIPHERAL_INFO_TABLE *peripheralInfoTab /* Search for USB nodes*/ offset = fdt_node_offset_by_compatible((const void *)dt_ptr, -1, usb_dt_compatible[i]); if (offset < 0) { - bsa_print(ACS_PRINT_DEBUG, L"USB compatible value not found for index:%d\n", i); + bsa_print(ACS_PRINT_DEBUG, L" USB compatible value not found for index:%d\n", i); continue; /* Search for next compatible item*/ } @@ -139,7 +142,7 @@ pal_peripheral_usb_create_info_table_dt(PERIPHERAL_INFO_TABLE *peripheralInfoTab interrupt_cell = fdt_interrupt_cells((const void *)dt_ptr, offset); bsa_print(ACS_PRINT_DEBUG, L" interrupt_cell %d\n", interrupt_cell); - if (interrupt_cell < 1 || interrupt_cell > 3) { + if (interrupt_cell < INTERRUPT_CELLS_MIN || interrupt_cell > INTERRUPT_CELLS_MAX) { bsa_print(ACS_PRINT_ERR, L" Invalid interrupt cell : %d \n", interrupt_cell); return; } @@ -154,7 +157,7 @@ pal_peripheral_usb_create_info_table_dt(PERIPHERAL_INFO_TABLE *peripheralInfoTab per_info->base0 = fdt32_to_cpu(Preg[index]); index = 0; - if (interrupt_cell == 3) { + if ((interrupt_cell == 3) || (interrupt_cell == 4)) { if (fdt32_to_cpu(Pintr[index++]) == GIC_SPI) per_info->irq = fdt32_to_cpu(Pintr[index++]); else @@ -208,7 +211,7 @@ pal_peripheral_sata_create_info_table_dt(PERIPHERAL_INFO_TABLE *peripheralInfoTa /* Search for sata node*/ offset = fdt_node_offset_by_compatible((const void *)dt_ptr, -1, sata_dt_compatible[i]); if (offset < 0) { - bsa_print(ACS_PRINT_DEBUG, L"SATA compatible value not found for index:%d\n", i); + bsa_print(ACS_PRINT_DEBUG, L" SATA compatible value not found for index:%d\n", i); continue; /* Search for next compatible item*/ } @@ -251,7 +254,7 @@ pal_peripheral_sata_create_info_table_dt(PERIPHERAL_INFO_TABLE *peripheralInfoTa interrupt_cell = fdt_interrupt_cells((const void *)dt_ptr, offset); bsa_print(ACS_PRINT_DEBUG, L" interrupt_cell %d\n", interrupt_cell); - if (interrupt_cell < 1 || interrupt_cell > 3) { + if (interrupt_cell < INTERRUPT_CELLS_MIN || interrupt_cell > INTERRUPT_CELLS_MAX) { bsa_print(ACS_PRINT_ERR, L" Invalid interrupt cell : %d \n", interrupt_cell); return; } @@ -266,7 +269,7 @@ pal_peripheral_sata_create_info_table_dt(PERIPHERAL_INFO_TABLE *peripheralInfoTa per_info->base1 = fdt32_to_cpu(Preg[index]); index = 0; - if (interrupt_cell == 3) { + if ((interrupt_cell == 3) || (interrupt_cell == 4)) { if (fdt32_to_cpu(Pintr[index++]) == GIC_SPI) per_info->irq = fdt32_to_cpu(Pintr[index++]); else @@ -323,12 +326,12 @@ pal_peripheral_uart_create_info_table_dt(PERIPHERAL_INFO_TABLE *peripheralInfoTa peripheralInfoTable->header.num_uart = 0; - for (i = 0; i < (sizeof(uart_dt_compatible)/UART_COMPATIBLE_STR_LEN); i++) { + for (i = 0; i < (sizeof(uart_dt_compatible) / UART_COMPATIBLE_STR_LEN); i++) { /* Search for uart nodes*/ offset = fdt_node_offset_by_compatible((const void *)dt_ptr, -1, uart_dt_compatible[i]); if (offset < 0) { - bsa_print(ACS_PRINT_DEBUG, L"UART compatible value not found for index:%d\n", i); + bsa_print(ACS_PRINT_DEBUG, L" UART compatible value not found for index:%d\n", i); continue; /* Search for next compatible item*/ } @@ -469,7 +472,7 @@ pal_peripheral_uart_create_info_table_dt(PERIPHERAL_INFO_TABLE *peripheralInfoTa interrupt_cell = fdt_interrupt_cells((const void *)dt_ptr, offset); bsa_print(ACS_PRINT_DEBUG, L" interrupt_cell %d\n", interrupt_cell); - if (interrupt_cell < 1 || interrupt_cell > 3) { + if (interrupt_cell < INTERRUPT_CELLS_MIN || interrupt_cell > INTERRUPT_CELLS_MAX) { bsa_print(ACS_PRINT_ERR, L" Invalid interrupt cell : %d \n", interrupt_cell); return; } @@ -477,7 +480,7 @@ pal_peripheral_uart_create_info_table_dt(PERIPHERAL_INFO_TABLE *peripheralInfoTa per_info->type = PERIPHERAL_TYPE_UART; index = 0; - if (interrupt_cell == 3) { + if ((interrupt_cell == 3) || (interrupt_cell == 4)) { if (fdt32_to_cpu(Pintr[index++]) == GIC_SPI) per_info->irq = fdt32_to_cpu(Pintr[index++]) + SPI_OFFSET; else @@ -485,8 +488,17 @@ pal_peripheral_uart_create_info_table_dt(PERIPHERAL_INFO_TABLE *peripheralInfoTa } else per_info->irq = fdt32_to_cpu(Pintr[index++]) + SPI_OFFSET; + if (!(pal_strncmp(uart_dt_compatible[i], "ns16550", sizeof("ns16550"))) + || !(pal_strncmp(uart_dt_compatible[i], "ns16550a", sizeof("ns16550a"))) + || !(pal_strncmp(uart_dt_compatible[i], "ns8250", sizeof("ns8250a")))) + { + per_info->interface_type = COMPATIBLE_FULL_16550; + } else + per_info->interface_type = ARM_PL011_UART; + per_info->bdf = 0; /* NA in DT*/ per_info->flags = 0; /* NA in DT*/ + per_info->baud_rate = 0; /* NA in DT*/ peripheralInfoTable->header.num_uart++; per_info++; offset = @@ -737,6 +749,10 @@ pal_memory_create_info_table(MEMORY_INFO_TABLE *memoryInfoTable) memoryInfoTable->info[i].virt_addr = MemoryMapPtr->VirtualStart; memoryInfoTable->info[i].size = (MemoryMapPtr->NumberOfPages * EFI_PAGE_SIZE); i++; + if (i >= MEM_INFO_TBL_MAX_ENTRY) { + bsa_print(ACS_PRINT_DEBUG, L"Memory Info tbl limit exceeded, Skipping remaining\n", 0); + break; + } MemoryMapPtr = (EFI_MEMORY_DESCRIPTOR*)((UINTN)MemoryMapPtr + DescriptorSize); } diff --git a/platform/pal_uefi_dt/src/pal_timer_wd.c b/platform/pal_uefi_dt/src/pal_timer_wd.c index a33adde6..dc7ac667 100644 --- a/platform/pal_uefi_dt/src/pal_timer_wd.c +++ b/platform/pal_uefi_dt/src/pal_timer_wd.c @@ -309,7 +309,7 @@ pal_wd_create_info_table_dt(WD_INFO_TABLE *WdTable) interrupt_cell = fdt_interrupt_cells((const void *)dt_ptr, offset); bsa_print(ACS_PRINT_DEBUG, L" interrupt_cell %d\n", interrupt_cell); - if (interrupt_cell < 1 || interrupt_cell > 3) { + if (interrupt_cell < INTERRUPT_CELLS_MIN || interrupt_cell > INTERRUPT_CELLS_MAX) { bsa_print(ACS_PRINT_ERR, L" Invalid interrupt cell : %d \n", interrupt_cell); return; } @@ -330,7 +330,7 @@ pal_wd_create_info_table_dt(WD_INFO_TABLE *WdTable) } index = 0; - if (interrupt_cell == 3) { + if ((interrupt_cell == 3) || (interrupt_cell == 4)) { if (Pintr_val[index++]) WdEntry->wd_gsiv = fdt32_to_cpu(Pintr_val[index++]) + PPI_OFFSET; else @@ -347,7 +347,7 @@ pal_wd_create_info_table_dt(WD_INFO_TABLE *WdTable) switch (intr_flg) /* Interrupt flag*/ { case IRQ_TYPE_NONE: - bsa_print(ACS_PRINT_DEBUG, L"interrupt type none\n"); + bsa_print(ACS_PRINT_DEBUG, L" interrupt type none\n"); wd_mode = INTERRUPT_IS_LEVEL_TRIGGERED; /* Set default*/ wd_polarity = INTERRUPT_IS_ACTIVE_HIGH; break; @@ -368,7 +368,7 @@ pal_wd_create_info_table_dt(WD_INFO_TABLE *WdTable) wd_polarity = INTERRUPT_IS_ACTIVE_LOW; break; default: - bsa_print(ACS_PRINT_ERR, L"interrupt type invalid :%X \n", + bsa_print(ACS_PRINT_ERR, L" interrupt type invalid :%X \n", fdt32_to_cpu(Pintr_val[2])); return; } @@ -440,7 +440,7 @@ pal_timer_create_info_table_dt(TIMER_INFO_TABLE *TimerTable) } interrupt_cell = fdt_interrupt_cells((const void *)dt_ptr, offset); bsa_print(ACS_PRINT_DEBUG, L" interrupt_cell %d\n", interrupt_cell); - if (interrupt_cell < 1 || interrupt_cell > 3) { + if (interrupt_cell < INTERRUPT_CELLS_MIN || interrupt_cell > INTERRUPT_CELLS_MAX) { bsa_print(ACS_PRINT_ERR, L" Invalid interrupt cell : %d \n", interrupt_cell); return; } @@ -452,19 +452,27 @@ pal_timer_create_info_table_dt(TIMER_INFO_TABLE *TimerTable) return; } - if (interrupt_cell == 3) { /* Interrupt type available*/ + if (interrupt_cell >= 3) { /* Interrupt type available*/ if (fdt32_to_cpu(Pintr[index++]) == GIC_PPI) TimerTable->header.s_el1_timer_gsiv = fdt32_to_cpu(Pintr[index++]) + PPI_OFFSET; index++; /* Skip interrupt flag*/ + if (interrupt_cell == 4) + index++; /* Skip CPU affinity*/ if (fdt32_to_cpu(Pintr[index++]) == GIC_PPI) TimerTable->header.ns_el1_timer_gsiv = fdt32_to_cpu(Pintr[index++]) + PPI_OFFSET; index++; /* Skip interrupt flag*/ + if (interrupt_cell == 4) + index++; /* Skip CPU affinity*/ if (fdt32_to_cpu(Pintr[index++]) == GIC_PPI) TimerTable->header.virtual_timer_gsiv = fdt32_to_cpu(Pintr[index++]) + PPI_OFFSET; index++; /* Skip interrupt flag*/ + if (interrupt_cell == 4) + index++; /* Skip CPU affinity*/ if (fdt32_to_cpu(Pintr[index++]) == GIC_PPI) TimerTable->header.el2_timer_gsiv = fdt32_to_cpu(Pintr[index++]) + PPI_OFFSET; index++; /* Skip interrupt flag*/ + if (interrupt_cell == 4) + index++; /* Skip CPU affinity*/ } else { TimerTable->header.s_el1_timer_gsiv = fdt32_to_cpu(Pintr[index++]); @@ -547,14 +555,14 @@ pal_timer_create_info_table_dt(TIMER_INFO_TABLE *TimerTable) /* Get frame sub node*/ subnode_offset = fdt_subnode_offset((const void *)dt_ptr, offset, "frame"); if (subnode_offset < 0) { - bsa_print(ACS_PRINT_DEBUG, L"frame node offset not found %d \n", subnode_offset); + bsa_print(ACS_PRINT_DEBUG, L" frame node offset not found %d \n", subnode_offset); return; } while (subnode_offset != -FDT_ERR_NOTFOUND) { /* Get frame number*/ frame_number = fdt_frame_number((const void *)dt_ptr, subnode_offset); - bsa_print(ACS_PRINT_DEBUG, L"Frame number is %d \n", frame_number); + bsa_print(ACS_PRINT_DEBUG, L" Frame number is %d \n", frame_number); /* Get reg property from frame to update GtCntBase */ Preg = (UINT32 *)fdt_getprop_namelen((void *)dt_ptr, subnode_offset, "reg", 3, &prop_len); @@ -574,7 +582,7 @@ pal_timer_create_info_table_dt(TIMER_INFO_TABLE *TimerTable) interrupt_cell = fdt_interrupt_cells((const void *)dt_ptr, subnode_offset); bsa_print(ACS_PRINT_DEBUG, L" interrupt_cell for subnode %d\n", interrupt_cell); - if (interrupt_cell < 1 || interrupt_cell > 3) { + if (interrupt_cell < INTERRUPT_CELLS_MIN || interrupt_cell > INTERRUPT_CELLS_MAX) { bsa_print(ACS_PRINT_ERR, L" Invalid interrupt cell subnode: %d \n", interrupt_cell); return; } @@ -591,13 +599,15 @@ pal_timer_create_info_table_dt(TIMER_INFO_TABLE *TimerTable) GtEntry->frame_num[GtEntry->timer_count] = frame_number; index = 0; - if (interrupt_cell == 3) { + if (interrupt_cell >= 3) { if (fdt32_to_cpu(Pintr[index++]) == GIC_SPI) GtEntry->gsiv[GtEntry->timer_count] = fdt32_to_cpu(Pintr[index++]) + SPI_OFFSET; else GtEntry->gsiv[GtEntry->timer_count] = 0; /* Invalid interrupt type*/ index++; /* Skip interrupt flag*/ + if (interrupt_cell == 4) + index++; /* Skip CPU affinity*/ if ((prop_len/sizeof(UINT32)) > interrupt_cell) {/* virt_gsiv is optional*/ if (fdt32_to_cpu(Pintr[index++]) == GIC_SPI) GtEntry->virt_gsiv[GtEntry->timer_count] = fdt32_to_cpu(Pintr[index]) + SPI_OFFSET; diff --git a/test_pool/Makefile b/test_pool/Makefile index bf4a502b..1157a4e8 100644 --- a/test_pool/Makefile +++ b/test_pool/Makefile @@ -25,12 +25,12 @@ TEST_POOL = $(ACS_DIR)/ obj-m += bsa_acs_test.o bsa_acs_test-objs += $(TEST_POOL)/pcie/operating_system/test_os_p001.o \ - $(TEST_POOL)/pcie/operating_system/test_os_p005.o \ - $(TEST_POOL)/pcie/operating_system/test_os_p006.o \ - $(TEST_POOL)/pcie/operating_system/test_os_p007.o \ - $(TEST_POOL)/pcie/operating_system/test_os_p011.o \ - $(TEST_POOL)/pcie/operating_system/test_os_p012.o \ - $(TEST_POOL)/pcie/operating_system/test_os_p016.o \ + $(TEST_POOL)/pcie/operating_system/test_os_p061.o \ + $(TEST_POOL)/pcie/operating_system/test_os_p062.o \ + $(TEST_POOL)/pcie/operating_system/test_os_p063.o \ + $(TEST_POOL)/pcie/operating_system/test_os_p064.o \ + $(TEST_POOL)/pcie/operating_system/test_os_p065.o \ + $(TEST_POOL)/pcie/operating_system/test_os_p066.o \ $(TEST_POOL)/peripherals/operating_system/test_os_d004.o \ $(TEST_POOL)/memory_map/operating_system/test_os_m004.o \ diff --git a/test_pool/exerciser/operating_system/test_os_e001.c b/test_pool/exerciser/operating_system/test_os_e001.c index b8770f20..02bfe5d1 100644 --- a/test_pool/exerciser/operating_system/test_os_e001.c +++ b/test_pool/exerciser/operating_system/test_os_e001.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2018-2019, Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2020,2021 Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,69 +20,257 @@ #include "val/include/bsa_acs_pcie_enumeration.h" #include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pe.h" +#include "val/include/bsa_acs_smmu.h" +#include "val/include/bsa_acs_memory.h" #include "val/include/bsa_acs_exerciser.h" #define TEST_NUM (ACS_EXERCISER_TEST_NUM_BASE + 1) -#define TEST_DESC "Enhanced ECAM Memory access check " +#define TEST_RULE "PCI_PP_04" +#define TEST_DESC "Check P2P ACS Functionality " +static +uint32_t +get_target_exer_bdf(uint32_t req_rp_bdf, uint32_t *tgt_e_bdf, + uint32_t *tgt_rp_bdf, uint64_t *bar_base) +{ + + uint32_t erp_bdf; + uint32_t e_bdf; + uint32_t instance; + uint32_t cap_base; + + instance = val_exerciser_get_info(EXERCISER_NUM_CARDS, 0); + + while (instance-- != 0) + { + /* if init fail moves to next exerciser */ + if (val_exerciser_init(instance)) + continue; + + e_bdf = val_exerciser_get_bdf(instance); + + /* Read e_bdf BAR Register to get the Address to perform P2P */ + /* If No BAR Space, continue */ + val_pcie_get_mmio_bar(e_bdf, bar_base); + if (*bar_base == 0) + continue; + + /* Get RP of the exerciser */ + if (val_pcie_get_rootport(e_bdf, &erp_bdf)) + continue; + + /* It ACS Not Supported, continue */ + if (val_pcie_find_capability(erp_bdf, PCIE_ECAP, ECID_ACS, &cap_base) != PCIE_SUCCESS) { + val_print(ACS_PRINT_DEBUG, "\n ACS Not Supported for BDF : 0x%x", erp_bdf); + continue; + } + + if (req_rp_bdf != erp_bdf) + { + *tgt_e_bdf = e_bdf; + *tgt_rp_bdf = erp_bdf; + + /* Enable Bus Master Enable */ + val_pcie_enable_bme(e_bdf); + /* Enable Memory Space Access */ + val_pcie_enable_msa(e_bdf); + + return ACS_STATUS_PASS; + } + } + + /* Return failure if No Such Exerciser Found */ + *tgt_e_bdf = 0; + *tgt_rp_bdf = 0; + *bar_base = 0; + return ACS_STATUS_FAIL; +} + +uint32_t +check_source_validation (uint32_t req_instance, uint32_t req_e_bdf, + uint32_t req_rp_bdf, uint32_t tgt_e_bdf, + uint64_t bar_base) +{ + /* Check 1 : ACS Source Validation */ + + uint32_t reg_value; + uint32_t sub_bus; + uint32_t new_bdf; + + /* Pass Sequence */ + val_exerciser_set_param(DMA_ATTRIBUTES, (uint64_t)bar_base, 1, req_instance); + + if (val_exerciser_ops(START_DMA, EDMA_FROM_DEVICE, req_instance)) { + val_print(ACS_PRINT_DEBUG, "\n DMA failure from exerciser %4x", req_instance); + return ACS_STATUS_FAIL; + } + + /* Clear Error Status Bits */ + val_pcie_clear_device_status_error(req_rp_bdf); + val_pcie_clear_sig_target_abort(req_rp_bdf); + + /* Change Requester ID for DMA such that it does not fall under req_rp_bdf + * Secondary & Subordinate bdf + */ + val_pcie_read_cfg(req_rp_bdf, TYPE1_PBN, ®_value); + sub_bus = (reg_value >> SUBBN_SHIFT) & SUBBN_MASK; + new_bdf = PCIE_CREATE_BDF(PCIE_EXTRACT_BDF_SEG(req_rp_bdf), + (sub_bus+1), 0, 0); + + val_exerciser_set_param(CFG_TXN_ATTRIBUTES, TXN_REQ_ID, new_bdf, req_instance); + val_exerciser_set_param(DMA_ATTRIBUTES, (uint64_t)bar_base, 1, req_instance); + + if (val_exerciser_ops(START_DMA, EDMA_FROM_DEVICE, req_instance)) { + val_print(ACS_PRINT_DEBUG, "\n DMA failure from exerciser %4x", req_instance); + return ACS_STATUS_FAIL; + } + + /* Check For Error in Device Status Register / Status Register + * Secondary Status Register + */ + if ((val_pcie_is_device_status_error(req_rp_bdf) == 0) && + (val_pcie_is_sig_target_abort(req_rp_bdf) == 0)) { + /* Fail the part */ + val_print(ACS_PRINT_DEBUG, + "\n Src Validation Expected Error RootPort : 0x%x", req_rp_bdf); + return ACS_STATUS_FAIL; + } + + return ACS_STATUS_PASS; +} + +uint32_t +check_transaction_blocking (uint32_t req_instance, uint32_t req_e_bdf, + uint32_t req_rp_bdf, uint32_t tgt_e_bdf, + uint64_t bar_base) +{ + /* Check 2 : ACS Transaction Blocking */ + + /* Clear Error Status Bits */ + val_pcie_clear_device_status_error(req_rp_bdf); + val_pcie_clear_sig_target_abort(req_rp_bdf); + + /* Transaction with Address Type other than default(0x0) + * Should result into Transaction blocking. + */ + val_exerciser_set_param(CFG_TXN_ATTRIBUTES, TXN_ADDR_TYPE, AT_RESERVED, req_instance); + val_exerciser_set_param(DMA_ATTRIBUTES, (uint64_t)bar_base, 1, req_instance); + + if (val_exerciser_ops(START_DMA, EDMA_FROM_DEVICE, req_instance)) { + val_print(ACS_PRINT_DEBUG, "\n DMA failure from exerciser %4x", req_instance); + return ACS_STATUS_FAIL; + } + + /* Check For Error in Device Status Register / Status Register + * Secondary Status Register + */ + if ((val_pcie_is_device_status_error(req_rp_bdf) == 0) && + (val_pcie_is_sig_target_abort(req_rp_bdf) == 0)) { + /* Fail the part */ + val_print(ACS_PRINT_DEBUG, + "\n Traxn Blocking Expected Error RootPort : 0x%x", req_rp_bdf); + return ACS_STATUS_FAIL; + } + + return ACS_STATUS_PASS; +} static void payload(void) { + uint32_t status; uint32_t pe_index; - uint32_t data; - uint32_t bdf; + uint32_t req_e_bdf; + uint32_t req_rp_bdf; + uint32_t tgt_e_bdf; + uint32_t tgt_rp_bdf; uint32_t instance; - uint32_t reg_index; - exerciser_data_t e_data; + uint32_t fail_cnt; + uint32_t cap_base; + uint32_t reg_value; + uint32_t test_skip; + uint64_t bar_base; + uint32_t curr_bdf_failed = 0; + fail_cnt = 0; + test_skip = 1; pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); instance = val_exerciser_get_info(EXERCISER_NUM_CARDS, 0); + /* Check If PCIe Hierarchy supports P2P. */ + if (val_pcie_p2p_support()) + { + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + return; + } - while (instance-- != 0) { + while (instance-- != 0) + { /* if init fail moves to next exerciser */ if (val_exerciser_init(instance)) continue; - if (val_exerciser_get_data(EXERCISER_DATA_CFG_SPACE, &e_data, instance)) { - val_print(ACS_PRINT_ERR, "\n Exerciser %d data read error ", instance); - goto check_fail; - } + req_e_bdf = val_exerciser_get_bdf(instance); - bdf = val_exerciser_get_bdf(instance); + /* Get RP of the exerciser */ + if (val_pcie_get_rootport(req_e_bdf, &req_rp_bdf)) + continue; - /* Check ECAM config register read/write */ - for (reg_index = 0; reg_index < TEST_REG_COUNT; reg_index++) { + /* It ACS Not Supported, Fail.*/ + if (val_pcie_find_capability(req_rp_bdf, PCIE_ECAP, ECID_ACS, &cap_base) != PCIE_SUCCESS) { + val_print(ACS_PRINT_ERR, "\n ACS Not Supported for BDF : 0x%x", req_rp_bdf); + fail_cnt++; + continue; + } + + /* Enable Source Validation & Transaction Blocking */ + val_pcie_read_cfg(req_rp_bdf, cap_base + ACSCR_OFFSET, ®_value); + reg_value = reg_value | (1 << ACS_CTRL_SVE_SHIFT) | (1 << ACS_CTRL_TBE_SHIFT); + val_pcie_write_cfg(req_rp_bdf, cap_base + ACSCR_OFFSET, reg_value); - if (e_data.cfg_space.reg[reg_index].attribute == ACCESS_TYPE_RW) { - val_pcie_write_cfg(bdf, e_data.cfg_space.reg[reg_index].offset, - e_data.cfg_space.reg[reg_index].value); + /* Find another exerciser on other rootport, + Break from the test if no such exerciser if found */ + if (get_target_exer_bdf(req_rp_bdf, &tgt_e_bdf, &tgt_rp_bdf, &bar_base)) + break; - if (val_pcie_read_cfg(bdf, e_data.cfg_space.reg[reg_index].offset, &data) - == PCIE_NO_MAPPING) { - val_print(ACS_PRINT_ERR, "\n Exerciser %d cfg reg read error ", instance); - goto check_fail; - } + /* If Both RP's Supports ACS Then Only Run Otherwise Skip the EP */ + test_skip = 0; - if (data != e_data.cfg_space.reg[reg_index].value) { - val_print(ACS_PRINT_ERR, "\n Exerciser cfg reg read write mismatch %d", data); - goto check_fail; - } - } + /* Check For ACS Functionality */ + status = check_source_validation(instance, req_e_bdf, req_rp_bdf, tgt_e_bdf, bar_base); + if (status == ACS_STATUS_SKIP) + val_print(ACS_PRINT_DEBUG, "\n ACS Source Validation Skipped for 0x%x", req_rp_bdf); + else if (status) + curr_bdf_failed++; - } + status = check_transaction_blocking(instance, req_e_bdf, req_rp_bdf, tgt_e_bdf, bar_base); + if (status == ACS_STATUS_SKIP) + val_print(ACS_PRINT_DEBUG, + "\n ACS Transaction Blocking Skipped for 0x%x", req_rp_bdf); + else if (status) + curr_bdf_failed++; + if (curr_bdf_failed > 0) { + val_print(ACS_PRINT_ERR, "\n ACS Functional Check Failed, RP Bdf : 0x%x", req_rp_bdf); + curr_bdf_failed = 0; + fail_cnt++; + } + /* Clear Error Status Bits */ + val_pcie_clear_device_status_error(req_rp_bdf); + val_pcie_clear_sig_target_abort(req_rp_bdf); } - val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); - return; + if (test_skip == 1) + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + else if (fail_cnt) + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, fail_cnt)); + else + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); -check_fail: - val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 02)); return; } @@ -98,9 +286,9 @@ os_e001_entry(void) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* Get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/exerciser/operating_system/test_os_e002.c b/test_pool/exerciser/operating_system/test_os_e002.c new file mode 100644 index 00000000..c4193802 --- /dev/null +++ b/test_pool/exerciser/operating_system/test_os_e002.c @@ -0,0 +1,416 @@ +/** @file + * Copyright (c) 2020,2021 Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_pcie_enumeration.h" +#include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pe.h" +#include "val/include/bsa_acs_smmu.h" +#include "val/include/bsa_acs_pgt.h" +#include "val/include/bsa_acs_iovirt.h" +#include "val/include/bsa_acs_memory.h" +#include "val/include/bsa_acs_exerciser.h" + +#define TEST_NUM (ACS_EXERCISER_TEST_NUM_BASE + 2) +#define TEST_RULE "PCI_PP_04" +#define TEST_DESC "Check ACS Redirect Req Valid " + +static +uint32_t +get_target_exer_bdf(uint32_t req_rp_bdf, uint32_t *tgt_e_bdf, + uint32_t *tgt_rp_bdf, uint64_t *bar_base) +{ + + uint32_t erp_bdf; + uint32_t e_bdf; + uint32_t instance; + uint32_t cap_base; + + instance = val_exerciser_get_info(EXERCISER_NUM_CARDS, 0); + + while (instance-- != 0) + { + /* if init fail moves to next exerciser */ + if (val_exerciser_init(instance)) + continue; + + e_bdf = val_exerciser_get_bdf(instance); + + /* Read e_bdf BAR Register to get the Address to perform P2P */ + /* If No BAR Space, continue */ + val_pcie_get_mmio_bar(e_bdf, bar_base); + if (*bar_base == 0) + continue; + + /* Get RP of the exerciser */ + if (val_pcie_get_rootport(e_bdf, &erp_bdf)) + continue; + + /* It ACS Not Supported, continue */ + if (val_pcie_find_capability(erp_bdf, PCIE_ECAP, ECID_ACS, &cap_base) != PCIE_SUCCESS) { + val_print(ACS_PRINT_DEBUG, "\n ACS Not Supported for BDF : 0x%x", erp_bdf); + continue; + } + + if (req_rp_bdf != erp_bdf) + { + *tgt_e_bdf = e_bdf; + *tgt_rp_bdf = erp_bdf; + + /* Enable Bus Master Enable */ + val_pcie_enable_bme(e_bdf); + /* Enable Memory Space Access */ + val_pcie_enable_msa(e_bdf); + + return ACS_STATUS_PASS; + } + } + + /* Return failure if No Such Exerciser Found */ + *tgt_e_bdf = 0; + *tgt_rp_bdf = 0; + *bar_base = 0; + return ACS_STATUS_FAIL; +} + +uint32_t +create_va_pa_mapping (uint64_t txn_va, uint64_t txn_pa, + smmu_master_attributes_t *smmu_master, + pgt_descriptor_t *pgt_descriptor, + uint32_t e_bdf, uint32_t pgt_ap) +{ + smmu_master_attributes_t master; + pgt_descriptor_t pgt_desc; + memory_region_descriptor_t mem_desc_array[2], *mem_desc; + uint64_t ttbr; + uint32_t num_smmus; + uint32_t instance; + uint32_t device_id, its_id; + + master = *smmu_master; + pgt_desc = *pgt_descriptor; + + val_memory_set(&master, sizeof(master), 0); + val_memory_set(mem_desc_array, sizeof(mem_desc_array), 0); + mem_desc = &mem_desc_array[0]; + + /* Get translation attributes via TCR and translation table base via TTBR */ + if (val_pe_reg_read_tcr(0 /*for TTBR0*/, &pgt_desc.tcr)) + return ACS_STATUS_FAIL; + if (val_pe_reg_read_ttbr(0 /*TTBR0*/, &ttbr)) + return ACS_STATUS_FAIL; + pgt_desc.pgt_base = (ttbr & AARCH64_TTBR_ADDR_MASK); + pgt_desc.mair = val_pe_reg_read(MAIR_ELx); + pgt_desc.stage = PGT_STAGE1; + + /* Get memory attributes of the test buffer, we'll use the same attibutes to create + * our own page table later. + */ + if (val_pgt_get_attributes(pgt_desc, (uint64_t)txn_va, &mem_desc->attributes)) + return ACS_STATUS_FAIL; + + num_smmus = val_iovirt_get_smmu_info(SMMU_NUM_CTRL, 0); + + /* Enable all SMMUs */ + for (instance = 0; instance < num_smmus; ++instance) + val_smmu_enable(instance); + + /* Get SMMU node index for this exerciser instance */ + master.smmu_index = val_iovirt_get_rc_smmu_index(PCIE_EXTRACT_BDF_SEG(e_bdf)); + + if (master.smmu_index != ACS_INVALID_INDEX && + val_iovirt_get_smmu_info(SMMU_CTRL_ARCH_MAJOR_REV, master.smmu_index) == 3) { + if (val_iovirt_get_device_info(PCIE_CREATE_BDF_PACKED(e_bdf), + PCIE_EXTRACT_BDF_SEG(e_bdf), + &device_id, &master.streamid, + &its_id)) + return ACS_STATUS_FAIL; + + /* Each exerciser instance accesses a unique IOVA, which, because of SMMU translations, + * will point to the same physical address. We create the requisite page tables and + * configure the SMMU for each exerciser as such. + */ + + mem_desc->virtual_address = (uint64_t)txn_va; + mem_desc->physical_address = txn_pa; + mem_desc->length = 4; /* 4 Bytes */ + mem_desc->attributes |= pgt_ap; + + /* Need to know input and output address sizes before creating page table */ + pgt_desc.ias = val_smmu_get_info(SMMU_IN_ADDR_SIZE, master.smmu_index); + if (pgt_desc.ias == 0) + return ACS_STATUS_FAIL; + + pgt_desc.oas = val_smmu_get_info(SMMU_OUT_ADDR_SIZE, master.smmu_index); + if (pgt_desc.oas == 0) + return ACS_STATUS_FAIL; + + if (val_pgt_create(mem_desc, &pgt_desc)) + return ACS_STATUS_FAIL; + + /* Configure SMMU tables for this exerciser to use this page table for VA to PA translations*/ + if (val_smmu_map(master, pgt_desc)) + { + val_print(ACS_PRINT_DEBUG, "\n SMMU mapping failed (%x) ", e_bdf); + return ACS_STATUS_FAIL; + } + return ACS_STATUS_PASS; + } + return ACS_STATUS_FAIL; +} + +uint32_t +check_redirected_req_validation (uint32_t req_instance, uint32_t req_e_bdf, + uint32_t req_rp_bdf, uint32_t tgt_e_bdf, + uint64_t bar_base) +{ + uint64_t txn_va; + uint32_t instance; + uint32_t e_bdf; + uint32_t num_smmus; + uint32_t status; + smmu_master_attributes_t master; + pgt_descriptor_t pgt_desc; + + /* Sequence 1 : No Write Permission, Trigger a DMA Write to bar address + * It should Result into ACS Violation + */ + + /* Create VA-PA Mapping in SMMU with PGT permissions as Read Only */ + /* Initialize DMA master and memory descriptors */ + + /* Set the virtual and physical addresses for test buffers */ + txn_va = (uint64_t)val_memory_phys_to_virt(bar_base); + + /* Get exerciser bdf */ + e_bdf = val_exerciser_get_bdf(req_instance); + + num_smmus = val_iovirt_get_smmu_info(SMMU_NUM_CTRL, 0); + + status = create_va_pa_mapping(txn_va, bar_base, &master, + &pgt_desc, e_bdf, + PGT_STAGE1_AP_RO); + if (status) { + val_print(ACS_PRINT_DEBUG, + "\n Seq1:SMMU Mapping Failed For : %4x", req_instance); + goto test_fail; + } + + /* Trigger DMA from req_e_bdf */ + val_exerciser_set_param(DMA_ATTRIBUTES, (uint64_t)txn_va, 1, req_instance); + + /* Clear Error Status Bits */ + val_pcie_clear_device_status_error(req_rp_bdf); + val_pcie_clear_sig_target_abort(req_rp_bdf); + + /* DMA Should fail because Write permission not given */ + if (val_exerciser_ops(START_DMA, EDMA_FROM_DEVICE, req_instance) == 0) { + val_print(ACS_PRINT_DEBUG, + "\n Seq1:DMA Write Should not happen For : %4x", req_instance); + goto test_fail; + } + + /* Check For Error in Device Status Register / Status Register + * Secondary Status Register + */ + if ((val_pcie_is_device_status_error(req_rp_bdf) == 0) && + (val_pcie_is_sig_target_abort(req_rp_bdf) == 0)) { + val_print(ACS_PRINT_DEBUG, "\n Seq1:Expected Error For RootPort : 0x%x", req_rp_bdf); + goto test_fail; + } + + /* Unmap SMMU & Pgt */ + val_smmu_unmap(master); + val_pgt_destroy(pgt_desc); + + /* Disable all SMMUs */ + for (instance = 0; instance < num_smmus; ++instance) + val_smmu_disable(instance); + + /* Sequence 2 : Read Write Permission, Trigger a DMA Write to bar address + * It should NOT Result into ACS Violation + */ + + /* Create VA-PA Mapping in SMMU with PGT permissions as Read Write */ + status = create_va_pa_mapping(txn_va, bar_base, &master, + &pgt_desc, e_bdf, + PGT_STAGE1_AP_RW); + if (status) { + val_print(ACS_PRINT_DEBUG, "\n Seq2:SMMU Mapping Failed For : %4x", req_instance); + goto test_fail; + } + + /* Trigger DMA from req_e_bdf */ + val_exerciser_set_param(DMA_ATTRIBUTES, (uint64_t)txn_va, 1, req_instance); + + /* Clear Error Status Bits */ + val_pcie_clear_device_status_error(req_rp_bdf); + val_pcie_clear_sig_target_abort(req_rp_bdf); + + /* DMA Should fail not because Write permission given */ + if (val_exerciser_ops(START_DMA, EDMA_FROM_DEVICE, req_instance) != 0) { + val_print(ACS_PRINT_DEBUG, "\n Seq2:DMA Write Should happen For : %4x", req_instance); + goto test_fail; + } + + /* Check For Error in Device Status Register / Status Register + * Secondary Status Register + */ + if (val_pcie_is_device_status_error(req_rp_bdf) || + val_pcie_is_sig_target_abort(req_rp_bdf)) { + val_print(ACS_PRINT_DEBUG, "\n Seq2:Expected No Error For RootPort : 0x%x", req_rp_bdf); + goto test_fail; + } + + status = ACS_STATUS_PASS; + goto test_clean; + +test_fail: + status = ACS_STATUS_FAIL; + +test_clean: + val_smmu_unmap(master); + val_pgt_destroy(pgt_desc); + + /* Clear Error Status Bits */ + val_pcie_clear_device_status_error(req_rp_bdf); + val_pcie_clear_sig_target_abort(req_rp_bdf); + + /* Disable all SMMUs */ + for (instance = 0; instance < num_smmus; ++instance) + val_smmu_disable(instance); + return status; +} + +static +void +payload(void) +{ + + uint32_t status; + uint32_t pe_index; + uint32_t bdf; + uint32_t req_e_bdf; + uint32_t req_rp_bdf; + uint32_t tgt_e_bdf; + uint32_t tgt_rp_bdf; + uint32_t instance; + uint32_t fail_cnt; + uint32_t cap_base; + uint32_t reg_value; + uint32_t test_skip; + uint32_t tbl_index; + uint64_t bar_base; + + fail_cnt = 0; + test_skip = 1; + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + instance = val_exerciser_get_info(EXERCISER_NUM_CARDS, 0); + pcie_device_bdf_table *bdf_tbl_ptr; + + tbl_index = 0; + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + + /* Check If PCIe Hierarchy supports P2P. */ + if (val_pcie_p2p_support()) + { + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + return; + } + + while (tbl_index < bdf_tbl_ptr->num_entries) + { + bdf = bdf_tbl_ptr->device[tbl_index++].bdf; + if (val_pcie_find_capability(bdf, PCIE_ECAP, ECID_ACS, &cap_base) == PCIE_SUCCESS) { + /* Enable P2P Request Redirect & Upstream Forwarding */ + val_pcie_read_cfg(bdf, cap_base + ACSCR_OFFSET, ®_value); + + reg_value = reg_value | (1 << ACS_CTRL_RRE_SHIFT) | (1 << ACS_CTRL_UFE_SHIFT); + val_pcie_write_cfg(bdf, cap_base + ACSCR_OFFSET, reg_value); + } + } + + while (instance-- != 0) + { + + /* if init fail moves to next exerciser */ + if (val_exerciser_init(instance)) + continue; + + req_e_bdf = val_exerciser_get_bdf(instance); + + /* Get RP of the exerciser */ + if (val_pcie_get_rootport(req_e_bdf, &req_rp_bdf)) + continue; + + /* It ACS Not Supported, Fail.*/ + if (val_pcie_find_capability(req_rp_bdf, PCIE_ECAP, ECID_ACS, &cap_base) != PCIE_SUCCESS) { + val_print(ACS_PRINT_ERR, "\n ACS Not Supported for BDF : 0x%x", req_rp_bdf); + fail_cnt++; + continue; + } + + /* Find another exerciser on other rootport, + Break from the test if no such exerciser if found */ + if (get_target_exer_bdf(req_rp_bdf, &tgt_e_bdf, &tgt_rp_bdf, &bar_base)) + break; + + /* If Both RP's Supports ACS Then Only Run Otherwise Skip the EP */ + test_skip = 0; + + /* Check For Redirected Request Validation Functionality */ + status = check_redirected_req_validation(instance, req_e_bdf, req_rp_bdf, + tgt_e_bdf, bar_base); + if (status == ACS_STATUS_SKIP) + val_print(ACS_PRINT_ERR, "\n ACS Validation Check Skipped for 0x%x", req_rp_bdf); + else if (status) { + fail_cnt++; + val_print(ACS_PRINT_ERR, "\n ACS Redirected Req Check Failed for 0x%x", req_rp_bdf); + } + + } + + if (test_skip == 1) + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + else if (fail_cnt) + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, fail_cnt)); + else + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); + + return; + +} + +uint32_t +os_e002_entry(void) +{ + uint32_t num_pe = 1; + uint32_t status = ACS_STATUS_FAIL; + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* Get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/exerciser/operating_system/test_os_e003.c b/test_pool/exerciser/operating_system/test_os_e003.c new file mode 100644 index 00000000..eb061cb1 --- /dev/null +++ b/test_pool/exerciser/operating_system/test_os_e003.c @@ -0,0 +1,351 @@ +/** @file + * Copyright (c) 2020-2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_pcie_enumeration.h" +#include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pe.h" +#include "val/include/bsa_acs_smmu.h" +#include "val/include/bsa_acs_memory.h" +#include "val/include/bsa_acs_exerciser.h" + +#define TEST_NUM (ACS_EXERCISER_TEST_NUM_BASE + 3) +#define TEST_RULE "PCI_IC_05, RE_ORD_1, RE_ORD_2" +#define TEST_DESC "Arrival order Check " + +/* This test checks for the Arrival Order & Gathering Check */ +/* 0 means read transction, 1 means write transaction */ +static uint32_t transaction_order[] = {1, 1, 0, 1, 0, 0, 0, 0}; +static uint32_t pattern[16] = {0}; +static uint32_t run_flag; +static uint32_t fail_cnt; + +static uint32_t read_config_space(uint32_t *addr) +{ + uint32_t idx; + + for (idx = 0; idx < 16; idx++) { + addr = addr + idx; + pattern[idx] = val_mmio_read((addr_t)addr); + } + + return 0; +} + +/* num of transactions captured and thier attributes is checked */ +static uint32_t test_sequence_check(uint32_t instance) +{ + uint64_t idx; + uint64_t num_transactions; + uint64_t transaction_type; + + /* Get number of transactions captured from exerciser */ + val_exerciser_get_param(NUM_TRANSACTIONS, NULL, &num_transactions, instance); + if (num_transactions != sizeof(transaction_order)/sizeof(transaction_order[0])) { + val_print(ACS_PRINT_ERR, "\n Exerciser %d gathering check failed", instance); + return 1; + } + + /* Check transactions arrival order */ + for (idx = 0; idx < sizeof(transaction_order)/sizeof(transaction_order[0]); idx++) { + val_exerciser_get_param(TRANSACTION_TYPE, &idx, &transaction_type, instance); + if (transaction_type != transaction_order[idx]) { + val_print(ACS_PRINT_ERR, "\n Exerciser %d arrival order check failed", instance); + return 1; + } + } + return 0; +} + +/* Performs reads/write on 1B data */ +static uint32_t test_sequence_1B(uint8_t *addr, uint8_t increment_addr, uint32_t instance) +{ + uint64_t idx; + uint8_t write_val; + uint32_t pidx; + uint8_t *pattern_ptr; + + /* Start monitoring exerciser transactions */ + if (val_exerciser_ops(START_TXN_MONITOR, CFG_READ, instance)) + return ACS_STATUS_SKIP; + + run_flag = 1; + + /* Send the transaction on incrementalt addresses */ + for (idx = 0; idx < sizeof(transaction_order)/sizeof(transaction_order[0]); idx++) { + pidx = ((uint64_t)addr & 0xFF); + pattern_ptr = (uint8_t *)&pattern; + write_val = pattern_ptr[pidx]; + /* Write transaction */ + if (transaction_order[idx]) + val_mmio_write8((addr_t)addr, write_val); + else + val_mmio_read8((addr_t)addr); + if (increment_addr) + addr++; + } + + /* Stop monitoring exerciser transactions */ + val_exerciser_ops(STOP_TXN_MONITOR, CFG_READ, instance); + + return test_sequence_check(instance); +} + +/* Performs reads/write on 2B data */ +static uint32_t test_sequence_2B(uint16_t *addr, uint8_t increment_addr, uint32_t instance) +{ + uint64_t idx; + uint16_t write_val; + uint32_t pidx; + uint16_t *pattern_ptr; + + /* Start monitoring exerciser transactions */ + if (val_exerciser_ops(START_TXN_MONITOR, CFG_READ, instance)) + return ACS_STATUS_SKIP; + + run_flag = 1; + + /* Send the transaction on incrementalt addresses */ + for (idx = 0; idx < sizeof(transaction_order)/sizeof(transaction_order[0]); idx++) { + pidx = ((uint64_t)addr & 0xFF)/2; + pattern_ptr = (uint16_t *)&pattern; + write_val = pattern_ptr[pidx]; + /* Write transaction */ + if (transaction_order[idx]) + val_mmio_write16((addr_t)addr, write_val); + else + val_mmio_read16((addr_t)addr); + if (increment_addr) + addr++; + } + + /* Stop monitoring exerciser transactions */ + val_exerciser_ops(STOP_TXN_MONITOR, CFG_READ, instance); + + return test_sequence_check(instance); +} + +/* Performs reads/write on 4B data */ +static uint32_t test_sequence_4B(uint32_t *addr, uint8_t increment_addr, uint32_t instance) +{ + uint64_t idx; + uint32_t write_val, pidx; + uint32_t *pattern_ptr; + /* Start monitoring exerciser transactions */ + if (val_exerciser_ops(START_TXN_MONITOR, CFG_READ, instance)) + return ACS_STATUS_SKIP; + + run_flag = 1; + + /* Send the transaction on incrementalt addresses */ + for (idx = 0; idx < sizeof(transaction_order)/sizeof(transaction_order[0]); idx++) { + pidx = ((uint64_t)addr & 0xFF)/4; + pattern_ptr = (uint32_t *)&pattern; + write_val = pattern_ptr[pidx]; + /* Write transaction */ + if (transaction_order[idx]) + val_mmio_write((addr_t)addr, write_val); + else + val_mmio_read((addr_t)addr); + if (increment_addr) + addr++; + } + + /* Stop monitoring exerciser transactions */ + val_exerciser_ops(STOP_TXN_MONITOR, CFG_READ, instance); + + return test_sequence_check(instance); +} + +/* Performs reads/write on 8B data */ +static uint32_t test_sequence_8B(uint64_t *addr, uint8_t increment_addr, uint32_t instance) +{ + uint64_t idx; + uint64_t write_val; + uint32_t pidx; + uint64_t *pattern_ptr; + /* Start monitoring exerciser transactions */ + if (val_exerciser_ops(START_TXN_MONITOR, CFG_READ, instance)) + return ACS_STATUS_SKIP; + + run_flag = 1; + + /* Send the transaction on incrementalt addresses */ + for (idx = 0; idx < sizeof(transaction_order)/sizeof(transaction_order[0]); idx++) { + pidx = ((uint64_t)addr & 0xFF)/8; + pattern_ptr = (uint64_t *)&pattern; + write_val = pattern_ptr[pidx]; + /* Write transaction */ + if (transaction_order[idx]) + val_mmio_write64((addr_t)addr, write_val); + else + val_mmio_read64((addr_t)addr); + if (increment_addr) + addr++; + } + + /* Stop monitoring exerciser transactions */ + val_exerciser_ops(STOP_TXN_MONITOR, CFG_READ, instance); + + return test_sequence_check(instance); +} + +/* Read and Write on config space mapped to Device memory */ + +static +void +cfgspace_transactions_order_check(void) +{ + uint32_t instance; + uint32_t bdf; + char *baseptr; + uint32_t cid_offset; + uint64_t bdf_addr; + + /* Read the number of excerciser cards */ + instance = val_exerciser_get_info(EXERCISER_NUM_CARDS, 0); + + while (instance-- != 0) { + + /* if init fail moves to next exerciser */ + if (val_exerciser_init(instance)) + continue; + + /* Get exerciser bdf */ + bdf = val_exerciser_get_bdf(instance); + + /* If exerciser doesn't have PCI_ECAP skip the bdf */ + if (val_pcie_find_capability(bdf, PCIE_ECAP, CID_PCIECS, &cid_offset) == PCIE_CAP_NOT_FOUND) + continue; + + bdf_addr = val_pcie_get_bdf_config_addr(bdf); + + /* Map config space to ARM device memory in MMU page tables */ + baseptr = (char *)val_memory_ioremap((void *)bdf_addr, 512, DEVICE_nGnRnE); + + if (!baseptr) { + val_print(ACS_PRINT_ERR, "\n Failed in config ioremap for instance %x", instance); + continue; + } + + read_config_space((uint32_t *)baseptr); + + /* Test Scenario 1 : Transactions on incremental aligned address */ + fail_cnt += test_sequence_1B((uint8_t *)baseptr, 1, instance); + fail_cnt += test_sequence_2B((uint16_t *)baseptr, 1, instance); + fail_cnt += test_sequence_4B((uint32_t *)baseptr, 1, instance); + + /* Test Scenario 2 : Transactions on same address */ + fail_cnt += test_sequence_1B((uint8_t *)baseptr, 0, instance); + fail_cnt += test_sequence_2B((uint16_t *)baseptr, 0, instance); + fail_cnt += test_sequence_4B((uint32_t *)baseptr, 0, instance); + + } +} + +/* Read and Write on BAR space mapped to Device memory */ + +static +void +barspace_transactions_order_check(void) +{ + uint32_t instance; + exerciser_data_t e_data; + char *baseptr; + + /* Read the number of excerciser cards */ + instance = val_exerciser_get_info(EXERCISER_NUM_CARDS, 0); + + while (instance-- != 0) { + + /* if init fail moves to next exerciser */ + if (val_exerciser_init(instance)) + continue; + + /* Get BAR 0 details for this instance */ + if (val_exerciser_get_data(EXERCISER_DATA_BAR0_SPACE, &e_data, instance)) { + val_print(ACS_PRINT_ERR, "\n Exerciser %d data read error ", instance); + continue; + } + + /* If BAR region is not Prefetchable, skip the exerciser */ + if (e_data.bar_space.type != MMIO_PREFETCHABLE) + continue; + + /* Map mmio space to ARM device memory in MMU page tables */ + baseptr = (char *)val_memory_ioremap((void *)e_data.bar_space.base_addr, 512, DEVICE_nGnRnE); + + if (!baseptr) { + val_print(ACS_PRINT_ERR, "\n Failed in BAR ioremap for instance %x", instance); + continue;; + } + + /* Test Scenario 1 : Transactions on incremental aligned address */ + fail_cnt += test_sequence_1B((uint8_t *)baseptr, 1, instance); + fail_cnt += test_sequence_2B((uint16_t *)baseptr, 1, instance); + fail_cnt += test_sequence_4B((uint32_t *)baseptr, 1, instance); + fail_cnt += test_sequence_8B((uint64_t *)baseptr, 1, instance); + + /* Test Scenario 2 : Transactions on same address */ + fail_cnt += test_sequence_1B((uint8_t *)baseptr, 0, instance); + fail_cnt += test_sequence_2B((uint16_t *)baseptr, 0, instance); + fail_cnt += test_sequence_4B((uint32_t *)baseptr, 0, instance); + fail_cnt += test_sequence_8B((uint64_t *)baseptr, 0, instance); + } +} + +static +void +payload(void) +{ + uint32_t pe_index; + + pe_index = val_pe_get_index_mpid (val_pe_get_mpid()); + + cfgspace_transactions_order_check(); + barspace_transactions_order_check(); + + if (!run_flag) { + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + return; + } + + if (fail_cnt) + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, fail_cnt)); + else + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); +} + +uint32_t +os_e003_entry(void) +{ + uint32_t num_pe = 1; + uint32_t status = ACS_STATUS_FAIL; + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* Get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/exerciser/operating_system/test_os_e004.c b/test_pool/exerciser/operating_system/test_os_e004.c index 2141c339..48cce235 100644 --- a/test_pool/exerciser/operating_system/test_os_e004.c +++ b/test_pool/exerciser/operating_system/test_os_e004.c @@ -25,10 +25,12 @@ #include "val/include/bsa_acs_exerciser.h" #define TEST_NUM (ACS_EXERCISER_TEST_NUM_BASE + 4) -#define TEST_DESC "PCI_MSI_2: MSI(-X) triggers interrupt with unique ID " +#define TEST_RULE "PCI_MSI_2" +#define TEST_DESC "MSI(-X) triggers intr with unique ID " static uint32_t irq_pending; static uint32_t lpi_int_id = 0x204C; +static uint32_t instance; static void @@ -37,8 +39,8 @@ intr_handler(void) /* Clear the interrupt pending state */ irq_pending = 0; - val_print(ACS_PRINT_INFO, "\n Received MSI interrupt %x ", lpi_int_id); - val_gic_end_of_interrupt(lpi_int_id); + val_print(ACS_PRINT_INFO, "\n Received MSI interrupt %x ", lpi_int_id + instance); + val_gic_end_of_interrupt(lpi_int_id + instance); return; } @@ -51,13 +53,25 @@ payload (void) uint32_t e_bdf = 0; uint32_t timeout; uint32_t status; - uint32_t instance; uint32_t num_cards; uint32_t num_smmus; + uint32_t test_skip = 1; uint32_t msi_index = 0; + uint32_t msi_cap_offset = 0; + + uint32_t req_id = 0; + uint32_t device_id = 0; + uint32_t stream_id = 0; + uint32_t its_id = 0; index = val_pe_get_index_mpid (val_pe_get_mpid()); + if (val_gic_get_info(GIC_INFO_NUM_ITS) == 0) { + val_print(ACS_PRINT_DEBUG, "\n No ITS, Skipping Test.\n", 0); + val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); + return; + } + /* Read the number of excerciser cards */ num_cards = val_exerciser_get_info(EXERCISER_NUM_CARDS, 0); @@ -76,24 +90,45 @@ payload (void) /* Get the exerciser BDF */ e_bdf = val_exerciser_get_bdf(instance); - status = val_gic_request_msi(e_bdf, lpi_int_id, msi_index); + /* Search for MSI-X Capability */ + if (val_pcie_find_capability(e_bdf, PCIE_CAP, CID_MSIX, &msi_cap_offset)) { + val_print(ACS_PRINT_INFO, "\n No MSI-X Capability, Skipping for 0x%x", e_bdf); + continue; + } + + test_skip = 0; + /* Get DeviceID & ITS_ID for this device */ + req_id = GET_DEVICE_ID(PCIE_EXTRACT_BDF_BUS(e_bdf), + PCIE_EXTRACT_BDF_DEV(e_bdf), + PCIE_EXTRACT_BDF_FUNC(e_bdf)); + + status = val_iovirt_get_device_info(req_id, PCIE_EXTRACT_BDF_SEG(e_bdf), &device_id, + &stream_id, &its_id); if (status) { val_print(ACS_PRINT_ERR, - "\n MSI Assignment failed for bdf : 0x%x", e_bdf); + "\n Could not get device info for BDF : 0x%x", e_bdf); val_set_status(index, RESULT_FAIL(TEST_NUM, 01)); return; } - status = val_gic_install_isr(lpi_int_id, intr_handler); - + status = val_gic_request_msi(e_bdf, device_id, its_id, lpi_int_id + instance, msi_index); if (status) { val_print(ACS_PRINT_ERR, - "\n Intr handler registration failed for Interrupt : 0x%x", lpi_int_id); + "\n MSI Assignment failed for bdf : 0x%x", e_bdf); val_set_status(index, RESULT_FAIL(TEST_NUM, 02)); return; } + status = val_gic_install_isr(lpi_int_id + instance, intr_handler); + + if (status) { + val_print(ACS_PRINT_ERR, + "\n Intr handler registration failed Interrupt : 0x%x", lpi_int_id + instance); + val_set_status(index, RESULT_FAIL(TEST_NUM, 03)); + return; + } + /* Set the interrupt trigger status to pending */ irq_pending = 1; @@ -107,17 +142,22 @@ payload (void) if (timeout == 0) { val_print(ACS_PRINT_ERR, - "\n Interrupt trigger failed for : 0x%x, ", lpi_int_id); + "\n Interrupt trigger failed for : 0x%x, ", lpi_int_id + instance); val_print(ACS_PRINT_ERR, "BDF : 0x%x ", e_bdf); - val_set_status(index, RESULT_FAIL(TEST_NUM, 03)); - val_gic_free_msi(e_bdf, lpi_int_id, msi_index); + val_set_status(index, RESULT_FAIL(TEST_NUM, 04)); + val_gic_free_msi(e_bdf, device_id, its_id, lpi_int_id + instance, msi_index); return; } /* Clear Interrupt and Mappings */ - val_gic_free_msi(e_bdf, lpi_int_id, msi_index); + val_gic_free_msi(e_bdf, device_id, its_id, lpi_int_id + instance, msi_index); + + } + if (test_skip) { + val_set_status(index, RESULT_SKIP(TEST_NUM, 02)); + return; } /* Pass Test */ @@ -138,9 +178,9 @@ os_e004_entry(void) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/exerciser/operating_system/test_os_e005.c b/test_pool/exerciser/operating_system/test_os_e005.c index b4cee2a9..78a93c9a 100644 --- a/test_pool/exerciser/operating_system/test_os_e005.c +++ b/test_pool/exerciser/operating_system/test_os_e005.c @@ -27,7 +27,8 @@ #include "val/include/bsa_acs_exerciser.h" #define TEST_NUM (ACS_EXERCISER_TEST_NUM_BASE + 5) -#define TEST_DESC "RE_SMU_4,IE_SMU_3: Generate PASID PCIe transactions " +#define TEST_RULE "PCI_PAS_1, RE_SMU_4" +#define TEST_DESC "Generate PASID transactions " #define TEST_DATA_NUM_PAGES 2 #define TEST_DATA 0xDE @@ -400,9 +401,9 @@ os_e005_entry(void) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* Get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/exerciser/operating_system/test_os_e006.c b/test_pool/exerciser/operating_system/test_os_e006.c index 42789f4d..9eb589eb 100644 --- a/test_pool/exerciser/operating_system/test_os_e006.c +++ b/test_pool/exerciser/operating_system/test_os_e006.c @@ -23,7 +23,8 @@ #include "val/include/bsa_acs_exerciser.h" #define TEST_NUM (ACS_EXERCISER_TEST_NUM_BASE + 6) -#define TEST_DESC "PCI_LI_02: Generate PCIe legacy interrupt " +#define TEST_RULE "PCI_LI_02" +#define TEST_DESC "Generate PCIe legacy interrupt " #define LEGACY_INTR_PIN_COUNT 1 @@ -142,9 +143,9 @@ os_e006_entry (void) } /* Get the result from all PE and check for failure */ - status = val_check_for_error (TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status (0, BSA_ACS_END (TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/exerciser/operating_system/test_os_e007.c b/test_pool/exerciser/operating_system/test_os_e007.c new file mode 100644 index 00000000..7382d314 --- /dev/null +++ b/test_pool/exerciser/operating_system/test_os_e007.c @@ -0,0 +1,248 @@ +/** @file + * Copyright (c) 2018-2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +/* First test sequence - Initialize a main memory region marked as WB, + * outer shareable by the PE page tables. CPU Write to this region with + * new data and ensure that the new data is cached in the CPU caches. + * Read the same data locations from the Exerciser with NS=0. The + * exerciser should get the latest data (hardware enforced cache coherency + * expected). + * + * Second test sequence - Initialize a main memory region marked as WB, + * outer shareable by the PE page tables. CPU reads these locations and + * ensures that the data is cached in its caches. Exerciser Writes to + * this region with new data and with NS=0. CPU reads the same data + * locations. The CPU should get the latest data (hardware enforced + * cache coherency expected). + * + * The above cases verify exerciser dma data check (both read and write) + * The test assume PCIe RC addr space is within PE outer shareable domain. + */ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" +#include "val/include/bsa_acs_memory.h" +#include "val/include/bsa_acs_exerciser.h" + +#include "val/include/bsa_acs_smmu.h" +#include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pcie_enumeration.h" + +#define TEST_NUM (ACS_EXERCISER_TEST_NUM_BASE + 7) +#define TEST_RULE "PCI_IC_01, PCI_IC_03, PCI_IC_06-08" +#define TEST_DESC "Check PCIe I/O Coherency " + +#define TEST_DATA_BLK_SIZE (4*1024) +#define KNOWN_DATA 0xDE +#define NEW_DATA 0xAD + + +uint32_t +test_sequence2(void *dram_buf1_virt, void *dram_buf1_phys, uint32_t e_bdf, uint32_t instance) +{ + + uint32_t dma_len; + void *dram_buf2_virt; + void *dram_buf2_phys; + + /* Set up a second dram buffer to send NEW_DATA to exerciser memory */ + dram_buf2_virt = dram_buf1_virt + (TEST_DATA_BLK_SIZE / 2); + dram_buf2_phys = dram_buf1_phys + (TEST_DATA_BLK_SIZE / 2); + dma_len = TEST_DATA_BLK_SIZE / 2; + + /* Write dram_buf1 with known data, this causes caching of the buffer */ + val_memory_set(dram_buf1_virt, dma_len, KNOWN_DATA); + + /* Write dram_buf2 with known data and flush the buffer to main memory */ + val_memory_set(dram_buf2_virt, dma_len, NEW_DATA); + val_data_cache_ops_by_va((addr_t)dram_buf2_virt, CLEAN_AND_INVALIDATE); + + /* Perform DMA OUT to copy contents of dram_buf2 to exerciser memory */ + val_exerciser_set_param(DMA_ATTRIBUTES, (uint64_t)dram_buf2_phys, dma_len, instance); + if (val_exerciser_ops(START_DMA, EDMA_TO_DEVICE, instance)) { + val_print(ACS_PRINT_ERR, "\n DMA write failure to exerciser %4x", instance); + return 1; + } + + /* Perform DMA IN to copy content back from exerciser memory to dram_buf1 */ + val_exerciser_set_param(DMA_ATTRIBUTES, (uint64_t)dram_buf1_phys, dma_len, instance); + if (val_exerciser_ops(START_DMA, EDMA_FROM_DEVICE, instance)) { + val_print(ACS_PRINT_ERR, "\n DMA read failure from exerciser %4x", instance); + return 1; + } + + /* Invalidate dram_buf1 and dram_buf2 contents present in CPU caches */ + val_data_cache_ops_by_va((addr_t)dram_buf1_virt, INVALIDATE); + val_data_cache_ops_by_va((addr_t)dram_buf2_virt, INVALIDATE); + + /* Compare the contents of ddr_buf1 and ddr_buf2 for NEW_DATA */ + if (val_memory_compare(dram_buf1_virt, dram_buf2_virt, dma_len)) { + val_print(ACS_PRINT_ERR, "\n I/O coherency failure for Exerciser %4x", instance); + return 1; + } + + /* Return success */ + return 0; +} + +uint32_t +test_sequence1(void *dram_buf1_virt, void *dram_buf1_phys, uint32_t e_bdf, uint32_t instance) +{ + + uint32_t dma_len; + void *dram_buf2_virt; + + dram_buf2_virt = dram_buf1_virt + (TEST_DATA_BLK_SIZE / 2); + dma_len = TEST_DATA_BLK_SIZE / 2; + + /* Write dram_buf1 with known data and flush the buffer to main memory */ + val_memory_set(dram_buf1_virt, dma_len, KNOWN_DATA); + val_data_cache_ops_by_va((addr_t)dram_buf1_virt, CLEAN_AND_INVALIDATE); + + /* Write dram_buf1 cache with new data, don't flush the data to main memory */ + val_memory_set(dram_buf1_virt, dma_len, NEW_DATA); + + /* Perform DMA OUT to copy contents of dram_buf1 to exerciser memory */ + val_exerciser_set_param(DMA_ATTRIBUTES, (uint64_t)dram_buf1_phys, dma_len, instance); + if (val_exerciser_ops(START_DMA, EDMA_TO_DEVICE, instance)) { + val_print(ACS_PRINT_ERR, "\n DMA write failure to exerciser %4x", instance); + return 1; + } + + /* Perform DMA IN to copy the content from exerciser memory to dram_buf1 */ + val_exerciser_set_param(DMA_ATTRIBUTES, (uint64_t)dram_buf1_phys, dma_len, instance); + if (val_exerciser_ops(START_DMA, EDMA_FROM_DEVICE, instance)) { + val_print(ACS_PRINT_ERR, "\n DMA read failure from exerciser %4x", instance); + return 1; + } + + /* Write dram_buf2 with NEW_DATA to compare dram_buf1 content */ + val_memory_set(dram_buf2_virt, dma_len, NEW_DATA); + + /* Invalidate dram_buf1 contents present in CPU caches */ + val_data_cache_ops_by_va((addr_t)dram_buf1_virt, INVALIDATE); + + /* Compare the contents of ddr_buf1 and ddr_buf2 for NEW_DATA */ + if (val_memory_compare(dram_buf1_virt, dram_buf2_virt, dma_len)) { + val_print(ACS_PRINT_ERR, "\n I/O coherency failure for Exerciser %4x", instance); + return 1; + } + + /* Return success */ + return 0; +} + + +static +void +payload (void) +{ + + uint32_t pe_index; + uint32_t instance; + uint32_t e_bdf; + uint32_t smmu_index; + void *dram_buf1_virt; + void *dram_buf1_phys; + + dram_buf1_virt = NULL; + dram_buf1_phys = NULL; + + pe_index = val_pe_get_index_mpid (val_pe_get_mpid()); + + /* Read the number of excerciser cards */ + instance = val_exerciser_get_info(EXERCISER_NUM_CARDS, 0); + + while (instance-- != 0) { + + /* if init fail moves to next exerciser */ + if (val_exerciser_init(instance)) + continue; + + /* Get the exerciser BDF */ + e_bdf = val_exerciser_get_bdf(instance); + + /* Find SMMU node index for this exerciser instance */ + smmu_index = val_iovirt_get_rc_smmu_index(PCIE_EXTRACT_BDF_SEG(e_bdf)); + + /* Disable SMMU globally so that the transaction passes + * through the SMMU without any address modification. + * Global attributes, such as memory type or Shareability, + * might be applied from the SMMU_GBPA register of the SMMU. + * Or, the SMMU_GBPA register might be configured to abort + * all transactions. Do this only if the RC is behind an SMMU. + */ + if (smmu_index != ACS_INVALID_INDEX) { + if (val_smmu_disable(smmu_index)) { + val_print(ACS_PRINT_ERR, "\n Exerciser %x smmu disable error", instance); + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 02)); + return; + } + } + + /* Get a WB, outer shareable DDR Buffer of size TEST_DATA_BLK_SIZE */ + dram_buf1_virt = val_memory_alloc_cacheable(e_bdf, TEST_DATA_BLK_SIZE, &dram_buf1_phys); + if (!dram_buf1_virt) { + val_print(ACS_PRINT_ERR, "\n WB and OSH mem alloc failure %x", 02); + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 02)); + return; + } + + /* Program exerciser hierarchy to start sending/receiving TLPs + * with No Snoop attribute header. This includes disabling + * No snoop bit in exerciser control register. + */ + if (val_exerciser_ops(TXN_NO_SNOOP_DISABLE, 0, instance)) { + val_print(ACS_PRINT_ERR, "\n Exerciser %x No Snoop disable error", instance); + goto test_fail; + } + + if (test_sequence1(dram_buf1_virt, dram_buf1_phys, e_bdf, instance) || + test_sequence2(dram_buf1_virt, dram_buf1_phys, e_bdf, instance)) + goto test_fail; + + /* Return this exerciser dma memory back to the heap manager */ + val_memory_free_cacheable(e_bdf, TEST_DATA_BLK_SIZE, dram_buf1_virt, dram_buf1_phys); + + } + + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 0)); + return; + +test_fail: + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 02)); + val_memory_free_cacheable(e_bdf, TEST_DATA_BLK_SIZE, dram_buf1_virt, dram_buf1_phys); + return; +} + +uint32_t +os_e007_entry (void) +{ + uint32_t num_pe = 1; + uint32_t status = ACS_STATUS_FAIL; + + status = val_initialize_test (TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) { + val_run_test_payload (TEST_NUM, num_pe, payload, 0); + } + + /* Get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/exerciser/operating_system/test_os_e008.c b/test_pool/exerciser/operating_system/test_os_e008.c new file mode 100644 index 00000000..27e0f3a0 --- /dev/null +++ b/test_pool/exerciser/operating_system/test_os_e008.c @@ -0,0 +1,238 @@ +/** @file + * Copyright (c) 2018-2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +/* Test sequence - Initialize a main memory region marked as WB, + * outer shareable by the PE page tables. CPU Write to this region with + * new data. Perform actions to maintain software coherency. + * Read the same data locations from the Exerciser with NS=1. The + * exerciser should get the latest data. The exerciser updates the + * location with newest data. PE reads the location and must get NEWEST VAL. + */ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" +#include "val/include/bsa_acs_memory.h" +#include "val/include/bsa_acs_exerciser.h" + +#include "val/include/bsa_acs_smmu.h" +#include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pcie_enumeration.h" + +#define TEST_NUM (ACS_EXERCISER_TEST_NUM_BASE + 8) +#define TEST_RULE "PCI_IC_04" +#define TEST_DESC "Check PCIe Software Coherency " + +#define TEST_DATA_BLK_SIZE (4*1024) +#define NEW_DATA 0xAD +#define NEWEST_DATA 0xBC + +static +uint32_t +test_sequence2(void *dram_buf1_virt, void *dram_buf1_phys, uint32_t e_bdf, uint32_t instance) +{ + + uint32_t dma_len; + void *dram_buf2_virt; + void *dram_buf2_phys; + + /* Set up a second dram buffer to send NEWEST_DATA to exerciser memory */ + dram_buf2_virt = dram_buf1_virt + (TEST_DATA_BLK_SIZE / 2); + dram_buf2_phys = dram_buf1_phys + (TEST_DATA_BLK_SIZE / 2); + dma_len = TEST_DATA_BLK_SIZE / 2; + + /* Write dram_buf2 with known data and flush the buffer to main memory */ + val_memory_set(dram_buf2_virt, dma_len, NEWEST_DATA); + val_data_cache_ops_by_va((addr_t)dram_buf2_virt, CLEAN_AND_INVALIDATE); + + /* Perform DMA OUT to copy contents of dram_buf2 to exerciser memory */ + val_exerciser_set_param(DMA_ATTRIBUTES, (uint64_t)dram_buf2_phys, dma_len, instance); + if (val_exerciser_ops(START_DMA, EDMA_TO_DEVICE, instance)) { + val_print(ACS_PRINT_ERR, "\n DMA write failure to exerciser %4x", instance); + return 1; + } + + /* Perform DMA IN to copy content back from exerciser memory to dram_buf1 */ + val_exerciser_set_param(DMA_ATTRIBUTES, (uint64_t)dram_buf1_phys, dma_len, instance); + if (val_exerciser_ops(START_DMA, EDMA_FROM_DEVICE, instance)) { + val_print(ACS_PRINT_ERR, "\n DMA read failure from exerciser %4x", instance); + return 1; + } + + /* Invalidate dram_buf1 and dram_buf2 contents present in CPU caches */ + val_data_cache_ops_by_va((addr_t)dram_buf1_virt, INVALIDATE); + val_data_cache_ops_by_va((addr_t)dram_buf2_virt, INVALIDATE); + + /* Compare the contents of ddr_buf1 and ddr_buf2 for NEW_DATA */ + if (val_memory_compare(dram_buf1_virt, dram_buf2_virt, dma_len)) { + val_print(ACS_PRINT_ERR, "\n I/O coherency failure for Exerciser %4x", instance); + return 1; + } + + /* Return success */ + return 0; +} + +static +uint32_t +test_sequence1(void *dram_buf1_virt, void *dram_buf1_phys, uint32_t e_bdf, uint32_t instance) +{ + + uint32_t dma_len; + void *dram_buf2_virt; + void *dram_buf2_phys; + + dram_buf2_virt = dram_buf1_virt + (TEST_DATA_BLK_SIZE / 2); + dram_buf2_phys = dram_buf1_phys + (TEST_DATA_BLK_SIZE / 2); + dma_len = TEST_DATA_BLK_SIZE / 2; + + /* Write dram_buf1 cache with new data */ + val_memory_set(dram_buf1_virt, dma_len, NEW_DATA); + + /* Maintain software coherency */ + val_data_cache_ops_by_va((addr_t)dram_buf1_virt, CLEAN_AND_INVALIDATE); + + /* Perform DMA OUT to copy contents of dram_buf1 to exerciser memory */ + val_exerciser_set_param(DMA_ATTRIBUTES, (uint64_t)dram_buf1_phys, dma_len, instance); + if (val_exerciser_ops(START_DMA, EDMA_TO_DEVICE, instance)) { + val_print(ACS_PRINT_ERR, "\n DMA write failure to exerciser %4x", instance); + return 1; + } + + /* Perform DMA IN to copy the content from exerciser memory to dram_buf2 */ + val_exerciser_set_param(DMA_ATTRIBUTES, (uint64_t)dram_buf2_phys, dma_len, instance); + if (val_exerciser_ops(START_DMA, EDMA_FROM_DEVICE, instance)) { + val_print(ACS_PRINT_ERR, "\n DMA read failure from exerciser %4x", instance); + return 1; + } + + /* Invalidate dram_buf2 contents present in CPU caches */ + val_data_cache_ops_by_va((addr_t)dram_buf2_virt, INVALIDATE); + + /* Compare the contents of ddr_buf1 and ddr_buf2 for NEW_DATA */ + if (val_memory_compare(dram_buf1_virt, dram_buf2_virt, dma_len)) { + val_print(ACS_PRINT_ERR, "\n I/O coherency failure for Exerciser %4x", instance); + return 1; + } + + /* Return success */ + return 0; +} + + +static +void +payload (void) +{ + + uint32_t pe_index; + uint32_t instance; + uint32_t e_bdf; + uint32_t smmu_index; + void *dram_buf1_virt; + void *dram_buf1_phys; + + dram_buf1_virt = NULL; + dram_buf1_phys = NULL; + + pe_index = val_pe_get_index_mpid (val_pe_get_mpid()); + + /* Read the number of excerciser cards */ + instance = val_exerciser_get_info(EXERCISER_NUM_CARDS, 0); + + while (instance-- != 0) { + + /* if init fail moves to next exerciser */ + if (val_exerciser_init(instance)) + continue; + + /* Get the exerciser BDF */ + e_bdf = val_exerciser_get_bdf(instance); + + /* Find SMMU node index for this exerciser instance */ + smmu_index = val_iovirt_get_rc_smmu_index(PCIE_EXTRACT_BDF_SEG(e_bdf)); + + /* Disable SMMU globally so that the transaction passes + * through the SMMU without any address modification. + * Global attributes, such as memory type or Shareability, + * might be applied from the SMMU_GBPA register of the SMMU. + * Or, the SMMU_GBPA register might be configured to abort + * all transactions. Do this only if the RC is behind an SMMU. + */ + if (smmu_index != ACS_INVALID_INDEX) { + if (val_smmu_disable(smmu_index)) { + val_print(ACS_PRINT_ERR, "\n Exerciser %x smmu disable error", instance); + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 02)); + return; + } + } + + /* Get a WB, outer shareable DDR Buffer of size TEST_DATA_BLK_SIZE */ + dram_buf1_virt = val_memory_alloc_cacheable(e_bdf, TEST_DATA_BLK_SIZE, &dram_buf1_phys); + + if (!dram_buf1_virt) { + + val_print(ACS_PRINT_ERR, "\n WB and OSH mem alloc failure %x", 02); + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 02)); + return; + } + + /* Program exerciser hierarchy to start sending/receiving TLPs + * with No Snoop attribute header. This includes enabling + * No snoop bit in exerciser control register. + */ + if (val_exerciser_ops(TXN_NO_SNOOP_ENABLE, 0, instance)) { + val_print(ACS_PRINT_ERR, "\n Exerciser %x No Snoop enable error", instance); + goto test_fail; + } + + if (test_sequence1(dram_buf1_virt, dram_buf1_phys, e_bdf, instance) || + test_sequence2(dram_buf1_virt, dram_buf1_phys, e_bdf, instance)) + goto test_fail; + + /* Return this exerciser dma memory back to the heap manager */ + val_memory_free_cacheable(e_bdf, TEST_DATA_BLK_SIZE, dram_buf1_virt, dram_buf1_phys); + + } + + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 0)); + return; + +test_fail: + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 02)); + val_memory_free_cacheable(e_bdf, TEST_DATA_BLK_SIZE, dram_buf1_virt, dram_buf1_phys); + return; +} + +uint32_t +os_e008_entry (void) +{ + uint32_t num_pe = 1; + uint32_t status = ACS_STATUS_FAIL; + + status = val_initialize_test (TEST_NUM, TEST_DESC, num_pe); + + if (status != ACS_STATUS_SKIP) { + val_run_test_payload (TEST_NUM, num_pe, payload, 0); + } + + /* Get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/exerciser/operating_system/test_os_e009.c b/test_pool/exerciser/operating_system/test_os_e009.c new file mode 100644 index 00000000..323921b2 --- /dev/null +++ b/test_pool/exerciser/operating_system/test_os_e009.c @@ -0,0 +1,190 @@ +/** @file + * Copyright (c) 2019-2020, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" +#include "val/include/bsa_acs_memory.h" +#include "val/include/bsa_acs_exerciser.h" + +#include "val/include/bsa_acs_smmu.h" +#include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pcie_enumeration.h" + +#define TEST_NUM (ACS_EXERCISER_TEST_NUM_BASE + 9) +#define TEST_RULE "PCI_IN_10" +#define TEST_DESC "Check RP Sub Bus transaction are TYPE1" + +#define MAX_BUS 255 +#define BUS_SHIFT 8 +#define BUS_MASK 0xff + +uint8_t +get_rp_right_sibling(uint32_t rp_bdf, uint32_t *rs_bdf) +{ + + uint32_t dp_type; + uint32_t tbl_bdf; + uint32_t tbl_index; + uint32_t tbl_reg_value; + uint32_t rp_reg_value; + pcie_device_bdf_table *bdf_tbl_ptr; + + tbl_index = 0; + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + + while (tbl_index < bdf_tbl_ptr->num_entries) + { + tbl_bdf = bdf_tbl_ptr->device[tbl_index++].bdf; + dp_type = val_pcie_device_port_type(tbl_bdf); + + if (tbl_bdf != rp_bdf && dp_type == RP) + { + /* + * Check if the secondary bus of the root port + * corresponding to tbl_bdf is one gretaer than + * the suborinate bus number of the input root + * port. If equal, tbl_bdf must be right sibling + * of rp_bdf. + */ + val_pcie_read_cfg(rp_bdf, TYPE1_PBN, &rp_reg_value); + val_pcie_read_cfg(tbl_bdf, TYPE1_PBN, &tbl_reg_value); + if (((tbl_reg_value >> SECBN_SHIFT) & SECBN_MASK) == + (((rp_reg_value >> SUBBN_SHIFT) & SUBBN_MASK) + 1)) + { + *rs_bdf = tbl_bdf; + return 0; + } + } + } + + /* Return failure if No right sibling */ + *rs_bdf = 0; + return 1; +} + +static +void +payload(void) +{ + + uint32_t pe_index; + uint32_t rs_flag; + uint32_t e_bdf; + uint32_t e_bus; + uint32_t erp_bdf; + uint32_t erp_rs_bdf; + uint32_t reg_value; + uint32_t erp_sub_bus; + uint32_t erp_reg_value; + uint32_t erp_rs_reg_value; + uint32_t instance; + uint32_t fail_cnt; + uint64_t header_type; + + fail_cnt = 0; + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + instance = val_exerciser_get_info(EXERCISER_NUM_CARDS, 0); + + while (instance-- != 0) + { + rs_flag = 0; + + /* if init fail moves to next exerciser */ + if (val_exerciser_init(instance)) + continue; + + e_bdf = val_exerciser_get_bdf(instance); + + /* Check if exerciser is child of one of the rootports */ + if (val_pcie_parent_is_rootport(e_bdf, &erp_bdf)) + continue; + + /* Find right sibling of the exerciser rootport */ + if (!get_rp_right_sibling(erp_bdf, &erp_rs_bdf)) + { + /* + * Save exerciser right sibling sec and sub bus numbers. + * Program those bus numbers with invalid range so that + * the right sibling doesn't receive any transactions. + */ + rs_flag = 1; + val_pcie_read_cfg(erp_rs_bdf, TYPE1_PBN, &erp_rs_reg_value); + reg_value = erp_rs_reg_value & (~(SECBN_MASK << SECBN_SHIFT)); + reg_value = reg_value & (~(SUBBN_MASK << SUBBN_SHIFT)); + reg_value = reg_value | (MAX_BUS << SECBN_SHIFT); + reg_value = reg_value | ((MAX_BUS-1) << SUBBN_SHIFT); + val_pcie_write_cfg(erp_rs_bdf, TYPE1_PBN, reg_value); + } + + /* Increase Subordinate bus register of exerciser rootport by one */ + val_pcie_read_cfg(erp_bdf, TYPE1_PBN, &erp_reg_value); + erp_sub_bus = (erp_reg_value >> SUBBN_SHIFT) & SUBBN_MASK; + reg_value = reg_value & (~(SUBBN_MASK << SUBBN_SHIFT)); + reg_value = reg_value | ((erp_sub_bus + 1) << SUBBN_SHIFT); + + /* Increment bus number in e_bdf variable */ + e_bus = (e_bdf >> BUS_SHIFT) & BUS_MASK; + e_bdf = e_bdf & (~(BUS_MASK << BUS_SHIFT)); + e_bdf = e_bdf | ((e_bus + 1) << BUS_SHIFT); + + /* + * Generate a config request from PE to the Subordinate bus + * of the exerciser. Exerciser should see this request as a + * Type 1 Request. + */ + val_exerciser_ops(START_TXN_MONITOR, CFG_READ, instance); + val_pcie_read_cfg(e_bdf, TYPE01_VIDR, ®_value); + val_exerciser_ops(STOP_TXN_MONITOR, CFG_READ, instance); + val_exerciser_get_param(CFG_TXN_ATTRIBUTES, (uint64_t *)&header_type, 0, instance); + if (header_type != TYPE1) + { + val_print(ACS_PRINT_ERR, "\n BDF 0x%x Sub Bus Transaction failure", erp_bdf); + fail_cnt++; + } + + /* Restore Exerciser rootport and it's right sibling subordinate bus registers */ + val_pcie_write_cfg(erp_bdf, TYPE1_PBN, erp_reg_value); + if (rs_flag) + val_pcie_write_cfg(erp_rs_bdf, TYPE1_PBN, erp_rs_reg_value); + } + + if (fail_cnt) + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, fail_cnt)); + else + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); + + return; + +} + +uint32_t +os_e009_entry(void) +{ + uint32_t num_pe = 1; + uint32_t status = ACS_STATUS_FAIL; + + status = val_initialize_test (TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* Get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/exerciser/operating_system/test_os_e010.c b/test_pool/exerciser/operating_system/test_os_e010.c new file mode 100644 index 00000000..ba55eba7 --- /dev/null +++ b/test_pool/exerciser/operating_system/test_os_e010.c @@ -0,0 +1,102 @@ +/** @file + * Copyright (c) 2019-2020, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" +#include "val/include/bsa_acs_memory.h" +#include "val/include/bsa_acs_exerciser.h" + +#include "val/include/bsa_acs_smmu.h" +#include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pcie_enumeration.h" + +#define TEST_NUM (ACS_EXERCISER_TEST_NUM_BASE + 10) +#define TEST_RULE "PCI_IN_11" +#define TEST_DESC "Check RP Sec Bus transaction are TYPE0" + + +static +void +payload(void) +{ + + uint32_t pe_index; + uint32_t e_bdf; + uint32_t erp_bdf; + uint32_t reg_value; + uint32_t instance; + uint32_t fail_cnt; + uint64_t header_type; + + fail_cnt = 0; + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + instance = val_exerciser_get_info(EXERCISER_NUM_CARDS, 0); + + while (instance-- != 0) + { + + /* if init fail moves to next exerciser */ + if (val_exerciser_init(instance)) + continue; + + e_bdf = val_exerciser_get_bdf(instance); + + /* Check if exerciser is child of one of the rootports */ + if (val_pcie_parent_is_rootport(e_bdf, &erp_bdf)) + continue; + /* + * Generate a config request from PE to the Secondary bus + * of the exerciser's root port. Exerciser should see this + * request as a Type 0 Request. + */ + val_exerciser_ops(START_TXN_MONITOR, CFG_READ, instance); + val_pcie_read_cfg(e_bdf, TYPE01_VIDR, ®_value); + val_exerciser_ops(STOP_TXN_MONITOR, CFG_READ, instance); + val_exerciser_get_param(CFG_TXN_ATTRIBUTES, (uint64_t *)&header_type, 0, instance); + if (header_type != TYPE0) + { + val_print(ACS_PRINT_ERR, "\n BDF 0x%x Sec Bus Transaction failure", erp_bdf); + fail_cnt++; + } + } + + if (fail_cnt) + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, fail_cnt)); + else + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); + + return; + +} + +uint32_t +os_e010_entry(void) +{ + uint32_t num_pe = 1; + uint32_t status = ACS_STATUS_FAIL; + + status = val_initialize_test (TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload (TEST_NUM, num_pe, payload, 0); + + /* Get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/exerciser/operating_system/test_os_e011.c b/test_pool/exerciser/operating_system/test_os_e011.c new file mode 100644 index 00000000..c424c9d3 --- /dev/null +++ b/test_pool/exerciser/operating_system/test_os_e011.c @@ -0,0 +1,213 @@ +/** @file + * Copyright (c) 2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_memory.h" +#include "val/include/bsa_acs_iovirt.h" +#include "val/include/bsa_acs_smmu.h" +#include "val/include/bsa_acs_pcie_enumeration.h" +#include "val/include/bsa_acs_exerciser.h" + +#define TEST_NUM (ACS_EXERCISER_TEST_NUM_BASE + 11) +#define TEST_RULE "ITS_03, ITS_04" +#define TEST_DESC "MSI to Any ITS Blk in assigned group " + +static uint32_t irq_pending; +static uint32_t base_lpi_id = 0x204C; +static uint32_t instance; + +static +void +intr_handler(void) +{ + /* Clear the interrupt pending state */ + irq_pending = 0; + + val_print(ACS_PRINT_INFO, "\n Received MSI interrupt %x ", base_lpi_id + instance); + val_gic_end_of_interrupt(base_lpi_id + instance); + return; +} + +static +void +payload (void) +{ + + uint32_t index; + uint32_t e_bdf = 0, get_value = 0; + uint32_t timeout; + uint32_t status; + uint32_t num_instance, grp_id = 0, blk_index = 0; + uint32_t test_skip = 1; + uint32_t msi_index = 0; + uint32_t msi_cap_offset = 0; + + uint32_t req_id = 0; + uint32_t device_id = 0; + uint32_t stream_id = 0; + uint32_t its_id = 0; + + index = val_pe_get_index_mpid (val_pe_get_mpid()); + + if (val_gic_get_info(GIC_INFO_NUM_ITS) < 2) { + val_print(ACS_PRINT_DEBUG, "\n Skipping Test as multiple ITS not available", 0); + val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); + return; + } + + /* Disable all SMMUs */ + num_instance = val_iovirt_get_smmu_info(SMMU_NUM_CTRL, 0); + for (instance = 0; instance < num_instance; ++instance) + val_smmu_disable(instance); + + /* Read the number of excerciser cards */ + num_instance = val_exerciser_get_info(EXERCISER_NUM_CARDS, 0); + + for (instance = 0; instance < num_instance; instance++) + { + + /* if init fail moves to next exerciser */ + if (val_exerciser_init(instance)) + continue; + + /* Get the exerciser BDF */ + e_bdf = val_exerciser_get_bdf(instance); + + /* Search for MSI-X Capability */ + if (val_pcie_find_capability(e_bdf, PCIE_CAP, CID_MSIX, &msi_cap_offset)) { + val_print(ACS_PRINT_INFO, "\n No MSI-X Capability, Skipping for 0x%x", e_bdf); + continue; + } + + /* Get DeviceID & ITS_ID for this device */ + req_id = GET_DEVICE_ID(PCIE_EXTRACT_BDF_BUS(e_bdf), + PCIE_EXTRACT_BDF_DEV(e_bdf), + PCIE_EXTRACT_BDF_FUNC(e_bdf)); + + status = val_iovirt_get_device_info(req_id, PCIE_EXTRACT_BDF_SEG(e_bdf), &device_id, + &stream_id, &its_id); + if (status) { + val_print(ACS_PRINT_ERR, + "\n Could not get device info for BDF : 0x%x", e_bdf); + val_set_status(index, RESULT_FAIL(TEST_NUM, 01)); + return; + } + + /* Get ITS Group Index for current device */ + status = val_iovirt_get_its_info(ITS_GET_GRP_INDEX_FOR_ID, 0, its_id, &grp_id); + if (status) { + val_print(ACS_PRINT_DEBUG, "\n Invalid ITS ID, Skipping BDF 0x%x", e_bdf); + continue; + } + + /* Get Number of ITS Blocks in this Group */ + status = val_iovirt_get_its_info(ITS_GROUP_NUM_BLOCKS, grp_id, 0, &get_value); + if (status) { + val_print(ACS_PRINT_DEBUG, "\n Invalid ITS Group, Skipping BDF 0x%x", e_bdf); + continue; + } + + test_skip = 0; + + for (blk_index = 0; blk_index < get_value; blk_index++) { + + /* Run for all the ITS Blocks inside current group */ + status = val_iovirt_get_its_info(ITS_GET_ID_FOR_BLK_INDEX, grp_id, blk_index, &its_id); + if (status) { + val_print(ACS_PRINT_DEBUG, "\n Invalid ITS Index, Skipping BDF 0x%x", e_bdf); + continue; + } + + val_print(ACS_PRINT_DEBUG, "\n ITS Check for ITS ID : %x", its_id); + status = val_gic_request_msi(e_bdf, device_id, its_id, base_lpi_id + instance, msi_index); + if (status) { + val_print(ACS_PRINT_ERR, + "\n MSI Assignment failed for bdf : 0x%x", e_bdf); + val_set_status(index, RESULT_FAIL(TEST_NUM, 02)); + return; + } + + status = val_gic_install_isr(base_lpi_id + instance, intr_handler); + + if (status) { + val_print(ACS_PRINT_ERR, + "\n Intr handler registration fail, Interrupt : 0x%x", base_lpi_id + instance); + val_set_status(index, RESULT_FAIL(TEST_NUM, 03)); + return; + } + + /* Set the interrupt trigger status to pending */ + irq_pending = 1; + + /* Trigger the interrupt */ + val_exerciser_ops(GENERATE_MSI, msi_index, instance); + + /* PE busy polls to check the completion of interrupt service routine */ + timeout = TIMEOUT_LARGE; + while ((--timeout > 0) && irq_pending) + {}; + + /* Interrupt should not be generated */ + if (timeout == 0) { + val_print(ACS_PRINT_ERR, + "\n Interrupt trigger failed int_id : 0x%x", base_lpi_id + instance); + val_print(ACS_PRINT_ERR, + "\n BDF : 0x%x, ", e_bdf); + val_print(ACS_PRINT_ERR, + "its_id : 0x%x", its_id); + val_set_status(index, RESULT_FAIL(TEST_NUM, 04)); + val_gic_free_msi(e_bdf, device_id, its_id, base_lpi_id + instance, msi_index); + return; + } + + /* Clear Interrupt and Mappings */ + val_gic_free_msi(e_bdf, device_id, its_id, base_lpi_id + instance, msi_index); + } + + } + + if (test_skip) { + val_set_status(index, RESULT_SKIP(TEST_NUM, 02)); + return; + } + + /* Pass Test */ + val_set_status(index, RESULT_PASS(TEST_NUM, 01)); + +} + +uint32_t +os_e011_entry(void) +{ + + uint32_t status = ACS_STATUS_FAIL; + + uint32_t num_pe = 1; //This test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/exerciser/operating_system/test_os_e012.c b/test_pool/exerciser/operating_system/test_os_e012.c index 4319b7c3..5713cc9e 100644 --- a/test_pool/exerciser/operating_system/test_os_e012.c +++ b/test_pool/exerciser/operating_system/test_os_e012.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2020,2021 Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2021, Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,280 +14,191 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ - #include "val/include/bsa_acs_val.h" #include "val/include/val_interface.h" -#include "val/include/bsa_acs_pcie_enumeration.h" #include "val/include/bsa_acs_pcie.h" -#include "val/include/bsa_acs_pe.h" -#include "val/include/bsa_acs_smmu.h" #include "val/include/bsa_acs_memory.h" +#include "val/include/bsa_acs_iovirt.h" +#include "val/include/bsa_acs_smmu.h" +#include "val/include/bsa_acs_pcie_enumeration.h" #include "val/include/bsa_acs_exerciser.h" #define TEST_NUM (ACS_EXERCISER_TEST_NUM_BASE + 12) -#define TEST_DESC "PCI_PP_04: Check P2P ACS Functionality " +#define TEST_RULE "ITS_05" +#define TEST_DESC "MSI to ITS Blk outside assigned group " + +static uint32_t irq_pending; +static uint32_t base_lpi_id = 0x204C; +static uint32_t instance; static -uint32_t -get_target_exer_bdf(uint32_t req_rp_bdf, uint32_t *tgt_e_bdf, - uint32_t *tgt_rp_bdf, uint64_t *bar_base) +void +intr_handler(void) { + /* Clear the interrupt pending state */ + irq_pending = 0; - uint32_t erp_bdf; - uint32_t e_bdf; - uint32_t instance; - uint32_t cap_base; - - instance = val_exerciser_get_info(EXERCISER_NUM_CARDS, 0); - - while (instance-- != 0) - { - /* if init fail moves to next exerciser */ - if (val_exerciser_init(instance)) - continue; - - e_bdf = val_exerciser_get_bdf(instance); - - /* Read e_bdf BAR Register to get the Address to perform P2P */ - /* If No BAR Space, continue */ - val_pcie_get_mmio_bar(e_bdf, bar_base); - if (*bar_base == 0) - continue; - - /* Get RP of the exerciser */ - if (val_pcie_get_rootport(e_bdf, &erp_bdf)) - continue; - - /* It ACS Not Supported, continue */ - if (val_pcie_find_capability(erp_bdf, PCIE_ECAP, ECID_ACS, &cap_base) != PCIE_SUCCESS) { - val_print(ACS_PRINT_DEBUG, "\n ACS Not Supported for BDF : 0x%x", erp_bdf); - continue; - } - - if (req_rp_bdf != erp_bdf) - { - *tgt_e_bdf = e_bdf; - *tgt_rp_bdf = erp_bdf; - - /* Enable Bus Master Enable */ - val_pcie_enable_bme(e_bdf); - /* Enable Memory Space Access */ - val_pcie_enable_msa(e_bdf); - - return ACS_STATUS_PASS; - } - } - - /* Return failure if No Such Exerciser Found */ - *tgt_e_bdf = 0; - *tgt_rp_bdf = 0; - *bar_base = 0; - return ACS_STATUS_FAIL; + val_print(ACS_PRINT_INFO, "\n Received MSI interrupt %x ", base_lpi_id + instance); + val_gic_end_of_interrupt(base_lpi_id + instance); + return; } -uint32_t -check_source_validation (uint32_t req_instance, uint32_t req_e_bdf, - uint32_t req_rp_bdf, uint32_t tgt_e_bdf, - uint64_t bar_base) +static +void +payload (void) { - /* Check 1 : ACS Source Validation */ - - uint32_t reg_value; - uint32_t sub_bus; - uint32_t new_bdf; - - /* Pass Sequence */ - val_exerciser_set_param(DMA_ATTRIBUTES, (uint64_t)bar_base, 1, req_instance); - if (val_exerciser_ops(START_DMA, EDMA_FROM_DEVICE, req_instance)) { - val_print(ACS_PRINT_DEBUG, "\n DMA failure from exerciser %4x", req_instance); - return ACS_STATUS_FAIL; - } - - /* Clear Error Status Bits */ - val_pcie_clear_device_status_error(req_rp_bdf); - val_pcie_clear_sig_target_abort(req_rp_bdf); - - /* Change Requester ID for DMA such that it does not fall under req_rp_bdf - * Secondary & Subordinate bdf - */ - val_pcie_read_cfg(req_rp_bdf, TYPE1_PBN, ®_value); - sub_bus = (reg_value >> SUBBN_SHIFT) & SUBBN_MASK; - new_bdf = PCIE_CREATE_BDF(PCIE_EXTRACT_BDF_SEG(req_rp_bdf), - (sub_bus+1), 0, 0); - - val_exerciser_set_param(CFG_TXN_ATTRIBUTES, TXN_REQ_ID, new_bdf, req_instance); - val_exerciser_set_param(DMA_ATTRIBUTES, (uint64_t)bar_base, 1, req_instance); - - if (val_exerciser_ops(START_DMA, EDMA_FROM_DEVICE, req_instance)) { - val_print(ACS_PRINT_DEBUG, "\n DMA failure from exerciser %4x", req_instance); - return ACS_STATUS_FAIL; - } - - /* Check For Error in Device Status Register / Status Register - * Secondary Status Register - */ - if ((val_pcie_is_device_status_error(req_rp_bdf) == 0) && - (val_pcie_is_sig_target_abort(req_rp_bdf) == 0)) { - /* Fail the part */ - val_print(ACS_PRINT_DEBUG, - "\n Src Validation Expected Error RootPort : 0x%x", req_rp_bdf); - return ACS_STATUS_FAIL; + uint32_t index; + uint32_t e_bdf = 0, get_value = 0; + uint32_t timeout; + uint32_t status; + uint32_t num_cards; + uint32_t num_smmus, num_group; + uint32_t test_skip = 1; + uint32_t msi_index = 0; + uint32_t msi_cap_offset = 0; + + uint32_t req_id = 0; + uint32_t device_id = 0; + uint32_t stream_id = 0; + uint32_t its_id = 0; + + index = val_pe_get_index_mpid (val_pe_get_mpid()); + + status = val_iovirt_get_its_info(ITS_NUM_GROUPS, 0, 0, &num_group); + if (status || (num_group < 2)) { + val_print(ACS_PRINT_DEBUG, "\n Number of ITS Group < 2, Skipping Test", 0); + val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); + return; } - return ACS_STATUS_PASS; -} - -uint32_t -check_transaction_blocking (uint32_t req_instance, uint32_t req_e_bdf, - uint32_t req_rp_bdf, uint32_t tgt_e_bdf, - uint64_t bar_base) -{ - /* Check 2 : ACS Transaction Blocking */ + /* Read the number of excerciser cards */ + num_cards = val_exerciser_get_info(EXERCISER_NUM_CARDS, 0); - /* Clear Error Status Bits */ - val_pcie_clear_device_status_error(req_rp_bdf); - val_pcie_clear_sig_target_abort(req_rp_bdf); + /* Disable all SMMUs */ + num_smmus = val_iovirt_get_smmu_info(SMMU_NUM_CTRL, 0); + for (instance = 0; instance < num_smmus; ++instance) + val_smmu_disable(instance); - /* Transaction with Address Type other than default(0x0) - * Should result into Transaction blocking. - */ - val_exerciser_set_param(CFG_TXN_ATTRIBUTES, TXN_ADDR_TYPE, AT_RESERVED, req_instance); - val_exerciser_set_param(DMA_ATTRIBUTES, (uint64_t)bar_base, 1, req_instance); + for (instance = 0; instance < num_cards; instance++) + { - if (val_exerciser_ops(START_DMA, EDMA_FROM_DEVICE, req_instance)) { - val_print(ACS_PRINT_DEBUG, "\n DMA failure from exerciser %4x", req_instance); - return ACS_STATUS_FAIL; - } + /* if init fail moves to next exerciser */ + if (val_exerciser_init(instance)) + continue; + + /* Get the exerciser BDF */ + e_bdf = val_exerciser_get_bdf(instance); + + /* Search for MSI-X Capability */ + if (val_pcie_find_capability(e_bdf, PCIE_CAP, CID_MSIX, &msi_cap_offset)) { + val_print(ACS_PRINT_INFO, "\n No MSI-X Capability, Skipping for 0x%x", e_bdf); + continue; + } + + test_skip = 0; + + /* Get DeviceID & ITS_ID for this device */ + req_id = GET_DEVICE_ID(PCIE_EXTRACT_BDF_BUS(e_bdf), + PCIE_EXTRACT_BDF_DEV(e_bdf), + PCIE_EXTRACT_BDF_FUNC(e_bdf)); + + status = val_iovirt_get_device_info(req_id, PCIE_EXTRACT_BDF_SEG(e_bdf), &device_id, + &stream_id, &its_id); + if (status) { + val_print(ACS_PRINT_ERR, + "\n Could not get device info for BDF : 0x%x", e_bdf); + val_set_status(index, RESULT_FAIL(TEST_NUM, 01)); + return; + } + + /* Get ITS Group Index for current device */ + status = val_iovirt_get_its_info(ITS_GET_GRP_INDEX_FOR_ID, 0, its_id, &get_value); + if (status) { + val_print(ACS_PRINT_DEBUG, "\n Invalid ITS ID, Skipping BDF 0x%x", e_bdf); + continue; + } + + /* Get ITS_ID from an ITS Group != Current Group ID */ + status = val_iovirt_get_its_info(ITS_GET_ID_FOR_BLK_INDEX, + ((get_value+1)%num_group), 0, &get_value); + if (status) { + val_print(ACS_PRINT_DEBUG, "\n Could not get other Group," + " Skipping for BDF 0x%x", e_bdf); + continue; + } + + status = val_gic_request_msi(e_bdf, device_id, get_value, base_lpi_id + instance, msi_index); + if (status) { + val_print(ACS_PRINT_ERR, + "\n MSI Assignment failed for bdf : 0x%x", e_bdf); + val_set_status(index, RESULT_FAIL(TEST_NUM, 02)); + return; + } + + status = val_gic_install_isr(base_lpi_id + instance, intr_handler); + + if (status) { + val_print(ACS_PRINT_ERR, + "\n Intr handler registration failed Interrupt : 0x%x", base_lpi_id + instance); + val_set_status(index, RESULT_FAIL(TEST_NUM, 03)); + return; + } + + /* Set the interrupt trigger status to pending */ + irq_pending = 1; + + /* Trigger the interrupt */ + val_exerciser_ops(GENERATE_MSI, msi_index, instance); + + /* PE busy polls to check the completion of interrupt service routine */ + timeout = TIMEOUT_LARGE; + while ((--timeout > 0) && irq_pending) + {}; + + /* Interrupt should not be generated */ + if (irq_pending == 0) { + val_print(ACS_PRINT_ERR, + "\n Interrupt triggered for int_id : 0x%x, ", base_lpi_id + instance); + val_print(ACS_PRINT_ERR, + "BDF : 0x%x ", e_bdf); + val_set_status(index, RESULT_FAIL(TEST_NUM, 04)); + val_gic_free_msi(e_bdf, device_id, get_value, base_lpi_id + instance, msi_index); + return; + } + + /* Clear Interrupt and Mappings */ + val_gic_free_msi(e_bdf, device_id, get_value, base_lpi_id + instance, msi_index); - /* Check For Error in Device Status Register / Status Register - * Secondary Status Register - */ - if ((val_pcie_is_device_status_error(req_rp_bdf) == 0) && - (val_pcie_is_sig_target_abort(req_rp_bdf) == 0)) { - /* Fail the part */ - val_print(ACS_PRINT_DEBUG, - "\n Traxn Blocking Expected Error RootPort : 0x%x", req_rp_bdf); - return ACS_STATUS_FAIL; } - return ACS_STATUS_PASS; -} - -static -void -payload(void) -{ - - uint32_t status; - uint32_t pe_index; - uint32_t req_e_bdf; - uint32_t req_rp_bdf; - uint32_t tgt_e_bdf; - uint32_t tgt_rp_bdf; - uint32_t instance; - uint32_t fail_cnt; - uint32_t cap_base; - uint32_t reg_value; - uint32_t test_skip; - uint64_t bar_base; - uint32_t curr_bdf_failed = 0; - - fail_cnt = 0; - test_skip = 1; - pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); - instance = val_exerciser_get_info(EXERCISER_NUM_CARDS, 0); - - /* Check If PCIe Hierarchy supports P2P. */ - if (val_pcie_p2p_support()) - { - val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + if (test_skip) { + val_set_status(index, RESULT_SKIP(TEST_NUM, 02)); return; } - while (instance-- != 0) - { - - /* if init fail moves to next exerciser */ - if (val_exerciser_init(instance)) - continue; - - req_e_bdf = val_exerciser_get_bdf(instance); - - /* Get RP of the exerciser */ - if (val_pcie_get_rootport(req_e_bdf, &req_rp_bdf)) - continue; - - /* It ACS Not Supported, Fail.*/ - if (val_pcie_find_capability(req_rp_bdf, PCIE_ECAP, ECID_ACS, &cap_base) != PCIE_SUCCESS) { - val_print(ACS_PRINT_ERR, "\n ACS Not Supported for BDF : 0x%x", req_rp_bdf); - fail_cnt++; - continue; - } - - /* Enable Source Validation & Transaction Blocking */ - val_pcie_read_cfg(req_rp_bdf, cap_base + ACSCR_OFFSET, ®_value); - reg_value = reg_value | (1 << ACS_CTRL_SVE_SHIFT) | (1 << ACS_CTRL_TBE_SHIFT); - val_pcie_write_cfg(req_rp_bdf, cap_base + ACSCR_OFFSET, reg_value); - - /* Find another exerciser on other rootport, - Break from the test if no such exerciser if found */ - if (get_target_exer_bdf(req_rp_bdf, &tgt_e_bdf, &tgt_rp_bdf, &bar_base)) - break; - - /* If Both RP's Supports ACS Then Only Run Otherwise Skip the EP */ - test_skip = 0; - - /* Check For ACS Functionality */ - status = check_source_validation(instance, req_e_bdf, req_rp_bdf, tgt_e_bdf, bar_base); - if (status == ACS_STATUS_SKIP) - val_print(ACS_PRINT_DEBUG, "\n ACS Source Validation Skipped for 0x%x", req_rp_bdf); - else if (status) - curr_bdf_failed++; - - status = check_transaction_blocking(instance, req_e_bdf, req_rp_bdf, tgt_e_bdf, bar_base); - if (status == ACS_STATUS_SKIP) - val_print(ACS_PRINT_DEBUG, - "\n ACS Transaction Blocking Skipped for 0x%x", req_rp_bdf); - else if (status) - curr_bdf_failed++; - - if (curr_bdf_failed > 0) { - val_print(ACS_PRINT_ERR, "\n ACS Functional Check Failed, RP Bdf : 0x%x", req_rp_bdf); - curr_bdf_failed = 0; - fail_cnt++; - } - /* Clear Error Status Bits */ - val_pcie_clear_device_status_error(req_rp_bdf); - val_pcie_clear_sig_target_abort(req_rp_bdf); - } - - if (test_skip == 1) - val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); - else if (fail_cnt) - val_set_status(pe_index, RESULT_FAIL(TEST_NUM, fail_cnt)); - else - val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); - - return; + /* Pass Test */ + val_set_status(index, RESULT_PASS(TEST_NUM, 01)); } uint32_t os_e012_entry(void) { - uint32_t num_pe = 1; + uint32_t status = ACS_STATUS_FAIL; + uint32_t num_pe = 1; //This test is run on single processor + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); if (status != ACS_STATUS_SKIP) val_run_test_payload(TEST_NUM, num_pe, payload, 0); - /* Get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/gic/hypervisor/test_hyp_g001.c b/test_pool/gic/hypervisor/test_hyp_g001.c index 9885e014..0b26dca4 100644 --- a/test_pool/gic/hypervisor/test_hyp_g001.c +++ b/test_pool/gic/hypervisor/test_hyp_g001.c @@ -24,7 +24,8 @@ #include "val/include/bsa_acs_gic_support.h" #define TEST_NUM (ACS_GIC_HYP_TEST_NUM_BASE + 1) -#define TEST_DESC "B_PPI_02: Check PPI Assignments Hypervisor " +#define TEST_RULE "B_PPI_02" +#define TEST_DESC "Check PPI Assignments Hypervisor " static uint32_t intid; @@ -89,7 +90,8 @@ payload() uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); if (val_pe_reg_read(CurrentEL) == AARCH64_EL1) { - val_print(ACS_PRINT_WARN, "\n Skipping. Test accesses EL2 Registers ", 0); + val_print(ACS_PRINT_DEBUG, "\n Skipping. Test accesses EL2" + " Registers ", 0); val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); return; } @@ -118,20 +120,20 @@ payload() if (timeout == 0) { val_print(ACS_PRINT_ERR, - "\n EL2-Virtual timer interrupt not received on INTID: %d ", intid); + "\n EL2-Virtual timer interrupt %d not received", intid); val_set_status(index, RESULT_FAIL(TEST_NUM, 03)); } } else - val_print(ACS_PRINT_WARN, - "\n EL2-Virtual timer not mapped to PPI base range, INTID: %d ", intid); + val_print(ACS_PRINT_DEBUG, + "\n EL2-Virtual timer interrupt not mapped to PPI", intid); } else - val_print(ACS_PRINT_WARN, "\n v8.1 VHE not supported on this PE ", 0); + val_print(ACS_PRINT_DEBUG, "\n v8.1 VHE not supported on this PE ", 0); // Check non-secure EL2 physical timer val_set_status(index, RESULT_PENDING(TEST_NUM)); intid = val_timer_get_info(TIMER_INFO_PHY_EL2_INTID, 0); if (intid < 16 || intid > 31) { - val_print(ACS_PRINT_WARN, + val_print(ACS_PRINT_DEBUG, "\n EL2-Phy timer not mapped to PPI base range, INTID: %d ", intid); val_set_status(index, RESULT_SKIP(TEST_NUM, 03)); return; @@ -159,7 +161,7 @@ payload() val_set_status(index, RESULT_PENDING(TEST_NUM)); intid = val_pe_get_gmain_gsiv(index); if (intid < 16 || intid > 31) { - val_print(ACS_PRINT_WARN, + val_print(ACS_PRINT_DEBUG, "\n GIC Maintenance interrupt not mapped to PPI base range, INTID: %d ", intid); val_set_status(index, RESULT_SKIP(TEST_NUM, 05)); return; @@ -201,9 +203,9 @@ hyp_g001_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/gic/operating_system/test_os_g001.c b/test_pool/gic/operating_system/test_os_g001.c index f57f5aa1..faca3841 100755 --- a/test_pool/gic/operating_system/test_os_g001.c +++ b/test_pool/gic/operating_system/test_os_g001.c @@ -21,7 +21,8 @@ #include "val/include/bsa_acs_gic.h" #define TEST_NUM (ACS_GIC_TEST_NUM_BASE + 1) -#define TEST_DESC "B_GIC_01: Check GIC version " +#define TEST_RULE "B_GIC_01" +#define TEST_DESC "Check GIC version " static void @@ -58,9 +59,9 @@ os_g001_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/gic/operating_system/test_os_g002.c b/test_pool/gic/operating_system/test_os_g002.c index 5bcd7f98..0add14c9 100755 --- a/test_pool/gic/operating_system/test_os_g002.c +++ b/test_pool/gic/operating_system/test_os_g002.c @@ -22,7 +22,8 @@ #include "val/include/bsa_acs_pcie.h" #define TEST_NUM (ACS_GIC_TEST_NUM_BASE + 2) -#define TEST_DESC "B_GIC_02: Check GICv2 Valid Configuration " +#define TEST_RULE "B_GIC_02" +#define TEST_DESC "Check GICv2 Valid Configuration " static void @@ -72,9 +73,9 @@ os_g002_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/gic/operating_system/test_os_g003.c b/test_pool/gic/operating_system/test_os_g003.c index be225ec2..c51e80b9 100755 --- a/test_pool/gic/operating_system/test_os_g003.c +++ b/test_pool/gic/operating_system/test_os_g003.c @@ -22,7 +22,8 @@ #include "val/include/bsa_acs_pcie.h" #define TEST_NUM (ACS_GIC_TEST_NUM_BASE + 3) -#define TEST_DESC "B_GIC_03: If PCIe, GICv3 then ITS, LPI " +#define TEST_RULE "B_GIC_03" +#define TEST_DESC "If PCIe, GICv3 then ITS, LPI " static void @@ -78,9 +79,9 @@ os_g003_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/gic/operating_system/test_os_g004.c b/test_pool/gic/operating_system/test_os_g004.c index 8ecd511d..b0ecf259 100755 --- a/test_pool/gic/operating_system/test_os_g004.c +++ b/test_pool/gic/operating_system/test_os_g004.c @@ -21,7 +21,8 @@ #include "val/include/bsa_acs_gic.h" #define TEST_NUM (ACS_GIC_TEST_NUM_BASE + 4) -#define TEST_DESC "B_GIC_04: Check GICv3 Security States " +#define TEST_RULE "B_GIC_04" +#define TEST_DESC "Check GICv3 Security States " static void @@ -60,9 +61,9 @@ os_g004_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/gic/operating_system/test_os_g005.c b/test_pool/gic/operating_system/test_os_g005.c index 5be84ec2..202bb348 100644 --- a/test_pool/gic/operating_system/test_os_g005.c +++ b/test_pool/gic/operating_system/test_os_g005.c @@ -23,7 +23,8 @@ #include "val/include/bsa_acs_gic_support.h" #define TEST_NUM (ACS_GIC_TEST_NUM_BASE + 5) -#define TEST_DESC "B_GIC_05: Non-secure SGIs are implemented " +#define TEST_RULE "B_GIC_05" +#define TEST_DESC "Non-secure SGIs are implemented " #define RD_FRAME_SIZE 0x10000 @@ -109,9 +110,9 @@ os_g005_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/gic/operating_system/test_os_g006.c b/test_pool/gic/operating_system/test_os_g006.c index 5f25fb68..36ee5d3a 100644 --- a/test_pool/gic/operating_system/test_os_g006.c +++ b/test_pool/gic/operating_system/test_os_g006.c @@ -22,7 +22,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_GIC_TEST_NUM_BASE + 6) -#define TEST_DESC "B_PPI_01: Check PPI Assignments for OS " +#define TEST_RULE "B_PPI_01" +#define TEST_DESC "Check PPI Assignments for OS " static uint32_t intid; @@ -118,9 +119,9 @@ os_g006_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/gic/operating_system/test_os_its001.c b/test_pool/gic/operating_system/test_os_its001.c new file mode 100644 index 00000000..8ed2772f --- /dev/null +++ b/test_pool/gic/operating_system/test_os_its001.c @@ -0,0 +1,75 @@ +/** @file + * Copyright (c) 2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" +#include "val/include/bsa_acs_iovirt.h" + +#define TEST_NUM (ACS_GIC_ITS_TEST_NUM_BASE + 1) +#define TEST_RULE "ITS_01" +#define TEST_DESC "Check number of ITS blocks in a group " + +static +void +payload() +{ + uint32_t status; + uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); + uint32_t num_group, num_blocks; + int i; + + status = val_iovirt_get_its_info(ITS_NUM_GROUPS, 0, 0, &num_group); + if (status) { + val_print(ACS_PRINT_ERR, "\n ITS get group number failed ", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, 0x1)); + return; + } + + if (!num_group) { + val_print(ACS_PRINT_DEBUG, "\n No ITS group found ", 0); + val_set_status(index, RESULT_SKIP(TEST_NUM, 0x1)); + return; + } + val_print(ACS_PRINT_DEBUG, "\n Number of ITS groups = %d", num_group); + for (i = 0; i < num_group; i++) { + status = val_iovirt_get_its_info(ITS_GROUP_NUM_BLOCKS, i, 0, &num_blocks); + if (status) { + val_print(ACS_PRINT_ERR, "\n ITS get number of blocks failed ", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, 0x2)); + return; + } + if (!num_blocks) { + val_print(ACS_PRINT_ERR, "\n No valid ITS Blocks found in group %d ", i); + val_set_status(index, RESULT_FAIL(TEST_NUM, 0x3)); + return; + } + val_print(ACS_PRINT_DEBUG, "\n Number of ITS Blocks = %d", num_blocks); + } + val_set_status(index, RESULT_PASS(TEST_NUM, 01)); +} + +uint32_t +os_its001_entry(uint32_t num_pe) +{ + uint32_t status = ACS_STATUS_FAIL; + num_pe = 1; //This ITS test is run on single processor + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + return status; +} diff --git a/test_pool/gic/operating_system/test_os_its002.c b/test_pool/gic/operating_system/test_os_its002.c new file mode 100644 index 00000000..50364051 --- /dev/null +++ b/test_pool/gic/operating_system/test_os_its002.c @@ -0,0 +1,101 @@ +/** @file + * Copyright (c) 2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" +#include "val/include/bsa_acs_iovirt.h" + +#define TEST_NUM (ACS_GIC_ITS_TEST_NUM_BASE + 2) +#define TEST_RULE "ITS_02" +#define TEST_DESC "Check ITS block association with group" + +static +void +payload() +{ + uint32_t status; + uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); + uint32_t num_group, num_blocks, its_id, blk_index; + int i, j, k; + + status = val_iovirt_get_its_info(ITS_NUM_GROUPS, 0, 0, &num_group); + if (status) { + val_print(ACS_PRINT_ERR, "\n ITS get group number failed ", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, 0x1)); + return; + } + if (!num_group) { + val_print(ACS_PRINT_DEBUG, "\n No ITS group found ", 0); + val_set_status(index, RESULT_SKIP(TEST_NUM, 0x1)); + return; + } + + val_print(ACS_PRINT_DEBUG, "\n Number of ITS groups = %d", num_group); + + for (i = 0; i < (num_group - 1); i++) { + status = val_iovirt_get_its_info(ITS_GROUP_NUM_BLOCKS, i, 0, &num_blocks); + if (status) { + val_print(ACS_PRINT_ERR, "\n ITS get number of blocks failed ", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, 0x2)); + return; + } + + if (!num_blocks) { + val_print(ACS_PRINT_ERR, "\n No valid ITS Blocks found in group %d ", i); + val_set_status(index, RESULT_FAIL(TEST_NUM, 0x3)); + return; + } + val_print(ACS_PRINT_DEBUG, "\n ITS group index = %d", i); + val_print(ACS_PRINT_DEBUG, "\n Number of ITS Blocks = %d", num_blocks); + + for (j = 0; j < num_blocks; j++) { + status = val_iovirt_get_its_info(ITS_GET_ID_FOR_BLK_INDEX, i, j, &its_id); + if (status) { + val_print(ACS_PRINT_ERR, "\n ITS get id failed ", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, 0x4)); + return; + } + + val_print(ACS_PRINT_DEBUG, "\n ITS block index = %d", j); + for (k = (i + 1); k < num_group; k++) { + status = + val_iovirt_get_its_info(ITS_GET_BLK_INDEX_FOR_ID, k, its_id, &blk_index); + if (status != ACS_INVALID_INDEX) { + val_print(ACS_PRINT_ERR, "\n ITS ID (%d) repeated in multiple groups", + its_id); + val_set_status(index, RESULT_FAIL(TEST_NUM, 0x5)); + return; + } + } + } + } + val_set_status(index, RESULT_PASS(TEST_NUM, 01)); +} + +uint32_t +os_its002_entry(uint32_t num_pe) +{ + uint32_t status = ACS_STATUS_FAIL; + num_pe = 1; //This ITS test is run on single processor + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/gic/operating_system/test_os_v2m001.c b/test_pool/gic/operating_system/test_os_v2m001.c new file mode 100644 index 00000000..2803ed2a --- /dev/null +++ b/test_pool/gic/operating_system/test_os_v2m001.c @@ -0,0 +1,107 @@ +/** @file + * Copyright (c) 2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_gic.h" + +#define TEST_NUM (ACS_GIC_V2M_TEST_NUM_BASE + 1) +#define TEST_RULE "Appendix I.6" +#define TEST_DESC "Check MSI SPI are Edge Triggered " + +static +void +payload() +{ + + uint32_t status; + uint32_t test_skip; + uint32_t fail_cnt, instance; + uint32_t msi_frame, spi_id; + uint32_t spi_base, num_spi; + INTR_TRIGGER_INFO_TYPE_e trigger_type; + uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); + + msi_frame = val_gic_get_info(GIC_INFO_NUM_MSI_FRAME); + if (msi_frame == 0) { + val_print(ACS_PRINT_DEBUG, "\n No MSI frame, Skipping ", 0); + val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); + return; + } + + fail_cnt = 0; + test_skip = 1; + + for (instance = 0; instance < msi_frame; instance++) { + spi_base = val_gic_v2m_get_info(V2M_MSI_SPI_BASE, instance); + num_spi = val_gic_v2m_get_info(V2M_MSI_SPI_NUM, instance); + + /* Check All the SPIs which are mapped to MSI are Edge Triggered */ + for (spi_id = spi_base; spi_id < spi_base+num_spi; spi_id++) { + + test_skip = 0; + + /* Read GICD_ICFGR register to Check for Level/Edge Sensitive. */ + status = val_gic_get_intr_trigger_type(spi_id, &trigger_type); + if (status) { + val_set_status(index, RESULT_FAIL(TEST_NUM, 01)); + return; + } + + if (trigger_type != INTR_TRIGGER_INFO_EDGE_RISING) { + val_print(ACS_PRINT_DEBUG, "\n Error : SPI ID 0x%x Level Triggered ", spi_id); + fail_cnt++; + } + } + } + + if (test_skip) { + val_print(ACS_PRINT_WARN, "\n No SPI Information Found. Skipping ", 0); + val_set_status(index, RESULT_SKIP(TEST_NUM, 02)); + return; + } + + if (fail_cnt) { + val_print(ACS_PRINT_ERR, "\n SPI Trigger Type Check Failed", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, 02)); + return; + } + + val_set_status(index, RESULT_PASS(TEST_NUM, 01)); +} + +uint32_t +os_v2m001_entry(uint32_t num_pe) +{ + + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This GIC test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/gic/operating_system/test_os_v2m002.c b/test_pool/gic/operating_system/test_os_v2m002.c new file mode 100644 index 00000000..d42c617a --- /dev/null +++ b/test_pool/gic/operating_system/test_os_v2m002.c @@ -0,0 +1,114 @@ +/** @file + * Copyright (c) 2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_gic.h" + +#define TEST_NUM (ACS_GIC_V2M_TEST_NUM_BASE + 2) +#define TEST_RULE "Appendix I.9" +#define TEST_DESC "Check GICv2m MSI Frame Register " + +static +void +payload() +{ + + uint32_t num_spi; + uint32_t data, new_data; + uint32_t fail_cnt, instance; + uint32_t msi_frame, min_spi_id; + uint64_t frame_base; + uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); + + msi_frame = val_gic_get_info(GIC_INFO_NUM_MSI_FRAME); + if (msi_frame == 0) { + val_print(ACS_PRINT_DEBUG, "\n No MSI frame, Skipping ", 0); + val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); + return; + } + + fail_cnt = 0; + + for (instance = 0; instance < msi_frame; instance++) { + frame_base = val_gic_v2m_get_info(V2M_MSI_FRAME_BASE, instance); + + /* Part 1 : GICv2m_MSI_TYPER Read Only Register */ + data = val_mmio_read(frame_base + GICv2m_MSI_TYPER); + + /* Try Changing all the bits of the RO register */ + val_mmio_write(frame_base + GICv2m_MSI_TYPER, (data ^ 0xFFFFFFFF)); + + new_data = val_mmio_read(frame_base + GICv2m_MSI_TYPER); + if (data != new_data) { + fail_cnt++; + val_print(ACS_PRINT_DEBUG, "\n MSI_TYPER RO Check Failed for instance %d", instance); + } + + /* Part 2 : Check SPI ID allocated is b/w 32-1020 */ + min_spi_id = val_gic_v2m_get_info(V2M_MSI_SPI_BASE, instance); + num_spi = val_gic_v2m_get_info(V2M_MSI_SPI_NUM, instance); + + if ((min_spi_id < 32) || (min_spi_id + num_spi) > 1020) { + fail_cnt++; + val_print(ACS_PRINT_DEBUG, "\n SPI ID Check Failed for instance %d", instance); + } + + /* Part 3 : GICv2m_MSI_IIDR Read Only Register */ + data = val_mmio_read(frame_base + GICv2m_MSI_IIDR); + + /* Try Changing all the bits of the RO register */ + val_mmio_write(frame_base + GICv2m_MSI_IIDR, (data ^ 0xFFFFFFFF)); + + new_data = val_mmio_read(frame_base + GICv2m_MSI_IIDR); + if (data != new_data) { + fail_cnt++; + val_print(ACS_PRINT_DEBUG, "\n MSI_IIDR RO Check Failed for instance %d", instance); + } + + } + + if (fail_cnt) { + val_print(ACS_PRINT_ERR, "\n MSI_TYPER Register Check Failed", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, 01)); + return; + } + + val_set_status(index, RESULT_PASS(TEST_NUM, 01)); +} + +uint32_t +os_v2m002_entry(uint32_t num_pe) +{ + + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This GIC test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/gic/operating_system/test_os_v2m003.c b/test_pool/gic/operating_system/test_os_v2m003.c new file mode 100644 index 00000000..d796305e --- /dev/null +++ b/test_pool/gic/operating_system/test_os_v2m003.c @@ -0,0 +1,125 @@ +/** @file + * Copyright (c) 2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_gic.h" + +#define TEST_NUM (ACS_GIC_V2M_TEST_NUM_BASE + 3) +#define TEST_RULE "Appendix I.6" +#define TEST_DESC "Check GICv2m MSI to SPI Generation " + +static uint32_t int_id; + +static +void +isr() +{ + uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); + + val_print(ACS_PRINT_INFO, "\n Received SPI ", 0); + val_set_status(index, RESULT_PASS(TEST_NUM, 01)); + val_gic_end_of_interrupt(int_id); + + return; +} + +static +void +payload() +{ + + uint32_t num_spi; + uint32_t instance; + uint32_t timeout = TIMEOUT_MEDIUM; + uint32_t msi_frame, min_spi_id; + uint64_t frame_base; + uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); + + msi_frame = val_gic_get_info(GIC_INFO_NUM_MSI_FRAME); + if (msi_frame == 0) { + val_print(ACS_PRINT_DEBUG, "\n No MSI frame, Skipping ", 0); + val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); + return; + } + + for (instance = 0; instance < msi_frame; instance++) { + frame_base = val_gic_v2m_get_info(V2M_MSI_FRAME_BASE, instance); + + min_spi_id = val_gic_v2m_get_info(V2M_MSI_SPI_BASE, instance); + num_spi = val_gic_v2m_get_info(V2M_MSI_SPI_NUM, instance); + + int_id = min_spi_id + num_spi - 1; + + /* Register an interrupt handler to verify */ + if (val_gic_install_isr(int_id, isr)) { + val_print(ACS_PRINT_ERR, "\n GIC Install Handler Failed...", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, 01)); + return; + } + + /* Part 1 : SPI Generation using 32 Bit Write */ + /* Generate the Interrupt by writing the int_id to SETSPI_NS Register */ + val_mmio_write(frame_base + GICv2m_MSI_SETSPI, int_id); + + while ((timeout > 0) && (IS_RESULT_PENDING(val_get_status(index)))) { + timeout--; + } + + if (timeout == 0) { + val_print(ACS_PRINT_ERR, "\n Interrupt not received within timeout", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, 02)); + return; + } + + /* Part 2 : SETSPI Should Support 16 Bit Access. */ + /* Generate the Interrupt by writing the int_id to SETSPI_NS Register */ + val_mmio_write16(frame_base + GICv2m_MSI_SETSPI, int_id); + + while ((timeout > 0) && (IS_RESULT_PENDING(val_get_status(index)))) { + timeout--; + } + + if (timeout == 0) { + val_print(ACS_PRINT_ERR, "\n Interrupt not received within timeout", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, 03)); + return; + } + } +} + +uint32_t +os_v2m003_entry(uint32_t num_pe) +{ + + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This GIC test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/gic/operating_system/test_os_v2m004.c b/test_pool/gic/operating_system/test_os_v2m004.c new file mode 100644 index 00000000..8ee13579 --- /dev/null +++ b/test_pool/gic/operating_system/test_os_v2m004.c @@ -0,0 +1,134 @@ +/** @file + * Copyright (c) 2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_gic.h" + +#define TEST_NUM (ACS_GIC_V2M_TEST_NUM_BASE + 4) +#define TEST_RULE "Appendix I.5" +#define TEST_DESC "Check GICv2m SPI allocated to MSI Ctrl" + +static uint32_t int_id; + +static +void +isr() +{ + uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); + + val_print(ACS_PRINT_INFO, "\n Received SPI ", 0); + val_set_status(index, RESULT_PASS(TEST_NUM, 01)); + val_gic_end_of_interrupt(int_id); + + return; +} + +static +void +payload() +{ + + uint32_t num_spi; + uint32_t instance; + uint32_t timeout = TIMEOUT_MEDIUM; + uint32_t msi_frame, min_spi_id; + uint64_t frame_base; + uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); + uint32_t reg_offset; + uint32_t reg_shift; + + msi_frame = val_gic_get_info(GIC_INFO_NUM_MSI_FRAME); + if (msi_frame == 0) { + val_print(ACS_PRINT_DEBUG, "\n No MSI frame, Skipping ", 0); + val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); + return; + } + + for (instance = 0; instance < msi_frame; instance++) { + frame_base = val_gic_v2m_get_info(V2M_MSI_FRAME_BASE, instance); + + min_spi_id = val_gic_v2m_get_info(V2M_MSI_SPI_BASE, instance); + num_spi = val_gic_v2m_get_info(V2M_MSI_SPI_NUM, instance); + + int_id = min_spi_id + num_spi - 1; + + /* Register an interrupt handler to verify */ + if (val_gic_install_isr(int_id, isr)) { + val_print(ACS_PRINT_ERR, "\n GIC Install Handler Failed...", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, 01)); + return; + } + + /* Part 1 : Generate SPI using GICD Regsiters, It should Not generate the MSI/SPI */ + + /* Follwing code calculates the GICD_ISPENDR offset for int_id. + * Every ISPENDR register add the pending state for 32 Interrupts hence reg_offset + * reg_shift is the bit number which need to be set for a particular interrupt */ + reg_offset = int_id / 32; + reg_shift = int_id % 32; + + val_mmio_write(val_get_gicd_base() + GICD_ISPENDR + (4 * reg_offset), 1 << reg_shift); + + while ((timeout > 0) && (IS_RESULT_PENDING(val_get_status(index)))) { + timeout--; + } + + /* If the Status is changed that means interrupt handler is called & test is failed. */ + if (timeout != 0) { + val_print(ACS_PRINT_ERR, "\n Interrupt generated by GICD registers", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, 02)); + return; + } + + /* Part 2 : SETSPI Should Generate the SPI. */ + /* Generate the Interrupt by writing the int_id to SETSPI_NS Register */ + val_mmio_write(frame_base + GICv2m_MSI_SETSPI, int_id); + + while ((timeout > 0) && (IS_RESULT_PENDING(val_get_status(index)))) { + timeout--; + } + + if (timeout == 0) { + val_print(ACS_PRINT_ERR, "\n Interrupt not received within timeout", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, 03)); + return; + } + } +} + +uint32_t +os_v2m004_entry(uint32_t num_pe) +{ + + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This GIC test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/memory_map/operating_system/test_os_m001.c b/test_pool/memory_map/operating_system/test_os_m001.c index b1d1f22f..35619588 100644 --- a/test_pool/memory_map/operating_system/test_os_m001.c +++ b/test_pool/memory_map/operating_system/test_os_m001.c @@ -23,7 +23,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_MEMORY_MAP_TEST_BASE + 1) -#define TEST_DESC "B_MEM_02: Memory Access to Un-Populated addr" +#define TEST_RULE "B_MEM_02" +#define TEST_DESC "Memory Access to Un-Populated addr " #define LOOP_VAR 3 /* Number of Addresses to check */ @@ -112,14 +113,14 @@ os_m001_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - error_flag = val_check_for_error(TEST_NUM, num_pe); + error_flag = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); if (!error_flag) status = ACS_STATUS_PASS; else status = ACS_STATUS_FAIL; - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/memory_map/operating_system/test_os_m002.c b/test_pool/memory_map/operating_system/test_os_m002.c index d4565389..a035502c 100644 --- a/test_pool/memory_map/operating_system/test_os_m002.c +++ b/test_pool/memory_map/operating_system/test_os_m002.c @@ -23,7 +23,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_MEMORY_MAP_TEST_BASE + 2) -#define TEST_DESC "B_MEM_01: Mem Access Response in finite time" +#define TEST_RULE "B_MEM_01" +#define TEST_DESC "Mem Access Response in finite time " #define LOOP_VAR 3 /* Number of Addresses to check */ @@ -65,7 +66,7 @@ payload() /* Get the address of device memory region */ addr = val_memory_get_addr(MEMORY_TYPE_DEVICE, instance, &attr); if (!addr) { - val_print(ACS_PRINT_DEBUG, "\n Error in obtaining device memory for" + val_print(ACS_PRINT_DEBUG, "\n Error in obtaining dev mem for" " instance %d", instance); goto normal_mem_test; } @@ -123,14 +124,14 @@ os_m002_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* Get the result from the PE and check for failure */ - error_flag = val_check_for_error(TEST_NUM, num_pe); + error_flag = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); if (!error_flag) status = ACS_STATUS_PASS; else status = ACS_STATUS_FAIL; - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/memory_map/operating_system/test_os_m003.c b/test_pool/memory_map/operating_system/test_os_m003.c index 78aa39a8..181bf75c 100644 --- a/test_pool/memory_map/operating_system/test_os_m003.c +++ b/test_pool/memory_map/operating_system/test_os_m003.c @@ -23,7 +23,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_MEMORY_MAP_TEST_BASE + 3) -#define TEST_DESC "B_MEM_05: PE must access all NS addr space " +#define TEST_RULE "B_MEM_05" +#define TEST_DESC "PE must access all NS addr space " static uint64_t check_number_of_bits(uint32_t index, uint64_t data) { @@ -89,9 +90,9 @@ os_m003_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/memory_map/operating_system/test_os_m004.c b/test_pool/memory_map/operating_system/test_os_m004.c index 53ffacf6..c6646e93 100644 --- a/test_pool/memory_map/operating_system/test_os_m004.c +++ b/test_pool/memory_map/operating_system/test_os_m004.c @@ -20,7 +20,8 @@ #include "val/include/bsa_acs_pcie.h" #define TEST_NUM (ACS_MEMORY_MAP_TEST_BASE + 4) -#define TEST_DESC "B_MEM_03,B_MEM_04,B_MEM_06: Addressability " +#define TEST_RULE "B_MEM_03-04, B_MEM_06" +#define TEST_DESC "Addressability " static void @@ -37,7 +38,7 @@ payload (void) count = val_peripheral_get_info (NUM_ALL, 0); if (!count) { - val_print (ACS_PRINT_WARN, "\n Skip as No peripherals detected ", 0); + val_print (ACS_PRINT_DEBUG, "\n Skip as No peripherals detected ", 0); val_set_status (index, RESULT_SKIP (TEST_NUM, 1)); return; } @@ -85,9 +86,9 @@ os_m004_entry (uint32_t num_pe) } /* get the result from all PE and check for failure */ - status = val_check_for_error (TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status (0, BSA_ACS_END (TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p001.c b/test_pool/pcie/operating_system/test_os_p001.c index ff9d3d51..bb49a61a 100644 --- a/test_pool/pcie/operating_system/test_os_p001.c +++ b/test_pool/pcie/operating_system/test_os_p001.c @@ -20,7 +20,8 @@ #include "val/include/bsa_acs_pcie.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 1) -#define TEST_DESC "PCI_IN_01: Check ECAM Presence " +#define TEST_RULE "PCI_IN_01" +#define TEST_DESC "Check ECAM Presence " static void @@ -55,9 +56,9 @@ os_p001_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p002.c b/test_pool/pcie/operating_system/test_os_p002.c index 1306cbf4..45a10921 100644 --- a/test_pool/pcie/operating_system/test_os_p002.c +++ b/test_pool/pcie/operating_system/test_os_p002.c @@ -20,7 +20,8 @@ #include "val/include/bsa_acs_pcie.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 2) -#define TEST_DESC "PCI_IN_02: PE - ECAM Region accessiblity check " +#define TEST_RULE "PCI_IN_02" +#define TEST_DESC "PE - ECAM Region accessiblity check " #define PCIE_VENDOR_ID_REG_OFFSET 0x0 #define PCIE_CACHE_LINE_SIZE_REG_OFFSET 0xC @@ -46,7 +47,7 @@ payload(void) num_ecam = val_pcie_get_info(PCIE_INFO_NUM_ECAM, 0); if (num_ecam == 0) { - val_print(ACS_PRINT_ERR, "\n No ECAM in MCFG ", 0); + val_print(ACS_PRINT_DEBUG, "\n No ECAM in MCFG ", 0); val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); return; } @@ -54,7 +55,7 @@ payload(void) while (num_ecam--) { ecam_base = val_pcie_get_info(PCIE_INFO_ECAM, num_ecam); if (ecam_base == 0) { - val_print(ACS_PRINT_ERR, "\n ECAM Base in MCFG is 0 ", 0); + val_print(ACS_PRINT_DEBUG, "\n ECAM Base in MCFG is 0 ", 0); val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); return; } @@ -134,9 +135,9 @@ os_p002_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p003.c b/test_pool/pcie/operating_system/test_os_p003.c new file mode 100644 index 00000000..9da1d73a --- /dev/null +++ b/test_pool/pcie/operating_system/test_os_p003.c @@ -0,0 +1,135 @@ +/** @file + * Copyright (c) 2016-2018, 2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_pcie.h" + +#define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 3) +#define TEST_RULE "PCI_IN_04" +#define TEST_DESC "All EP/Sw under RP in same ECAM Region" + +uint8_t func_ecam_is_rp_ecam(uint32_t dsf_bdf) +{ + + uint8_t dsf_bus; + uint32_t bdf; + uint32_t dp_type; + uint32_t tbl_index; + uint32_t reg_value; + addr_t ecam_base; + addr_t dev_ecam_base; + pcie_device_bdf_table *bdf_tbl_ptr; + + tbl_index = 0; + dsf_bus = PCIE_EXTRACT_BDF_BUS(dsf_bdf); + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + + while (tbl_index < bdf_tbl_ptr->num_entries) { + bdf = bdf_tbl_ptr->device[tbl_index++].bdf; + dp_type = val_pcie_device_port_type(bdf); + + /* Check if this table entry is a Root Port */ + if (dp_type == RP || dp_type == iEP_RP) { + if (PCIE_EXTRACT_BDF_SEG(bdf) != PCIE_EXTRACT_BDF_SEG(dsf_bdf)) + continue; + + /* Check if the entry's bus range covers down stream function */ + val_pcie_read_cfg(bdf, TYPE1_PBN, ®_value); + if ((dsf_bus >= ((reg_value >> SECBN_SHIFT) & SECBN_MASK)) && + (dsf_bus <= ((reg_value >> SUBBN_SHIFT) & SUBBN_MASK))) { + ecam_base = val_pcie_get_ecam_base(bdf); + dev_ecam_base = val_pcie_get_ecam_base(dsf_bdf); + + /* Return success if both RP and EP / SW share the same ECAM region */ + if (ecam_base == dev_ecam_base) + return 0; + else + return 1; + } + } + } + + return 1; +} + +static +void +payload(void) +{ + + uint32_t bdf; + uint32_t dp_type; + uint32_t pe_index; + uint32_t tbl_index; + uint32_t fail_cnt; + uint32_t test_skip = 1; + pcie_device_bdf_table *bdf_tbl_ptr; + + fail_cnt = 0; + tbl_index = 0; + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + + while (tbl_index < bdf_tbl_ptr->num_entries) { + /* + * If a function is in the hierarchy domain + * originated by a Root Port, check its ECAM + * is same as its RootPort ECAM. + */ + bdf = bdf_tbl_ptr->device[tbl_index++].bdf; + dp_type = val_pcie_device_port_type(bdf); + if (dp_type == EP || dp_type == iEP_EP || + dp_type == UP || dp_type == DP) { + /* If test runs for atleast an endpoint */ + test_skip = 0; + + if (func_ecam_is_rp_ecam(bdf)) { + val_print(ACS_PRINT_ERR, "\n bdf: 0x%x ", bdf); + val_print(ACS_PRINT_ERR, "dp_type: 0x%x ", dp_type); + fail_cnt++; + } + } + } + + if (test_skip == 1) + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + else if (fail_cnt) + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, fail_cnt)); + else + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); +} + +uint32_t +os_p003_entry(uint32_t num_pe) +{ + + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/pcie/operating_system/test_os_p004.c b/test_pool/pcie/operating_system/test_os_p004.c new file mode 100644 index 00000000..3bcaa43a --- /dev/null +++ b/test_pool/pcie/operating_system/test_os_p004.c @@ -0,0 +1,163 @@ +/** @file + * Copyright (c) 2016-2018, 2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_pe.h" +#include "val/include/bsa_acs_pcie.h" + +#define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 4) +#define TEST_RULE "PCI_IN_13" +#define TEST_DESC "PHB,RP must recognize Txn frm upstream" + +#define KNOWN_DATA 0xABABABAB + +static void *branch_to_test; + +static +void +esr(uint64_t interrupt_type, void *context) +{ + uint32_t pe_index; + + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + + /* Update the ELR to return to test specified address */ + val_pe_update_elr(context, (uint64_t)branch_to_test); + + val_print(ACS_PRINT_INFO, "\n Received exception of type: %d", interrupt_type); + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 01)); +} + +static +void +payload(void) +{ + + uint32_t bdf; + uint32_t dp_type; + uint32_t pe_index; + uint32_t tbl_index; + uint32_t read_value, old_value; + uint32_t test_skip = 1; + uint64_t mem_base; + uint64_t mem_lim; + pcie_device_bdf_table *bdf_tbl_ptr; + + tbl_index = 0; + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + + /* Install sync and async handlers to handle exceptions.*/ + val_pe_install_esr(EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS, esr); + val_pe_install_esr(EXCEPT_AARCH64_SERROR, esr); + branch_to_test = &&exception_return; + + /* Since this is a memory space access test. + * Enable BME & MSE for all the BDFs. + */ + while (tbl_index < bdf_tbl_ptr->num_entries) + { + bdf = bdf_tbl_ptr->device[tbl_index++].bdf; + /* Enable Bus Master Enable */ + val_pcie_enable_bme(bdf); + /* Enable Memory Space Access */ + val_pcie_enable_msa(bdf); + } + + tbl_index = 0; + while (tbl_index < bdf_tbl_ptr->num_entries) + { + bdf = bdf_tbl_ptr->device[tbl_index++].bdf; + dp_type = val_pcie_device_port_type(bdf); + + if ((dp_type == RP) || (dp_type == iEP_RP)) { + /* Part 1: + * Check When Address is within the Range of Non-Prefetchable + * Memory Range. + */ + /* Clearing UR in Device Status Register */ + val_pcie_clear_urd(bdf); + + /* Read Function's NP Memory Base Limit Register */ + val_pcie_read_cfg(bdf, TYPE1_NP_MEM, &read_value); + if (read_value == 0) + continue; + + mem_base = (read_value & MEM_BA_MASK) << MEM_BA_SHIFT; + mem_lim = (read_value & MEM_LIM_MASK) | MEM_LIM_LOWER_BITS; + + /* If Memory Limit is programmed with value less the Base, then Skip.*/ + if (mem_lim < mem_base) + continue; + + /* If test runs for atleast an endpoint */ + test_skip = 0; + + /* Write known value to an address which is in range + * Base + 0x10 will always be in the range. + * Read the same + */ + old_value = (*(volatile uint32_t *)(mem_base + MEM_OFFSET_10)); + *(volatile uint32_t *)(mem_base + MEM_OFFSET_10) = KNOWN_DATA; + read_value = (*(volatile uint32_t *)(mem_base + MEM_OFFSET_10)); + +exception_return: + /* Memory Space might have constraint on RW/RO behaviour + * So not checking for Read-Write Data mismatch. + */ + if (IS_TEST_FAIL(val_get_status(pe_index))) { + val_print(ACS_PRINT_ERR, + "\n Failed. Exception on Memory Access For Bdf : 0x%x", bdf); + val_pcie_clear_urd(bdf); + return; + } + + if (val_pcie_is_urd(bdf) || + (old_value != read_value && read_value == PCIE_UNKNOWN_RESPONSE)) { + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 02)); + val_pcie_clear_urd(bdf); + return; + } + } + } + + if (test_skip == 1) + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + else + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); +} + +uint32_t +os_p004_entry(uint32_t num_pe) +{ + + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/pcie/operating_system/test_os_p005.c b/test_pool/pcie/operating_system/test_os_p005.c index 5d223aff..ba299d4f 100644 --- a/test_pool/pcie/operating_system/test_os_p005.c +++ b/test_pool/pcie/operating_system/test_os_p005.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2018, 2020-2021 Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2020-2021, Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,155 +14,73 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ + #include "val/include/bsa_acs_val.h" #include "val/include/val_interface.h" #include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pe.h" #include "val/include/bsa_acs_memory.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 5) -#define TEST_DESC "PCI_MM_01,02,03, RE_BAR_2: PCIe Unaligned access " - -#define DATA 0xC0DECAFE +#define TEST_RULE "RE_SMU_2" +#define TEST_DESC "Check ATS Support Rule " static void payload(void) { - uint32_t count = 0; - uint32_t data; + uint32_t bdf; - uint32_t bar_reg_value; - uint64_t bar_upper_bits; - uint32_t bar_value; - uint32_t bar_value_1; - uint64_t bar_size; - char *baseptr; - uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); - uint32_t test_skip = 1; - uint32_t test_fail = 0; - uint64_t offset; - uint64_t base; - - count = val_peripheral_get_info(NUM_SATA, 0); - - while (count--) { -next_bdf: - bdf = val_peripheral_get_info(SATA_BDF, count); - offset = BAR0_OFFSET; - - while (offset <= BAR_MAX_OFFSET) { - val_pcie_read_cfg(bdf, offset, &bar_value); - val_print(ACS_PRINT_DEBUG, "\n The BAR value of bdf %x", bdf); - val_print(ACS_PRINT_DEBUG, " is %x ", bar_value); - base = 0; - - if (bar_value == 0) - { - /** This BAR is not implemented **/ - count--; - goto next_bdf; - } - - /* Skip for IO address space */ - if (bar_value & 0x1) { - count--; - goto next_bdf; - } - - if (BAR_REG(bar_value) == BAR_64_BIT) - { - val_print(ACS_PRINT_INFO, "BAR supports 64-bit address decoding capability \n", 0); - val_pcie_read_cfg(bdf, offset+4, &bar_value_1); - base = bar_value_1; - - /* BAR supports 64-bit address therefore, write all 1's - * to BARn and BARn+1 and identify the size requested - */ - val_pcie_write_cfg(bdf, offset, 0xFFFFFFF0); - val_pcie_write_cfg(bdf, offset + 4, 0xFFFFFFFF); - val_pcie_read_cfg(bdf, offset, &bar_reg_value); - bar_size = bar_reg_value & 0xFFFFFFF0; - val_pcie_read_cfg(bdf, offset + 4, &bar_reg_value); - bar_upper_bits = bar_reg_value; - bar_size = bar_size | (bar_upper_bits << 32); - bar_size = ~bar_size + 1; - - /* Restore the original BAR value */ - val_pcie_write_cfg(bdf, offset + 4, bar_value_1); - val_pcie_write_cfg(bdf, offset, bar_value); - base = (base << 32) | bar_value; - } - - else { - val_print(ACS_PRINT_INFO, "The BAR supports 32-bit address decoding capability\n", 0); - - /* BAR supports 32-bit address. Write all 1's - * to BARn and identify the size requested - */ - val_pcie_write_cfg(bdf, offset, 0xFFFFFFF0); - val_pcie_read_cfg(bdf, offset, &bar_reg_value); - bar_reg_value = bar_reg_value & 0xFFFFFFF0; - bar_size = ~bar_reg_value + 1; - - /* Restore the original BAR value */ - val_pcie_write_cfg(bdf, offset, bar_value); - base = bar_value; - } - - val_print(ACS_PRINT_DEBUG, "\n BAR size is %x", bar_size); - - /* Check if bar supports the remap size */ - if (bar_size < 1024) { - val_print(ACS_PRINT_ERR, "Bar size less than remap requested size", 0); - goto next_bar; - } - - test_skip = 0; - - /* Map SATA Controller BARs to a NORMAL memory attribute. check unaligned access */ - baseptr = (char *)val_memory_ioremap((void *)base, 1024, NORMAL_NC); - - /* Check for unaligned access */ - *(uint32_t *)(baseptr) = DATA; - data = *(char *)(baseptr+3); - - val_memory_unmap(baseptr); - - if (data != (DATA >> 24)) { - val_print(ACS_PRINT_ERR, "Unaligned data mismatch", 0); - test_fail++; - } - - /* Map SATA Controller BARs to a DEVICE memory attribute and check transaction */ - baseptr = (char *)val_memory_ioremap((void *)base, 1024, DEVICE_nGnRnE); - - *(uint32_t *)(baseptr) = DATA; - data = *(uint32_t *)(baseptr); - - val_memory_unmap(baseptr); - - if (data != DATA) { - val_print(ACS_PRINT_ERR, "Data value mismatch", 0); - test_fail++; - } - -next_bar: - if (BAR_REG(bar_reg_value) == BAR_32_BIT) - offset = offset + 4; - - if (BAR_REG(bar_reg_value) == BAR_64_BIT) - offset = offset + 8; + uint32_t pe_index; + uint32_t tbl_index; + uint32_t dp_type; + uint32_t cap_base; + uint32_t test_skip; + uint32_t test_fails; + pcie_device_bdf_table *bdf_tbl_ptr; + + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + + test_fails = 0; + test_skip = 1; + + /* Check for all the function present in bdf table */ + for (tbl_index = 0; tbl_index < bdf_tbl_ptr->num_entries; tbl_index++) + { + bdf = bdf_tbl_ptr->device[tbl_index].bdf; + dp_type = val_pcie_device_port_type(bdf); + + /* Skip this Check for Host Bridge */ + if (val_pcie_is_host_bridge(bdf)) + continue; + + /* Check entry is rciep */ + if (dp_type == RCiEP) + { + /* Check if Address Translation Cache is Present in this device. */ + /* If ATC Not present, skip the test.*/ + if (!val_pcie_is_cache_present(bdf)) + continue; + + test_skip = 0; + + /* If ATC Present, Check ATS Capability should be present. */ + if (val_pcie_find_capability(bdf, PCIE_ECAP, ECID_ATS, &cap_base) != PCIE_SUCCESS) + { + val_print(ACS_PRINT_ERR, "\n ATS Capability Not Present, Bdf : 0x%x", bdf); + test_fails++; + } } } if (test_skip) - val_set_status(index, RESULT_SKIP(TEST_NUM, 0)); - else if (test_fail) - val_set_status(index, RESULT_FAIL(TEST_NUM, test_fail)); + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + else if (test_fails) + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, test_fails)); else - val_set_status(index, RESULT_PASS(TEST_NUM, 0)); - + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); } uint32_t @@ -178,9 +96,9 @@ os_p005_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p006.c b/test_pool/pcie/operating_system/test_os_p006.c index 54de7e7f..79cb736a 100644 --- a/test_pool/pcie/operating_system/test_os_p006.c +++ b/test_pool/pcie/operating_system/test_os_p006.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2018,2021 Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2016-2018, 2021, Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,84 +17,101 @@ #include "val/include/bsa_acs_val.h" #include "val/include/val_interface.h" -#include "val/include/bsa_acs_dma.h" -#include "val/include/bsa_acs_smmu.h" +#include "val/include/bsa_acs_pe.h" +#include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_gic.h" +#include "val/include/bsa_acs_memory.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 6) -#define TEST_DESC "PCI_MM_05, PCI_MM_06: No extra addr trans " +#define TEST_RULE "PCI_LI_01, PCI_LI_03" +#define TEST_DESC "Legacy int must be SPI & lvl-sensitive" - -/* For all DMA masters populated in the Info table, which are behind an SMMU, - verify there are no additional translations before address is given to SMMU */ static void payload(void) { - - uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); - uint32_t target_dev_index; - addr_t dma_addr = 0; - uint32_t dma_len = 0; - void *buffer; uint32_t status; - uint32_t iommu_flag = 0; - - target_dev_index = val_dma_get_info(DMA_NUM_CTRL, 0); - - if (!target_dev_index) { - val_print(ACS_PRINT_TEST, "\n No DMA controllers detected... ", 0); - val_set_status(index, RESULT_SKIP(TEST_NUM, 02)); - return; + uint32_t bdf; + uint32_t pe_index; + uint32_t tbl_index; + uint32_t reg_value; + uint32_t test_skip = 1; + uint32_t intr_pin, intr_line; + PERIPHERAL_IRQ_MAP *intr_map; + pcie_device_bdf_table *bdf_tbl_ptr; + INTR_TRIGGER_INFO_TYPE_e trigger_type; + + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + + /* Allocate memory for interrupt mappings */ + intr_map = val_memory_alloc(sizeof(PERIPHERAL_IRQ_MAP)); + if (!intr_map) { + val_print (ACS_PRINT_ERR, "\n Memory allocation error", 0); + val_set_status(pe_index, RESULT_FAIL (TEST_NUM, 01)); + return; } - while (target_dev_index) + tbl_index = 0; + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + + while (tbl_index < bdf_tbl_ptr->num_entries) { - target_dev_index--; //index is zero based - - /* Check there were no additional translations between Device and SMMU */ - if (val_dma_get_info(DMA_HOST_IOMMU_ATTACHED, target_dev_index)) { - iommu_flag++; - val_dma_device_get_dma_addr(target_dev_index, &dma_addr, &dma_len); - status = val_smmu_ops(SMMU_CHECK_DEVICE_IOVA, 0, &target_dev_index, &dma_addr); - if (status) { - val_print(ACS_PRINT_ERR, "\n The DMA address %lx used by device ", dma_addr); - val_print(ACS_PRINT_ERR, "\n is not present in the SMMU IOVA table \n", 0); - val_set_status(index, RESULT_FAIL(TEST_NUM, target_dev_index)); - return; - } + bdf = bdf_tbl_ptr->device[tbl_index++].bdf; + + /* Read Interrupt Line Register */ + val_pcie_read_cfg(bdf, TYPE01_ILR, ®_value); + + intr_pin = (reg_value >> TYPE01_IPR_SHIFT) & TYPE01_IPR_MASK; + if ((intr_pin == 0) || (intr_pin > 0x4)) + continue; + + status = val_pci_get_legacy_irq_map(bdf, intr_map); + if (status) { + // Skip the test if the Legacy IRQ map does not exist + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 02)); + return; } - } - target_dev_index = val_dma_get_info(DMA_NUM_CTRL, 0); + /* If test runs for atleast an endpoint */ + test_skip = 0; - /* Check if IOMMU ops is properly integrated for this device by making the standard OS - DMA API call and verifying the DMA address is part of the IOVA translation table */ - while (target_dev_index) - { - target_dev_index--; - if (val_dma_get_info(DMA_HOST_IOMMU_ATTACHED, target_dev_index)) { - /* Allocate DMA-able memory region in DDR */ - dma_addr = val_dma_mem_alloc(&buffer, 512, target_dev_index, DMA_COHERENT); - status = val_smmu_ops(SMMU_CHECK_DEVICE_IOVA, 0, &target_dev_index, &dma_addr); - if (status) { - val_print(ACS_PRINT_ERR, "\n The DMA addr allocated to device %d ", target_dev_index); - val_print(ACS_PRINT_ERR, "\n is not present in the SMMU IOVA table \n", 0); - val_set_status(index, RESULT_FAIL(TEST_NUM, target_dev_index)); - return; - } - /* Free the allocated memory here */ - val_dma_mem_free(buffer, dma_addr, 512, target_dev_index, DMA_COHERENT); + intr_line = intr_map->legacy_irq_map[intr_pin-1].irq_list[0]; + + /* Check if the int falls in SPI range */ + if ((intr_line >= 32 && intr_line <= 1019) || + (val_gic_espi_supported() && (intr_line >= 4096 && + intr_line <= val_gic_max_espi_val()))) { + val_print(ACS_PRINT_INFO, "\n Int is SPI", 0); + } + else { + val_print(ACS_PRINT_ERR, "\n Int id %d is not SPI", intr_line); + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 03)); + return; + } + + /* Read GICD_ICFGR/ICFGR-E register to Check for Level/Edge Sensitive. */ + if (intr_line >= 32 && intr_line <= 1019) + status = val_gic_get_intr_trigger_type(intr_line, &trigger_type); + else + status = val_gic_get_espi_intr_trigger_type(intr_line, &trigger_type); + + if (status) { + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 04)); + return; + } + + if (trigger_type != INTR_TRIGGER_INFO_LEVEL_HIGH) { + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 05)); + return; } } - if (iommu_flag) - val_set_status(index, RESULT_PASS(TEST_NUM, 02)); + if (test_skip == 1) + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); else - val_set_status(index, RESULT_SKIP(TEST_NUM, 02)); - + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); } - uint32_t os_p006_entry(uint32_t num_pe) { @@ -108,9 +125,9 @@ os_p006_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p008.c b/test_pool/pcie/operating_system/test_os_p008.c new file mode 100644 index 00000000..45f63c77 --- /dev/null +++ b/test_pool/pcie/operating_system/test_os_p008.c @@ -0,0 +1,153 @@ +/** @file + * Copyright (c) 2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pe.h" +#include "val/include/bsa_acs_memory.h" + +#define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 8) +#define TEST_RULE "PCI_IN_16" +#define TEST_DESC "Check all 1's for out of range " + +/* Returns the maximum bdf value for that segment from bdf table */ +static uint32_t get_max_bdf(uint32_t segment, uint32_t end_bus) +{ + pcie_device_bdf_table *bdf_tbl_ptr; + uint32_t seg_num; + uint32_t bus_num; + uint32_t bdf; + uint32_t tbl_index = 0; + uint32_t max_bdf = 0; + + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + for (tbl_index = 0; tbl_index < bdf_tbl_ptr->num_entries; tbl_index++) + { + bdf = bdf_tbl_ptr->device[tbl_index].bdf; + seg_num = PCIE_EXTRACT_BDF_SEG(bdf); + bus_num = PCIE_EXTRACT_BDF_BUS(bdf); + + if ((segment == seg_num) && (bus_num <= end_bus)) + max_bdf = bdf; + } + + return max_bdf; +} + +static +void +payload(void) +{ + + uint32_t reg_value; + uint32_t pe_index; + uint32_t ecam_index; + uint32_t num_ecam; + uint32_t end_bus; + uint32_t cfg_addr; + uint32_t bus_index; + uint32_t dev_index; + uint32_t func_index; + uint32_t bdf; + uint32_t segment = 0; + addr_t ecam_base = 0; + + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + num_ecam = val_pcie_get_info(PCIE_INFO_NUM_ECAM, 0); + + for (ecam_index = 0; ecam_index < num_ecam; ecam_index++) + { + /* Get the maximum bus value from PCIe info table */ + end_bus = val_pcie_get_info(PCIE_INFO_END_BUS, ecam_index); + segment = val_pcie_get_info(PCIE_INFO_SEGMENT, ecam_index); + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + + /* Get the highest BDF value for that segment */ + bdf = get_max_bdf(segment, end_bus); + + /* Get the least highest of max bus number */ + bus_index = (PCIE_EXTRACT_BDF_BUS(bdf) < end_bus) ? PCIE_EXTRACT_BDF_BUS(bdf):end_bus; + val_print(ACS_PRINT_INFO, "Maximum bus value is 0x%x", bus_index); + bus_index += 1; + + /* Bus value should not exceed 255 */ + if (bus_index > end_bus) { + val_print(ACS_PRINT_ERR, "\n Bus index exceeded END_BUS Number", 0); + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 02)); + return; + } + + for (dev_index = 0; dev_index < PCIE_MAX_DEV; dev_index++) + { + for (func_index = 0; func_index < PCIE_MAX_FUNC; func_index++) + { + /* Form bdf using seg, bus, device, function numbers. + * This BDF does not fall into the secondary and subordinate + * bus of any of the rootports because the bus value is one + * greater than the higest bus value. This BDF also doesn't + * match any of the existing BDF. + */ + bdf = PCIE_CREATE_BDF(segment, bus_index, dev_index, func_index); + ecam_base = val_pcie_get_info(PCIE_INFO_ECAM, ecam_index); + + if (ecam_base == 0) { + val_print(ACS_PRINT_ERR, "\n ECAM Base is zero ", 0); + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 01)); + return; + } + + /* There are 8 functions / device, 32 devices / Bus and each has a 4KB config space */ + cfg_addr = (bus_index * PCIE_MAX_DEV * PCIE_MAX_FUNC * 4096) + \ + (dev_index * PCIE_MAX_FUNC * 4096) + (func_index * 4096); + + val_print(ACS_PRINT_INFO, "\n Calculated config address is %lx", + ecam_base + cfg_addr + TYPE01_VIDR); + reg_value = pal_mmio_read(ecam_base + cfg_addr + TYPE01_VIDR); + if (reg_value != PCIE_UNKNOWN_RESPONSE) + { + val_print(ACS_PRINT_ERR, "\n Failed for BDF: 0x%x", bdf); + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 02)); + return; + } + + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); + } + } + } +} + +uint32_t +os_p008_entry(uint32_t num_pe) +{ + + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from single PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/pcie/operating_system/test_os_p009.c b/test_pool/pcie/operating_system/test_os_p009.c new file mode 100644 index 00000000..c829ea0f --- /dev/null +++ b/test_pool/pcie/operating_system/test_os_p009.c @@ -0,0 +1,137 @@ +/** @file + * Copyright (c) 2016-2018, 2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_pcie.h" + +#define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 9) +#define TEST_RULE "PCI_IN_20" +#define TEST_DESC "Vendor specfic data are PCIe compliant" + +// Valid PCIe CapID ranges (PCIe 5.0 - v1.0) +#define PCIE_CAP_ID_END 0x15 +#define PCIE_ECAP_ID_END 0x29 + +/* + Check if vendor specific data are presented as non-PCIe compliant capabilities + in either the regular or extended PCIe spaces + returns: 0 - No violations present 1 - One or more violations present + */ +static +uint32_t +check_pcie_cfg_space(uint32_t bdf) +{ + uint32_t reg_value; + uint32_t next_cap; + uint32_t err = 0; + uint32_t cid; + + // Search through regular PCIe cfg space first (start at first implemented cap) + val_pcie_read_cfg(bdf, TYPE01_CPR, ®_value); + // DWORD aligned: next_cap[1:0] are hardwired to '0' + next_cap = VAL_EXTRACT_BITS(reg_value, 2, 7) << 2; + + while (next_cap) { + + val_pcie_read_cfg(bdf, next_cap, ®_value); + next_cap = VAL_EXTRACT_BITS(reg_value, 7, 15); + cid = VAL_EXTRACT_BITS(reg_value, 0, 7); + + // Check PCIe Cap IDs are in range + if (cid > PCIE_CAP_ID_END) { + val_print(ACS_PRINT_ERR, + "\n Invalid Cap ID: 0x%x found in regular cfg space", cid); + err = 1; + } + } + + // Search through extended PCIe cfg space next + next_cap = PCIE_ECAP_START; + + while (next_cap) { + + val_pcie_read_cfg(bdf, next_cap, ®_value); + next_cap = VAL_EXTRACT_BITS(reg_value, 20, 31); + cid = VAL_EXTRACT_BITS(reg_value, 0, 15); + + // Check PCIe Ext Cap IDs are in range + if (cid > PCIE_ECAP_ID_END) { + val_print(ACS_PRINT_ERR, + "\n Invalid Cap ID: 0x%x found in extended cfg space", cid); + err = 1; + } + } + + return err; +} + +static +void +payload(void) +{ + uint32_t pe_index; + uint32_t tbl_index; + uint32_t bdf; + uint32_t dp_type; + pcie_device_bdf_table *bdf_tbl_ptr; + + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + + tbl_index = 0; + + while (tbl_index < bdf_tbl_ptr->num_entries) { + + bdf = bdf_tbl_ptr->device[tbl_index++].bdf; + dp_type = val_pcie_device_port_type(bdf); + + // Only check for Root Ports + if (dp_type == RP) { + if (check_pcie_cfg_space(bdf)) { + val_print(ACS_PRINT_ERR, + "\n Invalid PCIe capability found on dev: %d", tbl_index); + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 02)); + return; + } + } + } + + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); + return; + +} + +uint32_t +os_p009_entry(uint32_t num_pe) +{ + + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/pcie/operating_system/test_os_p010.c b/test_pool/pcie/operating_system/test_os_p010.c new file mode 100644 index 00000000..090b9974 --- /dev/null +++ b/test_pool/pcie/operating_system/test_os_p010.c @@ -0,0 +1,166 @@ +/** @file + * Copyright (c) 2021 Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pe.h" + +#define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 10) +#define TEST_RULE "RE_BAR_1" +#define TEST_DESC "Read and write to RCiEP BAR reg " + +#define TEST_DATA_1 0xDEADDAED +#define TEST_DATA_2 0xABABABAB + +static +void +payload(void) +{ + uint32_t bdf, offset; + uint32_t bar_value; + uint32_t bar_value_1; + uint32_t bar_reg_value; + uint32_t base_lower; + uint32_t base_upper; + uint32_t dp_type; + uint32_t pe_index; + uint32_t tbl_index; + uint32_t fail_cnt; + uint32_t test_skip = 1; + pcie_device_bdf_table *bdf_tbl_ptr; + uint64_t bar_orig; + uint64_t bar_new; + uint64_t bar_upper_bits; + + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + + fail_cnt = 0; + tbl_index = 0; + + while (tbl_index < bdf_tbl_ptr->num_entries) + { + bdf = bdf_tbl_ptr->device[tbl_index++].bdf; + dp_type = val_pcie_device_port_type(bdf); + if (dp_type == RCiEP) { + /* If test runs for atleast an endpoint */ + test_skip = 0; + offset = BAR0_OFFSET; + + while (offset <= TYPE1_BAR_MAX_OFFSET) { + val_pcie_read_cfg(bdf, offset, &bar_value); + val_print(ACS_PRINT_DEBUG, "\n The BAR value of bdf %x", + bdf); + val_print(ACS_PRINT_DEBUG, " is %x ", bar_value); + bar_orig = 0; + bar_new = 0; + + if (bar_value == 0) + { + /** This BAR is not implemented **/ + offset = offset + 4; + continue; + } + + if (BAR_REG(bar_value) == BAR_64_BIT) + { + val_print(ACS_PRINT_INFO, "The BAR supports 64-bit address capability \n", 0); + val_pcie_read_cfg(bdf, offset+4, &bar_value_1); + base_upper = bar_value_1; + + /* BAR supports 64-bit address therefore, write all 1's + * to BARn and BARn+1 and identify the size requested + */ + val_pcie_read_cfg(bdf, offset, &bar_reg_value); + bar_value = bar_reg_value; + base_lower = bar_reg_value; + val_pcie_read_cfg(bdf, offset + 4, &bar_reg_value); + bar_upper_bits = bar_reg_value; + base_upper = bar_reg_value; + bar_orig = (bar_upper_bits << 32) | bar_value; + val_pcie_write_cfg(bdf, offset, TEST_DATA_1); + val_pcie_write_cfg(bdf, offset + 4, TEST_DATA_2); + val_pcie_read_cfg(bdf, offset, &bar_reg_value); + bar_value = bar_reg_value; + val_pcie_read_cfg(bdf, offset + 4, &bar_reg_value); + bar_upper_bits = bar_reg_value; + bar_new = (bar_upper_bits << 32) | bar_value; + if (bar_orig == bar_new) { + val_print(ACS_PRINT_TEST, "Read write to BAR reg not supported bdf %x\n", bdf); + fail_cnt++; + } + + /* Restore the original BAR value */ + val_pcie_write_cfg(bdf, offset + 4, base_upper); + val_pcie_write_cfg(bdf, offset, base_lower); + offset = offset+8; + } + + else { + val_print(ACS_PRINT_INFO, "The BAR supports 32-bit address capability\n", 0); + + /* BAR supports 32-bit address. Write all 1's + * to BARn and identify the size requested + */ + val_pcie_read_cfg(bdf, offset, &bar_reg_value); + bar_orig = bar_reg_value; + base_lower = bar_reg_value; + val_pcie_write_cfg(bdf, offset, TEST_DATA_1); + val_pcie_read_cfg(bdf, offset, &bar_reg_value); + bar_new = bar_reg_value; + if (bar_orig == bar_new) { + val_print(ACS_PRINT_TEST, "Read write to BAR reg not supported bdf %x\n", bdf); + fail_cnt++; + } + + /* Restore the original BAR value */ + val_pcie_write_cfg(bdf, offset, base_lower); + offset = offset+4; + } + } + } + + + if (test_skip == 1) + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + else if (fail_cnt) + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, fail_cnt)); + else + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); + } +} + +uint32_t +os_p010_entry(uint32_t num_pe) +{ + + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from the PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/pcie/operating_system/test_os_p011.c b/test_pool/pcie/operating_system/test_os_p011.c index 69b43eec..829fea92 100644 --- a/test_pool/pcie/operating_system/test_os_p011.c +++ b/test_pool/pcie/operating_system/test_os_p011.c @@ -1,7 +1,6 @@ /** @file - * Copyright (c) 2016-2018,2021 Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2020-2021 Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 - * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -18,41 +17,135 @@ #include "val/include/bsa_acs_val.h" #include "val/include/val_interface.h" -#include "val/include/bsa_acs_iovirt.h" +#include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 11) -#define TEST_DESC "PCI_IC_02: PCIe RC, PE - Same Inn SH Dom. " - -#define INNER_SHAREABLE 1 +#define TEST_RULE "PCI_IN_18" +#define TEST_DESC "Check RP Byte Enable Rules " -static void +static +void payload(void) { - uint32_t num_pcie_rc; - uint32_t mem_attr; - uint32_t index = val_pe_get_index_mpid (val_pe_get_mpid()); - - num_pcie_rc = val_iovirt_get_pcie_rc_info(NUM_PCIE_RC, 0); - - if (!num_pcie_rc) { - val_print(ACS_PRINT_WARN, "\n Skip because no PCIe RC detected ", 0); - val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); - return; - } - while (num_pcie_rc) { - num_pcie_rc--; // Index is one lesser than the component number being accessed - mem_attr = val_iovirt_get_pcie_rc_info(RC_MEM_ATTRIBUTE, num_pcie_rc); + int8_t i; + uint32_t bdf; + uint32_t dp_type; + uint32_t pe_index; + uint32_t tbl_index; + uint32_t test_skip = 1; + uint32_t ecam_cr, ecam_cr_8, ecam_cr_16, ecam_cr_new; + uint32_t write_value = 0; + uint32_t command_reg_offset; + addr_t ecam_base; + pcie_device_bdf_table *bdf_tbl_ptr; + + tbl_index = 0; + ecam_cr = 0; + ecam_cr_8 = 0; + ecam_cr_16 = 0; + ecam_cr_new = 0; + + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + + while (tbl_index < bdf_tbl_ptr->num_entries) + { + bdf = bdf_tbl_ptr->device[tbl_index++].bdf; + dp_type = val_pcie_device_port_type(bdf); + + if ((dp_type == RP) || (dp_type == iEP_RP)) { + + /* If test runs for atleast an endpoint */ + test_skip = 0; + + ecam_base = val_pcie_get_ecam_base(bdf); + command_reg_offset = PCIE_EXTRACT_BDF_BUS(bdf) * + PCIE_MAX_DEV * PCIE_MAX_FUNC * PCIE_CFG_SIZE + + PCIE_EXTRACT_BDF_DEV(bdf) * PCIE_MAX_FUNC * PCIE_CFG_SIZE + + PCIE_EXTRACT_BDF_FUNC(bdf) * PCIE_CFG_SIZE + + TYPE01_CR; + + /* Read Command Register of RP with 8 Bit, 16 Bit, 32 Bit and compare it */ + ecam_cr = val_mmio_read(ecam_base + command_reg_offset); + for (i = 3; i >= 0; i--) { + ecam_cr_8 = ecam_cr_8 << 8; + ecam_cr_8 |= val_mmio_read8(ecam_base + command_reg_offset + i); + } + for (i = 1; i >= 0; i--) { + ecam_cr_16 = ecam_cr_16 << 16; + ecam_cr_16 |= val_mmio_read16(ecam_base + command_reg_offset + i*2); + } + + if ((ecam_cr != ecam_cr_8) || (ecam_cr_8 != ecam_cr_16)) + { + val_print(ACS_PRINT_ERR, "\n Byte Enable Read Failed", 0); + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 01)); + return; + } + + /* Check Read-Write-Read Behaviour for each 8 Bit */ + ecam_cr = val_mmio_read8(ecam_base + command_reg_offset); + + /* Change BME & MSE Bit Value */ + write_value = ecam_cr ^ ((1 << CR_MSE_SHIFT) | (1 << CR_BME_SHIFT)); + val_mmio_write8(ecam_base + command_reg_offset, write_value); + + ecam_cr_new = val_mmio_read8(ecam_base + command_reg_offset); + if (write_value != ecam_cr_new) + { + val_print(ACS_PRINT_ERR, "\n 8 Bit Write Failed", 0); + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 02)); + return; + } + + /* Restore the value */ + val_mmio_write8(ecam_base + command_reg_offset, ecam_cr); + + /* Check Read-Write-Read Behaviour for each 16 Bit */ + ecam_cr = val_mmio_read16(ecam_base + command_reg_offset); + + /* Change BME & MSE Bit Value */ + write_value = ecam_cr ^ ((1 << CR_MSE_SHIFT) | (1 << CR_BME_SHIFT)); + val_mmio_write16(ecam_base + command_reg_offset, write_value); + + ecam_cr_new = val_mmio_read16(ecam_base + command_reg_offset); + if (write_value != ecam_cr_new) + { + val_print(ACS_PRINT_ERR, "\n 16 Bit Write Failed", 0); + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 03)); + return; + } + + /* Restore the value */ + val_mmio_write16(ecam_base + command_reg_offset, ecam_cr); + + /* Check Read-Write-Read Behaviour for 32 Bit */ + ecam_cr = val_mmio_read(ecam_base + command_reg_offset); + + /* Change BME & MSE Bit Value */ + write_value = ecam_cr ^ ((1 << CR_MSE_SHIFT) | (1 << CR_BME_SHIFT)); + val_mmio_write(ecam_base + command_reg_offset, write_value); + + ecam_cr_new = val_mmio_read(ecam_base + command_reg_offset); + if (write_value != ecam_cr_new) + { + val_print(ACS_PRINT_ERR, "\n 32 Bit Write Failed", 0); + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 04)); + return; + } + + /* Restore the value */ + val_mmio_write(ecam_base + command_reg_offset, ecam_cr); - if (mem_attr == INNER_SHAREABLE) - val_set_status(index, RESULT_PASS(TEST_NUM, 01)); - else { - val_print(ACS_PRINT_ERR, "\n Failed mem attribute check for PCIe RC %d", num_pcie_rc); - val_set_status(index, RESULT_FAIL(TEST_NUM, 01)); - return; } } + if (test_skip == 1) + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + else + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); } uint32_t @@ -68,9 +161,9 @@ os_p011_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p012.c b/test_pool/pcie/operating_system/test_os_p012.c index 9bc102ba..247313b6 100644 --- a/test_pool/pcie/operating_system/test_os_p012.c +++ b/test_pool/pcie/operating_system/test_os_p012.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2018,2021 Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2020-2021, Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,155 +14,79 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ + #include "val/include/bsa_acs_val.h" #include "val/include/val_interface.h" -#include "val/include/bsa_acs_memory.h" #include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pe.h" +#include "val/include/bsa_acs_memory.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 12) -#define TEST_DESC "PCI_LI_01: PCI legacy intr SPI ID unique " - -static inline char pin_name(int pin) -{ - return 'A' + pin; -} +#define TEST_RULE "RE_PWR_1" +#define TEST_DESC "Check Power Management rules " static void -payload (void) +payload(void) { - uint32_t index; - uint32_t count; - PERIPHERAL_IRQ_MAP *irq_map; - uint8_t status; - uint32_t current_irq_pin; - uint32_t next_irq_pin; - uint64_t dev_bdf; - uint32_t ccnt; - uint32_t ncnt; - uint32_t test_skip; - - current_irq_pin = 0; - status = 0; - test_skip = 1; - next_irq_pin = current_irq_pin + 1; - index = val_pe_get_index_mpid (val_pe_get_mpid()); - count = val_peripheral_get_info (NUM_ALL, 0); - - if (!count) { - val_set_status (index, RESULT_SKIP (TEST_NUM, 01)); - return; - } - - irq_map = val_memory_alloc(sizeof(PERIPHERAL_IRQ_MAP)); - if (!irq_map) { - val_print (ACS_PRINT_ERR, "\n Memory allocation error", 0); - val_set_status (index, RESULT_FAIL (TEST_NUM, 01)); - return; - } - - /* get legacy IRQ info from PCI devices */ - while (count > 0 && status == 0) { - count--; - if (val_peripheral_get_info (ANY_GSIV, count)) { - dev_bdf = val_peripheral_get_info (ANY_BDF, count); - status = val_pci_get_legacy_irq_map (dev_bdf, irq_map); - - switch (status) { - case 0: - break; - case 1: - val_print (ACS_PRINT_WARN, "\n Unable to access PCI bridge device", 0); - break; - case 2: - val_print (ACS_PRINT_WARN, "\n Unable to fetch _PRT ACPI handle", 0); - /* Not a fatal error, just skip this device */ - status = 0; - continue; - case 3: - val_print (ACS_PRINT_WARN, "\n Unable to access _PRT ACPI object", 0); - /* Not a fatal error, just skip this device */ - status = 0; - continue; - case 4: - val_print (ACS_PRINT_WARN, "\n Interrupt hard-wire error", 0); - /* Not a fatal error, just skip this device */ - status = 0; - continue; - case 5: - val_print (ACS_PRINT_ERR, "\n Legacy interrupt out of range", 0); - break; - case 6: - val_print (ACS_PRINT_ERR, "\n Maximum number of interrupts has been reached", 0); - break; - default: - val_print (ACS_PRINT_ERR, "\n Unknown error", 0); - break; - } - } - - /* Compare IRQ routings */ - if (!status) { - while (current_irq_pin < LEGACY_PCI_IRQ_CNT && status == 0) { - while (next_irq_pin < LEGACY_PCI_IRQ_CNT && status == 0) { - - for (ccnt = 0; (ccnt < irq_map->legacy_irq_map[current_irq_pin].irq_count) - && (status == 0); ccnt++) { - for (ncnt = 0; (ncnt < irq_map->legacy_irq_map[next_irq_pin].irq_count) - && (status == 0); ncnt++) { - test_skip = 0; - if (irq_map->legacy_irq_map[current_irq_pin].irq_list[ccnt] == - irq_map->legacy_irq_map[next_irq_pin].irq_list[ncnt]) { - status = 7; - val_print (ACS_PRINT_ERR, "\n Legacy interrupt %c routing", - pin_name(current_irq_pin)); - val_print (ACS_PRINT_ERR, "\n is the same as %c routing", - pin_name(next_irq_pin)); - } - } - } - - next_irq_pin++; - } - current_irq_pin++; - next_irq_pin = current_irq_pin + 1; + uint32_t bdf; + uint32_t pe_index; + uint32_t tbl_index; + uint32_t dp_type; + uint32_t cap_base; + uint32_t test_fails; + uint32_t test_skip = 1; + pcie_device_bdf_table *bdf_tbl_ptr; + + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + + test_fails = 0; + + /* Check for all the function present in bdf table */ + for (tbl_index = 0; tbl_index < bdf_tbl_ptr->num_entries; tbl_index++) + { + bdf = bdf_tbl_ptr->device[tbl_index].bdf; + dp_type = val_pcie_device_port_type(bdf); + + /* Check entry is onchip peripherals */ + if ((dp_type == RCiEP) || (dp_type == iEP_RP)) + { + /* If test runs for atleast an endpoint */ + test_skip = 0; + + /* If Power Management capability not supported, test fails */ + if (val_pcie_find_capability(bdf, PCIE_CAP, CID_PMC, &cap_base) == PCIE_CAP_NOT_FOUND) + test_fails++; } - } } - val_memory_free (irq_map); - - - if (test_skip) { - val_set_status (index, RESULT_SKIP (TEST_NUM, 02)); - return; - } - - if (!status) { - val_set_status (index, RESULT_PASS (TEST_NUM, 01)); - } else { - val_set_status (index, RESULT_FAIL (TEST_NUM, status)); - } + if (test_skip == 1) + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + else if (test_fails) + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, test_fails)); + else + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); } uint32_t -os_p012_entry (uint32_t num_pe) +os_p012_entry(uint32_t num_pe) { + uint32_t status = ACS_STATUS_FAIL; num_pe = 1; //This test is run on single processor - status = val_initialize_test (TEST_NUM, TEST_DESC, num_pe); - if (status != ACS_STATUS_SKIP) { - val_run_test_payload (TEST_NUM, num_pe, payload, 0); - } + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error (TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status (0, BSA_ACS_END (TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p013.c b/test_pool/pcie/operating_system/test_os_p013.c new file mode 100644 index 00000000..9d04fcd3 --- /dev/null +++ b/test_pool/pcie/operating_system/test_os_p013.c @@ -0,0 +1,105 @@ +/** @file + * Copyright (c) 2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pe.h" + +#define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 13) +#define TEST_RULE "RE_PCI_2" +#define TEST_DESC "Check RCEC Class code and Ext Cap " + +static +void +payload(void) +{ + + uint32_t bdf; + uint32_t dp_type; + uint32_t pe_index; + uint32_t tbl_index; + uint32_t fail_cnt; + uint32_t test_skip = 1; + uint32_t cap_base; + pcie_device_bdf_table *bdf_tbl_ptr; + uint32_t reg_value; + + fail_cnt = 0; + tbl_index = 0; + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + + while (tbl_index < bdf_tbl_ptr->num_entries) + { + bdf = bdf_tbl_ptr->device[tbl_index++].bdf; + dp_type = val_pcie_device_port_type(bdf); + if (dp_type == RCEC) { + /* If test runs for atleast an endpoint */ + test_skip = 0; + + /* Read Function's Class Code */ + val_pcie_read_cfg(bdf, TYPE01_RIDR, ®_value); + + if ((RCEC_BASE_CLASS != ((reg_value >> CC_BASE_SHIFT) & CC_BASE_MASK)) || + (RCEC_SUB_CLASS != ((reg_value >> CC_SUB_SHIFT) & CC_SUB_MASK)) || + (RCEC_PGMING_IF != ((reg_value >> CC_PGM_IF_SHIFT) & CC_PGM_IF_MASK))) + { + val_print(ACS_PRINT_ERR, " Class code mismatch for bdf: 0x%x\n", bdf); + val_print(ACS_PRINT_ERR, " dp_type: 0x%x\n", dp_type); + val_print(ACS_PRINT_ERR, " CCR: 0x%x\n", reg_value); + fail_cnt++; + } + + /* If Root Complex Event + Collector Endpoint Association Extended Capability not supported for RCEC, test fails*/ + if (val_pcie_find_capability(bdf, PCIE_ECAP, ECID_RCECEA, &cap_base) != PCIE_SUCCESS) { + fail_cnt++; + continue; + } + + } + } + + if (test_skip == 1) + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + else if (fail_cnt) + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, fail_cnt)); + else + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); +} + +uint32_t +os_p013_entry(uint32_t num_pe) +{ + + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/pcie/operating_system/test_os_p014.c b/test_pool/pcie/operating_system/test_os_p014.c new file mode 100644 index 00000000..fafa65b1 --- /dev/null +++ b/test_pool/pcie/operating_system/test_os_p014.c @@ -0,0 +1,102 @@ +/** @file + * Copyright (c) 2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pe.h" + +#define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 14) +#define TEST_RULE "RE_PCI_1" +#define TEST_DESC "Check RCiEP Hdr type & link Cap " + +static +void +payload(void) +{ + + uint32_t bdf; + uint32_t dp_type; + uint32_t pe_index; + uint32_t tbl_index; + uint32_t fail_cnt; + uint32_t test_skip = 1; + pcie_device_bdf_table *bdf_tbl_ptr; + uint32_t hdr_type; + uint32_t link_cap_sup; + + fail_cnt = 0; + tbl_index = 0; + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + + while (tbl_index < bdf_tbl_ptr->num_entries) + { + bdf = bdf_tbl_ptr->device[tbl_index++].bdf; + dp_type = val_pcie_device_port_type(bdf); + if ((dp_type == RCiEP) || (dp_type == RCEC)) { + /* If test runs for atleast an endpoint */ + test_skip = 0; + + /* Extract Hdr Type */ + hdr_type = val_pcie_function_header_type(bdf); + /* Type should be 0 for RCiEP*/ + if (hdr_type != TYPE0_HEADER) { + val_print(ACS_PRINT_ERR, "\n Invalid HDR TYPE 0x%x", hdr_type); + val_print(ACS_PRINT_ERR, " Bdf : 0x%x", bdf); + fail_cnt++; + continue; + } + + link_cap_sup = val_pcie_link_cap_support(bdf); + if (link_cap_sup != 0) { + val_print(ACS_PRINT_ERR, "\n Invalid Link Capabilities 0x%x", link_cap_sup); + val_print(ACS_PRINT_ERR, " Bdf : 0x%x", bdf); + fail_cnt++; + } + + } + } + + if (test_skip == 1) + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + else if (fail_cnt) + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, fail_cnt)); + else + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); +} + +uint32_t +os_p014_entry(uint32_t num_pe) +{ + + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from the PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/pcie/operating_system/test_os_p015.c b/test_pool/pcie/operating_system/test_os_p015.c new file mode 100644 index 00000000..bd28c3d0 --- /dev/null +++ b/test_pool/pcie/operating_system/test_os_p015.c @@ -0,0 +1,147 @@ +/** @file + * Copyright (c) 2020-2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pe.h" +#include "val/include/bsa_acs_memory.h" + +#define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 15) +#define TEST_RULE "RE_ACS_1, RE_ACS_2" +#define TEST_DESC "Check RCiEP P2P Supp " + +static +void +payload(void) +{ + + uint32_t bdf; + uint32_t pe_index; + uint32_t tbl_index; + uint32_t dp_type; + uint32_t cap_base = 0; + uint32_t test_fails; + uint32_t test_skip = 1; + uint32_t acs_data; + uint32_t data; + uint8_t p2p_support_flag = 0; + uint32_t curr_bdf_failed = 0; + pcie_device_bdf_table *bdf_tbl_ptr; + + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + + test_fails = 0; + + /* Check for all the function present in bdf table */ + for (tbl_index = 0; tbl_index < bdf_tbl_ptr->num_entries; tbl_index++) + { + bdf = bdf_tbl_ptr->device[tbl_index].bdf; + dp_type = val_pcie_device_port_type(bdf); + + /* Check entry is RCiEP */ + if (dp_type == RCiEP) + { + /* Check if the EP Supports Multifunction */ + if (val_pcie_multifunction_support(bdf)) + continue; + + /* Check If Endpoint supports P2P with other Functions. */ + if (val_pcie_dev_p2p_support(bdf)) + continue; + + /* If test runs for atleast an endpoint */ + test_skip = 0; + + /* Read the ACS Capability */ + if (val_pcie_find_capability(bdf, PCIE_ECAP, ECID_ACS, &cap_base) != PCIE_SUCCESS) + { + val_print(ACS_PRINT_ERR, "\n ACS Capability not supported, Bdf : 0x%x", bdf); + test_fails++; + continue; + } + + /* If RCiEP supports ACS then it should have AER Capability */ + if (val_pcie_find_capability(bdf, PCIE_ECAP, ECID_AER, &cap_base) != PCIE_SUCCESS) + { + val_print(ACS_PRINT_DEBUG, "\n AER Capability not supported, Bdf : 0x%x", bdf); + curr_bdf_failed++; + } + + val_pcie_read_cfg(bdf, cap_base + ACSCR_OFFSET, &acs_data); + + /* Extract ACS p2p Request Redirect bit */ + data = VAL_EXTRACT_BITS(acs_data, 2, 2); + if (data == 0) { + val_print(ACS_PRINT_DEBUG, "\n Request Redirect P2P not supported", 0); + p2p_support_flag++; + } + /* Extract ACS p2p Completion Redirect bit */ + data = VAL_EXTRACT_BITS(acs_data, 3, 3); + if (data == 0) { + val_print(ACS_PRINT_DEBUG, "\n Completion Redirect P2P not supported", 0); + p2p_support_flag++; + } + /* Extract ACS p2p Direct Translated bit */ + data = VAL_EXTRACT_BITS(acs_data, 6, 6); + if (data == 0) { + val_print(ACS_PRINT_DEBUG, "\n Direct Translated P2P not supported", 0); + p2p_support_flag++; + } + if (p2p_support_flag > 0) { + val_print(ACS_PRINT_ERR, "\n P2P not supported for bdf: %d", bdf); + p2p_support_flag = 0; + curr_bdf_failed++; + } + + if (curr_bdf_failed > 0) { + val_print(ACS_PRINT_ERR, "\n ACS Capability Check Failed, Bdf : 0x%x", bdf); + curr_bdf_failed = 0; + test_fails++; + } + } + } + + if (test_skip == 1) + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + else if (test_fails) + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, test_fails)); + else + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); +} + +uint32_t +os_p015_entry(uint32_t num_pe) +{ + + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/pcie/operating_system/test_os_p016.c b/test_pool/pcie/operating_system/test_os_p016.c index bd163780..cf12f360 100644 --- a/test_pool/pcie/operating_system/test_os_p016.c +++ b/test_pool/pcie/operating_system/test_os_p016.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2018,2021 Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2021, Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,92 +14,84 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ + #include "val/include/bsa_acs_val.h" #include "val/include/val_interface.h" #include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pe.h" +#include "val/include/bsa_acs_memory.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 16) -#define TEST_DESC "PCI_MM_04: NP type-1 PCIe supp 32-bit only " - -#define BAR0 0x10 +#define TEST_RULE "RE_INT_1" +#define TEST_DESC "Check MSI and MSI-X support rule " static void payload(void) { - uint32_t index; - uint32_t count; - uint32_t status = 0; - uint32_t ret; - uint32_t bar_data; - uint32_t data; - uint32_t dev_type; - uint64_t dev_bdf; - - index = val_pe_get_index_mpid(val_pe_get_mpid()); - - count = val_peripheral_get_info (NUM_ALL, 0); - if (!count) { - val_set_status(index, RESULT_SKIP (TEST_NUM, 3)); - return; - } - - while (count > 0) { - count--; - dev_bdf = val_peripheral_get_info (ANY_BDF, count); - - dev_type = val_pcie_get_device_type(dev_bdf); - /* Allow only type-1 headers and skip others */ - if (dev_type != 3) - continue; - ret = val_pcie_read_cfg(dev_bdf, BAR0, &bar_data); - if (bar_data) { - /* Extract pref type */ - data = VAL_EXTRACT_BITS(bar_data, 3, 3); - if (data == 0) { - status = 1; - /* Extract mem type */ - data = VAL_EXTRACT_BITS(bar_data, 1, 2); - if (data != 0) { - val_print(ACS_PRINT_ERR, "\n NP type-1 pcie is not 32-bit mem type", 0); - val_set_status(index, RESULT_FAIL(TEST_NUM, 01)); - status = 2; - break; - } - /* Scan the all PCIe bridge devices and check memory type */ - ret = val_pcie_scan_bridge_devices_and_check_memtype(dev_bdf); - if (ret) { - val_print(ACS_PRINT_ERR, "\n NP type-1 pcie bridge end device" - "is not 32-bit mem type", 0); - val_set_status(index, RESULT_FAIL(TEST_NUM, 01)); - status = 2; - break; - } - } - } - } - - if (!status) - val_set_status(index, RESULT_SKIP (TEST_NUM, 3)); - else if (status == 1) - val_set_status(index, RESULT_PASS(TEST_NUM, 01)); + + uint32_t bdf; + uint32_t pe_index; + uint32_t tbl_index; + uint32_t dp_type; + uint32_t cap_base; + uint32_t test_fails; + uint32_t test_skip = 1; + pcie_device_bdf_table *bdf_tbl_ptr; + + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + + test_fails = 0; + + /* Check for all the function present in bdf table */ + for (tbl_index = 0; tbl_index < bdf_tbl_ptr->num_entries; tbl_index++) + { + bdf = bdf_tbl_ptr->device[tbl_index].bdf; + dp_type = val_pcie_device_port_type(bdf); + + /* Skip this Check for Host Bridge */ + if (val_pcie_is_host_bridge(bdf)) + continue; + + /* Check entry is rciep */ + if (dp_type == RCiEP) + { + /* If test runs for atleast an endpoint */ + test_skip = 0; + + /* If MSI or MSI-X not supported, test fails */ + if ((val_pcie_find_capability(bdf, PCIE_CAP, CID_MSI, &cap_base) == PCIE_CAP_NOT_FOUND) && + (val_pcie_find_capability(bdf, PCIE_CAP, CID_MSIX, &cap_base) == PCIE_CAP_NOT_FOUND)) + test_fails++; + } + } + + if (test_skip == 1) + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + else if (test_fails) + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, test_fails)); + else + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); } uint32_t os_p016_entry(uint32_t num_pe) { - uint32_t status = ACS_STATUS_FAIL; - /* This test is run on single processor */ - num_pe = 1; - status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); - if (status != ACS_STATUS_SKIP) - val_run_test_payload(TEST_NUM, num_pe, payload, 0); + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); - return status; + return status; } diff --git a/test_pool/pcie/operating_system/test_os_p017.c b/test_pool/pcie/operating_system/test_os_p017.c new file mode 100644 index 00000000..cfeb6e4d --- /dev/null +++ b/test_pool/pcie/operating_system/test_os_p017.c @@ -0,0 +1,117 @@ +/** @file + * Copyright (c) 2020,2021 Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pe.h" +#include "val/include/bsa_acs_memory.h" + +#define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 17) +#define TEST_RULE "PCI_PP_05" +#define TEST_DESC "Check Direct Transl P2P Support " + +static +void +payload(void) +{ + + uint32_t bdf; + uint32_t pe_index; + uint32_t tbl_index; + uint32_t dp_type; + uint32_t cap_base = 0; + uint32_t test_fails; + uint32_t test_skip = 1; + uint32_t acs_data; + uint32_t data; + pcie_device_bdf_table *bdf_tbl_ptr; + + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + + test_fails = 0; + + /* Check for all the function present in bdf table */ + for (tbl_index = 0; tbl_index < bdf_tbl_ptr->num_entries; tbl_index++) + { + bdf = bdf_tbl_ptr->device[tbl_index].bdf; + dp_type = val_pcie_device_port_type(bdf); + + /* Check entry is RP */ + if (dp_type == RP) + { + /* Check If RP supports P2P with other RP's. */ + if (val_pcie_dev_p2p_support(bdf)) + continue; + + /* It ATS Not supported, Skip the BDF. */ + if (val_pcie_find_capability(bdf, PCIE_ECAP, ECID_ATS, &cap_base) != PCIE_SUCCESS) { + continue; + } + + /* If test runs for atleast an endpoint */ + test_skip = 0; + + val_print(ACS_PRINT_DEBUG, "\n For BDF : 0x%x", bdf); + + /* Read the ACS Capability */ + if (val_pcie_find_capability(bdf, PCIE_ECAP, ECID_ACS, &cap_base) != PCIE_SUCCESS) { + val_print(ACS_PRINT_ERR, "\n ACS Capability not supported, Bdf : 0x%x", bdf); + test_fails++; + continue; + } + val_pcie_read_cfg(bdf, cap_base + ACSCR_OFFSET, &acs_data); + + /* Extract ACS directed translated p2p bit */ + data = VAL_EXTRACT_BITS(acs_data, 6, 6); + if (data == 0) { + val_print(ACS_PRINT_ERR, + "\n Directed Translated P2P not supported, Bdf : 0x%x", bdf); + test_fails++; + } + } + } + + if (test_skip == 1) + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + else if (test_fails) + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, test_fails)); + else + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); +} + +uint32_t +os_p017_entry(uint32_t num_pe) +{ + + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/pcie/operating_system/test_os_p018.c b/test_pool/pcie/operating_system/test_os_p018.c new file mode 100644 index 00000000..06aed24e --- /dev/null +++ b/test_pool/pcie/operating_system/test_os_p018.c @@ -0,0 +1,108 @@ +/** @file + * Copyright (c) 2020,2021 Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_pe.h" +#include "val/include/bsa_acs_memory.h" + +#define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 18) +#define TEST_RULE "PCI_PP_05" +#define TEST_DESC "Check RP Adv Error Report " + +static +void +payload(void) +{ + + uint32_t bdf; + uint32_t pe_index; + uint32_t tbl_index; + uint32_t dp_type; + uint32_t cap_base = 0; + uint32_t test_fails; + uint32_t test_skip = 1; + pcie_device_bdf_table *bdf_tbl_ptr; + + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + + /* Check If PCIe Hierarchy supports P2P */ + if (val_pcie_p2p_support()) + { + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + return; + } + + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + test_fails = 0; + + /* Check for all the function present in bdf table */ + for (tbl_index = 0; tbl_index < bdf_tbl_ptr->num_entries; tbl_index++) + { + bdf = bdf_tbl_ptr->device[tbl_index].bdf; + dp_type = val_pcie_device_port_type(bdf); + + /* Check entry is RP */ + if (dp_type == RP) + { + /* Test runs for atleast an endpoint */ + test_skip = 0; + + /* It ACS Not Supported, Fail. */ + if (val_pcie_find_capability(bdf, PCIE_ECAP, ECID_ACS, &cap_base) != PCIE_SUCCESS) { + val_print(ACS_PRINT_ERR, "\n ACS Capability not supported, Bdf : 0x%x", bdf); + test_fails++; + continue; + } + + /* If AER Not Supported, Fail. */ + if (val_pcie_find_capability(bdf, PCIE_ECAP, ECID_AER, &cap_base) != PCIE_SUCCESS) { + val_print(ACS_PRINT_DEBUG, "\n AER Capability not supported, Bdf : 0x%x", bdf); + test_fails++; + } + } + } + + if (test_skip == 1) + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 02)); + else if (test_fails) + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, test_fails)); + else + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); +} + +uint32_t +os_p018_entry(uint32_t num_pe) +{ + + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/pcie/operating_system/test_os_p019.c b/test_pool/pcie/operating_system/test_os_p019.c new file mode 100644 index 00000000..9ecfde3d --- /dev/null +++ b/test_pool/pcie/operating_system/test_os_p019.c @@ -0,0 +1,150 @@ +/** @file + * Copyright (c) 2016-2018, 2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_pe.h" +#include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_memory.h" + +#define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 19) +#define TEST_RULE "PCI_PP_03" +#define TEST_DESC "RP must suprt ACS if P2P Txn are allow" + +static +void +payload(void) +{ + + uint32_t bdf; + uint32_t pe_index; + uint32_t tbl_index; + uint32_t dp_type; + uint32_t cap_base = 0; + uint32_t test_fails; + uint32_t test_skip = 1; + uint32_t acs_data; + uint32_t data; + uint32_t curr_bdf_failed = 0; + pcie_device_bdf_table *bdf_tbl_ptr; + + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + + /* Check If PCIe Hierarchy supports P2P */ + if (val_pcie_p2p_support()) + { + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); + return; + } + + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + test_fails = 0; + + /* Check for all the function present in bdf table */ + for (tbl_index = 0; tbl_index < bdf_tbl_ptr->num_entries; tbl_index++) + { + bdf = bdf_tbl_ptr->device[tbl_index].bdf; + dp_type = val_pcie_device_port_type(bdf); + + /* Check entry is RP */ + if (dp_type == RP) + { + /* Test runs for atleast an endpoint */ + test_skip = 0; + + /* Read the ACS Capability */ + if (val_pcie_find_capability(bdf, PCIE_ECAP, ECID_ACS, &cap_base) != PCIE_SUCCESS) { + val_print(ACS_PRINT_ERR, + "\n ACS Capability not supported, Bdf : 0x%x", bdf); + test_fails++; + continue; + } + + val_pcie_read_cfg(bdf, cap_base + ACSCR_OFFSET, &acs_data); + + /* Extract ACS source validation bit */ + data = VAL_EXTRACT_BITS(acs_data, 0, 0); + if (data == 0) { + val_print(ACS_PRINT_DEBUG, + "\n Source validation not supported, Bdf : 0x%x", bdf); + curr_bdf_failed++; + } + /* Extract ACS translation blocking bit */ + data = VAL_EXTRACT_BITS(acs_data, 1, 1); + if (data == 0) { + val_print(ACS_PRINT_DEBUG, + "\n Translation blocking not supported, Bdf : 0x%x", bdf); + curr_bdf_failed++; + } + /* Extract ACS P2P request redirect bit */ + data = VAL_EXTRACT_BITS(acs_data, 2, 2); + if (data == 0) { + val_print(ACS_PRINT_DEBUG, + "\n P2P request redirect not supported, Bdf : 0x%x", bdf); + curr_bdf_failed++; + } + /* Extract ACS P2P completion redirect bit */ + data = VAL_EXTRACT_BITS(acs_data, 3, 3); + if (data == 0) { + val_print(ACS_PRINT_DEBUG, + "\n P2P completion redirect not supported, Bdf : 0x%x", bdf); + curr_bdf_failed++; + } + /* Extract ACS upstream forwarding bit */ + data = VAL_EXTRACT_BITS(acs_data, 4, 4); + if (data == 0) { + val_print(ACS_PRINT_DEBUG, + "\n Upstream forwarding not supported, Bdf : 0x%x", bdf); + curr_bdf_failed++; + } + + if (curr_bdf_failed > 0) { + val_print(ACS_PRINT_ERR, + "\n ACS Capability Check Failed, Bdf : 0x%x", bdf); + curr_bdf_failed = 0; + test_fails++; + } + } + } + + if (test_skip == 1) + val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 02)); + else if (test_fails) + val_set_status(pe_index, RESULT_FAIL(TEST_NUM, test_fails)); + else + val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); +} + +uint32_t +os_p019_entry(uint32_t num_pe) +{ + + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/pcie/operating_system/test_os_p020.c b/test_pool/pcie/operating_system/test_os_p020.c index 6fe49843..8e29cf06 100644 --- a/test_pool/pcie/operating_system/test_os_p020.c +++ b/test_pool/pcie/operating_system/test_os_p020.c @@ -20,7 +20,8 @@ #include "val/include/bsa_acs_val.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 20) -#define TEST_DESC "RE_REC_1,RE_REC_2: Check Type 0/1 common config rule" +#define TEST_RULE "RE_REG_1, RE_REC_1, RE_REC_2" +#define TEST_DESC "Type 0/1 common config rule " static void @@ -58,9 +59,9 @@ os_p020_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p021.c b/test_pool/pcie/operating_system/test_os_p021.c index afad0f17..784f6062 100644 --- a/test_pool/pcie/operating_system/test_os_p021.c +++ b/test_pool/pcie/operating_system/test_os_p021.c @@ -20,7 +20,8 @@ #include "val/include/bsa_acs_val.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 21) -#define TEST_DESC "RE_REC_1,2: Check Type 0 config header rules " +#define TEST_RULE "RE_REG_1, RE_REC_1, RE_REC_2" +#define TEST_DESC "Type 0 config header rules " static void @@ -58,9 +59,9 @@ os_p021_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p022.c b/test_pool/pcie/operating_system/test_os_p022.c index bac431c3..c8d3cdc9 100644 --- a/test_pool/pcie/operating_system/test_os_p022.c +++ b/test_pool/pcie/operating_system/test_os_p022.c @@ -20,7 +20,8 @@ #include "test_os_p022_data.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 22) -#define TEST_DESC "RE_REC_1,2: Check Type 1 config header rules " +#define TEST_RULE "RE_REC_1, RE_REC_2" +#define TEST_DESC "Check Type 1 config header rules " static void @@ -58,9 +59,9 @@ os_p022_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p023.c b/test_pool/pcie/operating_system/test_os_p023.c index c21fd87c..77282589 100644 --- a/test_pool/pcie/operating_system/test_os_p023.c +++ b/test_pool/pcie/operating_system/test_os_p023.c @@ -21,7 +21,8 @@ #include "test_os_p023_data.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 23) -#define TEST_DESC "RE_REC_1,2: Check PCIe capability rules " +#define TEST_RULE "RE_REG_3, RE_REC_1, RE_REC_2" +#define TEST_DESC "PCIe capability rules " static void @@ -59,9 +60,9 @@ os_p023_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p024.c b/test_pool/pcie/operating_system/test_os_p024.c index 58f49607..fb3f633a 100644 --- a/test_pool/pcie/operating_system/test_os_p024.c +++ b/test_pool/pcie/operating_system/test_os_p024.c @@ -21,7 +21,8 @@ #include "test_os_p024_data.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 24) -#define TEST_DESC "RE_REC_1,2: Check Device capabilities reg rules " +#define TEST_RULE "RE_REG_3, RE_REC_1, RE_REC_2" +#define TEST_DESC "Device capabilities reg rule " static void @@ -59,9 +60,9 @@ os_p024_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p025.c b/test_pool/pcie/operating_system/test_os_p025.c index b8c80607..d5c66e25 100644 --- a/test_pool/pcie/operating_system/test_os_p025.c +++ b/test_pool/pcie/operating_system/test_os_p025.c @@ -21,7 +21,8 @@ #include "test_os_p025_data.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 25) -#define TEST_DESC "RE_REC_1,2: Check Device Control register rule " +#define TEST_RULE "RE_REG_3, RE_REC_1, RE_REC_2" +#define TEST_DESC "Device Control register rule " static void @@ -59,9 +60,9 @@ os_p025_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p026.c b/test_pool/pcie/operating_system/test_os_p026.c index edd8dc43..037b7b89 100644 --- a/test_pool/pcie/operating_system/test_os_p026.c +++ b/test_pool/pcie/operating_system/test_os_p026.c @@ -21,7 +21,8 @@ #include "test_os_p026_data.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 26) -#define TEST_DESC "RE_REC_1,2: Check Device cap 2 register rules " +#define TEST_RULE "RE_REG_3, RE_REC_1, RE_REC_2" +#define TEST_DESC "Device cap 2 register rules " static void @@ -59,9 +60,9 @@ os_p026_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p027.c b/test_pool/pcie/operating_system/test_os_p027.c index e758cb5f..b32fb635 100644 --- a/test_pool/pcie/operating_system/test_os_p027.c +++ b/test_pool/pcie/operating_system/test_os_p027.c @@ -21,7 +21,8 @@ #include "test_os_p027_data.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 27) -#define TEST_DESC "RE_REC_1,2: Check Device control 2 reg rules " +#define TEST_RULE "RE_REG_3, RE_REC_1, RE_REC_2" +#define TEST_DESC "Device control 2 reg rules " static void @@ -59,9 +60,9 @@ os_p027_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p028.c b/test_pool/pcie/operating_system/test_os_p028.c index f859addf..f35c85e8 100644 --- a/test_pool/pcie/operating_system/test_os_p028.c +++ b/test_pool/pcie/operating_system/test_os_p028.c @@ -21,7 +21,8 @@ #include "test_os_p028_data.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 28) -#define TEST_DESC "RE_REC_1,2: Check Power management cap rules " +#define TEST_RULE "RE_REG_2, RE_REC_1, RE_REC_2" +#define TEST_DESC "Power management cap rules " static void @@ -59,9 +60,9 @@ os_p028_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p029.c b/test_pool/pcie/operating_system/test_os_p029.c index 088ddc1b..c5019086 100644 --- a/test_pool/pcie/operating_system/test_os_p029.c +++ b/test_pool/pcie/operating_system/test_os_p029.c @@ -21,7 +21,8 @@ #include "test_os_p029_data.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 29) -#define TEST_DESC "RE_REC_1,2: Check Power management/status rule " +#define TEST_RULE "RE_REG_2, RE_REC_1, RE_REC_2" +#define TEST_DESC "Power management/status rule " static void @@ -59,9 +60,9 @@ os_p029_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p030.c b/test_pool/pcie/operating_system/test_os_p030.c index 46d4f0c9..c35cdfa0 100644 --- a/test_pool/pcie/operating_system/test_os_p030.c +++ b/test_pool/pcie/operating_system/test_os_p030.c @@ -22,7 +22,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 30) -#define TEST_DESC "RE_REC_1,2: Check Cmd Reg memory space enable " +#define TEST_RULE "RE_REC_1, RE_REC_2" +#define TEST_DESC "Check Cmd Reg memory space enable " static void *branch_to_test; @@ -164,9 +165,9 @@ os_p030_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p031.c b/test_pool/pcie/operating_system/test_os_p031.c index 43ddfdda..f13067a1 100644 --- a/test_pool/pcie/operating_system/test_os_p031.c +++ b/test_pool/pcie/operating_system/test_os_p031.c @@ -22,7 +22,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 31) -#define TEST_DESC "RE_REC_1,2: Check Type0/1 BIST Register rule " +#define TEST_RULE "RE_REC_1, RE_REC_2" +#define TEST_DESC "Check Type0/1 BIST Register rule " static void @@ -90,9 +91,9 @@ os_p031_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p032.c b/test_pool/pcie/operating_system/test_os_p032.c index 3dedf1a7..5a98f04c 100644 --- a/test_pool/pcie/operating_system/test_os_p032.c +++ b/test_pool/pcie/operating_system/test_os_p032.c @@ -22,7 +22,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 32) -#define TEST_DESC "RE_REC_1,2: Check HDR CapPtr Register rule " +#define TEST_RULE "RE_REC_1, RE_REC_2" +#define TEST_DESC "Check HDR CapPtr Register rule " static void @@ -87,9 +88,9 @@ os_p032_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p033.c b/test_pool/pcie/operating_system/test_os_p033.c index d0ab66e3..5b6a0e8d 100644 --- a/test_pool/pcie/operating_system/test_os_p033.c +++ b/test_pool/pcie/operating_system/test_os_p033.c @@ -22,7 +22,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 33) -#define TEST_DESC "RE_REC_1,2: Check Max payload size supported " +#define TEST_RULE "RE_REC_1, RE_REC_2" +#define TEST_DESC "Check Max payload size supported " static void @@ -91,9 +92,9 @@ os_p033_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p034.c b/test_pool/pcie/operating_system/test_os_p034.c index 640507bb..dbba3d01 100644 --- a/test_pool/pcie/operating_system/test_os_p034.c +++ b/test_pool/pcie/operating_system/test_os_p034.c @@ -21,7 +21,8 @@ #include "val/include/bsa_acs_pcie.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 34) -#define TEST_DESC "RE_BAR_3,IE_BAR_3: Check BAR mem space & Type rule " +#define TEST_RULE "RE_BAR_3" +#define TEST_DESC "Check BAR mem space & Type rule " static void @@ -53,8 +54,8 @@ payload(void) bdf = bdf_tbl_ptr->device[tbl_index++].bdf; dp_type = val_pcie_device_port_type(bdf); - /* Check for RCiEP and iEP */ - if (dp_type == RCiEP || dp_type == iEP_EP) + /* Check for RCiEP */ + if (dp_type == RCiEP) { /* Extract Hdr Type */ hdr_type = val_pcie_function_header_type(bdf); @@ -125,9 +126,9 @@ os_p034_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p035.c b/test_pool/pcie/operating_system/test_os_p035.c index df77e8f6..49592734 100644 --- a/test_pool/pcie/operating_system/test_os_p035.c +++ b/test_pool/pcie/operating_system/test_os_p035.c @@ -23,7 +23,8 @@ #include "val/include/bsa_acs_memory.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 35) -#define TEST_DESC "RE_RST_1,IE_RST_1: Check Function level reset rule " +#define TEST_RULE "RE_RST_1, PCI_SM_02" +#define TEST_DESC "Check Function level reset " uint32_t is_flr_failed(uint32_t bdf) { @@ -93,8 +94,8 @@ payload(void) bdf = bdf_tbl_ptr->device[tbl_index++].bdf; dp_type = val_pcie_device_port_type(bdf); - /* Check entry is RCiEP or iEP endpoint or normal EP */ - if ((dp_type == RCiEP) || (dp_type == iEP_EP) || (dp_type == EP)) + /* Check entry is RCiEP or normal EP */ + if ((dp_type == RCiEP) || (dp_type == EP)) { /* Read FLR capability bit value */ val_pcie_find_capability(bdf, PCIE_CAP, CID_PCIECS, &cap_base); @@ -181,9 +182,9 @@ os_p035_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p036.c b/test_pool/pcie/operating_system/test_os_p036.c index 68f59f04..5abf2be5 100644 --- a/test_pool/pcie/operating_system/test_os_p036.c +++ b/test_pool/pcie/operating_system/test_os_p036.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2019-2021, Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2020, Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,10 +20,10 @@ #include "val/include/bsa_acs_pcie.h" #include "val/include/bsa_acs_pe.h" -#include "val/include/bsa_acs_memory.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 36) -#define TEST_DESC "IE_REG_2: Check ARI forwarding support rule " +#define TEST_RULE "PCI_IN_17" +#define TEST_DESC "Check ARI forwarding enable rule " static void @@ -31,15 +31,19 @@ payload(void) { uint32_t bdf; - uint32_t rp_bdf; uint32_t pe_index; uint32_t tbl_index; - uint32_t reg_value; uint32_t dp_type; uint32_t cap_base; - uint32_t ari_frwd_support; + uint32_t ari_frwd_enable; + uint32_t seg_num; + uint32_t dev_num; + uint32_t dev_bdf; + uint32_t sec_bus; + uint32_t sub_bus; uint32_t test_fails; uint32_t test_skip = 1; + uint32_t reg_value; pcie_device_bdf_table *bdf_tbl_ptr; pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); @@ -53,29 +57,47 @@ payload(void) bdf = bdf_tbl_ptr->device[tbl_index].bdf; dp_type = val_pcie_device_port_type(bdf); - /* Check entry is iEP */ - if (dp_type == iEP_EP) + /* Check entry is Downstream port or RP */ + if ((dp_type == DP) || (dp_type == iEP_RP) || (dp_type == RP)) { - /* Check ARI capability support */ - if (val_pcie_find_capability(bdf, PCIE_ECAP, ECID_ARICS, &cap_base) == - PCIE_CAP_NOT_FOUND) + /* Read the ARI forwarding enable bit */ + val_pcie_find_capability(bdf, PCIE_CAP, CID_PCIECS, &cap_base); + val_pcie_read_cfg(bdf, cap_base + DCTL2R_OFFSET, ®_value); + ari_frwd_enable = (reg_value >> DCTL2R_AFE_SHIFT) & DCTL2R_AFE_MASK; + + /* If ARI forwarding enable set, skip the entry */ + if (ari_frwd_enable != 0) continue; - /* Get the rootport of ARI device */ - rp_bdf = bdf_tbl_ptr->device[tbl_index].rp_bdf; + val_pcie_read_cfg(bdf, TYPE1_PBN, ®_value); + sec_bus = ((reg_value >> SECBN_SHIFT) & SECBN_MASK); + sub_bus = ((reg_value >> SUBBN_SHIFT) & SUBBN_MASK); - /* Read the ARI forwarding bit */ - val_pcie_find_capability(rp_bdf, PCIE_CAP, CID_PCIECS, &cap_base); - val_pcie_read_cfg(rp_bdf, cap_base + DCAP2R_OFFSET, ®_value); - ari_frwd_support = (reg_value >> DCAP2R_AFS_SHIFT) & DCAP2R_AFS_MASK; + /* Skip the port, if switch is present below it */ + if (sec_bus != sub_bus) + continue; /* If test runs for atleast an endpoint */ test_skip = 0; - /* If root port not support ARI forwarding, fail the test */ - if (!ari_frwd_support) - test_fails++; - + /* Configuration Requests specifying Device Numbers (1-31) must be terminated by the + * Downstream Port or the Root Port with an Unsupported Request Completion Status + */ + + for (dev_num = 1; dev_num < PCIE_MAX_DEV; dev_num++) + { + seg_num = PCIE_EXTRACT_BDF_SEG(bdf); + + /* Create bdf for Dev 1 to 31 below the RP */ + dev_bdf = PCIE_CREATE_BDF(seg_num, sec_bus, dev_num, 0); + val_pcie_read_cfg(dev_bdf, TYPE01_VIDR, ®_value); + if (reg_value != PCIE_UNKNOWN_RESPONSE) + { + test_fails++; + val_print(ACS_PRINT_ERR, "\n Dev 0x%x found under", dev_bdf); + val_print(ACS_PRINT_ERR, " RP bdf 0x%x", bdf); + } + } } } @@ -100,9 +122,9 @@ os_p036_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p061.c b/test_pool/pcie/operating_system/test_os_p061.c index 3436d3d4..bc0961c4 100644 --- a/test_pool/pcie/operating_system/test_os_p061.c +++ b/test_pool/pcie/operating_system/test_os_p061.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2018, 2021, Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2016-2018, 2020-2021 Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,98 +18,151 @@ #include "val/include/val_interface.h" #include "val/include/bsa_acs_pcie.h" +#include "val/include/bsa_acs_memory.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 61) -#define TEST_DESC "PCI_IN_20: Vendor specific data are PCIe compliant " +#define TEST_RULE "PCI_MM_01-02, RE_BAR_2" +#define TEST_DESC "PCIe Unaligned access " -// Valid PCIe CapID ranges (PCIe 5.0 - v1.0) -#define PCIE_CAP_ID_END 0x15 -#define PCIE_ECAP_ID_END 0x29 - -// Check if vendor specific data are presented as non-PCIe compliant capabilities -// in either the regular or extended PCIe spaces -// returns: 0 - No violations present 1 - One or more violations present -static -uint32_t -check_pcie_cfg_space(uint32_t bdf) -{ - uint32_t reg_value; - uint32_t next_cap; - uint32_t err = 0; - uint32_t cid; - - // Search through regular PCIe cfg space first (start at first implemented cap) - val_pcie_read_cfg(bdf, TYPE01_CPR, ®_value); - // DWORD aligned: next_cap[1:0] are hardwired to '0' - next_cap = VAL_EXTRACT_BITS(reg_value, 2, 7) << 2; - - while (next_cap) { - - val_pcie_read_cfg(bdf, next_cap, ®_value); - next_cap = VAL_EXTRACT_BITS(reg_value, 7, 15); - cid = VAL_EXTRACT_BITS(reg_value, 0, 7); - - // Check PCIe Cap IDs are in range - if (cid > PCIE_CAP_ID_END) { - val_print(ACS_PRINT_ERR, - "\n Invalid Cap ID: 0x%x found in regular cfg space", cid); - err = 1; - } - } - - // Search through extended PCIe cfg space next - next_cap = PCIE_ECAP_START; - - while (next_cap) { - - val_pcie_read_cfg(bdf, next_cap, ®_value); - next_cap = VAL_EXTRACT_BITS(reg_value, 20, 31); - cid = VAL_EXTRACT_BITS(reg_value, 0, 15); - - // Check PCIe Ext Cap IDs are in range - if (cid > PCIE_ECAP_ID_END) { - val_print(ACS_PRINT_ERR, - "\n Invalid Cap ID: 0x%x found in extended cfg space", cid); - err = 1; - } - } - - return err; -} +#define DATA 0xC0DECAFE static void payload(void) { - uint32_t pe_index; - uint32_t tbl_index; - uint32_t bdf; - uint32_t dp_type; - pcie_device_bdf_table *bdf_tbl_ptr; - - pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); - bdf_tbl_ptr = val_pcie_bdf_table_ptr(); - - tbl_index = 0; - - while (tbl_index < bdf_tbl_ptr->num_entries) { - - bdf = bdf_tbl_ptr->device[tbl_index++].bdf; - dp_type = val_pcie_device_port_type(bdf); - - // Only check for Root Ports - if (dp_type == RP) { - if (check_pcie_cfg_space(bdf)) { - val_print(ACS_PRINT_ERR, - "\n Invalid PCIe capability found on dev: %d", tbl_index); - val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 02)); - return; - } - } - } - - val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); - return; + uint32_t count = 0; + uint32_t data; + uint32_t bdf; + uint32_t bar_reg_value; + uint64_t bar_upper_bits; + uint32_t bar_value; + uint32_t bar_value_1; + uint64_t bar_size; + char *baseptr; + uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); + uint32_t test_skip = 1; + uint32_t test_fail = 0; + uint64_t offset; + uint64_t base; + + count = val_peripheral_get_info(NUM_SATA, 0); + + while (count--) { +next_bdf: + bdf = val_peripheral_get_info(SATA_BDF, count); + offset = BAR0_OFFSET; + + while (offset <= BAR_MAX_OFFSET) { + val_pcie_read_cfg(bdf, offset, &bar_value); + val_print(ACS_PRINT_DEBUG, "\n The BAR value of bdf %x", bdf); + val_print(ACS_PRINT_DEBUG, " is %x ", bar_value); + base = 0; + + if (bar_value == 0) + { + /** This BAR is not implemented **/ + count--; + goto next_bdf; + } + + /* Skip for IO address space */ + if (bar_value & 0x1) { + count--; + goto next_bdf; + } + + if (BAR_REG(bar_value) == BAR_64_BIT) + { + val_print(ACS_PRINT_INFO, "BAR supports 64-bit address decoding capability \n", 0); + val_pcie_read_cfg(bdf, offset+4, &bar_value_1); + base = bar_value_1; + + /* BAR supports 64-bit address therefore, write all 1's + * to BARn and BARn+1 and identify the size requested + */ + val_pcie_write_cfg(bdf, offset, 0xFFFFFFF0); + val_pcie_write_cfg(bdf, offset + 4, 0xFFFFFFFF); + val_pcie_read_cfg(bdf, offset, &bar_reg_value); + bar_size = bar_reg_value & 0xFFFFFFF0; + val_pcie_read_cfg(bdf, offset + 4, &bar_reg_value); + bar_upper_bits = bar_reg_value; + bar_size = bar_size | (bar_upper_bits << 32); + bar_size = ~bar_size + 1; + + /* Restore the original BAR value */ + val_pcie_write_cfg(bdf, offset + 4, bar_value_1); + val_pcie_write_cfg(bdf, offset, bar_value); + base = (base << 32) | bar_value; + } + + else { + val_print(ACS_PRINT_INFO, "The BAR supports 32-bit address decoding capability\n", 0); + + /* BAR supports 32-bit address. Write all 1's + * to BARn and identify the size requested + */ + val_pcie_write_cfg(bdf, offset, 0xFFFFFFF0); + val_pcie_read_cfg(bdf, offset, &bar_reg_value); + bar_reg_value = bar_reg_value & 0xFFFFFFF0; + bar_size = ~bar_reg_value + 1; + + /* Restore the original BAR value */ + val_pcie_write_cfg(bdf, offset, bar_value); + base = bar_value; + } + + val_print(ACS_PRINT_DEBUG, "\n BAR size is %x", bar_size); + + /* Check if bar supports the remap size */ + if (bar_size < 1024) { + val_print(ACS_PRINT_ERR, "Bar size less than remap requested size", 0); + goto next_bar; + } + + test_skip = 0; + + /* Map SATA Controller BARs to a NORMAL memory attribute. check unaligned access */ + baseptr = (char *)val_memory_ioremap((void *)base, 1024, NORMAL_NC); + + /* Check for unaligned access */ + *(uint32_t *)(baseptr) = DATA; + data = *(char *)(baseptr+3); + + val_memory_unmap(baseptr); + + if (data != (DATA >> 24)) { + val_print(ACS_PRINT_ERR, "Unaligned data mismatch", 0); + test_fail++; + } + + /* Map SATA Controller BARs to a DEVICE memory attribute and check transaction */ + baseptr = (char *)val_memory_ioremap((void *)base, 1024, DEVICE_nGnRnE); + + *(uint32_t *)(baseptr) = DATA; + data = *(uint32_t *)(baseptr); + + val_memory_unmap(baseptr); + + if (data != DATA) { + val_print(ACS_PRINT_ERR, "Data value mismatch", 0); + test_fail++; + } + +next_bar: + if (BAR_REG(bar_reg_value) == BAR_32_BIT) + offset = offset + 4; + + if (BAR_REG(bar_reg_value) == BAR_64_BIT) + offset = offset + 8; + } + } + + if (test_skip) + val_set_status(index, RESULT_SKIP(TEST_NUM, 0)); + else if (test_fail) + val_set_status(index, RESULT_FAIL(TEST_NUM, test_fail)); + else + val_set_status(index, RESULT_PASS(TEST_NUM, 0)); } @@ -126,9 +179,9 @@ os_p061_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p062.c b/test_pool/pcie/operating_system/test_os_p062.c index 93e8a531..5c5c1714 100644 --- a/test_pool/pcie/operating_system/test_os_p062.c +++ b/test_pool/pcie/operating_system/test_os_p062.c @@ -1,6 +1,7 @@ /** @file - * Copyright (c) 2021 Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2016-2018,2021 Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,136 +14,88 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ - #include "val/include/bsa_acs_val.h" #include "val/include/val_interface.h" -#include "val/include/bsa_acs_pcie.h" -#include "val/include/bsa_acs_pe.h" +#include "val/include/bsa_acs_dma.h" +#include "val/include/bsa_acs_smmu.h" #define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 62) -#define TEST_DESC "RE_BAR_1: Read and write to RCiEP BAR reg " +#define TEST_RULE "PCI_MM_05-07" +#define TEST_DESC "No extra address translation " -#define TEST_DATA_1 0xDEADDAED -#define TEST_DATA_2 0xABABABAB +/* For all DMA masters populated in the Info table, which are behind an SMMU, + verify there are no additional translations before address is given to SMMU */ static void payload(void) { - uint32_t bdf, offset; - uint32_t bar_value; - uint32_t bar_value_1; - uint32_t bar_reg_value; - uint32_t base_lower; - uint32_t base_upper; - uint32_t dp_type; - uint32_t pe_index; - uint32_t tbl_index; - uint32_t fail_cnt; - uint32_t test_skip = 1; - pcie_device_bdf_table *bdf_tbl_ptr; - uint64_t bar_orig; - uint64_t bar_new; - uint64_t bar_upper_bits; - - bdf_tbl_ptr = val_pcie_bdf_table_ptr(); - pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); - - fail_cnt = 0; - tbl_index = 0; - - while (tbl_index < bdf_tbl_ptr->num_entries) + + uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); + uint32_t target_dev_index; + addr_t dma_addr = 0; + uint32_t dma_len = 0; + void *buffer; + uint32_t status; + uint32_t iommu_flag = 0; + + target_dev_index = val_dma_get_info(DMA_NUM_CTRL, 0); + + if (!target_dev_index) { + val_print(ACS_PRINT_TEST, "\n No DMA controllers detected... ", 0); + val_set_status(index, RESULT_SKIP(TEST_NUM, 02)); + return; + } + + while (target_dev_index) { - bdf = bdf_tbl_ptr->device[tbl_index++].bdf; - dp_type = val_pcie_device_port_type(bdf); - if (dp_type == RCiEP) { - /* If test runs for atleast an endpoint */ - test_skip = 0; - offset = BAR0_OFFSET; - - while (offset <= TYPE1_BAR_MAX_OFFSET) { - val_pcie_read_cfg(bdf, offset, &bar_value); - val_print(ACS_PRINT_DEBUG, "\n The BAR value of bdf %x", bdf); - val_print(ACS_PRINT_DEBUG, " is %x ", bar_value); - bar_orig = 0; - bar_new = 0; - - if (bar_value == 0) - { - /** This BAR is not implemented **/ - offset = offset + 4; - continue; - } - - if (BAR_REG(bar_value) == BAR_64_BIT) - { - val_print(ACS_PRINT_INFO, "The BAR supports 64-bit address capability \n", 0); - val_pcie_read_cfg(bdf, offset+4, &bar_value_1); - base_upper = bar_value_1; - - /* BAR supports 64-bit address therefore, write all 1's - * to BARn and BARn+1 and identify the size requested - */ - val_pcie_read_cfg(bdf, offset, &bar_reg_value); - bar_value = bar_reg_value; - base_lower = bar_reg_value; - val_pcie_read_cfg(bdf, offset + 4, &bar_reg_value); - bar_upper_bits = bar_reg_value; - base_upper = bar_reg_value; - bar_orig = (bar_upper_bits << 32) | bar_value; - val_pcie_write_cfg(bdf, offset, TEST_DATA_1); - val_pcie_write_cfg(bdf, offset + 4, TEST_DATA_2); - val_pcie_read_cfg(bdf, offset, &bar_reg_value); - bar_value = bar_reg_value; - val_pcie_read_cfg(bdf, offset + 4, &bar_reg_value); - bar_upper_bits = bar_reg_value; - bar_new = (bar_upper_bits << 32) | bar_value; - if (bar_orig == bar_new) { - val_print(ACS_PRINT_TEST, "Read write to BAR reg not supported bdf %x\n", bdf); - fail_cnt++; - } - - /* Restore the original BAR value */ - val_pcie_write_cfg(bdf, offset + 4, base_upper); - val_pcie_write_cfg(bdf, offset, base_lower); - offset = offset+8; - } - - else { - val_print(ACS_PRINT_INFO, "The BAR supports 32-bit address capability\n", 0); - - /* BAR supports 32-bit address. Write all 1's - * to BARn and identify the size requested - */ - val_pcie_read_cfg(bdf, offset, &bar_reg_value); - bar_orig = bar_reg_value; - base_lower = bar_reg_value; - val_pcie_write_cfg(bdf, offset, TEST_DATA_1); - val_pcie_read_cfg(bdf, offset, &bar_reg_value); - bar_new = bar_reg_value; - if (bar_orig == bar_new) { - val_print(ACS_PRINT_TEST, "Read write to BAR reg not supported bdf %x\n", bdf); - fail_cnt++; - } - - /* Restore the original BAR value */ - val_pcie_write_cfg(bdf, offset, base_lower); - offset = offset+4; - } + target_dev_index--; //index is zero based + + /* Check there were no additional translations between Device and SMMU */ + if (val_dma_get_info(DMA_HOST_IOMMU_ATTACHED, target_dev_index)) { + iommu_flag++; + val_dma_device_get_dma_addr(target_dev_index, &dma_addr, &dma_len); + status = val_smmu_ops(SMMU_CHECK_DEVICE_IOVA, 0, &target_dev_index, &dma_addr); + if (status) { + val_print(ACS_PRINT_ERR, "\n The DMA address %lx used by device ", dma_addr); + val_print(ACS_PRINT_ERR, "\n is not present in the SMMU IOVA table \n", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, target_dev_index)); + return; } } + } + target_dev_index = val_dma_get_info(DMA_NUM_CTRL, 0); - if (test_skip == 1) - val_set_status(pe_index, RESULT_SKIP(TEST_NUM, 01)); - else if (fail_cnt) - val_set_status(pe_index, RESULT_FAIL(TEST_NUM, fail_cnt)); - else - val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); + /* Check if IOMMU ops is properly integrated for this device by making the standard OS + DMA API call and verifying the DMA address is part of the IOVA translation table */ + while (target_dev_index) + { + target_dev_index--; + if (val_dma_get_info(DMA_HOST_IOMMU_ATTACHED, target_dev_index)) { + /* Allocate DMA-able memory region in DDR */ + dma_addr = val_dma_mem_alloc(&buffer, 512, target_dev_index, DMA_COHERENT); + status = val_smmu_ops(SMMU_CHECK_DEVICE_IOVA, 0, &target_dev_index, &dma_addr); + if (status) { + val_print(ACS_PRINT_ERR, "\n The DMA addr allocated to device %d ", target_dev_index); + val_print(ACS_PRINT_ERR, "\n is not present in the SMMU IOVA table \n", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, target_dev_index)); + return; + } + /* Free the allocated memory here */ + val_dma_mem_free(buffer, dma_addr, 512, target_dev_index, DMA_COHERENT); } + } + + if (iommu_flag) + val_set_status(index, RESULT_PASS(TEST_NUM, 02)); + else + val_set_status(index, RESULT_SKIP(TEST_NUM, 02)); + } + uint32_t os_p062_entry(uint32_t num_pe) { @@ -155,10 +108,10 @@ os_p062_entry(uint32_t num_pe) if (status != ACS_STATUS_SKIP) val_run_test_payload(TEST_NUM, num_pe, payload, 0); - /* get the result from the PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pcie/operating_system/test_os_p063.c b/test_pool/pcie/operating_system/test_os_p063.c new file mode 100644 index 00000000..1bab6fae --- /dev/null +++ b/test_pool/pcie/operating_system/test_os_p063.c @@ -0,0 +1,85 @@ +/** @file + * Copyright (c) 2016-2018,2021 Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_pcie.h" + +#define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 63) +#define TEST_RULE "PCI_MSI_01" +#define TEST_DESC "Check MSI support for PCIe dev " + +static +void +payload(void) +{ + + uint32_t count = val_peripheral_get_info(NUM_ALL, 0); + uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); + uint32_t data; + uint32_t dev_type; + uint64_t dev_bdf; + uint32_t status = 0; + + if (!count) { + val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); + return; + } + + while (count > 0) { + count--; + dev_bdf = val_peripheral_get_info(ANY_BDF, count); + /* Check for pcie device */ + if (!val_peripheral_is_pcie(dev_bdf)) + continue; + + dev_type = val_pcie_get_device_type(dev_bdf); + /* Skipping MSI check for type-1 and type-2 headers */ + if ((!dev_type) || (dev_type > 1)) + continue; + + data = val_peripheral_get_info(ANY_FLAGS, count); + + if ((data & PER_FLAG_MSI_ENABLED) == 0) { + val_print(ACS_PRINT_ERR, "\n MSI should be enabled for a PCIe device ", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, 01)); + status = 1; + break; + } + } + if (!status) + val_set_status(index, RESULT_PASS(TEST_NUM, 01)); +} + +uint32_t +os_p063_entry(uint32_t num_pe) +{ + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/pcie/operating_system/test_os_p064.c b/test_pool/pcie/operating_system/test_os_p064.c new file mode 100644 index 00000000..91cd3ad1 --- /dev/null +++ b/test_pool/pcie/operating_system/test_os_p064.c @@ -0,0 +1,77 @@ +/** @file + * Copyright (c) 2016-2018,2021 Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_iovirt.h" + +#define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 64) +#define TEST_RULE "PCI_IC_02" +#define TEST_DESC "PCIe RC,PE - Same Inr Shareable Domain" + +#define INNER_SHAREABLE 1 + +static void +payload(void) +{ + uint32_t num_pcie_rc; + uint32_t mem_attr; + uint32_t index = val_pe_get_index_mpid (val_pe_get_mpid()); + + num_pcie_rc = val_iovirt_get_pcie_rc_info(NUM_PCIE_RC, 0); + + if (!num_pcie_rc) { + val_print(ACS_PRINT_WARN, "\n Skip because no PCIe RC detected ", 0); + val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); + return; + } + + while (num_pcie_rc) { + num_pcie_rc--; // Index is one lesser than the component number being accessed + mem_attr = val_iovirt_get_pcie_rc_info(RC_MEM_ATTRIBUTE, num_pcie_rc); + + if (mem_attr == INNER_SHAREABLE) + val_set_status(index, RESULT_PASS(TEST_NUM, 01)); + else { + val_print(ACS_PRINT_ERR, "\n Failed mem attribute check for PCIe RC %d", num_pcie_rc); + val_set_status(index, RESULT_FAIL(TEST_NUM, 01)); + return; + } + } + +} + +uint32_t +os_p064_entry(uint32_t num_pe) +{ + + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/pcie/operating_system/test_os_p065.c b/test_pool/pcie/operating_system/test_os_p065.c new file mode 100644 index 00000000..12af943a --- /dev/null +++ b/test_pool/pcie/operating_system/test_os_p065.c @@ -0,0 +1,169 @@ +/** @file + * Copyright (c) 2016-2018,2021 Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_memory.h" +#include "val/include/bsa_acs_pcie.h" + +#define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 65) +#define TEST_RULE "PCI_LI_01" +#define TEST_DESC "PCI legacy intr SPI ID unique " + +static inline char pin_name(int pin) +{ + return 'A' + pin; +} + +static +void +payload (void) +{ + + uint32_t index; + uint32_t count; + PERIPHERAL_IRQ_MAP *irq_map; + uint8_t status; + uint32_t current_irq_pin; + uint32_t next_irq_pin; + uint64_t dev_bdf; + uint32_t ccnt; + uint32_t ncnt; + uint32_t test_skip; + + current_irq_pin = 0; + status = 0; + test_skip = 1; + next_irq_pin = current_irq_pin + 1; + index = val_pe_get_index_mpid (val_pe_get_mpid()); + count = val_peripheral_get_info (NUM_ALL, 0); + + if (!count) { + val_set_status (index, RESULT_SKIP (TEST_NUM, 01)); + return; + } + + irq_map = val_memory_alloc(sizeof(PERIPHERAL_IRQ_MAP)); + if (!irq_map) { + val_print (ACS_PRINT_ERR, "\n Memory allocation error", 0); + val_set_status (index, RESULT_FAIL (TEST_NUM, 01)); + return; + } + + /* get legacy IRQ info from PCI devices */ + while (count > 0 && status == 0) { + count--; + if (val_peripheral_get_info (ANY_GSIV, count)) { + dev_bdf = val_peripheral_get_info (ANY_BDF, count); + status = val_pci_get_legacy_irq_map (dev_bdf, irq_map); + + switch (status) { + case 0: + break; + case 1: + val_print (ACS_PRINT_WARN, "\n Unable to access PCI bridge device", 0); + break; + case 2: + val_print (ACS_PRINT_WARN, "\n Unable to fetch _PRT ACPI handle", 0); + /* Not a fatal error, just skip this device */ + status = 0; + continue; + case 3: + val_print (ACS_PRINT_WARN, "\n Unable to access _PRT ACPI object", 0); + /* Not a fatal error, just skip this device */ + status = 0; + continue; + case 4: + val_print (ACS_PRINT_WARN, "\n Interrupt hard-wire error", 0); + /* Not a fatal error, just skip this device */ + status = 0; + continue; + case 5: + val_print (ACS_PRINT_ERR, "\n Legacy interrupt out of range", 0); + break; + case 6: + val_print (ACS_PRINT_ERR, "\n Maximum number of interrupts has been reached", 0); + break; + default: + val_print (ACS_PRINT_ERR, "\n Unknown error", 0); + break; + } + } + + /* Compare IRQ routings */ + if (!status) { + while (current_irq_pin < LEGACY_PCI_IRQ_CNT && status == 0) { + while (next_irq_pin < LEGACY_PCI_IRQ_CNT && status == 0) { + + for (ccnt = 0; (ccnt < irq_map->legacy_irq_map[current_irq_pin].irq_count) + && (status == 0); ccnt++) { + for (ncnt = 0; (ncnt < irq_map->legacy_irq_map[next_irq_pin].irq_count) + && (status == 0); ncnt++) { + test_skip = 0; + if (irq_map->legacy_irq_map[current_irq_pin].irq_list[ccnt] == + irq_map->legacy_irq_map[next_irq_pin].irq_list[ncnt]) { + status = 7; + val_print (ACS_PRINT_ERR, "\n Legacy interrupt %c routing", + pin_name(current_irq_pin)); + val_print (ACS_PRINT_ERR, "\n is the same as %c routing", + pin_name(next_irq_pin)); + } + } + } + + next_irq_pin++; + } + current_irq_pin++; + next_irq_pin = current_irq_pin + 1; + } + } + } + + val_memory_free (irq_map); + + + if (test_skip) { + val_set_status (index, RESULT_SKIP (TEST_NUM, 02)); + return; + } + + if (!status) { + val_set_status (index, RESULT_PASS (TEST_NUM, 01)); + } else { + val_set_status (index, RESULT_FAIL (TEST_NUM, status)); + } +} + +uint32_t +os_p065_entry (uint32_t num_pe) +{ + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This test is run on single processor + + status = val_initialize_test (TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) { + val_run_test_payload (TEST_NUM, num_pe, payload, 0); + } + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/pcie/operating_system/test_os_p066.c b/test_pool/pcie/operating_system/test_os_p066.c new file mode 100644 index 00000000..beda0fc0 --- /dev/null +++ b/test_pool/pcie/operating_system/test_os_p066.c @@ -0,0 +1,106 @@ +/** @file + * Copyright (c) 2016-2018,2021 Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_pcie.h" + +#define TEST_NUM (ACS_PCIE_TEST_NUM_BASE + 66) +#define TEST_RULE "PCI_MM_04" +#define TEST_DESC "NP type-1 PCIe supp 32-bit only " + +#define BAR0 0x10 + +static +void +payload(void) +{ + uint32_t index; + uint32_t count; + uint32_t status = 0; + uint32_t ret; + uint32_t bar_data; + uint32_t data; + uint32_t dev_type; + uint64_t dev_bdf; + + index = val_pe_get_index_mpid(val_pe_get_mpid()); + + count = val_peripheral_get_info (NUM_ALL, 0); + if (!count) { + val_set_status(index, RESULT_SKIP (TEST_NUM, 3)); + return; + } + + while (count > 0) { + count--; + dev_bdf = val_peripheral_get_info (ANY_BDF, count); + + dev_type = val_pcie_get_device_type(dev_bdf); + /* Allow only type-1 headers and skip others */ + if (dev_type != 3) + continue; + ret = val_pcie_read_cfg(dev_bdf, BAR0, &bar_data); + if (bar_data) { + /* Extract pref type */ + data = VAL_EXTRACT_BITS(bar_data, 3, 3); + if (data == 0) { + status = 1; + /* Extract mem type */ + data = VAL_EXTRACT_BITS(bar_data, 1, 2); + if (data != 0) { + val_print(ACS_PRINT_ERR, "\n NP type-1 pcie is not 32-bit mem type", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, 01)); + status = 2; + break; + } + /* Scan the all PCIe bridge devices and check memory type */ + ret = val_pcie_scan_bridge_devices_and_check_memtype(dev_bdf); + if (ret) { + val_print(ACS_PRINT_ERR, "\n NP type-1 pcie bridge end device" + "is not 32-bit mem type", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, 01)); + status = 2; + break; + } + } + } + } + + if (!status) + val_set_status(index, RESULT_SKIP (TEST_NUM, 3)); + else if (status == 1) + val_set_status(index, RESULT_PASS(TEST_NUM, 01)); +} + +uint32_t +os_p066_entry(uint32_t num_pe) +{ + uint32_t status = ACS_STATUS_FAIL; + + /* This test is run on single processor */ + num_pe = 1; + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/pe/hypervisor/test_hyp_c001.c b/test_pool/pe/hypervisor/test_hyp_c001.c index 5b2eea9f..2b4286c6 100755 --- a/test_pool/pe/hypervisor/test_hyp_c001.c +++ b/test_pool/pe/hypervisor/test_hyp_c001.c @@ -19,7 +19,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_PE_HYP_TEST_NUM_BASE + 1) -#define TEST_DESC "B_PE_18: Check EL2 implementation " +#define TEST_RULE "B_PE_18" +#define TEST_DESC "Check EL2 implementation " static void @@ -49,9 +50,9 @@ hyp_c001_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/hypervisor/test_hyp_c002.c b/test_pool/pe/hypervisor/test_hyp_c002.c index bc8ed086..3c99161a 100755 --- a/test_pool/pe/hypervisor/test_hyp_c002.c +++ b/test_pool/pe/hypervisor/test_hyp_c002.c @@ -19,7 +19,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_PE_HYP_TEST_NUM_BASE + 2) -#define TEST_DESC "B_PE_19: Check Stage 2 4KB Granule Support " +#define TEST_RULE "B_PE_19" +#define TEST_DESC "Check Stage 2 4KB Granule Support " static void @@ -51,9 +52,9 @@ hyp_c002_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/hypervisor/test_hyp_c003.c b/test_pool/pe/hypervisor/test_hyp_c003.c index d43bf68c..75761123 100644 --- a/test_pool/pe/hypervisor/test_hyp_c003.c +++ b/test_pool/pe/hypervisor/test_hyp_c003.c @@ -19,7 +19,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_PE_HYP_TEST_NUM_BASE + 3) -#define TEST_DESC "B_PE_20: Check Stage2, Stage1 Granule match" +#define TEST_RULE "B_PE_20" +#define TEST_DESC "Check Stage2 and Stage1 Granule match " static void @@ -110,9 +111,9 @@ hyp_c003_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/hypervisor/test_hyp_c004.c b/test_pool/pe/hypervisor/test_hyp_c004.c index b61b5901..d1e5c1c7 100644 --- a/test_pool/pe/hypervisor/test_hyp_c004.c +++ b/test_pool/pe/hypervisor/test_hyp_c004.c @@ -18,8 +18,9 @@ #include "val/include/bsa_acs_val.h" #include "val/include/bsa_acs_pe.h" -#define TEST_NUM (ACS_PE_HYP_TEST_NUM_BASE + 4) -#define TEST_DESC "B_PE_21: Check for PMU counters " +#define TEST_NUM (ACS_PE_HYP_TEST_NUM_BASE + 4) +#define TEST_RULE "B_PE_21" +#define TEST_DESC "Check for PMU counters " static void @@ -49,9 +50,9 @@ hyp_c004_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/hypervisor/test_hyp_c005.c b/test_pool/pe/hypervisor/test_hyp_c005.c index b8f8a51e..9c8c7e96 100644 --- a/test_pool/pe/hypervisor/test_hyp_c005.c +++ b/test_pool/pe/hypervisor/test_hyp_c005.c @@ -18,45 +18,28 @@ #include "val/include/bsa_acs_val.h" #include "val/include/bsa_acs_pe.h" -#define TEST_NUM (ACS_PE_HYP_TEST_NUM_BASE + 5) -#define TEST_DESC "B_PE_22: Check VMID breakpoint number " +#define TEST_NUM (ACS_PE_HYP_TEST_NUM_BASE + 5) +#define TEST_RULE "B_PE_22" +#define TEST_DESC "Check VMID breakpoint number " static void payload() { uint64_t data = 0; - int32_t i, breakpointcount; - uint32_t bt; - uint32_t vmid_breakpoint = 0; + uint32_t context_aware_breakpoints = 0; uint32_t pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); data = val_pe_reg_read(ID_AA64DFR0_EL1); - breakpointcount = VAL_EXTRACT_BITS(data, 12, 15); //bits 15:12 for Number of breakpoints - 1 - - for (i = 0; i <= breakpointcount; i++) { - - data = val_pe_reg_read(i + DBGBCR0_EL1); - /* breakpoint type : bits 23:20 - * Shift by 1 to get only 3 bit to ignore LSB*/ - bt = (((VAL_EXTRACT_BITS(data, 20, 23)) >> 1) & 0x7); - - /* 0b100x VMID match. - 0b101x VMID + CONTEXTIDR match.*/ - if ((bt == 0x4) || (bt == 0x5)) { - vmid_breakpoint++; - } - - } - - if ((vmid_breakpoint > 1)) + /*bits [31:28] Number of breakpoints that are context-aware, minus 1*/ + context_aware_breakpoints = VAL_EXTRACT_BITS(data, 28, 31) + 1; + if (context_aware_breakpoints > 1) val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); else val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 01)); return; - } /** @@ -73,9 +56,9 @@ hyp_c005_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c001.c b/test_pool/pe/operating_system/test_os_c001.c index c82466ec..213fed51 100755 --- a/test_pool/pe/operating_system/test_os_c001.c +++ b/test_pool/pe/operating_system/test_os_c001.c @@ -18,8 +18,9 @@ #include "val/include/bsa_acs_val.h" #include "val/include/bsa_acs_pe.h" -#define TEST_NUM (ACS_PE_TEST_NUM_BASE + 1) -#define TEST_DESC "B_PE_01: Check Arch symmetry across PE " +#define TEST_NUM (ACS_PE_TEST_NUM_BASE + 1) +#define TEST_RULE "B_PE_01" +#define TEST_DESC "Check Arch symmetry across PE " #define NUM_OF_REGISTERS 32 @@ -194,7 +195,7 @@ payload(uint32_t num_pe) uint64_t reg_read_data, debug_data=0, array_index=0; if (num_pe == 1) { - val_print(ACS_PRINT_WARN, "\n Skipping as num of PE is 1 ", 0); + val_print(ACS_PRINT_DEBUG, "\n Skipping as num of PE is 1 ", 0); val_set_status(my_index, RESULT_SKIP(TEST_NUM, 01)); return; } @@ -258,9 +259,9 @@ os_c001_entry(uint32_t num_pe) payload(num_pe); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c002.c b/test_pool/pe/operating_system/test_os_c002.c index 18134fab..ed9ee39e 100755 --- a/test_pool/pe/operating_system/test_os_c002.c +++ b/test_pool/pe/operating_system/test_os_c002.c @@ -18,8 +18,9 @@ #include "val/include/bsa_acs_val.h" #include "val/include/bsa_acs_pe.h" -#define TEST_NUM (ACS_PE_TEST_NUM_BASE + 2) -#define TEST_DESC "B_PE_02: Check for number of PE " +#define TEST_NUM (ACS_PE_TEST_NUM_BASE + 2) +#define TEST_RULE "B_PE_02" +#define TEST_DESC "Check for number of PE " static void @@ -61,9 +62,9 @@ os_c002_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c003.c b/test_pool/pe/operating_system/test_os_c003.c index cccbf67a..1982628a 100755 --- a/test_pool/pe/operating_system/test_os_c003.c +++ b/test_pool/pe/operating_system/test_os_c003.c @@ -19,7 +19,8 @@ #include "val/include/val_interface.h" #define TEST_NUM (ACS_PE_TEST_NUM_BASE + 3) -#define TEST_DESC "B_PE_03: Check for AdvSIMD and FP support " +#define TEST_RULE "B_PE_03" +#define TEST_DESC "Check for AdvSIMD and FP support " static void @@ -53,9 +54,9 @@ os_c003_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c004.c b/test_pool/pe/operating_system/test_os_c004.c index bf4630d8..5158d511 100755 --- a/test_pool/pe/operating_system/test_os_c004.c +++ b/test_pool/pe/operating_system/test_os_c004.c @@ -19,7 +19,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_PE_TEST_NUM_BASE + 4) -#define TEST_DESC "B_PE_04: Check PE 4KB Granule Support " +#define TEST_RULE "B_PE_04" +#define TEST_DESC "Check PE 4KB Granule Support " static void @@ -51,9 +52,9 @@ os_c004_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c005.c b/test_pool/pe/operating_system/test_os_c005.c index e15365aa..195ceb17 100755 --- a/test_pool/pe/operating_system/test_os_c005.c +++ b/test_pool/pe/operating_system/test_os_c005.c @@ -19,7 +19,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_PE_TEST_NUM_BASE + 5) -#define TEST_DESC "B_PE_05: Check HW Coherence support " +#define TEST_RULE "B_PE_05" +#define TEST_DESC "Check HW Coherence support " static void @@ -60,9 +61,9 @@ os_c005_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c006.c b/test_pool/pe/operating_system/test_os_c006.c index e590bcc0..1e0b1893 100755 --- a/test_pool/pe/operating_system/test_os_c006.c +++ b/test_pool/pe/operating_system/test_os_c006.c @@ -19,7 +19,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_PE_TEST_NUM_BASE + 6) -#define TEST_DESC "B_PE_06: Check Cryptographic extensions " +#define TEST_RULE "B_PE_06" +#define TEST_DESC "Check Cryptographic extensions " static void @@ -51,9 +52,9 @@ os_c006_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c007.c b/test_pool/pe/operating_system/test_os_c007.c index 5176cc79..ea565dec 100755 --- a/test_pool/pe/operating_system/test_os_c007.c +++ b/test_pool/pe/operating_system/test_os_c007.c @@ -19,7 +19,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_PE_TEST_NUM_BASE + 7) -#define TEST_DESC "B_PE_07: Check Little Endian support " +#define TEST_RULE "B_PE_07" +#define TEST_DESC "Check Little Endian support " static void @@ -53,9 +54,9 @@ os_c007_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c008.c b/test_pool/pe/operating_system/test_os_c008.c index 2e1658bf..bc855686 100755 --- a/test_pool/pe/operating_system/test_os_c008.c +++ b/test_pool/pe/operating_system/test_os_c008.c @@ -19,7 +19,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_PE_TEST_NUM_BASE + 8) -#define TEST_DESC "B_PE_08: Check EL1 and EL0 implementation " +#define TEST_RULE "B_PE_08" +#define TEST_DESC "Check EL1 and EL0 implementation " static void @@ -50,9 +51,9 @@ os_c008_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c009.c b/test_pool/pe/operating_system/test_os_c009.c index 55dc3d3b..579dc25f 100755 --- a/test_pool/pe/operating_system/test_os_c009.c +++ b/test_pool/pe/operating_system/test_os_c009.c @@ -18,8 +18,9 @@ #include "val/include/bsa_acs_val.h" #include "val/include/bsa_acs_pe.h" -#define TEST_NUM (ACS_PE_TEST_NUM_BASE + 9) -#define TEST_DESC "B_PE_09: Check for PMU and PMU counters " +#define TEST_NUM (ACS_PE_TEST_NUM_BASE + 9) +#define TEST_RULE "B_PE_09" +#define TEST_DESC "Check for PMU and PMU counters " static void @@ -60,9 +61,9 @@ os_c009_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c010.c b/test_pool/pe/operating_system/test_os_c010.c index fbf35ea6..f25a1cb5 100755 --- a/test_pool/pe/operating_system/test_os_c010.c +++ b/test_pool/pe/operating_system/test_os_c010.c @@ -20,7 +20,8 @@ #define TEST_NUM (ACS_PE_TEST_NUM_BASE + 10) -#define TEST_DESC "B_PE_10: Check PMU Overflow signal " +#define TEST_RULE "B_PE_10" +#define TEST_DESC "Check PMU Overflow signal " static uint32_t int_id; static void *branch_to_test; @@ -89,10 +90,12 @@ payload() return; } - val_pe_install_esr(EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS, esr); - val_pe_install_esr(EXCEPT_AARCH64_SERROR, esr); - - int_id = val_pe_get_pmu_gsiv(index); //This is currently set to zero + int_id = val_pe_get_pmu_gsiv(index); + if (int_id == 0) { + /* PMU interrupt number not updated */ + val_set_status(index, RESULT_SKIP(TEST_NUM, 02)); + return; + } if (val_gic_install_isr(int_id, isr)) { val_print(ACS_PRINT_ERR, "\n GIC Install Handler Failed...", 0); @@ -100,6 +103,9 @@ payload() return; } + val_pe_install_esr(EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS, esr); + val_pe_install_esr(EXCEPT_AARCH64_SERROR, esr); + branch_to_test = &&exception_taken; set_pmu_overflow(); @@ -130,9 +136,9 @@ os_c010_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c011.c b/test_pool/pe/operating_system/test_os_c011.c index 4e0fa45b..d60fc2e0 100644 --- a/test_pool/pe/operating_system/test_os_c011.c +++ b/test_pool/pe/operating_system/test_os_c011.c @@ -18,56 +18,31 @@ #include "val/include/bsa_acs_val.h" #include "val/include/bsa_acs_pe.h" -#define TEST_NUM (ACS_PE_TEST_NUM_BASE + 11) -#define TEST_DESC "B_PE_11: Check num of Breakpoints & type " +#define TEST_NUM (ACS_PE_TEST_NUM_BASE + 11) +#define TEST_RULE "B_PE_11" +#define TEST_DESC "Check num of Breakpoints and type " static void payload() { uint64_t data = 0; - int32_t i, breakpointcount; - uint32_t bt, addr_breakpoint = 0; - uint32_t contextid_breakpoint = 0; - uint32_t vmid_breakpoint = 0; + int32_t breakpointcount; + uint32_t context_aware_breakpoints = 0; uint32_t pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); data = val_pe_reg_read(ID_AA64DFR0_EL1); - breakpointcount = VAL_EXTRACT_BITS(data, 12, 15); - if (breakpointcount < 5) { //bits 15:12 for Number of breakpoints - 1 + /* bits 15:12 for Number of breakpoints - 1 */ + breakpointcount = VAL_EXTRACT_BITS(data, 12, 15) + 1; + if (breakpointcount < 6) { val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 01)); return; } - for (i = 0; i <= breakpointcount; i++) { - - data = val_pe_reg_read(i + DBGBCR0_EL1); - /* breakpoint type : bits 23:20 - * Shift by 1 to get only 3 bit to ignore LSB*/ - bt = (((VAL_EXTRACT_BITS(data, 20, 23)) >> 1) & 0x7); - - /* BT is 0b000x: virtual address*/ - if (bt == 0x00) - addr_breakpoint++; - - /* BT is 0b001x, 0b011x, or 0b110x: Single Context ID. - BT is 0b111x: Two Context ID values*/ - if (bt == 0x01 || bt == 0x03 || bt == 0x06 || bt == 0x07) - contextid_breakpoint++; - - /* BT is 0b100x: VMID*/ - if (bt == 0x4) - vmid_breakpoint++; - - /* BT is 0b101x: VMID and a Context ID */ - if (bt == 0x5) { - vmid_breakpoint++; - contextid_breakpoint++; - } - } - - if ((addr_breakpoint >= 2) || (contextid_breakpoint >= 2) || (vmid_breakpoint >= 2)) + /*bits [31:28] Number of breakpoints that are context-aware, minus 1*/ + context_aware_breakpoints = VAL_EXTRACT_BITS(data, 28, 31) + 1; + if (context_aware_breakpoints > 1) val_set_status(pe_index, RESULT_PASS(TEST_NUM, 01)); else val_set_status(pe_index, RESULT_FAIL(TEST_NUM, 02)); @@ -90,9 +65,9 @@ os_c011_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c012.c b/test_pool/pe/operating_system/test_os_c012.c index fbcc6519..53dd50f4 100755 --- a/test_pool/pe/operating_system/test_os_c012.c +++ b/test_pool/pe/operating_system/test_os_c012.c @@ -19,7 +19,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_PE_TEST_NUM_BASE + 12) -#define TEST_DESC "B_PE_12: Check Synchronous Watchpoints " +#define TEST_RULE "B_PE_12" +#define TEST_DESC "Check Synchronous Watchpoints " static void @@ -51,9 +52,9 @@ os_c012_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c013.c b/test_pool/pe/operating_system/test_os_c013.c index 1342a167..34f85057 100755 --- a/test_pool/pe/operating_system/test_os_c013.c +++ b/test_pool/pe/operating_system/test_os_c013.c @@ -18,8 +18,9 @@ #include "val/include/bsa_acs_val.h" #include "val/include/bsa_acs_pe.h" -#define TEST_NUM (ACS_PE_TEST_NUM_BASE + 13) -#define TEST_DESC "B_PE_13: Check CRC32 instruction support " +#define TEST_NUM (ACS_PE_TEST_NUM_BASE + 13) +#define TEST_RULE "B_PE_13" +#define TEST_DESC "Check CRC32 instruction support " static void @@ -51,9 +52,9 @@ os_c013_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c014.c b/test_pool/pe/operating_system/test_os_c014.c index 4fde05d8..f625a6b4 100644 --- a/test_pool/pe/operating_system/test_os_c014.c +++ b/test_pool/pe/operating_system/test_os_c014.c @@ -19,7 +19,8 @@ #include "val/include/val_interface.h" #define TEST_NUM (ACS_PE_TEST_NUM_BASE + 14) -#define TEST_DESC "B_PE_15: Check PAuth if implementation " +#define TEST_RULE "B_PE_15" +#define TEST_DESC "Check PAuth if implementation " static void check_pauth_algorithm(uint32_t index, uint64_t data) { @@ -69,8 +70,8 @@ os_c014_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c015.c b/test_pool/pe/operating_system/test_os_c015.c index 29541b86..32e4df26 100644 --- a/test_pool/pe/operating_system/test_os_c015.c +++ b/test_pool/pe/operating_system/test_os_c015.c @@ -20,7 +20,8 @@ #include "val/include/val_interface.h" #define TEST_NUM (ACS_PE_TEST_NUM_BASE + 15) -#define TEST_DESC "B_PE_17: Check SPE if implemented " +#define TEST_RULE "B_PE_17" +#define TEST_DESC "Check SPE if implemented " static void @@ -65,8 +66,8 @@ os_c015_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c016.c b/test_pool/pe/operating_system/test_os_c016.c index 55eb8b61..0fbbdfdd 100644 --- a/test_pool/pe/operating_system/test_os_c016.c +++ b/test_pool/pe/operating_system/test_os_c016.c @@ -20,7 +20,8 @@ #include "val/include/val_interface.h" #define TEST_NUM (ACS_PE_TEST_NUM_BASE + 16) -#define TEST_DESC "B_SEC_01: Check Speculation Restriction " +#define TEST_RULE "B_SEC_01" +#define TEST_DESC "Check Speculation Restriction " static void @@ -54,8 +55,8 @@ os_c016_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c017.c b/test_pool/pe/operating_system/test_os_c017.c index 1eb20e9c..0e82529a 100755 --- a/test_pool/pe/operating_system/test_os_c017.c +++ b/test_pool/pe/operating_system/test_os_c017.c @@ -20,7 +20,8 @@ #include "val/include/val_interface.h" #define TEST_NUM (ACS_PE_TEST_NUM_BASE + 17) -#define TEST_DESC "B_SEC_02: Check Speculative Str Bypass Safe" +#define TEST_RULE "B_SEC_02" +#define TEST_DESC "Check Speculative Str Bypass Safe " static void @@ -49,8 +50,8 @@ os_c017_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c018.c b/test_pool/pe/operating_system/test_os_c018.c index e3404e10..b6785fa9 100755 --- a/test_pool/pe/operating_system/test_os_c018.c +++ b/test_pool/pe/operating_system/test_os_c018.c @@ -20,7 +20,8 @@ #include "val/include/val_interface.h" #define TEST_NUM (ACS_PE_TEST_NUM_BASE + 18) -#define TEST_DESC "B_SEC_03: Check PEs Impl CSDB,SSBB,PSSBB " +#define TEST_RULE "B_SEC_03" +#define TEST_DESC "Check PEs Impl CSDB,SSBB,PSSBB " static void @@ -49,8 +50,8 @@ os_c018_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c019.c b/test_pool/pe/operating_system/test_os_c019.c index c1249342..c60b4b14 100755 --- a/test_pool/pe/operating_system/test_os_c019.c +++ b/test_pool/pe/operating_system/test_os_c019.c @@ -20,7 +20,8 @@ #include "val/include/val_interface.h" #define TEST_NUM (ACS_PE_TEST_NUM_BASE + 19) -#define TEST_DESC "B_SEC_04: Check PEs Implement SB Barrier " +#define TEST_RULE "B_SEC_04" +#define TEST_DESC "Check PEs Implement SB Barrier " static void @@ -49,8 +50,8 @@ os_c019_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/operating_system/test_os_c020.c b/test_pool/pe/operating_system/test_os_c020.c index e09d0d86..ae378ab5 100755 --- a/test_pool/pe/operating_system/test_os_c020.c +++ b/test_pool/pe/operating_system/test_os_c020.c @@ -20,7 +20,8 @@ #include "val/include/val_interface.h" #define TEST_NUM (ACS_PE_TEST_NUM_BASE + 20) -#define TEST_DESC "B_SEC_05: Check PE Impl CFP,DVP,CPP RCTX " +#define TEST_RULE "B_SEC_05" +#define TEST_DESC "Check PE Impl CFP,DVP,CPP RCTX " static void @@ -49,8 +50,8 @@ os_c020_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/pe/platform_security/test_ps_c001.c b/test_pool/pe/platform_security/test_ps_c001.c index 2a18b81a..5834b02f 100755 --- a/test_pool/pe/platform_security/test_ps_c001.c +++ b/test_pool/pe/platform_security/test_ps_c001.c @@ -18,8 +18,9 @@ #include "val/include/bsa_acs_val.h" #include "val/include/bsa_acs_pe.h" -#define TEST_NUM (ACS_PE_PS_TEST_NUM_BASE + 1) -#define TEST_DESC "B_PE_23, B_PE_24: Check EL3 implementation " +#define TEST_NUM (ACS_PE_PS_TEST_NUM_BASE + 1) +#define TEST_RULE "B_PE_23, B_PE_24" +#define TEST_DESC "Check EL3 implementation " static void @@ -50,9 +51,9 @@ ps_c001_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/peripherals/operating_system/test_os_d001.c b/test_pool/peripherals/operating_system/test_os_d001.c index 84683dfd..b8f4d669 100755 --- a/test_pool/peripherals/operating_system/test_os_d001.c +++ b/test_pool/peripherals/operating_system/test_os_d001.c @@ -22,7 +22,8 @@ #include "val/include/bsa_acs_pcie.h" #define TEST_NUM (ACS_PER_TEST_NUM_BASE + 1) -#define TEST_DESC "B_PER_01,B_PER_02: USB CTRL Interface (PCIe)" +#define TEST_RULE "B_PER_01, B_PER_02" +#define TEST_DESC "USB CTRL Interface (PCIe) " static void @@ -46,7 +47,8 @@ payload() interface = (interface >> 8) & 0xFF; if (ret == PCIE_NO_MAPPING || (interface < 0x20) || (interface == 0xFF)) { val_print(ACS_PRINT_WARN, "\n WARN: USB CTRL ECAM access failed 0x%x ", interface); - val_print(ACS_PRINT_WARN, "\n Re-checking USB CTRL using PciIo protocol ", 0); + val_print(ACS_PRINT_WARN, "\n Re-checking using PCIIO protocol", + 0); ret = val_pcie_io_read_cfg(bdf, 0x8, &interface); if (ret == PCIE_NO_MAPPING) { val_print(ACS_PRINT_ERR, "\n Reading device class code using PciIo protocol failed ", 0); @@ -84,9 +86,9 @@ os_d001_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/peripherals/operating_system/test_os_d002.c b/test_pool/peripherals/operating_system/test_os_d002.c index aa027dbe..9b8ef153 100755 --- a/test_pool/peripherals/operating_system/test_os_d002.c +++ b/test_pool/peripherals/operating_system/test_os_d002.c @@ -22,7 +22,8 @@ #include "val/include/bsa_acs_pcie.h" #define TEST_NUM (ACS_PER_TEST_NUM_BASE + 2) -#define TEST_DESC "B_PER_03: Check SATA CTRL Interface via PCIe" +#define TEST_RULE "B_PER_03" +#define TEST_DESC "Check SATA CTRL Interface via PCIe " static void @@ -85,9 +86,9 @@ os_d002_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/peripherals/operating_system/test_os_d003.c b/test_pool/peripherals/operating_system/test_os_d003.c index 7f2bcf4b..7890817c 100755 --- a/test_pool/peripherals/operating_system/test_os_d003.c +++ b/test_pool/peripherals/operating_system/test_os_d003.c @@ -23,13 +23,16 @@ #include "val/include/bsa_acs_gic.h" #define TEST_NUM (ACS_PER_TEST_NUM_BASE + 3) -#define TEST_DESC "B_PER_05: Check BSA UART register offsets " -#define TEST_NUM2 (ACS_PER_TEST_NUM_BASE + 4) -#define TEST_DESC1 "B_PER_06: Check GENERIC UART Interrupt " +#define TEST_RULE "B_PER_05" +#define TEST_DESC "Check Arm BSA UART register offsets " +#define TEST_NUM1 (ACS_PER_TEST_NUM_BASE + 4) +#define TEST_RULE1 "B_PER_06, B_PER_07" +#define TEST_DESC1 "Check Arm GENERIC UART Interrupt " uint64_t l_uart_base; static uint32_t int_id; static void *branch_to_test; +static uint32_t test_pass, test_fail; static void @@ -113,7 +116,8 @@ isr() uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); uart_disable_txintr(); - val_print(ACS_PRINT_DEBUG, "\n Received interrupt ", 0); + test_pass++; + val_print(ACS_PRINT_DEBUG, "\n Received interrupt on %d ", int_id); val_set_status(index, RESULT_PASS(TEST_NUM, 0x01)); val_gic_end_of_interrupt(int_id); } @@ -164,49 +168,55 @@ payload() uint32_t count = val_peripheral_get_info(NUM_UART, 0); uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); uint32_t data; + uint32_t interface_type; val_pe_install_esr(EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS, esr); val_pe_install_esr(EXCEPT_AARCH64_SERROR, esr); branch_to_test = &&exception_taken; + val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); if (count == 0) { val_print(ACS_PRINT_WARN, "\n No UART defined by Platform ", 0); - val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); return; } while (count != 0) { + interface_type = val_peripheral_get_info(UART_INTERFACE_TYPE, count - 1); + if (interface_type != COMPATIBLE_FULL_16550 + && interface_type != COMPATIBLE_SUBSET_16550 + && interface_type != COMPATIBLE_GENERIC_16550) + { + l_uart_base = val_peripheral_get_info(UART_BASE0, count - 1); + if (l_uart_base == 0) { + val_set_status(index, RESULT_SKIP(TEST_NUM, 02)); + return; + } - l_uart_base = val_peripheral_get_info(UART_BASE0, count - 1); - if (l_uart_base == 0) { - val_set_status(index, RESULT_SKIP(TEST_NUM, 02)); - return; - } + uart_setup(); - uart_setup(); + if (validate_register_readonly(BSA_UARTFR, WIDTH_BIT8 | WIDTH_BIT16 | WIDTH_BIT32)) + return; - if (validate_register_readonly(BSA_UARTFR, WIDTH_BIT8 | WIDTH_BIT16 | WIDTH_BIT32)) - return; + if (validate_register_readonly(BSA_UARTRIS, WIDTH_BIT16 | WIDTH_BIT32)) + return; - if (validate_register_readonly(BSA_UARTRIS, WIDTH_BIT16 | WIDTH_BIT32)) - return; + if (validate_register_readonly(BSA_UARTMIS, WIDTH_BIT16 | WIDTH_BIT32)) + return; - if (validate_register_readonly(BSA_UARTMIS, WIDTH_BIT16 | WIDTH_BIT32)) - return; + /* Check bits 11:8 in the UARTDR reg are read-only */ + data = uart_reg_read(BSA_UARTDR, WIDTH_BIT32); + uart_reg_write(BSA_UARTDR, WIDTH_BIT32, data | 0x0F00); + data = (data >> 8) & 0x0F; + if (data != ((uart_reg_read(BSA_UARTDR, WIDTH_BIT32)>>8) & 0x0F)) { + val_print(ACS_PRINT_ERR, "\n UARTDR Bits 11:8 are not Read Only", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM, BSA_UARTDR)); + return; + } - /* Check bits 11:8 in the UARTDR reg are read-only */ - data = uart_reg_read(BSA_UARTDR, WIDTH_BIT32); - uart_reg_write(BSA_UARTDR, WIDTH_BIT32, data | 0x0F00); - data = (data >> 8) & 0x0F; - if (data != ((uart_reg_read(BSA_UARTDR, WIDTH_BIT32)>>8) & 0x0F)) { - val_print(ACS_PRINT_ERR, "\n UARTDR Bits 11:8 are not Read Only", 0); - val_set_status(index, RESULT_FAIL(TEST_NUM, BSA_UARTDR)); - return; + val_set_status(index, RESULT_PASS(TEST_NUM, 01)); } - val_set_status(index, RESULT_PASS(TEST_NUM, 01)); - count--; } exception_taken: @@ -220,44 +230,56 @@ payload1() uint32_t count = val_peripheral_get_info(NUM_UART, 0); uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); uint32_t timeout = TIMEOUT_MEDIUM; + uint32_t interface_type; if (count == 0) { - val_set_status(index, RESULT_SKIP(TEST_NUM2, 01)); + val_set_status(index, RESULT_SKIP(TEST_NUM1, 01)); return; } - while (count != 0) { + val_set_status(index, RESULT_FAIL(TEST_NUM1, 01)); + while (count != 0) { + timeout = TIMEOUT_MEDIUM; int_id = val_peripheral_get_info(UART_GSIV, count - 1); - - /* If Interrupt ID is available, check for interrupt generation */ - if (int_id != 0x0) { - /* PASS will be set from ISR */ - val_set_status(index, RESULT_PENDING(TEST_NUM2)); - - if (val_gic_install_isr(int_id, isr)) { - val_print(ACS_PRINT_ERR, "\n GIC Install Handler Failed...", 0); - val_set_status(index, RESULT_FAIL(TEST_NUM2, 01)); - return; - } - - uart_enable_txintr(); - val_print_raw(g_print_level, "\nTest Message ", 0); - - while ((--timeout > 0) && (IS_RESULT_PENDING(val_get_status(index)))) { - }; - - if (timeout == 0) { - val_print(ACS_PRINT_ERR, "\n Did not receive UART interrupt on %d ", int_id); - val_set_status(index, RESULT_FAIL(TEST_NUM2, 02)); - return; + interface_type = val_peripheral_get_info(UART_INTERFACE_TYPE, count - 1); + if (interface_type != COMPATIBLE_FULL_16550 + && interface_type != COMPATIBLE_SUBSET_16550 + && interface_type != COMPATIBLE_GENERIC_16550) { + + /* If Interrupt ID is available, check for interrupt generation */ + if (int_id != 0x0) { + /* PASS will be set from ISR */ + val_set_status(index, RESULT_PENDING(TEST_NUM1)); + + if (val_gic_install_isr(int_id, isr)) { + val_print(ACS_PRINT_ERR, "\n GIC Install Handler Failed...", 0); + val_set_status(index, RESULT_FAIL(TEST_NUM1, 02)); + return; + } + + uart_enable_txintr(); + val_print_raw(g_print_level, "\nTest Message ", 0); + + while ((--timeout > 0) && (IS_RESULT_PENDING(val_get_status(index)))) { + }; + + if (timeout == 0) { + val_print(ACS_PRINT_ERR, "\n Did not receive UART interrupt on %d ", int_id); + test_fail++; + } + } else { + val_set_status(index, RESULT_SKIP(TEST_NUM1, 02)); } - } else { - val_set_status(index, RESULT_SKIP(TEST_NUM2, 03)); } - count--; } + + if (test_pass) + val_set_status(index, RESULT_PASS(TEST_NUM1, 02)); + else if (test_fail) + val_set_status(index, RESULT_FAIL(TEST_NUM1, 03)); + return; } @@ -279,18 +301,18 @@ os_d003_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); if (!status) { - status = val_initialize_test(TEST_NUM2, TEST_DESC1, val_pe_get_num()); + status = val_initialize_test(TEST_NUM1, TEST_DESC1, val_pe_get_num()); if (status != ACS_STATUS_SKIP) - val_run_test_payload(TEST_NUM2, num_pe, payload1, 0); + val_run_test_payload(TEST_NUM1, num_pe, payload1, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM2, num_pe); + status = val_check_for_error(TEST_NUM1, num_pe, TEST_RULE1); } - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/peripherals/operating_system/test_os_d004.c b/test_pool/peripherals/operating_system/test_os_d004.c index 6e974b0f..22c970eb 100644 --- a/test_pool/peripherals/operating_system/test_os_d004.c +++ b/test_pool/peripherals/operating_system/test_os_d004.c @@ -21,7 +21,8 @@ #include "val/include/bsa_acs_smmu.h" #define TEST_NUM (ACS_PER_TEST_NUM_BASE + 5) -#define TEST_DESC "B_PER_09,B_PER_10: Memory Attribute of DMA " +#define TEST_RULE "B_PER_09, B_PER_10" +#define TEST_DESC "Memory Attribute of DMA " /* For all DMA masters populated in the Info table, which are behind an SMMU, @@ -110,9 +111,9 @@ os_d004_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/peripherals/operating_system/test_os_d005.c b/test_pool/peripherals/operating_system/test_os_d005.c new file mode 100755 index 00000000..d41c1950 --- /dev/null +++ b/test_pool/peripherals/operating_system/test_os_d005.c @@ -0,0 +1,214 @@ +/** @file + * Copyright (c) 2016-2019, 2021 Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "val/include/bsa_acs_val.h" +#include "val/include/val_interface.h" + +#include "val/include/bsa_acs_peripherals.h" +#include "val/include/bsa_acs_pcie.h" + +#define TEST_NUM (ACS_PER_TEST_NUM_BASE + 6) +#define TEST_RULE "B_PER_06" +#define TEST_DESC "16550 compatible UART " + +static +void +uart_reg_write(uint64_t uart_base, uint32_t offset, uint32_t width_mask, uint32_t data) +{ + if (width_mask & WIDTH_BIT8) + *((volatile uint8_t *)(uart_base + offset)) = (uint8_t)data; + + if (width_mask & WIDTH_BIT16) + *((volatile uint16_t *)(uart_base + offset)) = (uint16_t)data; + + if (width_mask & WIDTH_BIT32) + *((volatile uint32_t *)(uart_base + offset)) = (uint32_t)data; + +} + +static +uint32_t +uart_reg_read(uint64_t uart_base, uint32_t offset, uint32_t width_mask) +{ + if (width_mask & WIDTH_BIT8) + return *((volatile uint8_t *)(uart_base + offset)); + + if (width_mask & WIDTH_BIT16) + return *((volatile uint16_t *)(uart_base + offset)); + + if (width_mask & WIDTH_BIT32) + return *((volatile uint32_t *)(uart_base + offset)); + + return 0; +} + +static +void +payload() +{ + + uint64_t count = val_peripheral_get_info(NUM_UART, 0); + uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); + uint32_t interface_type; + uint32_t baud_rate; + uint32_t counter_freq; + uint32_t ier_reg; + uint32_t ier_scratch2; + uint32_t ier_scratch3; + uint32_t mcr_reg; + uint32_t msr_status; + uint32_t divisor; + uint32_t uart_base; + uint32_t lcr_reg; + uint32_t lcr_scratch2; + uint32_t lcr_scratch3; + uint32_t skip_test = 0; + uint32_t test_fail = 0; + + if (count == 0) { + val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); + val_print(ACS_PRINT_DEBUG, "\n No UART defined by Platform ", 0); + return; + } + + while (count != 0) { + interface_type = val_peripheral_get_info(UART_INTERFACE_TYPE, count - 1); + if (interface_type == COMPATIBLE_FULL_16550 + || interface_type == COMPATIBLE_SUBSET_16550 + || interface_type == COMPATIBLE_GENERIC_16550) + { + skip_test = 1; + val_print(ACS_PRINT_DEBUG, "\n UART 16550 found with instance: %x", count - 1); + + /* Check the I/O base address */ + uart_base = val_peripheral_get_info(UART_BASE0, count - 1); + if (uart_base == 0) + { + val_print(ACS_PRINT_ERR, "\n UART base must be specified" + " for instance: %x", count - 1); + val_set_status(index, RESULT_FAIL(TEST_NUM, 01)); + return; + } + + /* Check the Baudrate from the hardware map */ + baud_rate = val_peripheral_get_info(UART_BAUDRATE, count - 1); + if (baud_rate < BAUDRATE_9600 || baud_rate > BAUDRATE_115200) + { + if (baud_rate != 0) + { + val_print(ACS_PRINT_ERR, "\n Baud rate %d outside" + " supported range", baud_rate); + val_print(ACS_PRINT_ERR, " for instance %x", count - 1); + test_fail = 1; + } + } + + /* Check the baudrate in the UART register. Obtained the divisor by + * enabling the divisor latch access and reading the divisor latch + * byte1 and byte2. Divisor = system clock speed / (16 * baudrate) + */ + uart_reg_write(uart_base, LCR, WIDTH_BIT8, DIVISOR_LATCH_EN); + divisor = uart_reg_read(uart_base, DIVISOR_LATCH_BYTE1, WIDTH_BIT8); + divisor |= uart_reg_read(uart_base, DIVISOR_LATCH_BYTE2, WIDTH_BIT8) << 8; + uart_reg_write(uart_base, LCR, WIDTH_BIT8, DIVISOR_LATCH_DIS); + counter_freq = val_timer_get_info(TIMER_INFO_CNTFREQ, 0); + baud_rate = counter_freq / (16 * divisor); + if (baud_rate < BAUDRATE_1200 || baud_rate > BAUDRATE_115200) + { + val_print(ACS_PRINT_ERR, "\n Baud rate %d outside supported range", baud_rate); + val_print(ACS_PRINT_ERR, " for instance %x", count - 1); + test_fail = 1; + } + + /* Check the read/write property of Line Control Register */ + lcr_reg = uart_reg_read(uart_base, LCR, WIDTH_BIT8); + uart_reg_write(uart_base, LCR, WIDTH_BIT8, 0); + lcr_scratch2 = uart_reg_read(uart_base, LCR, WIDTH_BIT8); + uart_reg_write(uart_base, LCR, WIDTH_BIT8, 0xFF); + lcr_scratch3 = uart_reg_read(uart_base, LCR, WIDTH_BIT8); + uart_reg_write(uart_base, LCR, WIDTH_BIT8, lcr_reg); + if ((lcr_scratch2 != 0) || (lcr_scratch3 != 0xFF)) + { + val_print(ACS_PRINT_ERR, "\n LCR register are not read/write" + " for instance: %x", count - 1); + test_fail = 1; + } + + /* Check the read/write property of Interrupt Enable Register */ + ier_reg = uart_reg_read(uart_base, IER, WIDTH_BIT8); + uart_reg_write(uart_base, IER, WIDTH_BIT8, 0); + ier_scratch2 = uart_reg_read(uart_base, IER, WIDTH_BIT8) & 0xF; + uart_reg_write(uart_base, IER, WIDTH_BIT8, 0xF); + ier_scratch3 = uart_reg_read(uart_base, IER, WIDTH_BIT8); + uart_reg_write(uart_base, IER, WIDTH_BIT8, ier_reg); + if ((ier_scratch2 != 0) || (ier_scratch3 != 0xF)) + { + val_print(ACS_PRINT_ERR, "\n IER register[0:3] are not read/write" + " for instance: %x", count - 1); + test_fail = 1; + } + + /* Check if UART is really present using loopback test mode */ + mcr_reg = uart_reg_read(uart_base, MCR, WIDTH_BIT8); + uart_reg_write(uart_base, MCR, WIDTH_BIT8, MCR_LOOP | 0xA); + msr_status = uart_reg_read(uart_base, MSR, WIDTH_BIT8); + uart_reg_write(uart_base, MCR, WIDTH_BIT8, mcr_reg); + if (msr_status != CTS_DCD_EN) + { + val_print(ACS_PRINT_ERR, "\n Loopback test mode failed" + " for instance: %x", count - 1); + test_fail = 1; + } + + } + count--; + } + + if (!skip_test) + val_set_status(index, RESULT_SKIP(TEST_NUM, 02)); + else if (test_fail) + val_set_status(index, RESULT_FAIL(TEST_NUM, 02)); + else + val_set_status(index, RESULT_PASS(TEST_NUM, 01)); + + return; +} + +/** + @brief Read PCI CFG space class and sub-class register + to determine the USB interface version +**/ +uint32_t +os_d005_entry(uint32_t num_pe) +{ + + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This test is run on single processor + + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/test_pool/power_wakeup/operating_system/test_os_u001.c b/test_pool/power_wakeup/operating_system/test_os_u001.c index 8cbfceea..28bbebca 100755 --- a/test_pool/power_wakeup/operating_system/test_os_u001.c +++ b/test_pool/power_wakeup/operating_system/test_os_u001.c @@ -21,20 +21,24 @@ #include "val/include/bsa_acs_wakeup.h" -#define TEST_DESC " TEST Wakeup from Power Semantic B \n" -#define TEST_NUM1 (ACS_WAKEUP_TEST_NUM_BASE + 1) -#define TEST_RULES "B_WAK_01,B_WAK_03,B_WAK_04,B_WAK_05,B_WAK_06,B_WAK_07,B_WAK_10,B_WAK_11 \n" -#define TEST_DESC1 "Wake from Watchdog WS0 Interrupt " +#define TEST_NUM1 (ACS_WAKEUP_TEST_NUM_BASE + 1) +#define TEST_RULE1 "B_WAK_01, B_WAK_02-07, B_WAK_10-11" +#define TEST_DESC1 "Wake from Watchdog WS0 Int " #define TEST_NUM2 (ACS_WAKEUP_TEST_NUM_BASE + 2) -#define TEST_DESC2 "Wake from System Timer Interrupt " +#define TEST_RULE2 "B_WAK_01, B_WAK_02-07, B_WAK_10-11" +#define TEST_DESC2 "Wake from System Timer Int " #define TEST_NUM3 (ACS_WAKEUP_TEST_NUM_BASE + 3) -#define TEST_DESC3 "Wake from EL0 PHY Timer Interrupt " +#define TEST_RULE3 "B_WAK_01, B_WAK_02-07, B_WAK_10-11" +#define TEST_DESC3 "Wake from EL0 PHY Timer Int " #define TEST_NUM4 (ACS_WAKEUP_TEST_NUM_BASE + 4) -#define TEST_DESC4 "Wake from EL0 VIRT Timer Interrupt" +#define TEST_RULE4 "B_WAK_01, B_WAK_02-07, B_WAK_10-11" +#define TEST_DESC4 "Wake from EL0 VIR Timer Int " #define TEST_NUM5 (ACS_WAKEUP_TEST_NUM_BASE + 5) -#define TEST_DESC5 "Wake from EL2 PHY Timer Interrupt " +#define TEST_RULE5 "B_WAK_01, B_WAK_02-07, B_WAK_10-11" +#define TEST_DESC5 "Wake from EL2 PHY Timer Int " static uint32_t intid; +static uint32_t failsafe_test_num; uint64_t timer_num; static @@ -70,7 +74,7 @@ isr_failsafe() uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); val_timer_set_phy_el1(0); val_print(ACS_PRINT_ERR, " Received Failsafe interrupt \n", 0); - val_set_status(index, RESULT_FAIL(TEST_NUM3, 01)); + val_set_status(index, RESULT_FAIL(failsafe_test_num, 01)); intid = val_timer_get_info(TIMER_INFO_PHY_EL1_INTID, 0); val_gic_end_of_interrupt(intid); } @@ -140,7 +144,7 @@ payload1() timer_num = val_wd_get_info(0, WD_INFO_COUNT); if(!timer_num){ - val_print(ACS_PRINT_DEBUG, " No watchdog implemented \n", 0); + val_print(ACS_PRINT_DEBUG, "\n No watchdog implemented ", 0); val_set_status(index, RESULT_SKIP(TEST_NUM1, 01)); return; } @@ -153,6 +157,7 @@ payload1() intid = val_wd_get_info(timer_num, WD_INFO_GSIV); status = val_gic_install_isr(intid, isr1); if (status == 0) { + failsafe_test_num = TEST_NUM1; wakeup_set_failsafe(); status = val_wd_set_ws0(timer_num, timer_expire_val); if (status) { @@ -169,7 +174,7 @@ payload1() } if(!ns_wdg){ - val_print(ACS_PRINT_WARN, " No non-secure watchdog implemented \n", 0); + val_print(ACS_PRINT_DEBUG, " No non-secure watchdog implemented \n", 0); val_set_status(index, RESULT_SKIP(TEST_NUM1, 02)); return; } @@ -187,7 +192,7 @@ payload2() timer_num = val_timer_get_info(TIMER_INFO_NUM_PLATFORM_TIMERS, 0); if(!timer_num){ - val_print(ACS_PRINT_WARN, " No system timers implemented \n", 0); + val_print(ACS_PRINT_DEBUG, " No system timers implemented \n", 0); val_set_status(index, RESULT_SKIP(TEST_NUM2, 01)); return; } @@ -218,6 +223,7 @@ payload2() status = val_gic_install_isr(intid, isr2); if(status == 0) { + failsafe_test_num = TEST_NUM2; wakeup_set_failsafe(); /* enable System timer */ val_timer_set_system_timer((addr_t)cnt_base_n, timer_expire_val); @@ -271,10 +277,12 @@ payload4() val_set_status(index, RESULT_FAIL(TEST_NUM4, 02)); return; } + failsafe_test_num = TEST_NUM4; wakeup_set_failsafe(); val_timer_set_vir_el1(timer_expire_val); val_power_enter_semantic(BSA_POWER_SEM_B); wakeup_clear_failsafe(); + return; } @@ -292,10 +300,12 @@ payload5() val_set_status(index, RESULT_FAIL(TEST_NUM5, 02)); return; } + failsafe_test_num = TEST_NUM5; wakeup_set_failsafe(); val_timer_set_phy_el2(timer_expire_val); val_power_enter_semantic(BSA_POWER_SEM_B); wakeup_clear_failsafe(); + return; } uint32_t @@ -306,41 +316,35 @@ os_u001_entry(uint32_t num_pe) num_pe = 1; //This Timer test is run on single processor - val_print(ACS_PRINT_TEST, TEST_DESC, 0); - val_print(ACS_PRINT_DEBUG, TEST_RULES, 0); status_test = val_initialize_test(TEST_NUM1, TEST_DESC1, num_pe); if (status_test != ACS_STATUS_SKIP) val_run_test_payload(TEST_NUM1, num_pe, payload1, 0); - status = val_check_for_error(TEST_NUM1, num_pe); + status = val_check_for_error(TEST_NUM1, num_pe, TEST_RULE1); - val_print(ACS_PRINT_DEBUG, TEST_RULES, 0); status_test = val_initialize_test(TEST_NUM2, TEST_DESC2, num_pe); if (status_test != ACS_STATUS_SKIP) val_run_test_payload(TEST_NUM2, num_pe, payload2, 0); - status |= val_check_for_error(TEST_NUM2, num_pe); + status |= val_check_for_error(TEST_NUM2, num_pe, TEST_RULE2); - val_print(ACS_PRINT_DEBUG, TEST_RULES, 0); status_test = val_initialize_test(TEST_NUM3, TEST_DESC3, num_pe); if (status_test != ACS_STATUS_SKIP) val_run_test_payload(TEST_NUM3, num_pe, payload3, 0); - status |= val_check_for_error(TEST_NUM3, num_pe); + status |= val_check_for_error(TEST_NUM3, num_pe, TEST_RULE3); - val_print(ACS_PRINT_DEBUG, TEST_RULES, 0); status_test = val_initialize_test(TEST_NUM4, TEST_DESC4, num_pe); if (status_test != ACS_STATUS_SKIP) val_run_test_payload(TEST_NUM4, num_pe, payload4, 0); - status |= val_check_for_error(TEST_NUM4, num_pe); + status |= val_check_for_error(TEST_NUM4, num_pe, TEST_RULE4); /* Run this test if current exception level is EL2 */ if (val_pe_reg_read(CurrentEL) == AARCH64_EL2) { - val_print(ACS_PRINT_DEBUG, TEST_RULES, 0); status_test = val_initialize_test(TEST_NUM5, TEST_DESC5, num_pe); if (status_test != ACS_STATUS_SKIP) val_run_test_payload(TEST_NUM5, num_pe, payload5, 0); - status |= val_check_for_error(TEST_NUM5, num_pe); + status |= val_check_for_error(TEST_NUM5, num_pe, TEST_RULE5); } - val_report_status(0, BSA_ACS_END(TEST_NUM1)); + val_report_status(0, BSA_ACS_END(TEST_NUM1), NULL); return status; } diff --git a/test_pool/power_wakeup/operating_system/test_os_u002.c b/test_pool/power_wakeup/operating_system/test_os_u002.c index 55b0237d..e9b2d7b8 100644 --- a/test_pool/power_wakeup/operating_system/test_os_u002.c +++ b/test_pool/power_wakeup/operating_system/test_os_u002.c @@ -23,8 +23,8 @@ #include "val/include/bsa_std_smc.h" #define TEST_NUM (ACS_WAKEUP_TEST_NUM_BASE + 6) -#define TEST_RULES "B_WAK_02,B_WAK_07,B_WAK_09,B_WAK_10,B_WAK_11 \n" -#define TEST_DESC "Test No-Wake from Power Semantic F" +#define TEST_RULE "B_WAK_02,B_WAK_09-10" +#define TEST_DESC "Test No-Wake from Power Semantic F " static uint32_t intid, wakeup_event, cnt_base_n; static uint64_t timer_num, wd_num; @@ -105,7 +105,7 @@ payload_target_pe() val_pe_reg_write(VBAR_EL2, data2); val_gic_cpuif_init(); - val_suspend_pe(0, 0, 0); + val_suspend_pe(0, 0); // Set the status to indicate that target PE has resumed execution from sleep mode val_set_status(index, RESULT_PASS(TEST_NUM, 01)); } @@ -138,7 +138,7 @@ payload() // if none of these are present in a platform, skip the test wakeup_event = wakeup_event_for_semantic_f(); if (wakeup_event == 0) { - val_print(ACS_PRINT_WARN, "\n No Watchdogs and system timers present", 0); + val_print(ACS_PRINT_DEBUG, "\n No Watchdogs and system timers present", 0); val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); return; } @@ -280,14 +280,13 @@ os_u002_entry(uint32_t num_pe) num_pe = 1; //This test is run on single processor, which will start and trigger interrupt to // target PE. - val_print(ACS_PRINT_DEBUG, TEST_RULES, 0); status_test = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); if (status_test != ACS_STATUS_SKIP) val_run_test_payload(TEST_NUM, num_pe, payload, 0); - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/smmu/hypervisor/test_hyp_i001.c b/test_pool/smmu/hypervisor/test_hyp_i001.c index 59602ea9..ace22f0a 100644 --- a/test_pool/smmu/hypervisor/test_hyp_i001.c +++ b/test_pool/smmu/hypervisor/test_hyp_i001.c @@ -23,7 +23,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_SMMU_HYP_TEST_NUM_BASE + 1) -#define TEST_DESC "B_SMMU_16,B_SMMU_17: Check Stage2 SMMU functionality" +#define TEST_RULE "B_SMMU_16, B_SMMU_17" +#define TEST_DESC "Check Stage2 SMMU functionality " static void @@ -84,9 +85,9 @@ hyp_i001_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/smmu/hypervisor/test_hyp_i002.c b/test_pool/smmu/hypervisor/test_hyp_i002.c index 0ed9195c..903cadfc 100644 --- a/test_pool/smmu/hypervisor/test_hyp_i002.c +++ b/test_pool/smmu/hypervisor/test_hyp_i002.c @@ -23,7 +23,8 @@ #include "val/include/bsa_acs_pcie.h" #define TEST_NUM (ACS_SMMU_HYP_TEST_NUM_BASE + 2) -#define TEST_DESC "B_SMMU_18,B_SMMU_20: SMMU Revision,S-EL2 support Hyp" +#define TEST_RULE "B_SMMU_18, B_SMMU_20" +#define TEST_DESC "SMMU Revision,S-EL2 support Hyp " static void @@ -97,9 +98,9 @@ hyp_i002_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/smmu/hypervisor/test_hyp_i003.c b/test_pool/smmu/hypervisor/test_hyp_i003.c index 870db2b1..e43c5931 100644 --- a/test_pool/smmu/hypervisor/test_hyp_i003.c +++ b/test_pool/smmu/hypervisor/test_hyp_i003.c @@ -21,7 +21,8 @@ #include "val/include/bsa_acs_iovirt.h" #define TEST_NUM (ACS_SMMU_HYP_TEST_NUM_BASE + 3) -#define TEST_DESC "B_SMMU_19: SMMUv2 unique intr per ctxt bank " +#define TEST_RULE "B_SMMU_19" +#define TEST_DESC "SMMUv2 unique intr per ctxt bank " static void @@ -34,14 +35,14 @@ payload() num_smmu = val_smmu_get_info(SMMU_NUM_CTRL, 0); if (num_smmu == 0) { - val_print(ACS_PRINT_ERR, "\n No SMMU Controllers are discovered ", 0); + val_print(ACS_PRINT_DEBUG, "\n No SMMU Controllers are discovered ", 0); val_set_status(index, RESULT_SKIP(TEST_NUM, 3)); return; } while (num_smmu--) { if (val_smmu_get_info(SMMU_CTRL_ARCH_MAJOR_REV, num_smmu) == 3) { - val_print(ACS_PRINT_WARN, "\n Not valid for SMMU v3 ", 0); + val_print(ACS_PRINT_DEBUG, "\n Not valid for SMMU v3 ", 0); val_set_status(index, RESULT_SKIP(TEST_NUM, 2)); return; } @@ -70,9 +71,9 @@ hyp_i003_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/smmu/hypervisor/test_hyp_i004.c b/test_pool/smmu/hypervisor/test_hyp_i004.c index b39df7fd..c062853f 100644 --- a/test_pool/smmu/hypervisor/test_hyp_i004.c +++ b/test_pool/smmu/hypervisor/test_hyp_i004.c @@ -22,7 +22,8 @@ #include "val/include/bsa_acs_pcie.h" #define TEST_NUM (ACS_SMMU_HYP_TEST_NUM_BASE + 4) -#define TEST_DESC "B_SMMU_21,SMMU_01: SMMUv3 Integration compliance Chk" +#define TEST_RULE "B_SMMU_21, SMMU_01" +#define TEST_DESC "SMMUv3 Integration compliance " static void @@ -83,9 +84,9 @@ hyp_i004_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/smmu/hypervisor/test_hyp_i005.c b/test_pool/smmu/hypervisor/test_hyp_i005.c index 9918fda5..01a76b48 100644 --- a/test_pool/smmu/hypervisor/test_hyp_i005.c +++ b/test_pool/smmu/hypervisor/test_hyp_i005.c @@ -23,7 +23,8 @@ #include "val/include/bsa_acs_pcie.h" #define TEST_NUM (ACS_SMMU_HYP_TEST_NUM_BASE + 5) -#define TEST_DESC "B_SMMU_23: Check SMMU 16 Bit VMID Support " +#define TEST_RULE "B_SMMU_23" +#define TEST_DESC "Check SMMU 16 Bit VMID Support " static void @@ -78,9 +79,9 @@ hyp_i005_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/smmu/operating_system/test_os_i001.c b/test_pool/smmu/operating_system/test_os_i001.c index 073f45cd..f4405932 100755 --- a/test_pool/smmu/operating_system/test_os_i001.c +++ b/test_pool/smmu/operating_system/test_os_i001.c @@ -21,7 +21,8 @@ #include "val/include/bsa_acs_smmu.h" #define TEST_NUM (ACS_SMMU_TEST_NUM_BASE + 1) -#define TEST_DESC "B_SMMU_01: All SMMUs have same Arch Revision " +#define TEST_RULE "B_SMMU_01" +#define TEST_DESC "All SMMUs have same Arch Revision " static void @@ -73,9 +74,9 @@ os_i001_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/smmu/operating_system/test_os_i002.c b/test_pool/smmu/operating_system/test_os_i002.c index a0d14f07..09a78e14 100755 --- a/test_pool/smmu/operating_system/test_os_i002.c +++ b/test_pool/smmu/operating_system/test_os_i002.c @@ -22,7 +22,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_SMMU_TEST_NUM_BASE + 2) -#define TEST_DESC "B_SMMU_02: Check SMMU Granule Support " +#define TEST_RULE "B_SMMU_02" +#define TEST_DESC "Check SMMU Granule Support " static void @@ -111,9 +112,9 @@ os_i002_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/smmu/operating_system/test_os_i003.c b/test_pool/smmu/operating_system/test_os_i003.c index 7f56a120..9947f397 100755 --- a/test_pool/smmu/operating_system/test_os_i003.c +++ b/test_pool/smmu/operating_system/test_os_i003.c @@ -22,7 +22,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_SMMU_TEST_NUM_BASE + 3) -#define TEST_DESC "B_SMMU_03: Check Large Virtual Addr Support " +#define TEST_RULE "B_SMMU_03" +#define TEST_DESC "Check Large Virtual Addr Support " static void @@ -37,7 +38,7 @@ payload() data_va_range = VAL_EXTRACT_BITS(val_pe_reg_read(ID_AA64MMFR2_EL1), 16, 19); if (data_va_range == 0) { - val_print(ACS_PRINT_WARN, "\n Large VA Not Supported by PE ", 0); + val_print(ACS_PRINT_DEBUG, "\n Large VA Not Supported by PE ", 0); val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); return; } @@ -85,9 +86,9 @@ os_i003_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/smmu/operating_system/test_os_i004.c b/test_pool/smmu/operating_system/test_os_i004.c index bcefc6c7..e061adec 100755 --- a/test_pool/smmu/operating_system/test_os_i004.c +++ b/test_pool/smmu/operating_system/test_os_i004.c @@ -22,7 +22,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_SMMU_TEST_NUM_BASE + 4) -#define TEST_DESC "B_SMMU_04,B_SMMU_05: Check TLB Range Invalidation " +#define TEST_RULE "B_SMMU_04, B_SMMU_05" +#define TEST_DESC "Check TLB Range Invalidation " static void @@ -37,7 +38,7 @@ payload() data_pe_tlb = VAL_EXTRACT_BITS(val_pe_reg_read(ID_AA64ISAR0_EL1), 56, 59); if (data_pe_tlb != 0x2) { - val_print(ACS_PRINT_WARN, "\n TLB Range Invalid Not " + val_print(ACS_PRINT_DEBUG, "\n TLB Range Invalid Not " "Supported For PE ", 0); val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); return; @@ -45,14 +46,16 @@ payload() num_smmu = val_smmu_get_info(SMMU_NUM_CTRL, 0); if (num_smmu == 0) { - val_print(ACS_PRINT_ERR, "\n No SMMU Controllers are discovered ", 0); + val_print(ACS_PRINT_DEBUG, "\n No SMMU Controllers are discovered" + " ", 0); val_set_status(index, RESULT_SKIP(TEST_NUM, 02)); return; } while (num_smmu--) { if (val_smmu_get_info(SMMU_CTRL_ARCH_MAJOR_REV, num_smmu) < 3) { - val_print(ACS_PRINT_WARN, "\n Not valid for SMMUv2 or older version ", 0); + val_print(ACS_PRINT_DEBUG, "\n Not valid for SMMUv2 or older" + "version ", 0); val_set_status(index, RESULT_SKIP(TEST_NUM, 03)); return; } @@ -87,9 +90,9 @@ os_i004_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/smmu/operating_system/test_os_i005.c b/test_pool/smmu/operating_system/test_os_i005.c index 4ca9745c..73b73297 100644 --- a/test_pool/smmu/operating_system/test_os_i005.c +++ b/test_pool/smmu/operating_system/test_os_i005.c @@ -22,7 +22,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_SMMU_TEST_NUM_BASE + 5) -#define TEST_DESC "B_SMMU_06: Check Large Physical Addr Support " +#define TEST_RULE "B_SMMU_06" +#define TEST_DESC "Check Large Physical Addr Support " static void @@ -37,21 +38,24 @@ payload() data_pa_range = VAL_EXTRACT_BITS(val_pe_reg_read(ID_AA64MMFR0_EL1), 0, 3); if (data_pa_range != 0x6) { - val_print(ACS_PRINT_WARN, "\n Large PA Not Supported by PE ", 0); + val_print(ACS_PRINT_DEBUG, "\n Large PA Not Supported by PE " + " ", 0); val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); return; } num_smmu = val_smmu_get_info(SMMU_NUM_CTRL, 0); if (num_smmu == 0) { - val_print(ACS_PRINT_ERR, "\n No SMMU Controllers are discovered ", 0); + val_print(ACS_PRINT_DEBUG, "\n No SMMU Controllers are discovered " + " ", 0); val_set_status(index, RESULT_SKIP(TEST_NUM, 02)); return; } while (num_smmu--) { if (val_smmu_get_info(SMMU_CTRL_ARCH_MAJOR_REV, num_smmu) == 2) { - val_print(ACS_PRINT_WARN, "\n Large PA Not Supported in SMMUv2", 0); + val_print(ACS_PRINT_ERR, "\n Large PA Not Supported in" + " SMMUv2", 0); val_set_status(index, RESULT_FAIL(TEST_NUM, 01)); return; } @@ -85,9 +89,9 @@ os_i005_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/smmu/operating_system/test_os_i006.c b/test_pool/smmu/operating_system/test_os_i006.c index fdaa088a..6255a24b 100755 --- a/test_pool/smmu/operating_system/test_os_i006.c +++ b/test_pool/smmu/operating_system/test_os_i006.c @@ -23,7 +23,8 @@ #include "val/include/bsa_acs_pcie.h" #define TEST_NUM (ACS_SMMU_TEST_NUM_BASE + 6) -#define TEST_DESC "B_SMMU_08,B_SMMU_09: SMMU revision and S-EL2 support" +#define TEST_RULE "B_SMMU_08, B_SMMU_09" +#define TEST_DESC "SMMU revision and S-EL2 support " static void @@ -97,9 +98,9 @@ os_i006_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/smmu/operating_system/test_os_i007.c b/test_pool/smmu/operating_system/test_os_i007.c index 631d8aa9..505cb365 100644 --- a/test_pool/smmu/operating_system/test_os_i007.c +++ b/test_pool/smmu/operating_system/test_os_i007.c @@ -23,7 +23,8 @@ #include "val/include/bsa_acs_pcie.h" #define TEST_NUM (ACS_SMMU_TEST_NUM_BASE + 7) -#define TEST_DESC "B_SMMU_13: Check SMMU 16 Bit ASID Support " +#define TEST_RULE "B_SMMU_13" +#define TEST_DESC "Check SMMU 16 Bit ASID Support " static void @@ -90,9 +91,9 @@ os_i007_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/smmu/operating_system/test_os_i008.c b/test_pool/smmu/operating_system/test_os_i008.c index 4d9712b0..918a702a 100644 --- a/test_pool/smmu/operating_system/test_os_i008.c +++ b/test_pool/smmu/operating_system/test_os_i008.c @@ -23,7 +23,8 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_SMMU_TEST_NUM_BASE + 8) -#define TEST_DESC "B_SMMU_14: Check SMMU Endianess Support " +#define TEST_RULE "B_SMMU_14" +#define TEST_DESC "Check SMMU Endianess Support " static void @@ -99,9 +100,9 @@ os_i008_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/smmu/operating_system/test_os_i009.c b/test_pool/smmu/operating_system/test_os_i009.c index 3b313e05..1756df0e 100644 --- a/test_pool/smmu/operating_system/test_os_i009.c +++ b/test_pool/smmu/operating_system/test_os_i009.c @@ -22,7 +22,8 @@ #include "val/include/bsa_acs_smmu.h" #define TEST_NUM (ACS_SMMU_TEST_NUM_BASE + 9) -#define TEST_DESC "B_SMMU_11,B_SMMU_22: Check system for MPAM support " +#define TEST_RULE "B_SMMU_11, B_SMMU_22" +#define TEST_DESC "Check system for MPAM support " static void @@ -45,13 +46,13 @@ payload() num_smmu = val_smmu_get_info(SMMU_NUM_CTRL, 0); if (num_smmu == 0) { - val_print(ACS_PRINT_ERR, "\n No SMMU Controllers are discovered ", 0); + val_print(ACS_PRINT_DEBUG, "\n No SMMU Controllers are discovered ", 0); val_set_status(index, RESULT_SKIP(TEST_NUM, 03)); return; } if (!(pe_mpam || frac)) { - val_print(ACS_PRINT_ERR, "\n No MPAM controlled resources present ", 0); + val_print(ACS_PRINT_DEBUG, "\n No MPAM controlled resources present ", 0); val_set_status(index, RESULT_SKIP(TEST_NUM, 03)); return; } @@ -60,7 +61,7 @@ payload() smmu_rev = val_smmu_get_info(SMMU_CTRL_ARCH_MAJOR_REV, num_smmu); if (smmu_rev < 3) { // MPAM support not required for SMMUv2 and below - val_print(ACS_PRINT_WARN, "\n SMMU revision v2 or lower detected ", 0); + val_print(ACS_PRINT_DEBUG, "\n SMMU revision v2 or lower detected ", 0); val_set_status(index, RESULT_SKIP(TEST_NUM, 04)); return; } @@ -107,9 +108,9 @@ os_i009_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/timer/operating_system/test_os_t001.c b/test_pool/timer/operating_system/test_os_t001.c index 88313ef5..60d9e686 100755 --- a/test_pool/timer/operating_system/test_os_t001.c +++ b/test_pool/timer/operating_system/test_os_t001.c @@ -21,7 +21,8 @@ #include "val/include/bsa_acs_timer.h" #define TEST_NUM (ACS_TIMER_TEST_NUM_BASE + 1) -#define TEST_DESC "B_TIME_01,B_TIME_02: Check Counter Frequency " +#define TEST_RULE "B_TIME_01, B_TIME_02" +#define TEST_DESC "Check Counter Frequency " static void @@ -56,9 +57,9 @@ os_t001_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/timer/operating_system/test_os_t002.c b/test_pool/timer/operating_system/test_os_t002.c index d8c31c43..567c82f8 100644 --- a/test_pool/timer/operating_system/test_os_t002.c +++ b/test_pool/timer/operating_system/test_os_t002.c @@ -21,7 +21,8 @@ #include "val/include/bsa_acs_timer.h" #define TEST_NUM (ACS_TIMER_TEST_NUM_BASE + 2) -#define TEST_DESC "B_TIME_06: SYS Timer if PE Timer not ON " +#define TEST_RULE "B_TIME_06" +#define TEST_DESC "SYS Timer if PE Timer not ON " static void @@ -66,9 +67,9 @@ os_t002_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/timer/operating_system/test_os_t003.c b/test_pool/timer/operating_system/test_os_t003.c index 6740c0f5..2248dcfd 100644 --- a/test_pool/timer/operating_system/test_os_t003.c +++ b/test_pool/timer/operating_system/test_os_t003.c @@ -20,7 +20,8 @@ #include "val/include/bsa_acs_timer.h" #define TEST_NUM (ACS_TIMER_TEST_NUM_BASE + 3) -#define TEST_DESC "B_TIME_07,B_TIME_10: Memory mapped timer check" +#define TEST_RULE "B_TIME_07, B_TIME_10" +#define TEST_DESC "Memory mapped timer check " #define ARBIT_VALUE 0xA000 @@ -30,12 +31,12 @@ payload() { uint64_t cnt_ctl_base, cnt_base_n; - uint32_t data, status, ns_timer = 0; + uint32_t data, data1, status, ns_timer = 0; uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); uint64_t timer_num = val_timer_get_info(TIMER_INFO_NUM_PLATFORM_TIMERS, 0); if (!timer_num) { - val_print(ACS_PRINT_WARN, "\n No System timers are defined ", 0); + val_print(ACS_PRINT_DEBUG, "\n No System timers are defined ", 0); val_set_status(index, RESULT_SKIP(TEST_NUM, 0x1)); return; } @@ -80,12 +81,17 @@ payload() return; } - data = val_mmio_read(cnt_base_n + CNTPCT); - // Writes to Read-Only registers should be ignored - val_mmio_write(cnt_base_n + CNTPCT, data - ARBIT_VALUE); - if (val_mmio_read(cnt_base_n + CNTPCT) < data) { + data = val_mmio_read(cnt_base_n + CNTPCT_LOWER); + data1 = val_mmio_read(cnt_base_n + CNTPCT_HIGHER); + + // Writes to Read-Only registers should be ignore + val_mmio_write(cnt_base_n + CNTPCT_LOWER, data - ARBIT_VALUE); + val_mmio_write(cnt_base_n + CNTPCT_HIGHER, data1 - ARBIT_VALUE); + + if ((val_mmio_read(cnt_base_n + CNTPCT_LOWER) != data) || + (val_mmio_read(cnt_base_n + CNTPCT_HIGHER) != data1)) { val_set_status(index, RESULT_FAIL(TEST_NUM, 0x4)); - val_print(ACS_PRINT_ERR, "\n CNTBaseN offset 0 should be read-only ", 0); + val_print(ACS_PRINT_ERR, "\n CNTBaseN: CNTPCT reg should be read-only ", 0); return; } @@ -102,22 +108,24 @@ payload() } val_mmio_write(cnt_base_n + CNTP_CTL, 0x0); // Disable timer - /* Write a random value to RW reg and verify*/ data = 0xFF00FF00; - val_mmio_write(cnt_base_n + CNTP_CVAL_LOW, data); - if (data != val_mmio_read(cnt_base_n + CNTP_CVAL_LOW)) { + /* Write a random value to CNTP_CVAL[31:0]*/ + val_mmio_write(cnt_base_n + CNTP_CVAL_LOWER, data); + /* Write a random value to CNTP_CVAL[63:32]*/ + val_mmio_write(cnt_base_n + CNTP_CVAL_HIGHER, data); + + if (data != val_mmio_read(cnt_base_n + CNTP_CVAL_LOWER)) { val_print(ACS_PRINT_ERR, "\n Read-write check failed for " - "CNTBaseN.CNTP_CVAL[31:0], expected value %x ", data); + "CNTBaseN.CNTP_CVAL[31:0], read value %x ", + val_mmio_read(cnt_base_n + CNTP_CVAL_LOWER)); val_set_status(index, RESULT_FAIL(TEST_NUM, 0x6)); return; } - /* Write a random value to RW reg and verify*/ - data = 0x00FF00FF; - val_mmio_write(cnt_base_n + CNTP_CVAL_HIGH, data); - if (data != val_mmio_read(cnt_base_n + CNTP_CVAL_HIGH)) { + if (data != val_mmio_read(cnt_base_n + CNTP_CVAL_HIGHER)) { val_print(ACS_PRINT_ERR, "\n Read-write check failed for" - " CNTBaseN.CNTP_CVAL[63:32], expected value %x ", data); + " CNTBaseN.CNTP_CVAL[63:32], read value %x ", + val_mmio_read(cnt_base_n + CNTP_CVAL_HIGHER)); val_set_status(index, RESULT_FAIL(TEST_NUM, 0x7)); return; } @@ -146,9 +154,9 @@ os_t003_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/timer/operating_system/test_os_t004.c b/test_pool/timer/operating_system/test_os_t004.c index 4f94b0c4..2c1cde3f 100644 --- a/test_pool/timer/operating_system/test_os_t004.c +++ b/test_pool/timer/operating_system/test_os_t004.c @@ -22,7 +22,8 @@ #define TEST_NUM (ACS_TIMER_TEST_NUM_BASE + 4) -#define TEST_DESC "B_TIME_08: Generate Mem Mapped SYS Timer Intr " +#define TEST_RULE "B_TIME_08" +#define TEST_DESC "Generate Mem Mapped SYS Timer Intr " static uint32_t intid; static uint64_t cnt_base_n; @@ -52,7 +53,7 @@ payload() uint64_t timer_num = val_timer_get_info(TIMER_INFO_NUM_PLATFORM_TIMERS, 0); if (!timer_num) { - val_print(ACS_PRINT_WARN, "\n No System timers are defined ", 0); + val_print(ACS_PRINT_DEBUG, "\n No System timers are defined ", 0); val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); return; } @@ -125,9 +126,9 @@ os_t004_entry(uint32_t num_pe) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/timer/operating_system/test_os_t005.c b/test_pool/timer/operating_system/test_os_t005.c index 3e5956b1..b030c679 100644 --- a/test_pool/timer/operating_system/test_os_t005.c +++ b/test_pool/timer/operating_system/test_os_t005.c @@ -22,29 +22,97 @@ #include "val/include/bsa_acs_pe.h" #define TEST_NUM (ACS_TIMER_TEST_NUM_BASE + 5) -#define TEST_DESC "B_TIME_09: Check always ON PE timer " -/* B_TIME_09 : The platform will either implement hardware always-on PE timers or - * use the platform firmware to save and restore the PE timers in - * a performance scalable fashion - * Test is covering : The platform will either implement hardware always-on PE timers - * Second part required multi-PE interrupt handling support - */ +#define TEST_RULE "B_TIME_09" +#define TEST_DESC "Restore PE timer on PE wake up " + +static uint32_t intid, cnt_base_n; +static int irq_received; + +static +void +isr_sys_timer() +{ + val_timer_disable_system_timer((addr_t)cnt_base_n); + val_gic_end_of_interrupt(intid); + irq_received = 1; + val_print(ACS_PRINT_INFO, "\n System timer interrupt received", 0); +} + static void payload() { uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); + uint64_t sys_timer_ticks = TIMEOUT_MEDIUM; + uint64_t pe_timer_ticks = TIMEOUT_LARGE; + uint32_t ns_timer = 0; + uint64_t timer_num, timer_cnt; + int32_t status; + + timer_num = val_timer_get_info(TIMER_INFO_NUM_PLATFORM_TIMERS, 0); + + while (timer_num--) { + if (val_timer_get_info(TIMER_INFO_IS_PLATFORM_TIMER_SECURE, timer_num)) + continue; + else{ + ns_timer++; + break; + } + } + + if (!ns_timer) { + val_print(ACS_PRINT_DEBUG, "\n No non-secure systimer implemented", 0); + val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); + return; + } + + irq_received = 0; + + intid = val_timer_get_info(TIMER_INFO_SYS_INTID, timer_num); + val_gic_install_isr(intid, isr_sys_timer); + cnt_base_n = val_timer_get_info(TIMER_INFO_SYS_CNT_BASE_N, timer_num); + + /* Start EL1 PHY timer */ + val_timer_set_phy_el1(pe_timer_ticks); + + /* Start Sys timer*/ + val_timer_set_system_timer((addr_t)cnt_base_n, sys_timer_ticks); - // Pass if always ON PE timer is available */ - if ((val_timer_get_info(TIMER_INFO_PHY_EL1_FLAGS, 0) & BSA_TIMER_FLAG_ALWAYS_ON) && - (val_timer_get_info(TIMER_INFO_PHY_EL2_FLAGS, 0) & BSA_TIMER_FLAG_ALWAYS_ON) && - (val_timer_get_info(TIMER_INFO_VIR_EL1_FLAGS, 0) & BSA_TIMER_FLAG_ALWAYS_ON)) { - val_set_status(index, RESULT_PASS(TEST_NUM, 01)); + /* Put current PE in to low power mode*/ + status = val_suspend_pe(0, 0); + if (status) { + val_print(ACS_PRINT_DEBUG, "\n Not able to suspend the PE : %d", status); + val_timer_disable_system_timer((addr_t)cnt_base_n); + val_gic_clear_interrupt(intid); + val_timer_set_phy_el1(0); + val_set_status(index, RESULT_SKIP(TEST_NUM, 02)); return; } - val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); + if (irq_received == 0) { + val_print(ACS_PRINT_ERR, "\n System timer interrupt not generated", 0); + val_timer_disable_system_timer((addr_t)cnt_base_n); + val_gic_clear_interrupt(intid); + val_timer_set_phy_el1(0); + val_set_status(index, RESULT_FAIL(TEST_NUM, 01)); + return; + } + + /* PE wake up from sys timer interrupt & start execution here */ + /* Read PE timer*/ + timer_cnt = val_get_phy_el1_timer_count(); + + /*Disable PE timer*/ + val_timer_set_phy_el1(0); + + val_print(ACS_PRINT_INFO, "\n Read back PE timer count :%d", timer_cnt); + /* Check whether count is moved or not*/ + if ((timer_cnt < ((pe_timer_ticks - sys_timer_ticks) + (sys_timer_ticks/100))) + && (timer_cnt != 0)) + val_set_status(index, RESULT_PASS(TEST_NUM, 01)); + else + val_set_status(index, RESULT_FAIL(TEST_NUM, 02)); } uint32_t @@ -53,16 +121,16 @@ os_t005_entry(uint32_t num_pe) uint32_t status = ACS_STATUS_FAIL; - num_pe = 1; //This Timer test is run on single processor + num_pe = 1; //This Timer test is run on single processor status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); if (status != ACS_STATUS_SKIP) val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - status = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/watchdog/operating_system/test_os_w001.c b/test_pool/watchdog/operating_system/test_os_w001.c index c4280d25..eda547bc 100755 --- a/test_pool/watchdog/operating_system/test_os_w001.c +++ b/test_pool/watchdog/operating_system/test_os_w001.c @@ -21,7 +21,8 @@ #include "val/include/bsa_acs_wd.h" #define TEST_NUM (ACS_WD_TEST_NUM_BASE + 1) -#define TEST_DESC "B_WD_01,B_WD_02: NS Watchdog Access " +#define TEST_RULE "B_WD_01-02" +#define TEST_DESC "Non Secure Watchdog Access " static void @@ -37,7 +38,6 @@ payload() val_print(ACS_PRINT_DEBUG, "\n Found %d watchdogs in table ", wd_num); if (wd_num == 0) { - val_print(ACS_PRINT_WARN, "\n No Watchdogs reported %d ", wd_num); val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); return; } @@ -90,22 +90,19 @@ uint32_t os_w001_entry(uint32_t num_pe) { - uint32_t error_flag = 0; uint32_t status = ACS_STATUS_FAIL; num_pe = 1; //This Timer test is run on single processor - val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); - val_run_test_payload(TEST_NUM, num_pe, payload, 0); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - error_flag = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - if (!error_flag) - status = ACS_STATUS_PASS; - - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/test_pool/watchdog/operating_system/test_os_w002.c b/test_pool/watchdog/operating_system/test_os_w002.c index 1a329e78..294dbe23 100644 --- a/test_pool/watchdog/operating_system/test_os_w002.c +++ b/test_pool/watchdog/operating_system/test_os_w002.c @@ -22,7 +22,8 @@ #include "val/include/bsa_acs_wd.h" #define TEST_NUM (ACS_WD_TEST_NUM_BASE + 2) -#define TEST_DESC "B_WD_03: Check Watchdog WS0 interrupt " +#define TEST_RULE "B_WD_03" +#define TEST_DESC "Check Watchdog WS0 interrupt " static uint32_t int_id; static uint64_t wd_num; @@ -50,7 +51,7 @@ payload() wd_num = val_wd_get_info(0, WD_INFO_COUNT); if (wd_num == 0) { - val_print(ACS_PRINT_WARN, "\n No Watchdogs reported %d ", wd_num); + val_print(ACS_PRINT_DEBUG, "\n No Watchdogs reported %d ", wd_num); val_set_status(index, RESULT_SKIP(TEST_NUM, 01)); return; } @@ -109,22 +110,19 @@ uint32_t os_w002_entry(uint32_t num_pe) { - uint32_t error_flag = 0; uint32_t status = ACS_STATUS_FAIL; num_pe = 1; //This Timer test is run on single processor - val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); - val_run_test_payload(TEST_NUM, num_pe, payload, 0); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); /* get the result from all PE and check for failure */ - error_flag = val_check_for_error(TEST_NUM, num_pe); + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); - if (!error_flag) - status = ACS_STATUS_PASS; - - val_report_status(0, BSA_ACS_END(TEST_NUM)); + val_report_status(0, BSA_ACS_END(TEST_NUM), NULL); return status; } diff --git a/uefi_app/BsaAcs.h b/uefi_app/BsaAcs.h index 41fc0752..35c1507a 100755 --- a/uefi_app/BsaAcs.h +++ b/uefi_app/BsaAcs.h @@ -21,7 +21,7 @@ #define BSA_ACS_MAJOR_VER 0 - #define BSA_ACS_MINOR_VER 5 + #define BSA_ACS_MINOR_VER 9 #define G_PRINT_LEVEL ACS_PRINT_TEST @@ -33,7 +33,7 @@ #define GIC_INFO_TBL_SZ 8192 /*Supports maximum 256 redistributors, 256 ITS blocks & 4 distributors*/ #define TIMER_INFO_TBL_SZ 1024 /*Supports maximum 2 system timers*/ #define WD_INFO_TBL_SZ 512 /*Supports maximum 20 Watchdogs*/ - #define MEM_INFO_TBL_SZ 4096 /*Supports maximum 110 memory regions*/ + #define MEM_INFO_TBL_SZ 32768/*Supports maximum 800 memory regions*/ #define IOVIRT_INFO_TBL_SZ 32768/*Supports maximum 240 nodes of a typical iort table*/ #define PERIPHERAL_INFO_TBL_SZ 1024 /*Supports maximum 20 PCIe EPs (USB and SATA controllers only) */ #define PCIE_INFO_TBL_SZ 512 /*Supports maximum 20 RC's*/ diff --git a/uefi_app/BsaAcs.inf b/uefi_app/BsaAcs.inf index 2fe1db38..a9b3050c 100644 --- a/uefi_app/BsaAcs.inf +++ b/uefi_app/BsaAcs.inf @@ -66,11 +66,13 @@ ../test_pool/gic/operating_system/test_os_g004.c ../test_pool/gic/operating_system/test_os_g005.c ../test_pool/gic/operating_system/test_os_g006.c + ../test_pool/gic/operating_system/test_os_v2m001.c + ../test_pool/gic/operating_system/test_os_v2m002.c + ../test_pool/gic/operating_system/test_os_v2m003.c + ../test_pool/gic/operating_system/test_os_v2m004.c + ../test_pool/gic/operating_system/test_os_its001.c + ../test_pool/gic/operating_system/test_os_its002.c ../test_pool/gic/hypervisor/test_hyp_g001.c - ../test_pool/gic_v2m/operating_system/test_os_v001.c - ../test_pool/gic_v2m/operating_system/test_os_v002.c - ../test_pool/gic_v2m/operating_system/test_os_v003.c - ../test_pool/gic_v2m/operating_system/test_os_v004.c ../test_pool/timer/operating_system/test_os_t001.c ../test_pool/timer/operating_system/test_os_t002.c ../test_pool/timer/operating_system/test_os_t003.c @@ -80,6 +82,22 @@ ../test_pool/watchdog/operating_system/test_os_w002.c ../test_pool/pcie/operating_system/test_os_p001.c ../test_pool/pcie/operating_system/test_os_p002.c + ../test_pool/pcie/operating_system/test_os_p003.c + ../test_pool/pcie/operating_system/test_os_p004.c + ../test_pool/pcie/operating_system/test_os_p005.c + ../test_pool/pcie/operating_system/test_os_p006.c + ../test_pool/pcie/operating_system/test_os_p008.c + ../test_pool/pcie/operating_system/test_os_p009.c + ../test_pool/pcie/operating_system/test_os_p010.c + ../test_pool/pcie/operating_system/test_os_p011.c + ../test_pool/pcie/operating_system/test_os_p012.c + ../test_pool/pcie/operating_system/test_os_p013.c + ../test_pool/pcie/operating_system/test_os_p014.c + ../test_pool/pcie/operating_system/test_os_p015.c + ../test_pool/pcie/operating_system/test_os_p016.c + ../test_pool/pcie/operating_system/test_os_p017.c + ../test_pool/pcie/operating_system/test_os_p018.c + ../test_pool/pcie/operating_system/test_os_p019.c ../test_pool/pcie/operating_system/test_os_p020.c ../test_pool/pcie/operating_system/test_os_p021.c ../test_pool/pcie/operating_system/test_os_p022.c @@ -97,26 +115,6 @@ ../test_pool/pcie/operating_system/test_os_p034.c ../test_pool/pcie/operating_system/test_os_p035.c ../test_pool/pcie/operating_system/test_os_p036.c - ../test_pool/pcie/operating_system/test_os_p037.c - ../test_pool/pcie/operating_system/test_os_p038.c - ../test_pool/pcie/operating_system/test_os_p039.c - ../test_pool/pcie/operating_system/test_os_p041.c - ../test_pool/pcie/operating_system/test_os_p042.c - ../test_pool/pcie/operating_system/test_os_p044.c - ../test_pool/pcie/operating_system/test_os_p048.c - ../test_pool/pcie/operating_system/test_os_p050.c - ../test_pool/pcie/operating_system/test_os_p053.c - ../test_pool/pcie/operating_system/test_os_p051.c - ../test_pool/pcie/operating_system/test_os_p052.c - ../test_pool/pcie/operating_system/test_os_p054.c - ../test_pool/pcie/operating_system/test_os_p055.c - ../test_pool/pcie/operating_system/test_os_p056.c - ../test_pool/pcie/operating_system/test_os_p057.c - ../test_pool/pcie/operating_system/test_os_p058.c - ../test_pool/pcie/operating_system/test_os_p059.c - ../test_pool/pcie/operating_system/test_os_p060.c - ../test_pool/pcie/operating_system/test_os_p061.c - ../test_pool/pcie/operating_system/test_os_p062.c ../test_pool/smmu/operating_system/test_os_i001.c ../test_pool/smmu/operating_system/test_os_i002.c ../test_pool/smmu/operating_system/test_os_i003.c @@ -136,13 +134,19 @@ ../test_pool/peripherals/operating_system/test_os_d001.c ../test_pool/peripherals/operating_system/test_os_d002.c ../test_pool/peripherals/operating_system/test_os_d003.c + ../test_pool/peripherals/operating_system/test_os_d005.c ../test_pool/exerciser/operating_system/test_os_e001.c + ../test_pool/exerciser/operating_system/test_os_e002.c + ../test_pool/exerciser/operating_system/test_os_e003.c ../test_pool/exerciser/operating_system/test_os_e004.c ../test_pool/exerciser/operating_system/test_os_e005.c ../test_pool/exerciser/operating_system/test_os_e006.c + ../test_pool/exerciser/operating_system/test_os_e007.c + ../test_pool/exerciser/operating_system/test_os_e008.c + ../test_pool/exerciser/operating_system/test_os_e009.c + ../test_pool/exerciser/operating_system/test_os_e010.c + ../test_pool/exerciser/operating_system/test_os_e011.c ../test_pool/exerciser/operating_system/test_os_e012.c - ../test_pool/exerciser/operating_system/test_os_e013.c - ../test_pool/exerciser/operating_system/test_os_e015.c [Packages] StdLib/StdLib.dec diff --git a/uefi_app/BsaAcsMain.c b/uefi_app/BsaAcsMain.c index 536608c2..c828be82 100644 --- a/uefi_app/BsaAcsMain.c +++ b/uefi_app/BsaAcsMain.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2020, Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2016-2021, Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -40,6 +40,7 @@ UINT64 g_stack_pointer; UINT64 g_exception_ret_addr; UINT64 g_ret_addr; SHELL_FILE_HANDLE g_bsa_log_file_handle; +SHELL_FILE_HANDLE g_dtb_log_file_handle; STATIC VOID FlushImage (VOID) { @@ -259,19 +260,21 @@ HelpMsg ( "-os Enable the execution of operating system tests\n" "-hyp Enable the execution of hypervisor tests\n" "-ps Enable the execution of platform security tests\n" + "-dtb Enable the execution of dtb dump\n" ); } STATIC CONST SHELL_PARAM_ITEM ParamList[] = { - {L"-v" , TypeValue}, // -v # Verbosity of the Prints. 1 shows all prints, 5 shows Errors - {L"-f" , TypeValue}, // -f # Name of the log file to record the test results in. - {L"-skip" , TypeValue}, // -skip # test(s) to skip execution - {L"-help" , TypeFlag}, // -help # help : info about commands - {L"-h" , TypeFlag}, // -h # help : info about commands - {L"-os" , TypeFlag}, // -os # Binary Flag to enable the execution of operating system tests. - {L"-hyp" , TypeFlag}, // -hyp # Binary Flag to enable the execution of hypervisor tests. - {L"-ps" , TypeFlag}, // -ps # Binary Flag to enable the execution of platform security tests. - {NULL , TypeMax} + {L"-v", TypeValue}, // -v # Verbosity of the Prints. 1 shows all prints, 5 shows Errors + {L"-f", TypeValue}, // -f # Name of the log file to record the test results in. + {L"-skip", TypeValue}, // -skip # test(s) to skip execution + {L"-help", TypeFlag}, // -help # help : info about commands + {L"-h", TypeFlag}, // -h # help : info about commands + {L"-os", TypeFlag}, // -os # Binary Flag to enable the execution of operating system tests. + {L"-hyp", TypeFlag}, // -hyp # Binary Flag to enable the execution of hypervisor tests. + {L"-ps", TypeFlag}, // -ps # Binary Flag to enable the execution of platform security tests. + {L"-dtb", TypeValue}, // -dtb # Binary Flag to enable dtb dump + {NULL, TypeMax} }; /*** @@ -313,11 +316,15 @@ ShellAppMain ( // Options with Values if (ShellCommandLineGetFlag (ParamPackage, L"-skip")) { CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-skip"); - for (i=0 ; i < StrLen(CmdLineArg) ; i++){ - g_skip_test_num[0] = StrDecimalToUintn((CONST CHAR16 *)(CmdLineArg+0)); - if(*(CmdLineArg+i) == L','){ + if (CmdLineArg == NULL) { + Print(L" No valid test number or module number specified for -skip\n"); + } else { + for (i = 0 ; i < StrLen(CmdLineArg) ; i++) { + g_skip_test_num[0] = StrDecimalToUintn((CONST CHAR16 *)(CmdLineArg+0)); + if (*(CmdLineArg+i) == L',') { g_skip_test_num[++j] = StrDecimalToUintn((CONST CHAR16 *)(CmdLineArg+i+1)); } + } } } @@ -363,6 +370,20 @@ ShellAppMain ( } } + // If user has pass dtb flag, then dump the dtb in file + CmdLineArg = ShellCommandLineGetValue(ParamPackage, L"-dtb"); + if (CmdLineArg == NULL) { + g_dtb_log_file_handle = NULL; + } else { + Status = ShellOpenFileByName(CmdLineArg, &g_dtb_log_file_handle, + EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ | EFI_FILE_MODE_CREATE, 0x0); + if (EFI_ERROR(Status)) { + Print(L"Failed to open file for dtb dump %s\n", CmdLineArg); + g_dtb_log_file_handle = NULL; + } else { + val_dump_dtb(); + } + } // Options with Flags if ((ShellCommandLineGetFlag (ParamPackage, L"-help")) || (ShellCommandLineGetFlag (ParamPackage, L"-h"))){ @@ -454,10 +475,14 @@ ShellAppMain ( freeBsaAcsMem(); - if(g_bsa_log_file_handle) { + if (g_bsa_log_file_handle) { ShellCloseFile(&g_bsa_log_file_handle); } + if (g_dtb_log_file_handle) { + ShellCloseFile(&g_dtb_log_file_handle); + } + Print(L"\n *** BSA tests complete. Reset the system. *** \n\n"); val_pe_context_restore(AA64WriteSp(g_stack_pointer)); diff --git a/val/BsaValLib.inf b/val/BsaValLib.inf index 0e544098..a4d54902 100644 --- a/val/BsaValLib.inf +++ b/val/BsaValLib.inf @@ -54,6 +54,8 @@ sys_arch_src/gic/v3/AArch64/v3_asm.S sys_arch_src/gic/v2/gic_v2.c sys_arch_src/pcie/pcie.c + sys_arch_src/gic/its/bsa_gic_its.c + sys_arch_src/gic/its/bsa_gic_redistributor.c [Packages] MdePkg/MdePkg.dec diff --git a/val/include/bsa_acs_common.h b/val/include/bsa_acs_common.h index 6712cfae..d901baa1 100644 --- a/val/include/bsa_acs_common.h +++ b/val/include/bsa_acs_common.h @@ -34,8 +34,9 @@ #define ACS_PE_PS_TEST_NUM_BASE (ACS_PE_HYP_TEST_NUM_BASE + 25) #define ACS_MEMORY_MAP_TEST_BASE 100 #define ACS_GIC_TEST_NUM_BASE 200 -#define ACS_GIC_HYP_TEST_NUM_BASE (ACS_GIC_TEST_NUM_BASE + 50) -#define ACS_GIC_V2M_TEST_NUM_BASE (ACS_GIC_TEST_NUM_BASE + 80) +#define ACS_GIC_HYP_TEST_NUM_BASE (ACS_GIC_TEST_NUM_BASE + 25) +#define ACS_GIC_V2M_TEST_NUM_BASE (ACS_GIC_HYP_TEST_NUM_BASE + 25) +#define ACS_GIC_ITS_TEST_NUM_BASE (ACS_GIC_V2M_TEST_NUM_BASE + 25) #define ACS_SMMU_TEST_NUM_BASE 300 #define ACS_SMMU_HYP_TEST_NUM_BASE (ACS_SMMU_TEST_NUM_BASE + 50) #define ACS_TIMER_TEST_NUM_BASE 400 @@ -119,7 +120,7 @@ uint32_t val_initialize_test(uint32_t test_num, char8_t * desc, uint32_t num_pe); uint32_t -val_check_for_error(uint32_t test_num, uint32_t num_pe); +val_check_for_error(uint32_t test_num, uint32_t num_pe, char8_t *ruleid); void val_run_test_payload(uint32_t test_num, uint32_t num_pe, void (*payload)(void), uint64_t test_input); diff --git a/val/include/bsa_acs_exerciser.h b/val/include/bsa_acs_exerciser.h index 4d7718ad..0d7019ca 100644 --- a/val/include/bsa_acs_exerciser.h +++ b/val/include/bsa_acs_exerciser.h @@ -53,11 +53,16 @@ uint32_t val_exerciser_execute_tests(uint32_t *g_sw_view); uint32_t val_exerciser_get_bdf(uint32_t instance); uint32_t os_e001_entry(void); +uint32_t os_e002_entry(void); +uint32_t os_e003_entry(void); uint32_t os_e004_entry(void); uint32_t os_e005_entry(void); uint32_t os_e006_entry(void); +uint32_t os_e007_entry(void); +uint32_t os_e008_entry(void); +uint32_t os_e009_entry(void); +uint32_t os_e010_entry(void); +uint32_t os_e011_entry(void); uint32_t os_e012_entry(void); -uint32_t os_e013_entry(void); -uint32_t os_e015_entry(void); #endif diff --git a/val/include/bsa_acs_gic.h b/val/include/bsa_acs_gic.h index 232af413..7a31ebfb 100644 --- a/val/include/bsa_acs_gic.h +++ b/val/include/bsa_acs_gic.h @@ -41,6 +41,7 @@ #define GICD_ICPENDR0 0x280 #define GICD_ICACTIVER0 0x380 #define GICD_ICFGR 0xC00 +#define GICD_ICFGRE 0x3000 #define GICD_IROUTER 0x6000 #define GICD_PIDR2 0xFFE8 @@ -102,9 +103,19 @@ val_get_gich_base(void); addr_t val_get_cpuif_base(void); -uint32_t os_v001_entry(uint32_t num_pe); -uint32_t os_v002_entry(uint32_t num_pe); -uint32_t os_v003_entry(uint32_t num_pe); -uint32_t os_v004_entry(uint32_t num_pe); +uint32_t +val_gic_espi_supported(void); + +uint32_t +val_gic_max_espi_val(void); + +uint32_t os_v2m001_entry(uint32_t num_pe); +uint32_t os_v2m002_entry(uint32_t num_pe); +uint32_t os_v2m003_entry(uint32_t num_pe); +uint32_t os_v2m004_entry(uint32_t num_pe); + +/* ITS tests */ +uint32_t os_its001_entry(uint32_t num_pe); +uint32_t os_its002_entry(uint32_t num_pe); #endif diff --git a/val/include/bsa_acs_iovirt.h b/val/include/bsa_acs_iovirt.h index d52a0225..4f9ce9ac 100644 --- a/val/include/bsa_acs_iovirt.h +++ b/val/include/bsa_acs_iovirt.h @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2020, Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2016-2021 Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,7 +21,10 @@ uint64_t val_iovirt_get_smmu_info(SMMU_INFO_e type, uint32_t index); uint32_t val_iovirt_check_unique_ctx_intid(uint32_t smmu_index); uint32_t val_iovirt_unique_rid_strid_map(uint32_t rc_index); -int val_iovirt_get_device_info(uint32_t rid, uint32_t segment, uint32_t *device_id, uint32_t *stream_id, uint32_t *its_id); +int val_iovirt_get_device_info( + uint32_t rid, uint32_t segment, uint32_t *device_id, uint32_t *stream_id, uint32_t *its_id); uint64_t val_iovirt_get_pcie_rc_info(PCIE_RC_INFO_e type, uint32_t index); +int val_iovirt_get_its_info( + uint32_t type, uint32_t group_index, uint32_t param, uint32_t *return_value); #endif diff --git a/val/include/bsa_acs_memory.h b/val/include/bsa_acs_memory.h index 7a32e9bc..d7c3839f 100644 --- a/val/include/bsa_acs_memory.h +++ b/val/include/bsa_acs_memory.h @@ -33,6 +33,7 @@ uint32_t val_memory_page_size(void); void *val_memory_alloc_pages(uint32_t num_pages); void val_memory_free_pages(void *page_base, uint32_t num_pages); addr_t val_memory_get_addr(MEMORY_INFO_e mem_type, uint32_t instance, uint64_t *attr); +void *val_aligned_alloc(uint32_t alignment, uint32_t size); uint32_t os_m001_entry(uint32_t num_pe); uint32_t os_m002_entry(uint32_t num_pe); diff --git a/val/include/bsa_acs_pcie.h b/val/include/bsa_acs_pcie.h index a95b66f8..fff337d5 100644 --- a/val/include/bsa_acs_pcie.h +++ b/val/include/bsa_acs_pcie.h @@ -197,12 +197,22 @@ val_pcie_is_cache_present(uint32_t bdf); uint32_t os_p001_entry(uint32_t num_pe); uint32_t os_p002_entry(uint32_t num_pe); +uint32_t os_p003_entry(uint32_t num_pe); +uint32_t os_p004_entry(uint32_t num_pe); uint32_t os_p005_entry(uint32_t num_pe); uint32_t os_p006_entry(uint32_t num_pe); -uint32_t os_p007_entry(uint32_t num_pe); +uint32_t os_p008_entry(uint32_t num_pe); +uint32_t os_p009_entry(uint32_t num_pe); +uint32_t os_p010_entry(uint32_t num_pe); uint32_t os_p011_entry(uint32_t num_pe); uint32_t os_p012_entry(uint32_t num_pe); +uint32_t os_p013_entry(uint32_t num_pe); +uint32_t os_p014_entry(uint32_t num_pe); +uint32_t os_p015_entry(uint32_t num_pe); uint32_t os_p016_entry(uint32_t num_pe); +uint32_t os_p017_entry(uint32_t num_pe); +uint32_t os_p018_entry(uint32_t num_pe); +uint32_t os_p019_entry(uint32_t num_pe); uint32_t os_p020_entry(uint32_t num_pe); uint32_t os_p021_entry(uint32_t num_pe); uint32_t os_p022_entry(uint32_t num_pe); @@ -220,25 +230,13 @@ uint32_t os_p033_entry(uint32_t num_pe); uint32_t os_p034_entry(uint32_t num_pe); uint32_t os_p035_entry(uint32_t num_pe); uint32_t os_p036_entry(uint32_t num_pe); -uint32_t os_p037_entry(uint32_t num_pe); -uint32_t os_p038_entry(uint32_t num_pe); -uint32_t os_p039_entry(uint32_t num_pe); -uint32_t os_p041_entry(uint32_t num_pe); -uint32_t os_p042_entry(uint32_t num_pe); -uint32_t os_p044_entry(uint32_t num_pe); -uint32_t os_p048_entry(uint32_t num_pe); -uint32_t os_p050_entry(uint32_t num_pe); -uint32_t os_p051_entry(uint32_t num_pe); -uint32_t os_p052_entry(uint32_t num_pe); -uint32_t os_p053_entry(uint32_t num_pe); -uint32_t os_p054_entry(uint32_t num_pe); -uint32_t os_p055_entry(uint32_t num_pe); -uint32_t os_p056_entry(uint32_t num_pe); -uint32_t os_p057_entry(uint32_t num_pe); -uint32_t os_p058_entry(uint32_t num_pe); -uint32_t os_p059_entry(uint32_t num_pe); -uint32_t os_p060_entry(uint32_t num_pe); + +/* Linux test */ uint32_t os_p061_entry(uint32_t num_pe); uint32_t os_p062_entry(uint32_t num_pe); +uint32_t os_p063_entry(uint32_t num_pe); +uint32_t os_p064_entry(uint32_t num_pe); +uint32_t os_p065_entry(uint32_t num_pe); +uint32_t os_p066_entry(uint32_t num_pe); #endif diff --git a/val/include/bsa_acs_peripherals.h b/val/include/bsa_acs_peripherals.h index a52ec1bd..3c4823d5 100644 --- a/val/include/bsa_acs_peripherals.h +++ b/val/include/bsa_acs_peripherals.h @@ -24,12 +24,33 @@ uint32_t os_d001_entry(uint32_t num_pe); uint32_t os_d002_entry(uint32_t num_pe); uint32_t os_d003_entry(uint32_t num_pe); uint32_t os_d004_entry(uint32_t num_pe); +uint32_t os_d005_entry(uint32_t num_pe); #define WIDTH_BIT8 0x1 #define WIDTH_BIT16 0x2 #define WIDTH_BIT32 0x4 +#define IER 0x1 +#define LCR 0x3 +#define MCR 0x4 +#define MSR 0x6 +#define CTS_DCD_EN 0x90 +#define LCR_DATA_BIT_MASK 0x3 +#define LCR_DATA_BIT_SHIFT 0x0 +#define LCR_STOP_BIT_MASK 0x4 +#define LCR_STOP_BIT_SHIFT 0x2 +#define MCR_LOOP 0x10 + +#define DIVISOR_LATCH_EN 0x80 +#define DIVISOR_LATCH_DIS 0x0 +#define DIVISOR_LATCH_BYTE1 0x0 +#define DIVISOR_LATCH_BYTE2 0x1 + +#define BAUDRATE_1200 1200 +#define BAUDRATE_9600 9200 +#define BAUDRATE_115200 115200 + #define BSA_UARTDR 0x0 #define BSA_UARTRSR 0x4 #define BSA_UARTFR 0x18 @@ -40,6 +61,10 @@ uint32_t os_d004_entry(uint32_t num_pe); #define BSA_UARTMIS 0x40 #define BSA_UARTICR 0x44 - +#define COMPATIBLE_FULL_16550 0x0 +#define COMPATIBLE_SUBSET_16550 0x1 +#define ARM_PL011_UART 0x3 +#define ARM_SBSA_GENERIC_UART 0xE +#define COMPATIBLE_GENERIC_16550 0x12 #endif // __BSA_ACS_PERIPHERAL_H__ diff --git a/val/include/bsa_acs_timer.h b/val/include/bsa_acs_timer.h index 347f5732..f9482019 100644 --- a/val/include/bsa_acs_timer.h +++ b/val/include/bsa_acs_timer.h @@ -41,9 +41,10 @@ #define CNTACR 0x40 /* CNTBaseN register offset*/ -#define CNTPCT 0 -#define CNTP_CVAL_LOW 0x20 -#define CNTP_CVAL_HIGH 0x24 +#define CNTPCT_LOWER 0x00 +#define CNTPCT_HIGHER 0x04 +#define CNTP_CVAL_LOWER 0x20 +#define CNTP_CVAL_HIGHER 0x24 #define CNTP_TVAL 0x28 #define CNTP_CTL 0x2C #define COUNTER_ID 0xFD0 diff --git a/val/include/bsa_acs_val.h b/val/include/bsa_acs_val.h index 0666c31b..70513159 100755 --- a/val/include/bsa_acs_val.h +++ b/val/include/bsa_acs_val.h @@ -49,7 +49,7 @@ uint8_t val_is_el2_enabled(void); void -val_report_status(uint32_t id, uint32_t status); +val_report_status(uint32_t id, uint32_t status, char8_t *ruleid); void val_set_status(uint32_t index, uint32_t status); diff --git a/val/include/bsa_std_smc.h b/val/include/bsa_std_smc.h index ceb3873b..e3dbd81b 100644 --- a/val/include/bsa_std_smc.h +++ b/val/include/bsa_std_smc.h @@ -60,12 +60,8 @@ #define ARM_SMC_ID_PSCI_MIGRATE_AARCH32 0x84000005 #define ARM_SMC_ID_PSCI_SYSTEM_OFF 0x84000008 #define ARM_SMC_ID_PSCI_SYSTEM_RESET 0x84000009 +#define ARM_SMC_ID_PSCI_FEATURES 0x8400000A -/* The current PSCI version is: 0.2 */ -#define ARM_SMC_PSCI_VERSION_MAJOR 0 -#define ARM_SMC_PSCI_VERSION_MINOR 2 -#define ARM_SMC_PSCI_VERSION \ - ((ARM_SMC_PSCI_VERSION_MAJOR << 16) | ARM_SMC_PSCI_VERSION_MINOR) /* PSCI return error codes */ #define ARM_SMC_PSCI_RET_SUCCESS 0 @@ -96,6 +92,9 @@ #define ARM_SMC_ID_PSCI_AFFINITY_INFO_OFF 1 #define ARM_SMC_ID_PSCI_AFFINITY_INFO_ON_PENDING 2 +#define ARM_SMC_ID_PSCI_POWER_STATE_FMT_ORIGINAL 0 +#define ARM_SMC_ID_PSCI_POWER_STATE_FMT_EXT_STATEID 1 + /** Trigger an SMC call diff --git a/val/include/pal_interface.h b/val/include/pal_interface.h index b627abe9..b2b1ec74 100644 --- a/val/include/pal_interface.h +++ b/val/include/pal_interface.h @@ -49,6 +49,8 @@ #define PCIE_CAP_NOT_FOUND 0x10000010 /* The specified capability was not found */ #define PCIE_UNKNOWN_RESPONSE 0xFFFFFFFF /* Function not found or UR response from completer */ +void pal_dump_dtb(void); + /** PE Test related Definitions **/ /** @@ -160,17 +162,28 @@ typedef struct { GIC_INFO_ENTRY gic_info[]; ///< Array of Information blocks - instantiated for each GIC type }GIC_INFO_TABLE; +typedef struct { + uint32_t ID; + uint64_t Base; + uint64_t CommandQBase; + uint32_t IDBits; + uint64_t ITTBase; +} GIC_ITS_BLOCK; + +typedef struct { + uint64_t GicDBase; + uint64_t GicRdBase; + uint32_t GicNumIts; + GIC_ITS_BLOCK GicIts[]; +} GIC_ITS_INFO; + void pal_gic_create_info_table(GIC_INFO_TABLE *gic_info_table); uint32_t pal_gic_install_isr(uint32_t int_id, void (*isr)(void)); void pal_gic_end_of_interrupt(uint32_t int_id); uint32_t pal_gic_request_irq(unsigned int irq_num, unsigned int mapped_irq_num, void *isr); void pal_gic_free_irq(unsigned int irq_num, unsigned int mapped_irq_num); uint32_t pal_gic_set_intr_trigger(uint32_t int_id, INTR_TRIGGER_INFO_TYPE_e trigger_type); -uint32_t pal_gic_its_configure(void); -uint32_t pal_gic_request_msi(uint32_t its_id, uint32_t DevID, uint32_t IntID, uint32_t msi_index, uint32_t *msi_addr, uint32_t *msi_data); -void pal_gic_free_msi(uint32_t its_id, uint32_t DevID, uint32_t IntID, uint32_t msi_index); -uint32_t pal_gic_get_max_lpi_id(void); -uint32_t pal_bsa_gic_imp(void); +uint32_t pal_target_is_dt(void); /** Timer tests related definitions **/ @@ -447,6 +460,8 @@ typedef struct { uint32_t msi; ///< MSI Enabled uint32_t msix; ///< MSIX Enabled uint32_t max_pasids; + uint32_t baud_rate; + uint32_t interface_type; }PERIPHERAL_INFO_BLOCK; /** @@ -608,6 +623,8 @@ void pal_mmio_write16(uint64_t addr, uint16_t data); void pal_mmio_write(uint64_t addr, uint32_t data); void pal_mmio_write64(uint64_t addr, uint64_t data); +void pal_mem_set(void *Buf, uint32_t Size, uint8_t Value); + void pal_pe_update_elr(void *context, uint64_t offset); uint64_t pal_pe_get_esr(void *context); uint64_t pal_pe_get_far(void *context); @@ -738,12 +755,17 @@ typedef enum { } EXERCISER_DATA_TYPE; uint32_t pal_is_bdf_exerciser(uint32_t bdf); -uint32_t pal_exerciser_set_param(EXERCISER_PARAM_TYPE type, uint64_t value1, uint64_t value2, uint32_t bdf); -uint32_t pal_exerciser_get_param(EXERCISER_PARAM_TYPE type, uint64_t *value1, uint64_t *value2, uint32_t bdf); -uint32_t pal_exerciser_set_state(EXERCISER_STATE state, uint64_t *value, uint32_t bdf); +uint32_t pal_exerciser_set_param(EXERCISER_PARAM_TYPE type, uint64_t value1, + uint64_t value2, uint32_t bdf, uint64_t ecam); +uint32_t pal_exerciser_get_param(EXERCISER_PARAM_TYPE type, uint64_t *value1, + uint64_t *value2, uint32_t bdf, uint64_t ecam); +uint32_t pal_exerciser_set_state(EXERCISER_STATE state, uint64_t *value, + uint32_t bdf); uint32_t pal_exerciser_get_state(EXERCISER_STATE *state, uint32_t bdf); -uint32_t pal_exerciser_ops(EXERCISER_OPS ops, uint64_t param, uint32_t instance); -uint32_t pal_exerciser_get_data(EXERCISER_DATA_TYPE type, exerciser_data_t *data, uint32_t bdf, uint64_t ecam); +uint32_t pal_exerciser_ops(EXERCISER_OPS ops, uint64_t param, + uint32_t instance, uint64_t ecam); +uint32_t pal_exerciser_get_data(EXERCISER_DATA_TYPE type, + exerciser_data_t *data, uint32_t bdf, uint64_t ecam); #endif diff --git a/val/include/val_interface.h b/val/include/val_interface.h index 18004755..24f97da6 100644 --- a/val/include/val_interface.h +++ b/val/include/val_interface.h @@ -46,7 +46,7 @@ void val_set_test_data(uint32_t index, uint64_t addr, uint64_t test_data); void val_get_test_data(uint32_t index, uint64_t *data0, uint64_t *data1); uint32_t val_strncmp(char8_t *str1, char8_t *str2, uint32_t len); void *val_memcpy(void *dest_buffer, void *src_buffer, uint32_t len); - +void val_dump_dtb(void); uint64_t val_time_delay_ms(uint64_t time_ms); /* VAL PE APIs */ @@ -62,7 +62,7 @@ uint32_t val_pe_get_index_mpid(uint64_t mpid); uint32_t val_pe_install_esr(uint32_t exception_type, void (*esr)(uint64_t, void *)); void val_execute_on_pe(uint32_t index, void (*payload)(void), uint64_t args); -void val_suspend_pe(uint32_t power_state, uint64_t entry, uint32_t context_id); +int val_suspend_pe(uint64_t entry, uint32_t context_id); /* GIC VAL APIs */ uint32_t val_gic_create_info_table(uint64_t *gic_info_table); @@ -96,9 +96,13 @@ uint32_t val_gic_request_irq(uint32_t irq_num, uint32_t mapped_irq_num, void *is void val_gic_free_irq(uint32_t irq_num, uint32_t mapped_irq_num); void val_gic_set_intr_trigger(uint32_t int_id, INTR_TRIGGER_INFO_TYPE_e trigger_type); uint32_t val_gic_get_intr_trigger_type(uint32_t int_id, INTR_TRIGGER_INFO_TYPE_e *trigger_type); +uint32_t val_gic_get_espi_intr_trigger_type(uint32_t int_id, + INTR_TRIGGER_INFO_TYPE_e *trigger_type); uint32_t val_gic_its_configure(void); -uint32_t val_gic_request_msi(uint32_t bdf, uint32_t IntID, uint32_t msi_index); -void val_gic_free_msi(uint32_t bdf, uint32_t IntID, uint32_t msi_index); +uint32_t val_gic_request_msi(uint32_t bdf, uint32_t device_id, uint32_t its_id, + uint32_t int_id, uint32_t msi_index); +void val_gic_free_msi(uint32_t bdf, uint32_t device_id, uint32_t its_id, + uint32_t int_id, uint32_t msi_index); /* GICv2m APIs */ typedef enum { @@ -147,6 +151,7 @@ void val_timer_disable_system_timer(addr_t cnt_base_n); uint32_t val_timer_skip_if_cntbase_access_not_allowed(uint64_t index); void val_platform_timer_get_entry_index(uint64_t instance, uint32_t *block, uint32_t *index); uint64_t val_get_phy_el2_timer_count(void); +uint64_t val_get_phy_el1_timer_count(void); /* Watchdog VAL APIs */ typedef enum { @@ -237,6 +242,14 @@ typedef enum { RC_IOVIRT_BLOCK }PCIE_RC_INFO_e; +typedef enum { + ITS_NUM_GROUPS = 1, + ITS_GROUP_NUM_BLOCKS, + ITS_GET_ID_FOR_BLK_INDEX, + ITS_GET_GRP_INDEX_FOR_ID, + ITS_GET_BLK_INDEX_FOR_ID +} ITS_INFO_e; + void val_iovirt_create_info_table(uint64_t *iovirt_info_table); void val_iovirt_free_info_table(void); uint32_t val_iovirt_get_rc_smmu_index(uint32_t rc_seg_num); @@ -297,8 +310,11 @@ typedef enum { SATA_GSIV, SATA_BDF, UART_BASE0, + UART_BASE1, UART_GSIV, UART_FLAGS, + UART_BAUDRATE, + UART_INTERFACE_TYPE, ANY_FLAGS, ANY_GSIV, ANY_BDF, diff --git a/val/src/acs_exerciser.c b/val/src/acs_exerciser.c index 3fe01735..7d96b6ea 100644 --- a/val/src/acs_exerciser.c +++ b/val/src/acs_exerciser.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2020,2021 Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2016-2021 Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -60,10 +60,10 @@ void val_exerciser_create_info_table(void) { g_exercier_info_table.e_info[g_exercier_info_table.num_exerciser].bdf = Bdf; g_exercier_info_table.e_info[g_exercier_info_table.num_exerciser++].initialized = 0; - val_print(ACS_PRINT_DEBUG, " exerciser Bdf %x\n", Bdf); + val_print(ACS_PRINT_INFO, "\n exerciser Bdf %x", Bdf); } } - val_print(ACS_PRINT_DEBUG, " exerciser cards in the system %x \n", + val_print(ACS_PRINT_INFO, "\n exerciser cards in the system %x \n", g_exercier_info_table.num_exerciser); } @@ -92,11 +92,13 @@ uint32_t val_exerciser_get_info(EXERCISER_INFO_TYPE type, uint32_t instance) @param instance - Stimulus hardware instance number @return status - SUCCESS if the input paramter type is successfully written **/ -uint32_t val_exerciser_set_param(EXERCISER_PARAM_TYPE type, uint64_t value1, uint64_t value2, - uint32_t instance) +uint32_t val_exerciser_set_param(EXERCISER_PARAM_TYPE type, uint64_t value1, + uint64_t value2, uint32_t instance) { - return pal_exerciser_set_param(type, value1, value2, - g_exercier_info_table.e_info[instance].bdf); + uint32_t bdf = g_exercier_info_table.e_info[instance].bdf; + uint64_t ecam = val_pcie_get_ecam_base(bdf); + + return pal_exerciser_set_param(type, value1, value2, bdf, ecam); } uint32_t val_exerciser_get_bdf(uint32_t instance) @@ -111,11 +113,13 @@ uint32_t val_exerciser_get_bdf(uint32_t instance) @param instance - Stimulus hardware instance number @return status - SUCCESS if the requested paramter type is successfully read **/ -uint32_t val_exerciser_get_param(EXERCISER_PARAM_TYPE type, uint64_t *value1, uint64_t *value2, - uint32_t instance) +uint32_t val_exerciser_get_param(EXERCISER_PARAM_TYPE type, uint64_t *value1, + uint64_t *value2, uint32_t instance) { - return pal_exerciser_get_param(type, value1, value2, - g_exercier_info_table.e_info[instance].bdf); + uint32_t bdf = g_exercier_info_table.e_info[instance].bdf; + uint64_t ecam = val_pcie_get_ecam_base(bdf); + + return pal_exerciser_get_param(type, value1, value2, bdf, ecam); } @@ -150,7 +154,7 @@ uint32_t val_exerciser_get_state(EXERCISER_STATE *state, uint32_t instance) uint32_t val_exerciser_init(uint32_t instance) { uint32_t Bdf; - uint32_t Ecam; + uint64_t Ecam; uint64_t cfg_addr; EXERCISER_STATE state; @@ -176,7 +180,8 @@ uint32_t val_exerciser_init(uint32_t instance) g_exercier_info_table.e_info[instance].initialized = 1; } else - val_print(ACS_PRINT_DEBUG, "\n Already initialized %d", instance); + val_print(ACS_PRINT_DEBUG, "\n Already initialized %d", + instance); return 0; } /** @@ -188,7 +193,10 @@ uint32_t val_exerciser_init(uint32_t instance) **/ uint32_t val_exerciser_ops(EXERCISER_OPS ops, uint64_t param, uint32_t instance) { - return pal_exerciser_ops(ops, param, g_exercier_info_table.e_info[instance].bdf); + uint32_t bdf = g_exercier_info_table.e_info[instance].bdf; + uint64_t ecam = val_pcie_get_ecam_base(bdf); + + return pal_exerciser_ops(ops, param, bdf, ecam); } /** @@ -203,6 +211,7 @@ uint32_t val_exerciser_get_data(EXERCISER_DATA_TYPE type, exerciser_data_t *data { uint32_t bdf = g_exercier_info_table.e_info[instance].bdf; uint64_t ecam = val_pcie_get_ecam_base(bdf); + return pal_exerciser_get_data(type, data, bdf, ecam); } @@ -241,15 +250,23 @@ val_exerciser_execute_tests(uint32_t *g_sw_view) } if (g_sw_view[G_SW_OS]) { - val_print(ACS_PRINT_ERR, "\nOperating System:\n", 0); + val_print(ACS_PRINT_ERR, "\nOperating System View:\n", 0); status |= os_e001_entry(); + status |= os_e002_entry(); + status |= os_e003_entry(); status |= os_e004_entry(); status |= os_e005_entry(); status |= os_e006_entry(); - status |= os_e012_entry(); - status |= os_e013_entry(); - status |= os_e015_entry(); + status |= os_e007_entry(); + status |= os_e008_entry(); + status |= os_e009_entry(); + status |= os_e010_entry(); + + if (!pal_target_is_dt()) { + status |= os_e011_entry(); + status |= os_e012_entry(); + } } diff --git a/val/src/acs_gic.c b/val/src/acs_gic.c index fdd8a7de..f825c9e1 100644 --- a/val/src/acs_gic.c +++ b/val/src/acs_gic.c @@ -47,7 +47,7 @@ val_gic_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) status = ACS_STATUS_PASS; if (g_sw_view[G_SW_OS]) { - val_print(ACS_PRINT_ERR, "\nOperating System:\n", 0); + val_print(ACS_PRINT_ERR, "\nOperating System View:\n", 0); status |= os_g001_entry(num_pe); status |= os_g002_entry(num_pe); status |= os_g003_entry(num_pe); @@ -57,7 +57,7 @@ val_gic_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) } if (g_sw_view[G_SW_HYP]) { - val_print(ACS_PRINT_ERR, "\nHypervisor:\n", 0); + val_print(ACS_PRINT_ERR, "\nHypervisor View:\n", 0); status |= hyp_g001_entry(num_pe); } @@ -67,21 +67,33 @@ val_gic_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) if ((gic_version != 2) || (num_msi_frame == 0)) { val_print(ACS_PRINT_TEST, "\n No GICv2m, Skipping all GICv2m tests \n", 0); - goto test_done; + goto its_test; } if (val_gic_v2m_parse_info()) { val_print(ACS_PRINT_TEST, "\n GICv2m info mismatch, Skipping all GICv2m tests \n", 0); - goto test_done; + goto its_test; } val_print(ACS_PRINT_ERR, "\n *** Starting GICv2m tests ***\n", 0); if (g_sw_view[G_SW_OS]) { - val_print(ACS_PRINT_ERR, "\nOperating System:\n", 0); - status |= os_v001_entry(num_pe); - status |= os_v002_entry(num_pe); - status |= os_v003_entry(num_pe); - status |= os_v004_entry(num_pe); + val_print(ACS_PRINT_ERR, "\nOperating System View:\n", 0); + status |= os_v2m001_entry(num_pe); + status |= os_v2m002_entry(num_pe); + status |= os_v2m003_entry(num_pe); + status |= os_v2m004_entry(num_pe); + } + +its_test: + if ((val_gic_get_info(GIC_INFO_NUM_ITS) == 0) || (pal_target_is_dt())) { + val_print(ACS_PRINT_TEST, "\n No ITS, Skipping all ITS tests \n", 0); + goto test_done; + } + val_print(ACS_PRINT_ERR, "\n *** Starting ITS tests ***\n", 0); + if (g_sw_view[G_SW_OS]) { + val_print(ACS_PRINT_ERR, "\nOperating System View:\n", 0); + status |= os_its001_entry(num_pe); + status |= os_its002_entry(num_pe); } test_done: @@ -124,7 +136,7 @@ val_gic_create_info_table(uint64_t *gic_info_table) return ACS_STATUS_ERR; } - if (pal_bsa_gic_imp()) + if (pal_target_is_dt()) val_bsa_gic_init(); return ACS_STATUS_PASS; } @@ -345,9 +357,11 @@ val_get_max_intid(void) **/ uint32_t val_gic_route_interrupt_to_pe(uint32_t int_id, uint64_t mpidr) { + uint64_t cpuaffinity; + if (int_id > 31) { - mpidr &= 0xF80FFFFFF; - val_mmio_write64(val_get_gicd_base() + GICD_IROUTER + (8 * int_id), mpidr); + cpuaffinity = mpidr & (PE_AFF0 | PE_AFF1 | PE_AFF2 | PE_AFF3); + val_mmio_write64(val_get_gicd_base() + GICD_IROUTER + (8 * int_id), cpuaffinity); } else{ val_print(ACS_PRINT_ERR, "\n Only SPIs can be routed, interrupt with INTID = %d cannot be routed", int_id); @@ -442,6 +456,39 @@ uint32_t val_gic_get_intr_trigger_type(uint32_t int_id, INTR_TRIGGER_INFO_TYPE_e return 0; } +/** + @brief This function will Get the trigger type Edge/Level for extended SPI int + 1. Caller - Test Suite + 2. Prerequisite - val_gic_create_info_table + @param int_id Interrupt ID + @return Status +**/ +uint32_t val_gic_get_espi_intr_trigger_type(uint32_t int_id, + INTR_TRIGGER_INFO_TYPE_e *trigger_type) +{ + uint32_t reg_value; + uint32_t reg_offset; + uint32_t config_bit_shift; + + if (!(int_id >= 4096 && int_id <= val_gic_max_espi_val())) { + val_print(ACS_PRINT_ERR, "\n Invalid Extended Int ID number 0x%x ", int_id); + return ACS_STATUS_ERR; + } + + /* 4096 is starting value of extended SPI int */ + reg_offset = (int_id - 4096) / GICD_ICFGR_INTR_STRIDE; + config_bit_shift = GICD_ICFGR_INTR_CONFIG1(int_id - 4096); + + reg_value = val_mmio_read(val_get_gicd_base() + GICD_ICFGRE + (4 * reg_offset)); + + if ((reg_value & (1 << config_bit_shift)) == 0) + *trigger_type = INTR_TRIGGER_INFO_LEVEL_HIGH; + else + *trigger_type = INTR_TRIGGER_INFO_EDGE_RISING; + + return 0; +} + /** @brief This function will Set the trigger type Edge/Level based on the GTDT table 1. Caller - Test Suite @@ -460,3 +507,35 @@ void val_gic_set_intr_trigger(uint32_t int_id, INTR_TRIGGER_INFO_TYPE_e trigger_ if (status) val_print(ACS_PRINT_ERR, "\n Error Could Not Configure Trigger Type", 0); } + +/** + @brief This API returns if extended SPI supported in system + @param None + @return 0 not supported, 1 supported +**/ +uint32_t +val_gic_espi_supported(void) +{ + uint32_t espi_support; + + espi_support = val_bsa_gic_espi_support(); + + val_print(ACS_PRINT_INFO, "\n ESPI supported %d ", espi_support); + return espi_support; +} + +/** + @brief This API returns max extended SPI interrupt value + @param None + @return max extended spi int value +**/ +uint32_t +val_gic_max_espi_val(void) +{ + uint32_t max_espi_val; + + max_espi_val = val_bsa_gic_max_espi_val(); + + val_print(ACS_PRINT_INFO, "\n max ESPI value %d ", max_espi_val); + return max_espi_val; +} diff --git a/val/src/acs_gic_support.c b/val/src/acs_gic_support.c index e0bf5b41..5e7b2ed3 100644 --- a/val/src/acs_gic_support.c +++ b/val/src/acs_gic_support.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2020, Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2016-2021, Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,6 +22,12 @@ #include "include/bsa_acs_pcie.h" #include "include/bsa_acs_iovirt.h" #include "sys_arch_src/gic/bsa_exception.h" +#include "sys_arch_src/gic/its/bsa_gic_its.h" +#include "sys_arch_src/gic/gic.h" + +extern GIC_INFO_TABLE *g_gic_info_table; +GIC_INFO_ENTRY *g_gic_entry = NULL; +GIC_ITS_INFO *g_gic_its_info; #ifndef TARGET_LINUX /** @@ -44,7 +50,8 @@ val_gic_reg_read(uint32_t reg_id) case ICH_MISR_EL2: return GicReadIchMisr(); default: - val_report_status(val_pe_get_index_mpid(val_pe_get_mpid()), RESULT_FAIL(0, 0x78)); + val_report_status(val_pe_get_index_mpid(val_pe_get_mpid()), + RESULT_FAIL(0, 0x78), NULL); } return 0x0; @@ -80,7 +87,8 @@ val_gic_reg_write(uint32_t reg_id, uint64_t write_data) GicWriteIccPmr(write_data); break; default: - val_report_status(val_pe_get_index_mpid(val_pe_get_mpid()), RESULT_FAIL(0, 0x78)); + val_report_status(val_pe_get_index_mpid(val_pe_get_mpid()), + RESULT_FAIL(0, 0x78), NULL); } } @@ -91,7 +99,7 @@ val_gic_is_valid_lpi(uint32_t int_id) { uint32_t max_lpi_id = 0; - max_lpi_id = pal_gic_get_max_lpi_id(); + max_lpi_id = val_its_get_max_lpi(); if ((int_id < LPI_MIN_ID) || (int_id > max_lpi_id)) { /* Not Vaild LPI */ @@ -124,7 +132,7 @@ val_gic_install_isr(uint32_t int_id, void (*isr)(void)) } #endif - if (pal_bsa_gic_imp()) + if (pal_target_is_dt()) return val_gic_bsa_install_isr(int_id, isr); else ret_val = pal_gic_install_isr(int_id, isr); @@ -136,6 +144,7 @@ val_gic_install_isr(uint32_t int_id, void (*isr)(void)) val_mmio_write(val_get_gicd_base() + GICD_ISENABLER + (4 * reg_offset), 1 << reg_shift); } #endif + return ret_val; } @@ -172,18 +181,104 @@ void val_gic_free_irq(uint32_t irq_num, uint32_t mapped_irq_num) **/ uint32_t val_gic_end_of_interrupt(uint32_t int_id) { - pal_gic_end_of_interrupt(int_id); + if (pal_target_is_dt()) + val_bsa_gic_endofInterrupt(int_id); + else + pal_gic_end_of_interrupt(int_id); return 0; } uint32_t val_gic_its_configure() { - uint32_t status; + uint32_t Status; - status = pal_gic_its_configure(); + if (pal_target_is_dt()) + return ACS_STATUS_SKIP; - return status; + g_gic_entry = g_gic_info_table->gic_info; + + if (g_gic_entry == NULL) + goto its_fail; + + /* Allocate memory to store ITS info */ + g_gic_its_info = (GIC_ITS_INFO *) val_memory_alloc(1024); + if (!g_gic_its_info) { + val_print(ACS_PRINT_ERR, "GIC : ITS table memory allocation failed\n", 0); + return ACS_STATUS_ERR; + } + + g_gic_its_info->GicNumIts = 0; + g_gic_its_info->GicRdBase = 0; + g_gic_its_info->GicDBase = 0; + + while (g_gic_entry->type != 0xFF) + { + if (g_gic_entry->type == ENTRY_TYPE_GICD) + g_gic_its_info->GicDBase = g_gic_entry->base; + else if ((g_gic_entry->type == ENTRY_TYPE_GICR_GICRD) + || (g_gic_entry->type == ENTRY_TYPE_GICC_GICRD)) { + /* Calculate Current PE Redistributor Base Address */ + if (g_gic_its_info->GicRdBase == 0) { + if (g_gic_entry->type == ENTRY_TYPE_GICR_GICRD) + g_gic_its_info->GicRdBase = val_its_get_curr_rdbase(g_gic_entry->base, + g_gic_entry->length); + else + g_gic_its_info->GicRdBase = val_its_get_curr_rdbase(g_gic_entry->base, 0); + } + } else if (g_gic_entry->type == ENTRY_TYPE_GICITS) { + g_gic_its_info->GicIts[g_gic_its_info->GicNumIts].Base = g_gic_entry->base; + g_gic_its_info->GicIts[g_gic_its_info->GicNumIts++].ID = g_gic_entry->entry_id; + } + + g_gic_entry++; + } + + /* Return if no ITS */ + if (g_gic_its_info->GicNumIts == 0) { + val_print(ACS_PRINT_DEBUG, "\n ITS Configure : No ITS Found", 0); + goto its_fail; + } + + /* Base Address Check. */ + if ((g_gic_its_info->GicRdBase == 0) || (g_gic_its_info->GicDBase == 0)) { + val_print(ACS_PRINT_DEBUG, "\n ITS Configure : Could not get GICD/GICRD Base", 0); + goto its_fail; + } + + if (val_its_gicd_lpi_support(g_gic_its_info->GicDBase) + && val_its_gicr_lpi_support(g_gic_its_info->GicRdBase)) { + Status = val_its_init(); + if ((Status)) { + val_print(ACS_PRINT_DEBUG, "\n ITS Configure : val_its_init failed", 0); + goto its_fail; + } + } else { + val_print(ACS_PRINT_DEBUG, "\n LPIs not supported in the system", 0); + goto its_fail; + } + + return 0; + +its_fail: + + val_print(ACS_PRINT_DEBUG, "\n GIC ITS Initialization Failed", 0); + val_print(ACS_PRINT_DEBUG, "\n LPI Interrupt related test may not pass", 0); + val_memory_free((void *)g_gic_its_info); + + return ACS_STATUS_ERR; +} + +uint32_t get_its_index(uint32_t its_id) +{ + uint32_t index; + + for (index = 0; index < g_gic_its_info->GicNumIts; index++) + { + if (its_id == g_gic_its_info->GicIts[index].ID) + return index; + } + return ACS_INVALID_INDEX; } void clear_msi_x_table(uint32_t bdf, uint32_t msi_index) @@ -194,7 +289,8 @@ void clear_msi_x_table(uint32_t bdf, uint32_t msi_index) uint32_t read_value; /* Get MSI Capability Offset */ - val_pcie_find_capability(bdf, PCIE_CAP, CID_MSIX, &msi_cap_offset); + if (val_pcie_find_capability(bdf, PCIE_CAP, CID_MSIX, &msi_cap_offset)) + return; /* Disable MSI-X in MSI-X Capability */ val_pcie_read_cfg(bdf, msi_cap_offset, &read_value); @@ -211,7 +307,7 @@ void clear_msi_x_table(uint32_t bdf, uint32_t msi_index) val_mmio_write(table_address + msi_index*MSI_X_ENTRY_SIZE + MSI_X_MSG_TBL_MVC_OFFSET, 0x1); } -void fill_msi_x_table(uint32_t bdf, uint32_t msi_index, uint32_t msi_addr, uint32_t msi_data) +uint32_t fill_msi_x_table(uint32_t bdf, uint32_t msi_index, uint32_t msi_addr, uint32_t msi_data) { uint32_t msi_cap_offset, msi_table_bar_index; @@ -223,7 +319,8 @@ void fill_msi_x_table(uint32_t bdf, uint32_t msi_index, uint32_t msi_addr, uint3 val_pcie_write_cfg(bdf, TYPE01_CR, (command_data | (1 << CR_MSE_SHIFT) | (1 << CR_BME_SHIFT))); /* Get MSI Capability Offset */ - val_pcie_find_capability(bdf, PCIE_CAP, CID_MSIX, &msi_cap_offset); + if (val_pcie_find_capability(bdf, PCIE_CAP, CID_MSIX, &msi_cap_offset)) + return ACS_STATUS_SKIP; /* Enable MSI-X in MSI-X Capability */ val_pcie_read_cfg(bdf, msi_cap_offset, &read_value); @@ -238,35 +335,38 @@ void fill_msi_x_table(uint32_t bdf, uint32_t msi_index, uint32_t msi_addr, uint3 val_mmio_write(table_address + msi_index*MSI_X_ENTRY_SIZE + MSI_X_MSG_TBL_ADDR_OFFSET, msi_addr); val_mmio_write(table_address + msi_index*MSI_X_ENTRY_SIZE + MSI_X_MSG_TBL_DATA_OFFSET, msi_data); val_mmio_write(table_address + msi_index*MSI_X_ENTRY_SIZE + MSI_X_MSG_TBL_MVC_OFFSET, 0x0); + + return ACS_STATUS_PASS; } /** @brief This function clear the MSI related mappings. @param bdf B:D:F for the device - @param IntID Interrupt ID + @param int_id Interrupt ID @param msi_index msi index in the table @return status **/ -void val_gic_free_msi(uint32_t bdf, uint32_t IntID, uint32_t msi_index) +void val_gic_free_msi(uint32_t bdf, uint32_t device_id, uint32_t its_id, + uint32_t int_id, uint32_t msi_index) { - uint32_t status; - uint32_t device_id, stream_id, its_id; - uint32_t req_id; - uint32_t bus = PCIE_EXTRACT_BDF_BUS(bdf); - uint32_t dev = PCIE_EXTRACT_BDF_DEV(bdf); - uint32_t func = PCIE_EXTRACT_BDF_FUNC(bdf); + uint32_t its_index; - req_id = GET_DEVICE_ID(bus, dev, func); - - status = val_iovirt_get_device_info(req_id, PCIE_EXTRACT_BDF_SEG(bdf), &device_id, &stream_id, &its_id); - if (status) { /* Use Requester-Id if val_iovirt_get_device_info fails.*/ - device_id = req_id; + its_index = get_its_index(its_id); + if (its_index >= g_gic_its_info->GicNumIts) + { + val_print(ACS_PRINT_ERR, "\n Could not find ITS ID [%x]", its_id); + return; } - pal_gic_free_msi(its_id, device_id, IntID, msi_index); + if ((g_gic_its_info->GicRdBase == 0) || (g_gic_its_info->GicDBase == 0)) + { + val_print(ACS_PRINT_ERR, "\n GICD/GICRD Base Invalid value", 0); + return; + } + val_its_clear_lpi_map(its_index, device_id, int_id); clear_msi_x_table(bdf, msi_index); } @@ -274,35 +374,43 @@ void val_gic_free_msi(uint32_t bdf, uint32_t IntID, uint32_t msi_index) @brief This function creates the MSI mappings, and programs the MSI Table. @param bdf B:D:F for the device - @param IntID Interrupt ID + @param device_id Device ID + @param its_id ITS ID + @param int_id Interrupt ID @param msi_index msi index in the table @return status **/ -uint32_t val_gic_request_msi(uint32_t bdf, uint32_t IntID, uint32_t msi_index) +uint32_t val_gic_request_msi(uint32_t bdf, uint32_t device_id, uint32_t its_id, + uint32_t int_id, uint32_t msi_index) { uint32_t status; uint32_t msi_addr, msi_data; - uint32_t device_id, stream_id, its_id; - uint32_t req_id; - uint32_t bus = PCIE_EXTRACT_BDF_BUS(bdf); - uint32_t dev = PCIE_EXTRACT_BDF_DEV(bdf); - uint32_t func = PCIE_EXTRACT_BDF_FUNC(bdf); + uint32_t its_index; - req_id = GET_DEVICE_ID(bus, dev, func); + if ((g_gic_its_info == NULL) || (g_gic_its_info->GicNumIts == 0)) + return ACS_STATUS_ERR; - status = val_iovirt_get_device_info(req_id, PCIE_EXTRACT_BDF_SEG(bdf), &device_id, &stream_id, &its_id); - if (status) { /* Use Requester-Id if val_iovirt_get_device_info fails.*/ - device_id = req_id; + its_index = get_its_index(its_id); + + if (its_index >= g_gic_its_info->GicNumIts) { + val_print(ACS_PRINT_ERR, "\n Could not find ITS ID [%x]", its_id); + return ACS_STATUS_ERR; } - status = pal_gic_request_msi(its_id, device_id, IntID, msi_index, &msi_addr, &msi_data); - if (status) { - /* MSI Assignment Failed. */ - return status; + if ((g_gic_its_info->GicRdBase == 0) || (g_gic_its_info->GicDBase == 0)) + { + val_print(ACS_PRINT_DEBUG, "\n GICD/GICRD Base Invalid value", 0); + return ACS_STATUS_ERR; } - fill_msi_x_table(bdf, msi_index, msi_addr, msi_data); + val_its_create_lpi_map(its_index, device_id, int_id, LPI_PRIORITY1); + + msi_addr = val_its_get_translator_addr(its_index); + msi_data = int_id; + + + status = fill_msi_x_table(bdf, msi_index, msi_addr, msi_data); return status; } diff --git a/val/src/acs_iovirt.c b/val/src/acs_iovirt.c index d55da2db..48c4a532 100644 --- a/val/src/acs_iovirt.c +++ b/val/src/acs_iovirt.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2020, Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2016-2021 Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -138,6 +138,98 @@ val_iovirt_get_pcie_rc_info(PCIE_RC_INFO_e type, uint32_t index) } +/** + @brief This API is a single point of entry to retrieve + ITS information stored in the IoVirt Info table + 1. Prerequisite - val_iovirt_create_info_table + @param type : The type of information being requested + @param group_index : ITS group index + @param param : value to be passed based on use-case + @param return_value : return data + @return Status +**/ +int +val_iovirt_get_its_info( + uint32_t type, uint32_t group_index, uint32_t param, uint32_t *return_value) +{ + uint32_t i = 0; + uint32_t j = 0; + uint32_t it = 0; + IOVIRT_BLOCK *block; + + + if (g_iovirt_info_table == NULL) { + val_print(ACS_PRINT_ERR, "GET_ITS_INFO: iovirt info table is not created \n", 0); + return ACS_STATUS_ERR; + } + if (!return_value) { + val_print(ACS_PRINT_ERR, "GET_ITS_INFO: Return pointer is NULL \n", 0); + return ACS_STATUS_ERR; + } + + if (type == ITS_NUM_GROUPS) { + *return_value = g_iovirt_info_table->num_its_groups; + return ACS_STATUS_PASS; + } + + /* Go through the table return the relevant field value for the ITS block */ + /* at the index position */ + block = &g_iovirt_info_table->blocks[0]; + + for (i = 0; i < g_iovirt_info_table->num_blocks; i++, block = IOVIRT_NEXT_BLOCK(block)) + { + if (block->type == IOVIRT_NODE_ITS_GROUP) { + if (type == ITS_GET_GRP_INDEX_FOR_ID) { + /* Return the ITS Group Index for ITS_ID = param */ + for (it = 0; it < block->data.its_count; it++) { + if (block->data_map[0].id[it] == param) { + *return_value = j; + return ACS_STATUS_PASS; + } + } + j++; + continue; + } + if (group_index == j) { + switch (type) + { + case ITS_GROUP_NUM_BLOCKS: /* Return Number of ITS blocks in this group */ + *return_value = block->data.its_count; + return ACS_STATUS_PASS; + case ITS_GET_ID_FOR_BLK_INDEX: + /* Get ITS Block ID for index = param in this current ITS Group */ + for (it = 0; it < block->data.its_count; it++) { + if (it == param) { + *return_value = block->data_map[0].id[it]; + return ACS_STATUS_PASS; + } + } + /* Return Error if block not found */ + return ACS_INVALID_INDEX; + case ITS_GET_BLK_INDEX_FOR_ID: + /* Get ITS Block index for ITS_ID = param in ITS Group = group_index */ + for (it = 0; it < block->data.its_count; it++) { + if (block->data_map[0].id[it] == param) { + *return_value = it; + return ACS_STATUS_PASS; + } + } + /* ITS_ID not found in current group, return error */ + return ACS_INVALID_INDEX; + default: + val_print(ACS_PRINT_ERR, "This ITS info option not supported %d \n", type); + return ACS_STATUS_ERR; + } + break; + } + j++; + } + } + + val_print(ACS_PRINT_ERR, "GET_ITS_INFO: ITS Group not found %d\n", group_index); + return ACS_INVALID_INDEX; +} + uint32_t val_iovirt_unique_rid_strid_map(uint32_t rc_index) { @@ -167,11 +259,11 @@ val_iovirt_get_device_info(uint32_t rid, uint32_t segment, uint32_t *device_id, NODE_DATA_MAP *map; if (g_iovirt_info_table == NULL) { - val_print(ACS_PRINT_ERR, "GET_DEVICE_ID: iovirt info table is not created \n", 0); + val_print(ACS_PRINT_ERR, "\n GET_DEVICE_ID: iovirt info table is not created", 0); return ACS_STATUS_ERR; } if (!device_id) { - val_print(ACS_PRINT_ERR, "GET_DEVICE_ID: Invalid parameters\n", 0); + val_print(ACS_PRINT_ERR, "\n GET_DEVICE_ID: Invalid parameters", 0); return ACS_STATUS_ERR; } @@ -199,7 +291,7 @@ val_iovirt_get_device_info(uint32_t rid, uint32_t segment, uint32_t *device_id, } if (!mapping_found) { val_print(ACS_PRINT_ERR, - "GET_DEVICE_ID: Requestor ID to Stream ID/Device ID mapping not found\n", 0); + "\n GET_DEVICE_ID: RID to Stream/Dev ID mapping not found", 0); return ACS_STATUS_ERR; } /* If output reference node is to ITS group, 'id' is device id */ @@ -235,12 +327,13 @@ val_iovirt_get_device_info(uint32_t rid, uint32_t segment, uint32_t *device_id, } else { - val_print(ACS_PRINT_ERR, "GET_DEVICE_ID: Invalid mapping for RC in IORT\n", 0); + val_print(ACS_PRINT_ERR, "\n GET_DEVICE_ID: Invalid mapping for RC in IORT", 0); return ACS_STATUS_ERR; } if (!mapping_found) { - val_print(ACS_PRINT_ERR, "GET_DEVICE_ID: Stream ID to Device ID mapping not found\n", 0); + val_print(ACS_PRINT_ERR, + "\n GET_DEVICE_ID: Stream ID to Device ID mapping not found", 0); return ACS_STATUS_ERR; } diff --git a/val/src/acs_memory.c b/val/src/acs_memory.c index 7049be45..68863e99 100644 --- a/val/src/acs_memory.c +++ b/val/src/acs_memory.c @@ -46,9 +46,9 @@ val_memory_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) status = ACS_STATUS_PASS; if (g_sw_view[G_SW_OS]) { - val_print(ACS_PRINT_ERR, "\nOperating System:\n", 0); + val_print(ACS_PRINT_ERR, "\nOperating System View:\n", 0); #ifndef TARGET_LINUX - status |= os_m001_entry(num_pe); +// status |= os_m001_entry(num_pe); status |= os_m002_entry(num_pe); status |= os_m003_entry(num_pe); #else @@ -300,3 +300,32 @@ val_memory_free_pages(void *addr, uint32_t num_pages) { pal_mem_free_pages(addr, num_pages); } + +/** + @brief Allocates memory with the given alignment. + + @param Alignment Specifies the alignment. + @param Size Requested memory allocation size. + + @return Pointer to the allocated memory with requested alignment. +**/ +void +*val_aligned_alloc(uint32_t alignment, uint32_t size) +{ + void *Mem = NULL; + void *Aligned_Ptr = NULL; + + /* Generate mask for the Alignment parameter*/ + uint64_t Mask = ~(uint64_t)(alignment - 1); + + /* Allocate memory with extra bytes, so we can return an aligned address*/ + Mem = (void *)pal_mem_alloc(size + alignment); + + if (Mem == NULL) + return 0; + + /* Add the alignment to allocated memory address and align it to target alignment*/ + Aligned_Ptr = (void *)(((uint64_t) Mem + alignment-1) & Mask); + + return Aligned_Ptr; +} diff --git a/val/src/acs_pcie.c b/val/src/acs_pcie.c index 29cb2d0a..89a5d06f 100644 --- a/val/src/acs_pcie.c +++ b/val/src/acs_pcie.c @@ -278,13 +278,7 @@ val_pcie_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) } if (g_sw_view[G_SW_OS]) { - val_print(ACS_PRINT_ERR, "\n PCI_IN_06: PCIe HB must recognise tranx from PE ", 0); - val_print(ACS_PRINT_ERR, " : Result: PASS", 0); - val_print(ACS_PRINT_ERR, "\n PCI_iEP_1: PCIe spec follow SW visible spec ", 0); - val_print(ACS_PRINT_ERR, " : Result: PASS", 0); - val_print(ACS_PRINT_ERR, "\n RE_CFG_1: Recognise RW request in ECAM reg ", 0); - val_print(ACS_PRINT_ERR, " : Result: PASS", 0); - val_print(ACS_PRINT_ERR, "\nOperating System:\n", 0); + val_print(ACS_PRINT_ERR, "\nOperating System View:\n", 0); status |= os_p001_entry(num_pe); if (status != ACS_STATUS_PASS) { @@ -300,14 +294,30 @@ val_pcie_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) if (g_sw_view[G_SW_OS]) { #ifdef TARGET_LINUX + status |= os_p061_entry(num_pe); + status |= os_p062_entry(num_pe); + status |= os_p063_entry(num_pe); + status |= os_p064_entry(num_pe); + status |= os_p065_entry(num_pe); + status |= os_p066_entry(num_pe); +#else + status |= os_p002_entry(num_pe); + status |= os_p003_entry(num_pe); + status |= os_p004_entry(num_pe); status |= os_p005_entry(num_pe); status |= os_p006_entry(num_pe); - status |= os_p007_entry(num_pe); + status |= os_p008_entry(num_pe); + status |= os_p009_entry(num_pe); + status |= os_p010_entry(num_pe); status |= os_p011_entry(num_pe); status |= os_p012_entry(num_pe); + status |= os_p013_entry(num_pe); + status |= os_p014_entry(num_pe); + status |= os_p015_entry(num_pe); status |= os_p016_entry(num_pe); -#else - status |= os_p002_entry(num_pe); + status |= os_p017_entry(num_pe); + status |= os_p018_entry(num_pe); + status |= os_p019_entry(num_pe); status |= os_p020_entry(num_pe); status |= os_p021_entry(num_pe); status |= os_p022_entry(num_pe); @@ -325,26 +335,6 @@ val_pcie_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) status |= os_p034_entry(num_pe); status |= os_p035_entry(num_pe); status |= os_p036_entry(num_pe); - status |= os_p037_entry(num_pe); - status |= os_p038_entry(num_pe); - status |= os_p039_entry(num_pe); - status |= os_p041_entry(num_pe); - status |= os_p042_entry(num_pe); - status |= os_p044_entry(num_pe); - status |= os_p048_entry(num_pe); - status |= os_p050_entry(num_pe); - status |= os_p051_entry(num_pe); - status |= os_p052_entry(num_pe); - status |= os_p053_entry(num_pe); - status |= os_p054_entry(num_pe); - status |= os_p055_entry(num_pe); - status |= os_p056_entry(num_pe); - status |= os_p057_entry(num_pe); - status |= os_p058_entry(num_pe); - status |= os_p059_entry(num_pe); - status |= os_p060_entry(num_pe); - status |= os_p061_entry(num_pe); - status |= os_p062_entry(num_pe); #endif @@ -365,7 +355,9 @@ val_pcie_print_device_info(void) uint32_t dp_type; uint32_t tbl_index; uint32_t ecam_index; - uint32_t ecam_base; + uint64_t ecam_base; + uint32_t ecam_start_bus; + uint32_t ecam_end_bus; pcie_device_bdf_table *bdf_tbl_ptr; uint32_t num_rciep = 0, num_rcec = 0; uint32_t num_iep = 0, num_irp = 0; @@ -407,21 +399,29 @@ val_pcie_print_device_info(void) while (ecam_index < val_pcie_get_info(PCIE_INFO_NUM_ECAM, 0)) { ecam_base = val_pcie_get_info(PCIE_INFO_ECAM, ecam_index); + ecam_start_bus = val_pcie_get_info(PCIE_INFO_START_BUS, ecam_index); + ecam_end_bus = val_pcie_get_info(PCIE_INFO_END_BUS, ecam_index); tbl_index = 0; - val_print(ACS_PRINT_INFO, "PCIE_INFO: ECAM Regions \n", ecam_index); - val_print(ACS_PRINT_INFO, " ECAM %d:\n", ecam_index); + val_print(ACS_PRINT_INFO, "PCIE_INFO: \nECAM %d:\n", ecam_index); + val_print(ACS_PRINT_INFO, " ECAM Base 0x%llx\n", ecam_base); while (tbl_index < bdf_tbl_ptr->num_entries) { - uint32_t bus_id; + uint32_t seg_num; + uint32_t bus_num; + uint32_t dev_num; + uint32_t func_num; uint32_t device_id; uint32_t vendor_id; uint32_t reg_value; - uint32_t dev_ecam_base; + uint64_t dev_ecam_base; bdf = bdf_tbl_ptr->device[tbl_index++].bdf; - bus_id = PCIE_EXTRACT_BDF_BUS(bdf); + seg_num = PCIE_EXTRACT_BDF_SEG(bdf); + bus_num = PCIE_EXTRACT_BDF_BUS(bdf); + dev_num = PCIE_EXTRACT_BDF_DEV(bdf); + func_num = PCIE_EXTRACT_BDF_FUNC(bdf); val_pcie_read_cfg(bdf, TYPE01_VIDR, ®_value); device_id = (reg_value >> TYPE01_DIDR_SHIFT) & TYPE01_DIDR_MASK; @@ -429,9 +429,13 @@ val_pcie_print_device_info(void) dev_ecam_base = val_pcie_get_ecam_base(bdf); - if (ecam_base == dev_ecam_base) + if ((ecam_base == dev_ecam_base) && (bus_num >= ecam_start_bus) + && (bus_num <= ecam_end_bus)) { - val_print(ACS_PRINT_INFO, " Bus ID: 0x%x, ", bus_id); + val_print(ACS_PRINT_INFO, " Seg: 0x%x, ", seg_num); + val_print(ACS_PRINT_INFO, "Bus: 0x%x, ", bus_num); + val_print(ACS_PRINT_INFO, "Dev: 0x%x, ", dev_num); + val_print(ACS_PRINT_INFO, "Func: 0x%x, ", func_num); val_print(ACS_PRINT_INFO, "Dev ID: 0x%x, ", device_id); val_print(ACS_PRINT_INFO, "Vendor ID: 0x%x\n", vendor_id); } diff --git a/val/src/acs_pe.c b/val/src/acs_pe.c index 01431af4..565de098 100644 --- a/val/src/acs_pe.c +++ b/val/src/acs_pe.c @@ -53,7 +53,7 @@ val_pe_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) status = ACS_STATUS_PASS; if (g_sw_view[G_SW_OS]) { - val_print(ACS_PRINT_ERR, "\nOperating System:\n", 0); + val_print(ACS_PRINT_ERR, "\nOperating System View:\n", 0); status |= os_c001_entry(num_pe); status |= os_c002_entry(num_pe); status |= os_c003_entry(num_pe); @@ -77,7 +77,7 @@ val_pe_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) } if (g_sw_view[G_SW_HYP]) { - val_print(ACS_PRINT_ERR, "\nHypervisor:\n", 0); + val_print(ACS_PRINT_ERR, "\nHypervisor View:\n", 0); status |= hyp_c001_entry(num_pe); status |= hyp_c002_entry(num_pe); status |= hyp_c003_entry(num_pe); @@ -86,7 +86,7 @@ val_pe_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) } if (g_sw_view[G_SW_PS]) { - val_print(ACS_PRINT_ERR, "\nPlatform Security:\n", 0); + val_print(ACS_PRINT_ERR, "\nPlatform Security View:\n", 0); status |= ps_c001_entry(num_pe); } @@ -264,7 +264,8 @@ val_pe_reg_read(uint32_t reg_id) case DBGBCR15_EL1: return AA64ReadDbgbcr15El1(); default: - val_report_status(val_pe_get_index_mpid(val_pe_get_mpid()), RESULT_FAIL(0, 0x78)); + val_report_status(val_pe_get_index_mpid(val_pe_get_mpid()), + RESULT_FAIL(0, 0x78), NULL); break; } @@ -324,7 +325,8 @@ val_pe_reg_write(uint32_t reg_id, uint64_t write_data) AA64WritePmblimitr(write_data); break; default: - val_report_status(val_pe_get_index_mpid(val_pe_get_mpid()), RESULT_FAIL(0, 0x78)); + val_report_status(val_pe_get_index_mpid(val_pe_get_mpid()), + RESULT_FAIL(0, 0x78), NULL); } } @@ -377,7 +379,7 @@ val_pe_get_pmu_gsiv(uint32_t index) PE_INFO_ENTRY *entry; if (index > g_pe_info_table->header.num_of_pe) { - val_report_status(index, RESULT_FAIL(0, 0xFF)); + val_report_status(index, RESULT_FAIL(0, 0xFF), NULL); return 0xFFFFFF; } @@ -401,7 +403,7 @@ val_pe_get_gmain_gsiv(uint32_t index) PE_INFO_ENTRY *entry; if (index > g_pe_info_table->header.num_of_pe) { - val_report_status(index, RESULT_FAIL(0, 0xFF)); + val_report_status(index, RESULT_FAIL(0, 0xFF), NULL); return 0xFFFFFF; } diff --git a/val/src/acs_pe_infra.c b/val/src/acs_pe_infra.c index 3c0e1536..fb88e512 100644 --- a/val/src/acs_pe_infra.c +++ b/val/src/acs_pe_infra.c @@ -122,8 +122,8 @@ val_pe_get_mpid_index(uint32_t index) PE_INFO_ENTRY *entry; if (index > g_pe_info_table->header.num_of_pe) { - val_report_status(index, RESULT_FAIL(0, 0xFF)); - return 0xFFFFFF; + val_report_status(index, RESULT_FAIL(0, 0xFF), NULL); + return 0xFFFFFF; } entry = g_pe_info_table->pe_info; @@ -203,7 +203,7 @@ val_execute_on_pe(uint32_t index, void (*payload)(void), uint64_t test_input) int timeout = TIMEOUT_LARGE; if (index > g_pe_info_table->header.num_of_pe) { val_print(ACS_PRINT_ERR, "Input Index exceeds Num of PE %x \n", index); - val_report_status(index, RESULT_FAIL(0, 0xFF)); + val_report_status(index, RESULT_FAIL(0, 0xFF), NULL); return; } @@ -251,7 +251,7 @@ val_pe_install_esr(uint32_t exception_type, void (*esr)(uint64_t, void *)) return ACS_STATUS_ERR; } #ifndef TARGET_LINUX - if (pal_bsa_gic_imp()) + if (pal_target_is_dt()) val_gic_bsa_install_esr(exception_type, esr); else pal_pe_install_esr(exception_type, esr); @@ -301,7 +301,7 @@ val_pe_default_esr(uint64_t interrupt_type, void *context) val_print(ACS_PRINT_WARN, "\n Unexpected exception occured", 0); #ifndef TARGET_LINUX - if (pal_bsa_gic_imp()) { + if (pal_target_is_dt()) { val_print(ACS_PRINT_WARN, "\n FAR reported = 0x%llx", bsa_gic_get_far()); val_print(ACS_PRINT_WARN, "\n ESR reported = 0x%llx", bsa_gic_get_esr()); } else { diff --git a/val/src/acs_peripherals.c b/val/src/acs_peripherals.c index 4b776d41..a9973a53 100644 --- a/val/src/acs_peripherals.c +++ b/val/src/acs_peripherals.c @@ -46,11 +46,14 @@ val_peripheral_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) } if (g_sw_view[G_SW_OS]) { - val_print(ACS_PRINT_ERR, "\nOperating System:\n", 0); + val_print(ACS_PRINT_ERR, "\nOperating System View:\n", 0); #ifndef TARGET_LINUX - status |= os_d001_entry(num_pe); - status |= os_d002_entry(num_pe); + if (!pal_target_is_dt()) { + status |= os_d001_entry(num_pe); + status |= os_d002_entry(num_pe); + } status |= os_d003_entry(num_pe); + status |= os_d005_entry(num_pe); #else status |= os_d004_entry(num_pe); #endif @@ -180,6 +183,16 @@ val_peripheral_get_info(PERIPHERAL_INFO_e info_type, uint32_t instance) if (i != 0xFFFF) return g_peripheral_info_table->info[i].flags; break; + case UART_BAUDRATE: + i = val_peripheral_get_entry_index(PERIPHERAL_TYPE_UART, instance); + if (i != 0xFFFF) + return g_peripheral_info_table->info[i].baud_rate; + break; + case UART_INTERFACE_TYPE: + i = val_peripheral_get_entry_index(PERIPHERAL_TYPE_UART, instance); + if (i != 0xFFFF) + return g_peripheral_info_table->info[i].interface_type; + break; case ANY_FLAGS: i = val_peripheral_get_entry_index (PERIPHERAL_TYPE_NONE, instance); if (i != 0xFFFF) diff --git a/val/src/acs_smmu.c b/val/src/acs_smmu.c index 459db36c..a022694f 100644 --- a/val/src/acs_smmu.c +++ b/val/src/acs_smmu.c @@ -73,7 +73,7 @@ val_smmu_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) } if (g_sw_view[G_SW_OS]) { - val_print(ACS_PRINT_ERR, "\nOperating System:\n", 0); + val_print(ACS_PRINT_ERR, "\nOperating System View:\n", 0); status |= os_i001_entry(num_pe); status |= os_i002_entry(num_pe); status |= os_i003_entry(num_pe); @@ -82,19 +82,19 @@ val_smmu_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) status |= os_i006_entry(num_pe); status |= os_i007_entry(num_pe); status |= os_i008_entry(num_pe); - } - - if (g_sw_view[G_SW_OS] || g_sw_view[G_SW_HYP]) { status |= os_i009_entry(num_pe); } if (g_sw_view[G_SW_HYP]) { - val_print(ACS_PRINT_ERR, "\nHypervisor:\n", 0); + val_print(ACS_PRINT_ERR, "\nHypervisor View:\n", 0); status |= hyp_i001_entry(num_pe); status |= hyp_i002_entry(num_pe); status |= hyp_i003_entry(num_pe); status |= hyp_i004_entry(num_pe); status |= hyp_i005_entry(num_pe); + /* if OS view is not enabled run below test as part of hyp view, else skip */ + if (!g_sw_view[G_SW_OS]) + status |= os_i009_entry(num_pe); } diff --git a/val/src/acs_status.c b/val/src/acs_status.c index f4b49e10..5817a3fb 100644 --- a/val/src/acs_status.c +++ b/val/src/acs_status.c @@ -29,27 +29,41 @@ @return none **/ void -val_report_status(uint32_t index, uint32_t status) +val_report_status(uint32_t index, uint32_t status, char8_t *ruleid) { if (IS_TEST_FAIL(status)) { - val_print(ACS_PRINT_ERR, "\n Failed on PE - %4d ", index); + val_print(ACS_PRINT_ERR, "\n Failed on PE - %4d", index); } if (IS_TEST_PASS(status)) - val_print(ACS_PRINT_TEST, ": Result: PASS \n", status); + val_print(ACS_PRINT_TEST, " : Result: PASS \n", status); else - if (IS_TEST_FAIL(status)) - val_print(ACS_PRINT_ERR, ": Result: --FAIL-- %x \n", status & STATUS_MASK); + if (IS_TEST_FAIL(status)) { + if (ruleid) { + val_print(ACS_PRINT_ERR, "\n ", 0); + val_print(ACS_PRINT_ERR, ruleid, 0); + val_print(ACS_PRINT_ERR, "\n Checkpoint -- %2d ", + status & STATUS_MASK); + } + val_print(ACS_PRINT_ERR, " : Result: FAIL \n", 0); + } else - if (IS_TEST_SKIP(status)) - val_print(ACS_PRINT_WARN, ": Result: -SKIPPED- %x \n", status & STATUS_MASK); + if (IS_TEST_SKIP(status)) { + if (ruleid) { + val_print(ACS_PRINT_WARN, "\n ", 0); + val_print(ACS_PRINT_WARN, ruleid, 0); + val_print(ACS_PRINT_WARN, "\n Checkpoint -- %2d ", + status & STATUS_MASK); + } + val_print(ACS_PRINT_WARN, " : Result: SKIPPED \n", 0); + } else if (IS_TEST_START(status)) - val_print(ACS_PRINT_INFO, " START ", status); + val_print(ACS_PRINT_INFO, " START\n", status); else if (IS_TEST_END(status)) - val_print(ACS_PRINT_INFO, " END \n\n", status); + val_print(ACS_PRINT_INFO, " END\n\n", status); else val_print(ACS_PRINT_ERR, ": Result: %8x \n", status); diff --git a/val/src/acs_test_infra.c b/val/src/acs_test_infra.c index 7e3b6f48..8d83bfe4 100644 --- a/val/src/acs_test_infra.c +++ b/val/src/acs_test_infra.c @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2020, Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2016-2021, Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -224,7 +224,7 @@ val_initialize_test(uint32_t test_num, char8_t *desc, uint32_t num_pe) val_print(ACS_PRINT_ERR, "%4d : ", test_num); //Always print this val_print(ACS_PRINT_TEST, desc, 0); - val_report_status(0, BSA_ACS_START(test_num)); + val_report_status(0, BSA_ACS_START(test_num), NULL); val_pe_initialize_default_exception_handler(val_pe_default_esr); g_bsa_tests_total++; @@ -425,7 +425,7 @@ val_run_test_payload(uint32_t test_num, uint32_t num_pe, void (*payload)(void), @return Success or on failure - status of the last failed PE **/ uint32_t -val_check_for_error(uint32_t test_num, uint32_t num_pe) +val_check_for_error(uint32_t test_num, uint32_t num_pe, char8_t *ruleid) { uint32_t i; uint32_t status = 0; @@ -436,7 +436,7 @@ val_check_for_error(uint32_t test_num, uint32_t num_pe) of pe_info_table but num_pe is 1 for SOC tests */ if (num_pe == 1) { status = val_get_status(my_index); - val_report_status(my_index, status); + val_report_status(my_index, status, ruleid); if (IS_TEST_PASS(status)) { g_bsa_tests_pass++; return ACS_STATUS_PASS; @@ -452,14 +452,14 @@ val_check_for_error(uint32_t test_num, uint32_t num_pe) status = val_get_status(i); //val_print(ACS_PRINT_ERR, "Status %4x \n", status); if (IS_TEST_FAIL_SKIP(status)) { - val_report_status(i, status); + val_report_status(i, status, ruleid); error_flag += 1; break; } } if (!error_flag) - val_report_status(my_index, status); + val_report_status(my_index, status, ruleid); if (IS_TEST_PASS(status)) { g_bsa_tests_pass++; @@ -489,7 +489,7 @@ val_data_cache_ops_by_va(addr_t addr, uint32_t type) void val_pe_update_elr(void *context, uint64_t offset) { - if (pal_bsa_gic_imp()) { + if (pal_target_is_dt()) { #ifndef TARGET_LINUX bsa_gic_update_elr(offset); #endif @@ -570,3 +570,17 @@ val_time_delay_ms(uint64_t timer_ms) { return pal_time_delay_ms(timer_ms); } + +/** + Calls pal API to dump dtb + + @param none + + @return none + +**/ +void +val_dump_dtb(void) +{ + pal_dump_dtb(); +} diff --git a/val/src/acs_timer.c b/val/src/acs_timer.c index 133ef80b..d47f497a 100644 --- a/val/src/acs_timer.c +++ b/val/src/acs_timer.c @@ -46,7 +46,7 @@ val_timer_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) } if (g_sw_view[G_SW_OS]) { - val_print(ACS_PRINT_ERR, "\nOperating System:\n", 0); + val_print(ACS_PRINT_ERR, "\nOperating System View:\n", 0); status |= os_t001_entry(num_pe); status |= os_t002_entry(num_pe); status |= os_t003_entry(num_pe); @@ -198,6 +198,20 @@ val_get_phy_el2_timer_count(void) return ArmArchTimerReadReg(CnthpTval); } +/** + @brief This API to get the el1 phy timer count. + 1. Caller - Test Suite + 2. Prerequisite - None + @param None + + @return Current timer count +**/ +uint64_t +val_get_phy_el1_timer_count(void) +{ + return ArmArchTimerReadReg(CntpTval); +} + /** @brief This API programs the el1 phy timer with the input timeout value. 1. Caller - Test Suite diff --git a/val/src/acs_wakeup.c b/val/src/acs_wakeup.c index 9500fb57..dfab01b7 100644 --- a/val/src/acs_wakeup.c +++ b/val/src/acs_wakeup.c @@ -44,7 +44,7 @@ val_wakeup_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) } if (g_sw_view[G_SW_OS]) { - val_print(ACS_PRINT_ERR, "\nOperating System:\n", 0); + val_print(ACS_PRINT_ERR, "\nOperating System View:\n", 0); status |= os_u001_entry(num_pe); // Test needs multi-PE interrupt handling support // status |= os_u002_entry(num_pe); @@ -59,24 +59,69 @@ val_wakeup_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) } +uint32_t val_get_pcsi_ver(void) +{ + ARM_SMC_ARGS smc_args; + + smc_args.Arg0 = ARM_SMC_ID_PSCI_VERSION; + + pal_pe_call_smc(&smc_args); + + val_print(ACS_PRINT_DEBUG, "\n PSCI VERSION = %X", smc_args.Arg0); + + return smc_args.Arg0; +} + + +uint32_t val_get_pcsi_features(uint64_t pcsi_func_id) +{ + ARM_SMC_ARGS smc_args; + + smc_args.Arg0 = ARM_SMC_ID_PSCI_FEATURES; + smc_args.Arg1 = pcsi_func_id; + + pal_pe_call_smc(&smc_args); + + val_print(ACS_PRINT_DEBUG, "\n PSCI FEATURS = %d", smc_args.Arg0); + + return smc_args.Arg0; +} /** @brief This API initiates a Power state Suspend sequence by calling SUSPEND PSCI call - @param power_state - See PSCI specification @entry - See PSCI specification @context_id - See PSCI specification + @return status of PSCI call. **/ -void -val_suspend_pe(uint32_t power_state, uint64_t entry, uint32_t context_id) +int +val_suspend_pe(uint64_t entry, uint32_t context_id) { ARM_SMC_ARGS smc_args; + int psci_major_ver, pwr_state_fmt; + uint32_t power_state; + + psci_major_ver = (val_get_pcsi_ver() >> 16); + val_print(ACS_PRINT_DEBUG, "\n PSCI MAJOR VERSION = %X", psci_major_ver); + if (psci_major_ver < 1) + power_state = 0; + else { + pwr_state_fmt = (val_get_pcsi_features(ARM_SMC_ID_PSCI_CPU_SUSPEND_AARCH64) >> 1); + val_print(ACS_PRINT_DEBUG, "\n PSCI PWR_STATE_FMT = %d ", + pwr_state_fmt); + if (pwr_state_fmt == ARM_SMC_ID_PSCI_POWER_STATE_FMT_ORIGINAL) + power_state = 0; + else + power_state = 1; + } smc_args.Arg0 = ARM_SMC_ID_PSCI_CPU_SUSPEND_AARCH64; smc_args.Arg1 = power_state; smc_args.Arg2 = entry; smc_args.Arg3 = context_id; pal_pe_call_smc(&smc_args); + + return smc_args.Arg0; } diff --git a/val/src/acs_wd.c b/val/src/acs_wd.c index faaab4ee..3a8d4a11 100644 --- a/val/src/acs_wd.c +++ b/val/src/acs_wd.c @@ -45,7 +45,7 @@ val_wd_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) } if (g_sw_view[G_SW_OS]) { - val_print(ACS_PRINT_ERR, "\nOperating System:\n", 0); + val_print(ACS_PRINT_ERR, "\nOperating System View:\n", 0); status |= os_w001_entry(num_pe); status |= os_w002_entry(num_pe); } diff --git a/val/sys_arch_src/gic/bsa_exception.c b/val/sys_arch_src/gic/bsa_exception.c index d38f33c3..c86ea065 100644 --- a/val/sys_arch_src/gic/bsa_exception.c +++ b/val/sys_arch_src/gic/bsa_exception.c @@ -82,7 +82,7 @@ void val_gic_bsa_install_esr(uint32_t exception_type, void (*esr)(uint64_t, void uint32_t common_exception_handler(uint32_t exception_type) { - val_print(ACS_PRINT_DEBUG, "\n GIC_INIT: In Exception Handler Type : %x", exception_type); + val_print(ACS_PRINT_INFO, "\n GIC_INIT: In Exception Handler Type : %x", exception_type); /* Call Handler for exception, Handler would have * already been installed using install_esr call diff --git a/val/sys_arch_src/gic/gic.c b/val/sys_arch_src/gic/gic.c index 19a8405a..b408a5ca 100644 --- a/val/sys_arch_src/gic/gic.c +++ b/val/sys_arch_src/gic/gic.c @@ -104,3 +104,41 @@ val_bsa_gic_endofInterrupt(uint32_t int_id) else v2_EndofInterrupt(int_id); } + +/** + @brief API used to find extended SPI support in system. + @param none + @return 0 if not supported, 1 supported +**/ +uint32_t +val_bsa_gic_espi_support(void) +{ + uint32_t gic_version; + + gic_version = val_gic_get_info(GIC_INFO_VERSION); + if (gic_version >= 3) + return (v3_read_gicdTyper() >> GICD_TYPER_ESPI_SHIFT) & GICD_TYPER_ESPI_MASK; + else + return 0; +} + +/** + @brief API used to find max espi value + @param none + @return max espi value +**/ +uint32_t +val_bsa_gic_max_espi_val(void) +{ + uint32_t gic_version; + uint32_t espi_range; + + gic_version = val_gic_get_info(GIC_INFO_VERSION); + if (gic_version >= 3) { + espi_range = (v3_read_gicdTyper() >> GICD_TYPER_ESPI_RANGE_SHIFT) & + GICD_TYPER_ESPI_RANGE_MASK; + return (32 * (espi_range + 1) + 4095); + } + else + return 0; +} diff --git a/val/sys_arch_src/gic/gic.h b/val/sys_arch_src/gic/gic.h index 719cfe2e..d38e1b9e 100644 --- a/val/sys_arch_src/gic/gic.h +++ b/val/sys_arch_src/gic/gic.h @@ -48,14 +48,17 @@ #define GIC_ICCEIOR 0x10 #define PE_AFF0 0xFF -#define PE_AFF1 (0xFF < 8) -#define PE_AFF2 (0xFF < 16) -#define PE_AFF3 (0xFFULL < 32) +#define PE_AFF1 (0xFF << 8) +#define PE_AFF2 (0xFF << 16) +#define PE_AFF3 (0xFFULL << 32) + void val_bsa_gic_init(void); void val_bsa_gic_disableInterruptSource(uint32_t int_id); void val_bsa_gic_enableInterruptSource(uint32_t int_id); uint32_t val_bsa_gic_acknowledgeInterrupt(void); void val_bsa_gic_endofInterrupt(uint32_t int_id); +uint32_t val_bsa_gic_espi_support(void); +uint32_t val_bsa_gic_max_espi_val(void); #endif /*__GIC_H__ */ diff --git a/val/sys_arch_src/gic/its/bsa_gic_its.c b/val/sys_arch_src/gic/its/bsa_gic_its.c new file mode 100644 index 00000000..31126a63 --- /dev/null +++ b/val/sys_arch_src/gic/its/bsa_gic_its.c @@ -0,0 +1,546 @@ +/** @file + * Copyright (c) 2021, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +**/ + + +#include "bsa_gic_its.h" + +uint64_t ArmReadMpidr(void); + +extern GIC_ITS_INFO *g_gic_its_info; +static uint32_t *g_cwriter_ptr; +static uint32_t g_its_setup_done; + +uint64_t val_its_get_curr_rdbase(uint64_t rd_base, uint32_t length) +{ + uint64_t Mpidr; + uint32_t Affinity, CpuAffinity; + uint32_t rd_granularity; + uint64_t curr_rd_base; /* RD Base for Current CPU */ + + Mpidr = ArmReadMpidr(); + + CpuAffinity = (Mpidr & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2)) | + ((Mpidr & ARM_CORE_AFF3) >> 8); + + rd_granularity = ARM_GICR_CTLR_FRAME_SIZE + + ARM_GICR_SGI_PPI_FRAME_SIZE; + + curr_rd_base = rd_base; + + /* If information is present in GICC Structure */ + if (length == 0) + { + Affinity = val_mmio_read(curr_rd_base + ARM_GICR_TYPER + NEXT_DW_OFFSET); + if (Affinity == CpuAffinity) { + return curr_rd_base; + } + return 0; + } + + /* If information is present in GICR Structure */ + while (curr_rd_base < (rd_base + length)) + { + Affinity = val_mmio_read(curr_rd_base + ARM_GICR_TYPER + NEXT_DW_OFFSET); + + if (Affinity == CpuAffinity) { + return curr_rd_base; + } + + /* Move to the next GIC Redistributor frame */ + curr_rd_base += rd_granularity; + } + + return 0; +} + +uint32_t val_its_gicd_lpi_support(uint64_t gicd_base) +{ + return (val_mmio_read(gicd_base + ARM_GICD_TYPER) & ARM_GICD_TYPER_LPIS); +} + +uint32_t val_its_gicr_lpi_support(uint64_t rd_base) +{ + return (val_mmio_read(rd_base + ARM_GICR_TYPER) & ARM_GICR_TYPER_PLPIS); +} + +uint32_t +ArmGicSetItsCommandQueueBase( + uint32_t its_index + ) +{ + /* Allocate Memory for Command queue. Set command queue base in GITS_CBASER. */ + uint64_t Address; + uint64_t write_value; + uint64_t ItsBase; + + ItsBase = g_gic_its_info->GicIts[its_index].Base; + + Address = (uint64_t)val_aligned_alloc(SIZE_64KB, (NUM_PAGES_8 * SIZE_4KB)); + + if (!Address) { + val_print(ACS_PRINT_ERR, "ITS : Could Not Allocate Memory CmdQ. Test may not pass.\n", 0); + return 1; + } + + val_memory_set((void *)Address, (NUM_PAGES_8*SIZE_4KB), 0); + + g_gic_its_info->GicIts[its_index].CommandQBase = Address; + + write_value = val_mmio_read64(ItsBase + ARM_GITS_CBASER) & (~ARM_GITS_CBASER_PA_MASK); + write_value = write_value | (Address & ARM_GITS_CBASER_PA_MASK); + write_value = write_value | ARM_GITS_CBASER_VALID; + + val_mmio_write64(ItsBase + ARM_GITS_CBASER, write_value); + + return 0; +} + + +uint32_t ArmGicSetItsTables(uint32_t its_index) +{ + uint32_t Pages; + uint32_t TableSize, entry_size; + uint64_t its_baser, its_typer; + uint8_t it, table_type; + uint64_t write_value; + uint32_t DevBits, CIDBits; + uint64_t Address; + uint64_t ItsBase; + + ItsBase = g_gic_its_info->GicIts[its_index].Base; + + /* Allocate Memory for Table Depending on the Type of the table in GITS_BASER. */ + for (it = 0; it < ARM_NUM_GITS_BASER; it++) { + + its_baser = val_mmio_read64(ItsBase + ARM_GITS_BASER(it)); + table_type = ARM_GITS_BASER_GET_TYPE(its_baser); + entry_size = ARM_GITS_BASER_GET_ENTRY_SIZE(its_baser); + + its_typer = val_mmio_read64(ItsBase + ARM_GITS_TYPER); + DevBits = ARM_GITS_TYPER_DevBits(its_typer); + CIDBits = ARM_GITS_TYPER_CIDBits(its_typer); + + if (table_type == ARM_GITS_TBL_TYPE_DEVICE) { + TableSize = (1 << (DevBits+1))*(entry_size+1); // Assuming Single Level Table + + } else if (table_type == ARM_GITS_TBL_TYPE_CLCN) { + TableSize = (1 << (CIDBits+1))*(entry_size+1); // Assuming Single Level Table + + } else { + continue; + } + + Pages = SIZE_TO_PAGES (TableSize); + + Address = (uint64_t)val_aligned_alloc(SIZE_64KB, TableSize); + + if (!Address) { + val_print(ACS_PRINT_ERR, "ITS : Could Not Allocate Memory DT/CT. Test may not pass.\n", 0); + return 1; + } + + val_memory_set((void *)Address, PAGES_TO_SIZE(Pages), 0); + + write_value = val_mmio_read64(ItsBase + ARM_GITS_BASER(it)); + write_value = write_value & (~ARM_GITS_BASER_PA_MASK); + write_value = write_value | (Address & ARM_GITS_BASER_PA_MASK); + write_value = write_value | ARM_GITS_BASER_VALID; + write_value = write_value | (Pages-1); + val_mmio_write64(ItsBase + ARM_GITS_BASER(it), write_value); + + } + + /* Allocate Memory for Interrupt Translation Table */ + Address = (uint64_t)val_aligned_alloc(SIZE_64KB, (NUM_PAGES_8 * SIZE_4KB)); + + if (!Address) { + val_print(ACS_PRINT_ERR, "ITS : Could Not Allocate Memory For ITT. Test may not pass.\n", 0); + return 1; + } + + val_memory_set((void *)Address, (NUM_PAGES_8*SIZE_4KB), 0); + + g_gic_its_info->GicIts[its_index].ITTBase = Address; + + return 0; +} + + +void EnableITS(uint64_t GicItsBase) +{ + /* Set GITS_CTLR.Enable as 1 to enable the ITS */ + uint32_t value; + + value = val_mmio_read(GicItsBase + ARM_GITS_CTLR); + val_mmio_write(GicItsBase + ARM_GITS_CTLR, (value | ARM_GITS_CTLR_ENABLE)); +} + +void +WriteCmdQMAPD( + uint32_t its_index, + uint64_t *CMDQ_BASE, + uint64_t device_id, + uint64_t ITT_BASE, + uint32_t Size, + uint64_t Valid + ) +{ + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index]), + (uint64_t)((device_id << ITS_CMD_SHIFT_DEVID) | ARM_ITS_CMD_MAPD)); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 1), (uint64_t)(Size)); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 2), + (uint64_t)((Valid << ITS_CMD_SHIFT_VALID) | (ITT_BASE & ITT_PAR_MASK))); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 3), (uint64_t)(0x0)); + g_cwriter_ptr[its_index] = g_cwriter_ptr[its_index] + ITS_NEXT_CMD_PTR; +} + +void +WriteCmdQMAPC( + uint32_t its_index, + uint64_t *CMDQ_BASE, + uint32_t device_id, + uint32_t Clctn_ID, + uint32_t RDBase, + uint64_t Valid + ) +{ + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index]), + (uint64_t)(ARM_ITS_CMD_MAPC)); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 1), (uint64_t)(0x0)); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 2), + (uint64_t)((Valid << ITS_CMD_SHIFT_VALID) | RDBase | Clctn_ID)); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 3), (uint64_t)(0x0)); + g_cwriter_ptr[its_index] = g_cwriter_ptr[its_index] + ITS_NEXT_CMD_PTR; +} + +void +WriteCmdQMAPI( + uint32_t its_index, + uint64_t *CMDQ_BASE, + uint64_t device_id, + uint32_t int_id, + uint32_t Clctn_ID + ) +{ + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index]), + (uint64_t)((device_id << ITS_CMD_SHIFT_DEVID) | ARM_ITS_CMD_MAPI)); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 1), (uint64_t)(int_id)); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 2), (uint64_t)(Clctn_ID)); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 3), (uint64_t)(0x0)); + g_cwriter_ptr[its_index] = g_cwriter_ptr[its_index] + ITS_NEXT_CMD_PTR; +} + +void +WriteCmdQINV( + uint32_t its_index, + uint64_t *CMDQ_BASE, + uint64_t device_id, + uint32_t int_id + ) +{ + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index]), + (uint64_t)((device_id << ITS_CMD_SHIFT_DEVID) | ARM_ITS_CMD_INV)); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 1), (uint64_t)(int_id)); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 2), (uint64_t)(0x0)); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 3), (uint64_t)(0x0)); + g_cwriter_ptr[its_index] = g_cwriter_ptr[its_index] + ITS_NEXT_CMD_PTR; +} + +void +WriteCmdQDISCARD( + uint32_t its_index, + uint64_t *CMDQ_BASE, + uint64_t device_id, + uint32_t int_id + ) +{ + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index]), + (uint64_t)((device_id << ITS_CMD_SHIFT_DEVID) | ARM_ITS_CMD_DISCARD)); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 1), (uint64_t)(int_id)); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 2), (uint64_t)(0x0)); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 3), (uint64_t)(0x0)); + g_cwriter_ptr[its_index] = g_cwriter_ptr[its_index] + ITS_NEXT_CMD_PTR; +} + + +void +WriteCmdQSYNC( + uint32_t its_index, + uint64_t *CMDQ_BASE, + uint32_t RDBase + ) +{ + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index]), + (uint64_t)(ARM_ITS_CMD_SYNC)); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 1), (uint64_t)(0x0)); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 2), (uint64_t)(RDBase)); + val_mmio_write64((uint64_t)(CMDQ_BASE + g_cwriter_ptr[its_index] + 3), (uint64_t)(0x0)); + g_cwriter_ptr[its_index] = g_cwriter_ptr[its_index] + ITS_NEXT_CMD_PTR; +} + +void PollTillCommandQueueDone(uint32_t its_index) +{ + uint32_t count; + uint64_t creadr_value; + uint64_t stall_value; + uint64_t cwriter_value; + uint64_t ItsBase; + + count = 0; + ItsBase = g_gic_its_info->GicIts[its_index].Base; + cwriter_value = val_mmio_read64(ItsBase + ARM_GITS_CWRITER); + creadr_value = val_mmio_read64(ItsBase + ARM_GITS_CREADR); + + while (creadr_value != cwriter_value) { + /* Check Stall Value */ + stall_value = creadr_value & ARM_GITS_CREADR_STALL; + + if (stall_value) { + /* Retry */ + val_mmio_write64((ItsBase + ARM_GITS_CWRITER), + (cwriter_value | ARM_GITS_CWRITER_RETRY) + ); + } + + count++; + if (count > WAIT_ITS_COMMAND_DONE) { + val_print(ACS_PRINT_ERR, "ITS : Command Queue READR not moving, Test may not pass.\n", 0); + break; + } + + creadr_value = val_mmio_read64(ItsBase + ARM_GITS_CREADR); + } + +} + +uint64_t GetRDBaseFormat(uint32_t its_index) +{ + uint32_t value; + uint64_t ItsBase; + + ItsBase = g_gic_its_info->GicIts[its_index].Base; + + /* Check GITS_TYPER.PTA. + If PTA = 1 then RDBase = Physical Address, + Else RDBase = GICR_TYPER.Processor_Number + */ + value = val_mmio_read64(ItsBase + ARM_GITS_TYPER); + if (value & ARM_GITS_TYPER_PTA) { + return g_gic_its_info->GicRdBase; + } else { + value = val_mmio_read64(g_gic_its_info->GicRdBase + ARM_GICR_TYPER); + return (value & ARM_GICR_TYPER_PN_MASK); + } +} + + +void val_its_clear_lpi_map(uint32_t its_index, uint32_t device_id, uint32_t int_id) +{ + uint64_t value; + uint64_t RDBase; + uint64_t ItsBase; + uint64_t ItsCommandBase; + + if (!g_its_setup_done) + return; + + ItsBase = g_gic_its_info->GicIts[its_index].Base; + ItsCommandBase = g_gic_its_info->GicIts[its_index].CommandQBase; + + /* Clear Config table for LPI=int_id */ + ClearConfigTable(int_id); + + /* Get RDBase Depending on GITS_TYPER.PTA */ + RDBase = GetRDBaseFormat(its_index); + + /* Discard Mappings */ + WriteCmdQDISCARD(its_index, (uint64_t *)(ItsCommandBase), device_id, int_id); + /* ITS SYNC Command */ + WriteCmdQSYNC(its_index, (uint64_t *)(ItsCommandBase), RDBase); + + /* Update the CWRITER Register so that all the commands from Command queue gets executed.*/ + value = ((g_cwriter_ptr[its_index] * NUM_BYTES_IN_DW)); + val_mmio_write64((ItsBase + ARM_GITS_CWRITER), value); + + /* Check CREADR value which ensures Command Queue is processed */ + PollTillCommandQueueDone(its_index); + +} + +void val_its_create_lpi_map(uint32_t its_index, uint32_t device_id, + uint32_t int_id, uint32_t Priority) +{ + uint64_t value; + uint64_t RDBase; + uint64_t ItsBase; + uint64_t ItsCommandBase; + + if (!g_its_setup_done) + return; + + ItsBase = g_gic_its_info->GicIts[its_index].Base; + ItsCommandBase = g_gic_its_info->GicIts[its_index].CommandQBase; + + /* Set Config table with enable the LPI = int_id, Priority. */ + SetConfigTable(int_id, Priority); + + /* Enable Redistributor */ + EnableLPIsRD(g_gic_its_info->GicRdBase); + + /* Enable ITS */ + EnableITS(ItsBase); + + /* Get RDBase Depending on GITS_TYPER.PTA */ + RDBase = GetRDBaseFormat(its_index); + + /* Map Device using MAPD */ + WriteCmdQMAPD(its_index, (uint64_t *)(ItsCommandBase), device_id, + g_gic_its_info->GicIts[its_index].ITTBase, + g_gic_its_info->GicIts[its_index].IDBits, 0x1 /*Valid*/); + /* Map Collection using MAPC */ + WriteCmdQMAPC(its_index, (uint64_t *)(ItsCommandBase), device_id, + 0x1 /*Clctn_ID*/, RDBase, 0x1 /*Valid*/); + /* Map Interrupt using MAPI */ + WriteCmdQMAPI(its_index, (uint64_t *)(ItsCommandBase), device_id, int_id, 0x1 /*Clctn_ID*/); + /* Invalid Entry */ + WriteCmdQINV(its_index, (uint64_t *)(ItsCommandBase), device_id, int_id); + /* ITS SYNC Command */ + WriteCmdQSYNC(its_index, (uint64_t *)(ItsCommandBase), RDBase); + + /* Update the CWRITER Register so that all the commands from Command queue gets executed.*/ + value = ((g_cwriter_ptr[its_index] * NUM_BYTES_IN_DW)); + val_mmio_write64((ItsBase + ARM_GITS_CWRITER), value); + + /* Check CREADR value which ensures Command Queue is processed */ + PollTillCommandQueueDone(its_index); + +} + + +uint32_t val_its_get_max_lpi(void) +{ + uint32_t index; + uint32_t min_idbits = ARM_LPI_MAX_IDBITS; + + if ((g_gic_its_info == NULL) || (g_gic_its_info->GicNumIts == 0)) + return 0; + + if (!g_its_setup_done) + return 0; + + /* Return The Minimum IDBits supported in ITS */ + for (index = 0; index < g_gic_its_info->GicNumIts; index++) + { + min_idbits = (min_idbits < g_gic_its_info->GicIts[index].IDBits) ? + (min_idbits) : + (g_gic_its_info->GicIts[index].IDBits); + } + return ((1 << (min_idbits+1)) - 1); +} + + +uint64_t val_its_get_translator_addr(uint32_t its_index) +{ + return (g_gic_its_info->GicIts[its_index].Base + ARM_GITS_TRANSLATER); +} + + +uint32_t +SetInitialConfiguration( + uint32_t its_index + ) +{ + /* Program GIC Redistributor with the Min ID bits supported. */ + uint32_t gicd_typer_idbits, gits_typer_bits; + uint64_t write_value; + uint64_t ItsBase; + + ItsBase = g_gic_its_info->GicIts[its_index].Base; + + gicd_typer_idbits = ARM_GICD_TYPER_IDbits(val_mmio_read( + g_gic_its_info->GicDBase + ARM_GICD_TYPER)); + gits_typer_bits = ARM_GITS_TYPER_IDbits(val_mmio_read64(ItsBase + ARM_GITS_TYPER)); + + /* Check least bits implemented is 14 if LPIs are supported. */ + if (GET_MIN(gicd_typer_idbits, gits_typer_bits) < ARM_LPI_MIN_IDBITS) { + return 1; + } + + write_value = val_mmio_read64(g_gic_its_info->GicRdBase + ARM_GICR_PROPBASER); + write_value |= GET_MIN(gicd_typer_idbits, gits_typer_bits); + g_gic_its_info->GicIts[its_index].IDBits = GET_MIN(gicd_typer_idbits, gits_typer_bits); + + val_mmio_write64((g_gic_its_info->GicRdBase + ARM_GICR_PROPBASER), write_value); + + return 0; +} + + +uint32_t val_its_init(void) +{ + uint32_t Status; + uint32_t index; + + g_cwriter_ptr = (uint32_t *)pal_mem_alloc(sizeof(uint32_t) * (g_gic_its_info->GicNumIts)); + + if (g_cwriter_ptr == NULL) { + val_print(ACS_PRINT_ERR, "ITS : Could Not Allocate Memory CWriteR. Test may not pass.\n", 0); + return 0; + } + + for (index = 0; index < g_gic_its_info->GicNumIts; index++) + g_cwriter_ptr[index] = 0; + + for (index = 0; index < g_gic_its_info->GicNumIts; index++) + { + /* Set Initial configuration */ // DONE + Status = SetInitialConfiguration(index); + if (Status) + return Status; + } + + /* Configure Redistributor For LPIs */ + Status = ArmGicRedistributorConfigurationForLPI(g_gic_its_info->GicDBase, + g_gic_its_info->GicRdBase); + if (Status) + return Status; + + for (index = 0; index < g_gic_its_info->GicNumIts; index++) + { + /* Set Command Queue Base */ + Status = ArmGicSetItsCommandQueueBase(index); + if (Status) + return Status; + + /* Set Up the ITS tables */ + Status = ArmGicSetItsTables(index); + if (Status) + return Status; + } + + g_its_setup_done = 1; + + val_print(ACS_PRINT_INFO, "ITS : Info Block \n", 0); + for (index = 0; index < g_gic_its_info->GicNumIts; index++) + { + val_print(ACS_PRINT_INFO, "GIC ITS Index : %x\n", index); + val_print(ACS_PRINT_INFO, "GIC ITS ID : %x\n", g_gic_its_info->GicIts[index].ID); + val_print(ACS_PRINT_INFO, "GIC ITS Base : %x\n\n", g_gic_its_info->GicIts[index].Base); + } + + return 0; +} diff --git a/platform/pal_uefi/src_gic_its/bsa_gic_its.h b/val/sys_arch_src/gic/its/bsa_gic_its.h similarity index 77% rename from platform/pal_uefi/src_gic_its/bsa_gic_its.h rename to val/sys_arch_src/gic/its/bsa_gic_its.h index a22691bb..5fd2fefe 100644 --- a/platform/pal_uefi/src_gic_its/bsa_gic_its.h +++ b/val/sys_arch_src/gic/its/bsa_gic_its.h @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2020, Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2021, Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,7 +18,19 @@ #ifndef __BSA_GIC_ITS_H #define __BSA_GIC_ITS_H -#include + +#include "include/val_interface.h" +#include "include/bsa_acs_common.h" +#include "include/bsa_acs_memory.h" + +#define SIZE_4KB 0x00001000 +#define SIZE_64KB 0x00010000 + +#define PAGE_MASK 0xFFF +#define PAGE_SHIFT 12 + +#define SIZE_TO_PAGES(Size) (((Size) >> PAGE_SHIFT) + (((Size) & PAGE_MASK) ? 1 : 0)) +#define PAGES_TO_SIZE(Pages) ((Pages) << PAGE_SHIFT) #define ARM_LPI_MINID 8192 #define ARM_LPI_MIN_IDBITS 14 @@ -42,6 +54,13 @@ #define ARM_GICR_CTLR_ENABLE_LPIS (1 << 0) +#define ARM_GICR_TYPER 0x0008 // Redistributor Type Register + + +// GIC Redistributor +#define ARM_GICR_CTLR_FRAME_SIZE SIZE_64KB +#define ARM_GICR_SGI_PPI_FRAME_SIZE SIZE_64KB + /* GICR_TYPER Bits */ #define NEXT_DW_OFFSET 0x4 /* Used to read Upper 4 Bytes of GICR_TYPER */ #define ARM_GICR_TYPER_PLPIS (1 << 0) @@ -106,6 +125,14 @@ #define ITT_PAR_LEN 44 #define ITT_PAR_MASK (((1ul << ITT_PAR_LEN) - 1) << ITT_PAR_SHIFT) +// +// ARM MP Core IDs +// +#define ARM_CORE_AFF0 0xFF +#define ARM_CORE_AFF1 (0xFF << 8) +#define ARM_CORE_AFF2 (0xFF << 16) +#define ARM_CORE_AFF3 (0xFFULL << 32) + #define GET_CONFIG_TABLE_SIZE_BY_BITS(gicd_idbits, gicr_idbits) ((gicd_idbits < gicr_idbits)?((1 << (gicd_idbits+1)) - 8192):((1 << (gicr_idbits+1)) - 8192)) #define GET_MIN(a,b) ((a