From a5b69c60b65ca6dbec69826e926889c5093f4e31 Mon Sep 17 00:00:00 2001 From: Sujana M Date: Tue, 6 Oct 2026 06:57:59 +0000 Subject: [PATCH] pal: add PCI peripheral visibility in BM and debug prints - Add bare-metal peripheral table support for generic PCI devices. The BM peripheral table previously added only USB, SATA and UART entries. Add a generic PCI scan over platform ECAM ranges and append non-duplicate PCI functions as PERIPHERAL_TYPE_OTHER entries with BDF and usable BAR information. - Also add debug prints for PCI peripheral entries in BM and UEFI paths, including BDF, class code and BAR values, so the populated peripheral table can be compared across environments. Signed-off-by: Sujana M Change-Id: Iec48fb0ffe5bde21de551bda0069c3a485b53889 --- pal/baremetal/base/src/pal_peripherals.c | 128 +++++++++++++++++- .../RDN2/include/platform_override_fvp.h | 2 +- .../RDV3/include/platform_override_fvp.h | 2 +- .../RDV3CFG1/include/platform_override_fvp.h | 2 +- pal/uefi_acpi/src/pal_peripherals.c | 13 +- pal/uefi_dt/src/pal_peripherals.c | 17 ++- tools/cmake/infra/bsa_test.txt | 1 - tools/cmake/infra/pc_bsa_test.txt | 6 + 8 files changed, 151 insertions(+), 20 deletions(-) diff --git a/pal/baremetal/base/src/pal_peripherals.c b/pal/baremetal/base/src/pal_peripherals.c index 405a5e92..138a47b5 100644 --- a/pal/baremetal/base/src/pal_peripherals.c +++ b/pal/baremetal/base/src/pal_peripherals.c @@ -35,6 +35,111 @@ extern const PCIE_INFO_TABLE platform_pcie_cfg; uint32_t spcr_baudrate_id[] = {0, 0, 0, 9600, 19200, 0, 57600, 115200}; +static uint32_t +pal_peripheral_is_duplicate(PERIPHERAL_INFO_BLOCK *start, + PERIPHERAL_INFO_BLOCK *current, + uint32_t bdf) +{ + PERIPHERAL_INFO_BLOCK *iter = start; + + while (iter < current) { + if ((iter->bdf == bdf) && (bdf != 0)) + return 1; + iter++; + } + + return 0; +} + +static void +pal_peripheral_add_all_pci(PERIPHERAL_INFO_TABLE *peripheralInfoTable, + PERIPHERAL_INFO_BLOCK **per_info) +{ + uint32_t ecam_index; + uint32_t bus; + uint32_t dev; + uint32_t func; + uint32_t seg; + uint32_t start_bus; + uint32_t end_bus; + uint32_t bdf; + uint32_t vendor_id; + uint32_t header_value; + uint32_t class_code; + uint32_t bar_count; + uint32_t bar_index; + uint32_t bar_reg_value; + uint64_t bar_value; + PERIPHERAL_INFO_BLOCK *info = *per_info; + PERIPHERAL_INFO_BLOCK *start = peripheralInfoTable->info; + + for (ecam_index = 0; ecam_index < platform_pcie_cfg.num_entries; ecam_index++) { + seg = platform_pcie_cfg.block[ecam_index].segment_num; + start_bus = platform_pcie_cfg.block[ecam_index].start_bus_num; + end_bus = platform_pcie_cfg.block[ecam_index].end_bus_num; + + for (bus = start_bus; bus <= end_bus; bus++) { + for (dev = 0; dev < PCIE_MAX_DEV; dev++) { + for (func = 0; func < PCIE_MAX_FUNC; func++) { + pal_pci_cfg_read(seg, bus, dev, func, 0, &vendor_id); + if ((vendor_id == 0x0) || (vendor_id == 0xFFFFFFFF)) + continue; + + bdf = PCIE_CREATE_BDF(seg, bus, dev, func); + if (pal_peripheral_is_duplicate(start, info, bdf)) + continue; + + pal_pci_cfg_read(seg, bus, dev, func, HEADER_OFFSET, &header_value); + pal_pci_cfg_read(seg, bus, dev, func, TYPE01_RIDR, &class_code); + + if (PCIE_HEADER_TYPE(header_value) != TYPE0_HEADER) + continue; + + bar_count = TYPE0_MAX_BARS; + + info->type = PERIPHERAL_TYPE_OTHER; + info->bdf = bdf; + info->base0 = 0; + info->base1 = 0; + info->width = 0; + info->irq = 0; + info->flags = 0; + info->msi = 0; + info->msix = 0; + info->max_pasids = 0; + info->baud_rate = 0; + info->interface_type = 0; + info->platform_type = 0; + + for (bar_index = 0; bar_index < bar_count; bar_index++) { + pal_pci_cfg_read(seg, bus, dev, func, BAR0_OFFSET + (4 * bar_index), &bar_reg_value); + bar_value = pal_pcie_get_base(bdf, bar_index); + if (bar_value != 0) { + if (info->base0 == 0) + info->base0 = bar_value; + else if (info->base1 == 0) + info->base1 = bar_value; + } + + if (BAR_REG(bar_reg_value) == BAR_64_BIT) + bar_index++; + } + + pal_print_msg(ACS_PRINT_DEBUG, "\n BDF is 0x%x", info->bdf); + pal_print_msg(ACS_PRINT_DEBUG, "\n Class code is 0x%x", class_code); + pal_print_msg(ACS_PRINT_DEBUG, "\n PCI peripheral BAR0 0x%llx BAR1 0x%llx", + info->base0, info->base1); + + peripheralInfoTable->header.num_all++; + info++; + } + } + } + } + + *per_info = info; +} + /** @brief This API fills in the PERIPHERAL_INFO_TABLE with information about peripherals in the system. @@ -50,6 +155,7 @@ pal_peripheral_create_info_table(PERIPHERAL_INFO_TABLE *peripheralInfoTable) uint32_t DeviceBdf = 0; uint32_t StartBdf = 0; uint32_t bar_index = 0; + uint32_t class_code = 0; uint32_t i = 0; uint64_t uart; PERIPHERAL_INFO_BLOCK *per_info = NULL; @@ -88,9 +194,14 @@ pal_peripheral_create_info_table(PERIPHERAL_INFO_TABLE *peripheralInfoTable) } per_info->bdf = DeviceBdf; per_info->platform_type = 0; - - pal_print_msg(ACS_PRINT_INFO, - "\n Found a USB controller %4x", + pal_pci_cfg_read(PCIE_EXTRACT_BDF_SEG(DeviceBdf), + PCIE_EXTRACT_BDF_BUS(DeviceBdf), + PCIE_EXTRACT_BDF_DEV(DeviceBdf), + PCIE_EXTRACT_BDF_FUNC(DeviceBdf), + TYPE01_RIDR, &class_code); + pal_print_msg(ACS_PRINT_INFO, "\n BDF is 0x%x", per_info->bdf); + pal_print_msg(ACS_PRINT_INFO, "\n Class code is 0x%x", class_code); + pal_print_msg(ACS_PRINT_INFO, "\n Found a USB controller %4x", per_info->base0); peripheralInfoTable->header.num_usb++; peripheralInfoTable->header.num_all++; @@ -119,7 +230,13 @@ pal_peripheral_create_info_table(PERIPHERAL_INFO_TABLE *peripheralInfoTable) } per_info->platform_type = 0; per_info->bdf = DeviceBdf; - + pal_pci_cfg_read(PCIE_EXTRACT_BDF_SEG(DeviceBdf), + PCIE_EXTRACT_BDF_BUS(DeviceBdf), + PCIE_EXTRACT_BDF_DEV(DeviceBdf), + PCIE_EXTRACT_BDF_FUNC(DeviceBdf), + TYPE01_RIDR, &class_code); + pal_print_msg(ACS_PRINT_INFO, "\n BDF is 0x%x", per_info->bdf); + pal_print_msg(ACS_PRINT_INFO, "\n Class code is 0x%x", class_code); pal_print_msg(ACS_PRINT_INFO, "\n Found a SATA controller %4x", per_info->base0); @@ -164,6 +281,9 @@ pal_peripheral_create_info_table(PERIPHERAL_INFO_TABLE *peripheralInfoTable) per_info++; } + if (platform_pcie_cfg.num_entries != 0) + pal_peripheral_add_all_pci(peripheralInfoTable, &per_info); + per_info->type = 0xFF; //indicate end of table } diff --git a/pal/baremetal/target/RDN2/include/platform_override_fvp.h b/pal/baremetal/target/RDN2/include/platform_override_fvp.h index ff1d292b..1386e2ea 100644 --- a/pal/baremetal/target/RDN2/include/platform_override_fvp.h +++ b/pal/baremetal/target/RDN2/include/platform_override_fvp.h @@ -604,7 +604,7 @@ #define VDM_RSP_MASK 7 /* PERIPHERAL platform config parameters */ -#define PLATFORM_OVERRIDE_PERIPHERAL_COUNT 3 //UART + USB + SATA +#define PLATFORM_OVERRIDE_PERIPHERAL_COUNT 64 //PCI peripherals + UART/USB/SATA #define UART_ADDRESS 0xF98DFE18 #define BASE_ADDRESS_ADDRESS_SPACE_ID 0x0 diff --git a/pal/baremetal/target/RDV3/include/platform_override_fvp.h b/pal/baremetal/target/RDV3/include/platform_override_fvp.h index ebd3a45a..8c6b67d2 100644 --- a/pal/baremetal/target/RDV3/include/platform_override_fvp.h +++ b/pal/baremetal/target/RDV3/include/platform_override_fvp.h @@ -634,7 +634,7 @@ #define PLATFORM_OVERRIDE_CXL0_WINDOW_RESTRICTIONS 0x0 /* CFMWS Window restrictions*/ /* ----------------------------- Peripheral info ----------------------------- */ -#define PLATFORM_OVERRIDE_PERIPHERAL_COUNT 2 //UART + USB + SATA +#define PLATFORM_OVERRIDE_PERIPHERAL_COUNT 64 //PCI peripherals + UART/USB/SATA #define UART_ADDRESS 0xF98DFE18 /* Non-zero if UART is present */ #define BASE_ADDRESS_ADDRESS 0x2A400000 /* UART MMIO base */ diff --git a/pal/baremetal/target/RDV3CFG1/include/platform_override_fvp.h b/pal/baremetal/target/RDV3CFG1/include/platform_override_fvp.h index f5057f77..764f4a8d 100644 --- a/pal/baremetal/target/RDV3CFG1/include/platform_override_fvp.h +++ b/pal/baremetal/target/RDV3CFG1/include/platform_override_fvp.h @@ -583,7 +583,7 @@ #define PLATFORM_OVERRIDE_CXL0_WINDOW_RESTRICTIONS 0x0 /* CFMWS Window restrictions*/ /* ----------------------------- Peripheral info ----------------------------- */ -#define PLATFORM_OVERRIDE_PERIPHERAL_COUNT 2 //UART + USB + SATA +#define PLATFORM_OVERRIDE_PERIPHERAL_COUNT 64 //PCI peripherals + UART/USB/SATA #define UART_ADDRESS 0xF98DFE18 /* Non-zero if UART is present */ #define BASE_ADDRESS_ADDRESS 0x2A400000 /* UART MMIO base */ diff --git a/pal/uefi_acpi/src/pal_peripherals.c b/pal/uefi_acpi/src/pal_peripherals.c index 40e37a09..765ccfe4 100644 --- a/pal/uefi_acpi/src/pal_peripherals.c +++ b/pal/uefi_acpi/src/pal_peripherals.c @@ -131,20 +131,12 @@ pal_peripheral_add_all_pci(PERIPHERAL_INFO_TABLE *peripheralInfoTable, if ((PciHeader.Device.Hdr.HeaderType & HEADER_LAYOUT_CODE) != HEADER_TYPE_DEVICE) continue; - /* Skip bridges and cardbus controllers, we only want endpoint functions */ - if (IS_PCI_BRIDGE(&(PciHeader.Bridge)) || IS_CARDBUS_BRIDGE(&(PciHeader.Bridge))) - continue; - bars = PciHeader.Device.Device.Bar; bar_count = TYPE0_MAX_BARS; class_code = ((PciHeader.Device.Hdr.ClassCode[2] << 16) | (PciHeader.Device.Hdr.ClassCode[1] << 8) | PciHeader.Device.Hdr.ClassCode[0]); - /* Skip all bridge class devices (host bridge, PCI-PCI bridge, etc.) */ - if ((class_code >> 16) == 0x06) - continue; - info->type = PERIPHERAL_TYPE_OTHER; info->bdf = DeviceBdf; info->platform_type = PLATFORM_TYPE_ACPI; @@ -173,6 +165,11 @@ pal_peripheral_add_all_pci(PERIPHERAL_INFO_TABLE *peripheralInfoTable, bar_index++; } + pal_print_msg(ACS_PRINT_INFO, "\n BDF is 0x%x", info->bdf); + pal_print_msg(ACS_PRINT_INFO, "\n Class code is 0x%x", class_code); + pal_print_msg(ACS_PRINT_INFO, "\n PCI peripheral BAR0 0x%llx BAR1 0x%llx", + info->base0, info->base1); + peripheralInfoTable->header.num_all++; info++; } diff --git a/pal/uefi_dt/src/pal_peripherals.c b/pal/uefi_dt/src/pal_peripherals.c index 2652fbad..3ded30fa 100644 --- a/pal/uefi_dt/src/pal_peripherals.c +++ b/pal/uefi_dt/src/pal_peripherals.c @@ -120,6 +120,7 @@ pal_peripheral_add_all_pci(PERIPHERAL_INFO_TABLE *peripheralInfoTable, UINT32 bar_count; UINT32 DeviceBdf; UINT32 *bars; + UINT32 class_code; PCI_TYPE_GENERIC PciHeader; PERIPHERAL_INFO_BLOCK *info = *per_info; PERIPHERAL_INFO_BLOCK *start = peripheralInfoTable->info; @@ -150,12 +151,15 @@ pal_peripheral_add_all_pci(PERIPHERAL_INFO_TABLE *peripheralInfoTable, if (EFI_ERROR (Status)) continue; + class_code = ((PciHeader.Device.Hdr.ClassCode[2] << 16) | + (PciHeader.Device.Hdr.ClassCode[1] << 8) | + PciHeader.Device.Hdr.ClassCode[0]); + + if ((PciHeader.Device.Hdr.HeaderType & HEADER_LAYOUT_CODE) != HEADER_TYPE_DEVICE) + continue; + bars = PciHeader.Device.Device.Bar; bar_count = TYPE0_MAX_BARS; - if (IS_PCI_BRIDGE(&(PciHeader.Bridge)) || IS_CARDBUS_BRIDGE(&(PciHeader.Bridge))) { - bars = PciHeader.Bridge.Bridge.Bar; - bar_count = TYPE1_MAX_BARS; - } info->type = PERIPHERAL_TYPE_OTHER; info->bdf = DeviceBdf; @@ -185,6 +189,11 @@ pal_peripheral_add_all_pci(PERIPHERAL_INFO_TABLE *peripheralInfoTable, bar_index++; } + pal_print_msg(ACS_PRINT_INFO, "\n BDF is 0x%x", info->bdf); + pal_print_msg(ACS_PRINT_INFO, "\n Class code is 0x%x", class_code); + pal_print_msg(ACS_PRINT_INFO, "\n PCI peripheral BAR0 0x%llx BAR1 0x%llx", + info->base0, info->base1); + peripheralInfoTable->header.num_all++; info++; } diff --git a/tools/cmake/infra/bsa_test.txt b/tools/cmake/infra/bsa_test.txt index a86592cb..1e4ab864 100644 --- a/tools/cmake/infra/bsa_test.txt +++ b/tools/cmake/infra/bsa_test.txt @@ -174,4 +174,3 @@ e035.c e036.c e039.c e046.c -p047.c diff --git a/tools/cmake/infra/pc_bsa_test.txt b/tools/cmake/infra/pc_bsa_test.txt index 9db97539..d9eb852b 100644 --- a/tools/cmake/infra/pc_bsa_test.txt +++ b/tools/cmake/infra/pc_bsa_test.txt @@ -31,6 +31,12 @@ g004.c g005.c g012.c g014.c +g015.c +g016.c +its003.c +its004.c +its005.c +its006.c interface010.c interface011.c i001.c