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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/uefi/Bsa.inf
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
../../test_pool/memory_map/m001.c
../../test_pool/memory_map/m002.c
../../test_pool/memory_map/m003.c
../../test_pool/memory_map/m004.c
../../test_pool/power_wakeup/u001.c
../../test_pool/power_wakeup/u002.c
../../test_pool/power_wakeup/u003.c
Expand Down
1 change: 1 addition & 0 deletions apps/uefi/Mem.inf
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
../../test_pool/peripherals/d005.c
../../test_pool/memory_map/m002.c
../../test_pool/memory_map/m003.c
../../test_pool/memory_map/m004.c
../../test_pool/power_wakeup/u001.c
../../test_pool/power_wakeup/u002.c
../../test_pool/power_wakeup/u003.c
Expand Down
1 change: 1 addition & 0 deletions apps/uefi/Sbsa.inf
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
../../test_pool/memory_map/m001.c
../../test_pool/memory_map/m002.c
../../test_pool/memory_map/m003.c
../../test_pool/memory_map/m004.c
../../test_pool/power_wakeup/u001.c
../../test_pool/power_wakeup/u002.c
../../test_pool/power_wakeup/u003.c
Expand Down
1 change: 1 addition & 0 deletions apps/uefi/Vbsa.inf
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
../../test_pool/memory_map/m001.c
../../test_pool/memory_map/m002.c
../../test_pool/memory_map/m003.c
../../test_pool/memory_map/m004.c
../../test_pool/power_wakeup/u001.c
../../test_pool/power_wakeup/u002.c
../../test_pool/power_wakeup/u003.c
Expand Down
1 change: 1 addition & 0 deletions apps/uefi/pc_bsa.inf
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
../../test_pool/memory_map/m001.c
../../test_pool/memory_map/m002.c
../../test_pool/memory_map/m003.c
../../test_pool/memory_map/m004.c
../../test_pool/power_wakeup/u001.c
../../test_pool/power_wakeup/u002.c
../../test_pool/power_wakeup/u003.c
Expand Down
1 change: 1 addition & 0 deletions apps/uefi/xbsa_acpi.inf
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
../../test_pool/memory_map/m001.c
../../test_pool/memory_map/m002.c
../../test_pool/memory_map/m003.c
../../test_pool/memory_map/m004.c
../../test_pool/power_wakeup/u001.c
../../test_pool/power_wakeup/u002.c
../../test_pool/power_wakeup/u003.c
Expand Down
4 changes: 2 additions & 2 deletions docs/bsa/arm_bsa_testcase_checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -1263,7 +1263,7 @@ The checklist provides information about:
<tr>
<td rowspan="3">PCI_IN_19</td>
<td>830</td>
<td>Check Cmd Reg memory space enable</td>
<td>Check Command,BIST,and Hdr Cap registers</td>
<td>Yes</td>
<td>Yes</td>
<td>No</td>
Expand Down Expand Up @@ -3260,7 +3260,7 @@ The checklist provides information about:
<tr>
<td>PCI_IN_19</td>
<td>830</td>
<td>Check Cmd Reg memory space enable</td>
<td>Check Command,BIST,and Hdr Cap registers</td>
<td>Yes</td>
<td>Yes</td>
<td>No</td>
Expand Down
2 changes: 1 addition & 1 deletion docs/sbsa/arm_sbsa_testcase_checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -1918,7 +1918,7 @@ The checklist provides information about:
<tr>
<td>PCI_IN_19</td>
<td></td>
<td>Check Cmd Reg memory space enable</td>
<td>Check Command,BIST,and Hdr Cap registers</td>
<td>Yes</td>
<td>Yes</td>
<td>No</td>
Expand Down
2 changes: 1 addition & 1 deletion docs/vbsa/arm_vbsa_testcase_checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,7 @@ The checklist provides information about:
<tr>
<td>PCI_IN_19</td>
<td>830</td>
<td>Check Cmd Reg memory space enable</td>
<td>Check Command,BIST,and Hdr Cap registers</td>
<td>✅</td>
<td>❌</td>
<td></td>
Expand Down
68 changes: 67 additions & 1 deletion pal/uefi_acpi/src/pal_pcie.c
Original file line number Diff line number Diff line change
Expand Up @@ -618,5 +618,71 @@ pal_pcie_is_device_behind_smmu(UINT32 seg, UINT32 bus, UINT32 dev, UINT32 fn)
UINT32
pal_pcie_is_devicedma_64bit(UINT32 seg, UINT32 bus, UINT32 dev, UINT32 fn)
{
return 0;
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *Pci;
EFI_HANDLE *HandleBuffer;
UINTN HandleCount;
UINTN Seg, Bus, Dev, Func;
UINT32 Index;
UINT64 Supported;
UINT64 Current;
INT8 Is64Bit = 0;

Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiPciIoProtocolGuid, NULL,
&HandleCount, &HandleBuffer);
if (EFI_ERROR(Status)) {
pal_print_msg(ACS_PRINT_ERR, " No PCI devices found in the system\n");
return 0;
}

for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->HandleProtocol(HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **)&Pci);
if (EFI_ERROR(Status))
continue;

Pci->GetLocation(Pci, &Seg, &Bus, &Dev, &Func);
if (Seg != seg || Bus != bus || Dev != dev || Func != fn)
continue;

Status = Pci->Attributes(Pci, EfiPciIoAttributeOperationSupported, 0, &Supported);
if (!EFI_ERROR(Status) && (Supported & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE)) {

/* Prefer reporting only if DAC is actually enabled */
Status = Pci->Attributes(Pci, EfiPciIoAttributeOperationGet, 0, &Current);
if (!EFI_ERROR(Status) && (Current & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE)) {
Is64Bit = 1;
} else {
/*
* Try enabling DAC to see if firmware/platform allows it.
* Do not treat failure as fatal; we simply report lack of 64-bit DMA.
*/
Status = Pci->Attributes(Pci, EfiPciIoAttributeOperationEnable,
EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE, NULL);
if (!EFI_ERROR(Status)) {
Status = Pci->Attributes(Pci, EfiPciIoAttributeOperationGet, 0, &Current);
if (!EFI_ERROR(Status) && (Current & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE))
Is64Bit = 1;
}
}
}

break;
}
pal_mem_free(HandleBuffer);
return Is64Bit;
}

/**
@brief Placeholder for UEFI

@param seg PCI segment number
@param bus PCI bus address
@param dev PCI device address
@param fn PCI function number

@retval Return 1
**/
UINT32 pal_pcie_device_driver_present(uint32_t seg, uint32_t bus, uint32_t dev, uint32_t fn)
{
return 1;
}
141 changes: 141 additions & 0 deletions pal/uefi_acpi/src/pal_peripherals.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
#include <Library/DxeServicesTableLib.h>

#include <Protocol/AcpiTable.h>
#include <Protocol/PciIo.h>
#include "Include/IndustryStandard/Acpi61.h"
#include "Include/IndustryStandard/Pci22.h"
#include "Include/IndustryStandard/SerialPortConsoleRedirectionTable.h"

#include "pal_uefi.h"
Expand All @@ -41,6 +43,144 @@ UINT32 spcr_baudrate_id[] = {0, 0, 0, 9600, 19200, 0, 57600, 115200};
UINT64
pal_get_spcr_ptr();

STATIC
BOOLEAN
pal_peripheral_is_duplicate(PERIPHERAL_INFO_BLOCK *start,
PERIPHERAL_INFO_BLOCK *current,
UINT32 bdf)
{
PERIPHERAL_INFO_BLOCK *iter = start;

while (iter < current) {
if ((iter->bdf == bdf) && (bdf != 0))
return TRUE;
iter++;
}

return FALSE;
}

STATIC
UINT64
pal_peripheral_get_bar_value(UINT32 *bar, UINT32 bar_index, UINT32 max_bars)
{
UINT64 bar_value;

if (bar_index >= max_bars)
return 0;

bar_value = bar[bar_index];

if ((((bar_value) >> BAR_MDT_SHIFT) & BAR_MDT_MASK) == BITS_64) {
if ((bar_index + 1) < max_bars) {
bar_value = bar[bar_index + 1];
bar_value = (bar_value << 32) | bar[bar_index];
}
}

return bar_value;
}

STATIC
VOID
pal_peripheral_add_all_pci(PERIPHERAL_INFO_TABLE *peripheralInfoTable,
PERIPHERAL_INFO_BLOCK **per_info)
{
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *Pci;
EFI_HANDLE *HandleBuffer;
UINTN HandleCount;
UINTN Index;
UINTN Seg, Bus, Dev, Func;
UINT32 bar_index;
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;

Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPciIoProtocolGuid, NULL,
&HandleCount, &HandleBuffer);
if (EFI_ERROR (Status)) {
pal_print_msg(ACS_PRINT_ERR, " No PCI devices found while populating peripheral table\n");
return;
}

for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **)&Pci);
if (EFI_ERROR (Status))
continue;

Status = Pci->GetLocation (Pci, &Seg, &Bus, &Dev, &Func);
if (EFI_ERROR (Status))
continue;

DeviceBdf = (UINT32)PCIE_CREATE_BDF(Seg, Bus, Dev, Func);

if (pal_peripheral_is_duplicate(start, info, DeviceBdf))
continue;

Status = Pci->Pci.Read (Pci, EfiPciIoWidthUint32, 0,
sizeof (PciHeader)/sizeof (UINT32), &PciHeader);
if (EFI_ERROR (Status))
continue;

/* We only want endpoint functions (header type = device) */
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;
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;

for (bar_index = 0; bar_index < bar_count; bar_index++) {
UINT64 bar_value = pal_peripheral_get_bar_value(bars, bar_index, bar_count);

if (bar_value != 0) {
if (info->base0 == 0)
info->base0 = bar_value;
else if (info->base1 == 0)
info->base1 = bar_value;
}

if ((((bars[bar_index]) >> BAR_MDT_SHIFT) & BAR_MDT_MASK) == BITS_64)
bar_index++;
}

peripheralInfoTable->header.num_all++;
info++;
}

pal_mem_free(HandleBuffer);
*per_info = info;
}

/**
@brief This API fills in the PERIPHERAL_INFO_TABLE with information about peripherals
in the system. This is achieved by parsing the ACPI - SPCR table and PCIe config space.
Expand Down Expand Up @@ -164,6 +304,7 @@ pal_peripheral_create_info_table(PERIPHERAL_INFO_TABLE *peripheralInfoTable)
per_info++;
}

pal_peripheral_add_all_pci(peripheralInfoTable, &per_info);
per_info->type = 0xFF; //indicate end of table

}
Expand Down
Loading
Loading