diff options
| author | gparikh <gparikh@qti.qualcomm.com> | 2026-07-17 05:56:57 +0300 |
|---|---|---|
| committer | Vishal Oliyil Kunnil <vishalo@users.noreply.github.com> | 2026-09-03 02:48:11 +0300 |
| commit | 061beb4c4bd259c073743f5ac01b5a1da4ce2010 (patch) | |
| tree | a8437a5323a9b6a6850b32012ba1b72683dc0471 /Silicon | |
| parent | c8295e076affae5cf04fd4234db13a0e025f44e1 (diff) | |
| download | edk2-platforms-master.tar.xz | |
Add Qualcomm SMEM lib implementation.
Signed-off-by: gparikh <gparikh@qti.qualcomm.com>
Diffstat (limited to 'Silicon')
15 files changed, 2041 insertions, 715 deletions
diff --git a/Silicon/Qualcomm/Common/QualcommCommonSiliconPkg/Library/ChipInfoLib/ChipInfoImage.c b/Silicon/Qualcomm/Common/QualcommCommonSiliconPkg/Library/ChipInfoLib/ChipInfoImage.c index d8b0d529c3..8ebda0149e 100644 --- a/Silicon/Qualcomm/Common/QualcommCommonSiliconPkg/Library/ChipInfoLib/ChipInfoImage.c +++ b/Silicon/Qualcomm/Common/QualcommCommonSiliconPkg/Library/ChipInfoLib/ChipInfoImage.c @@ -12,7 +12,7 @@ #include <Uefi.h>
#include <Base.h>
#include <Library/BaseLib.h>
-#include <Library/SmemLib.h>
+#include <Library/QualcommSmemLib.h>
#include "ChipInfoImage.h"
#include <ChipPlatformInfoSmem.h>
@@ -33,10 +33,17 @@ ChipInfoGetSocInfo ( )
{
PlatformInfoSmemType *Smem;
- UINT32 Size;
-
- Smem = (PlatformInfoSmemType *)SmemGetAddr (SmemHwSwBuildId, &Size);
- if ((Smem == NULL) || (Size == 0)) {
+ UINTN Size;
+ EFI_STATUS Status;
+
+ Status = QualcommSmemLookup (
+ QUALCOMM_SMEM_HOST_COMMON,
+ SMEM_HW_SW_BUILD_ID,
+ QUALCOMM_SMEM_FLAG_NONE,
+ (VOID **)&Smem,
+ &Size
+ );
+ if (EFI_ERROR (Status) || (Size == 0)) {
return NULL;
}
diff --git a/Silicon/Qualcomm/Common/QualcommCommonSiliconPkg/Library/ChipInfoLib/ChipInfoLib.inf b/Silicon/Qualcomm/Common/QualcommCommonSiliconPkg/Library/ChipInfoLib/ChipInfoLib.inf index 0ee3e096cf..1bf9ba8789 100644 --- a/Silicon/Qualcomm/Common/QualcommCommonSiliconPkg/Library/ChipInfoLib/ChipInfoLib.inf +++ b/Silicon/Qualcomm/Common/QualcommCommonSiliconPkg/Library/ChipInfoLib/ChipInfoLib.inf @@ -31,4 +31,4 @@ BaseLib
BaseMemoryLib
MemoryAllocationLib
- SmemLib
+ QualcommSmemLib
diff --git a/Silicon/Qualcomm/QualcommSiliconPkg/Include/Library/QualcommSmemLib.h b/Silicon/Qualcomm/QualcommSiliconPkg/Include/Library/QualcommSmemLib.h new file mode 100644 index 0000000000..aa61bd8855 --- /dev/null +++ b/Silicon/Qualcomm/QualcommSiliconPkg/Include/Library/QualcommSmemLib.h @@ -0,0 +1,220 @@ +/** @file
+ Qualcomm Shared Memory (SMEM) - Public API.
+
+ SMEM is a fixed-size, physically contiguous shared memory region used as
+ the primary inter-processor communication (IPC) substrate on Qualcomm SoCs.
+ It is allocated at boot time by the boot firmware and remains accessible
+ to all participating processors for the lifetime of the system. Each
+ processor (host) that participates in SMEM has a unique host identifier
+ and may read from or write to the portions of SMEM that it is permitted
+ to access.
+
+ Memory Layout
+ -------------
+ The SMEM region is divided into three logical areas:
+ - A boot/static metadata page at the start, containing version info.
+ - A set of partitions in the middle, each owned by one or two hosts.
+ - A Table of Contents (TOC) at the end, describing all partitions.
+
+ Partition Model
+ ---------------
+ SMEM data is organised into partitions of two kinds:
+
+ Common partition: accessible to all hosts; holds globally shared items.
+ Edge-pair partition: shared between exactly two hosts; holds items
+ private to that host pair.
+
+ Within each partition, items are stored in two heap regions that grow
+ toward each other: an uncached/upward region and a cached/downward region.
+
+ NOTE: This driver supports lookup of uncached/upward items only.
+ Cached/downward item allocation and lookup are not implemented; items
+ that exist only in the cached region are not visible to this driver.
+
+ Item Model
+ ----------
+ An SMEM item is a data blob identified by a 16-bit item ID.
+
+ Host Identifier Model
+ ---------------------
+ Each processor is assigned an opaque 16-bit host identifier that encodes
+ the processor type, instance, protection domain, and chiplet. Two
+ special values are reserved: QUALCOMM_SMEM_HOST_COMMON (common partition
+ access) and QUALCOMM_SMEM_HOST_INVALID (unset/error sentinel). Host
+ identifiers must be constructed with QualcommSmemHostId(), never directly.
+
+ @par Glossary
+ - Smem - Shared Memory
+ - Proc - Processor
+ - Pd - Protection-domain
+ - Ipc - Inter-processor Communication
+ - Toc - Table of Contents
+
+ Copyright (C) Qualcomm Technologies, Inc. and/or its subsidiaries.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#pragma once
+
+#include <Library/BaseLib.h>
+#include <Uefi.h>
+
+/**
+ QUALCOMM_SMEM_HOST - SMEM host (processor) identifier.
+
+ Opaque 16-bit host identifier. Use QualcommSmemHostId() to construct
+ a valid value from a processor ID, instance number, protection-domain
+ number, and chiplet identifier. Do not construct host values directly
+ or rely on the internal bit layout.
+**/
+typedef UINT16 QUALCOMM_SMEM_HOST;
+
+/**
+ QUALCOMM_SMEM_HOST_COMMON - pseudo-host for the common SMEM partition.
+
+ Items in the common partition are accessible to all hosts.
+**/
+#define QUALCOMM_SMEM_HOST_COMMON ((QUALCOMM_SMEM_HOST)0xfffeU)
+
+/**
+ QUALCOMM_SMEM_HOST_INVALID - sentinel value for an invalid or unset host.
+**/
+#define QUALCOMM_SMEM_HOST_INVALID ((QUALCOMM_SMEM_HOST)0xffffU)
+
+// -------------------------------------------------------------------------
+// Processor identifiers
+//
+// Pass one of these as the ProcId argument to QualcommSmemHostId().
+// -------------------------------------------------------------------------
+#define QUALCOMM_SMEM_PROC_APPS 0U
+#define QUALCOMM_SMEM_PROC_MODEM 1U
+#define QUALCOMM_SMEM_PROC_ADSP 2U
+#define QUALCOMM_SMEM_PROC_SSC 3U
+#define QUALCOMM_SMEM_PROC_WCN 4U
+#define QUALCOMM_SMEM_PROC_CDSP 5U
+#define QUALCOMM_SMEM_PROC_RPM 6U
+#define QUALCOMM_SMEM_PROC_TZ 7U
+#define QUALCOMM_SMEM_PROC_SPSS 8U
+#define QUALCOMM_SMEM_PROC_HYP 9U
+#define QUALCOMM_SMEM_PROC_BOOT 10U
+#define QUALCOMM_SMEM_PROC_SPSS_SP 11U
+#define QUALCOMM_SMEM_PROC_CDSP1 12U
+#define QUALCOMM_SMEM_PROC_WPSS 13U
+#define QUALCOMM_SMEM_PROC_TME 14U
+#define QUALCOMM_SMEM_PROC_APPS_VM_LA 15U
+#define QUALCOMM_SMEM_PROC_EXT_PM 16U
+#define QUALCOMM_SMEM_PROC_GPDSP 17U
+#define QUALCOMM_SMEM_PROC_GPDSP1 18U
+#define QUALCOMM_SMEM_PROC_SOCCP 19U
+#define QUALCOMM_SMEM_PROC_OOBSS 20U
+#define QUALCOMM_SMEM_PROC_OOBNS 21U
+#define QUALCOMM_SMEM_PROC_DCP 22U
+#define QUALCOMM_SMEM_PROC_WM 23U
+#define QUALCOMM_SMEM_PROC_AM 24U
+#define QUALCOMM_SMEM_PROC_QECP 25U
+#define QUALCOMM_SMEM_PROC_LMCU 26U
+
+// Lookup flags - currently only 0 is valid.
+#define QUALCOMM_SMEM_FLAG_NONE 0U
+
+// Ram Partition Location
+#define SMEM_USABLE_RAM_PARTITION_TABLE 402U
+
+// Platform HW/SW build ID
+#define SMEM_HW_SW_BUILD_ID 137U
+
+// -------------------------------------------------------------------------
+// Library version
+//
+// Encoded as a single UINT32:
+// bits [31:16] major version
+// bits [15:8] minor version
+// bits [7:0] patch version
+// -------------------------------------------------------------------------
+
+#define QUALCOMM_SMEM_LIB_VERSION_MAJOR 1U
+#define QUALCOMM_SMEM_LIB_VERSION_MINOR 0U
+#define QUALCOMM_SMEM_LIB_VERSION_PATCH 0U
+
+#define QUALCOMM_SMEM_LIB_VERSION \
+ ((UINT32)(((QUALCOMM_SMEM_LIB_VERSION_MAJOR) << 16U) | \
+ ((QUALCOMM_SMEM_LIB_VERSION_MINOR) << 8U) | \
+ ((QUALCOMM_SMEM_LIB_VERSION_PATCH) )))
+
+/**
+ Initialize the SMEM common core.
+
+ Called by platform boot integration code after the platform has
+ reserved the SMEM virtual address window. Internally calls
+ QualcommSmemPlatInit() to obtain platform target parameters, then
+ maps and validates the BOOT info page, TOC, and relevant partitions.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_ALREADY_STARTED Already initialized.
+ @retval other EFI_STATUS error code on failure.
+**/
+EFI_STATUS
+EFIAPI
+QualcommSmemInit (
+ VOID
+ );
+
+/**
+ Construct a SMEM host identifier.
+
+ Constructs a valid SMEM host identifier from the given parameters.
+ The internal bit encoding is an implementation detail; callers must
+ use this function rather than constructing host values directly.
+
+ @param[in] ProcId Processor ID (use QUALCOMM_SMEM_PROC_* macros).
+ @param[in] ProcNum Processor instance number.
+ @param[in] PdNum Protection-domain number.
+ @param[in] Chiplet Chiplet identifier.
+ @param[out] Host Output host identifier (must not be NULL).
+
+ @retval EFI_SUCCESS Host identifier constructed successfully.
+ @retval EFI_INVALID_PARAMETER Host is NULL, any parameter is out of
+ range, or the encoded value would collide
+ with a reserved host identifier.
+**/
+EFI_STATUS
+EFIAPI
+QualcommSmemHostId (
+ IN UINT16 ProcId,
+ IN UINT16 ProcNum,
+ IN UINT16 PdNum,
+ IN UINT16 Chiplet,
+ OUT QUALCOMM_SMEM_HOST *Host
+ );
+
+/**
+ Look up an existing SMEM item.
+
+ Searches the SMEM partition selected by RemoteHost for an item with the
+ given item ID.
+
+ @param[in] RemoteHost Remote host for a host-pair partition, or
+ QUALCOMM_SMEM_HOST_COMMON for the common partition.
+ @param[in] Item SMEM item ID.
+ @param[in] Flags Must be QUALCOMM_SMEM_FLAG_NONE.
+ @param[out] ItemPtr Pointer to item payload (must not be NULL).
+ @param[out] ItemSize Size of item payload in bytes (may be NULL).
+
+ @retval EFI_SUCCESS ItemPtr points to the item payload.
+ @retval EFI_INVALID_PARAMETER ItemPtr is NULL, RemoteHost is
+ QUALCOMM_SMEM_HOST_INVALID, Flags is not
+ QUALCOMM_SMEM_FLAG_NONE, or Item >= MaxItems.
+ @retval EFI_NOT_STARTED Driver has not been initialized.
+ @retval EFI_NOT_FOUND Item or partition not found.
+ @retval EFI_ACCESS_DENIED Partition not mapped or access denied.
+ @retval EFI_DEVICE_ERROR Corrupted shared-memory metadata.
+**/
+EFI_STATUS
+EFIAPI
+QualcommSmemLookup (
+ IN QUALCOMM_SMEM_HOST RemoteHost,
+ IN UINT16 Item,
+ IN UINT32 Flags,
+ OUT VOID **ItemPtr,
+ OUT UINTN *ItemSize OPTIONAL
+ );
diff --git a/Silicon/Qualcomm/QualcommSiliconPkg/Include/Library/SmemLib.h b/Silicon/Qualcomm/QualcommSiliconPkg/Include/Library/SmemLib.h deleted file mode 100644 index c4bd9870a1..0000000000 --- a/Silicon/Qualcomm/QualcommSiliconPkg/Include/Library/SmemLib.h +++ /dev/null @@ -1,253 +0,0 @@ -/** @file
- Public interface for the Qualcomm Shared Memory (SMEM) library.
-
- Provides functions for allocating and accessing shared memory regions
- used for inter-processor communication on Qualcomm platforms.
-
- Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Glossary:
- - SMEM - Shared Memory
-**/
-
-#pragma once
-
-#include <Base.h>
-#include <SmemType.h>
-
-#define SMEM_LIB_VERSION 0x00010001U
-
-/** SMEM Library version on platforms without SMEM support */
-#define SMEM_LIB_VERSION_NULL 0xFFFFFFFFU
-
-/** Extract major version number from version */
-#define SMEM_LIB_GET_MAJOR_VER(x) (((UINT32)(x)) >> 16)
-
-/** Major version number mask */
-#define SMEM_LIB_MAJOR_VERSION_MASK (0xFFFF0000U)
-
-/** Minor version number mask */
-#define SMEM_LIB_MINOR_VERSION_MASK (0x0000FFFFU)
-
-/** SMEM Status return codes */
-#define SMEM_STATUS_SUCCESS 0
-#define SMEM_STATUS_FAILURE -1
-#define SMEM_STATUS_INVALID_PARAM -2
-#define SMEM_STATUS_OUT_OF_RESOURCES -3
-#define SMEM_STATUS_NOT_FOUND -4
-#define SMEM_STATUS_DUPLICATE -5
-#define SMEM_STATUS_SIZE_MISMATCH -6
-
-/** Flags for use with SmemAllocEx() */
-#define SMEM_ALLOC_FLAG_NONE 0 /**< Default behavior */
-
-/**
- Get SMEM library version.
-
- This function returns the version number of the SMEM library implementation.
- The version number follows the format: Major.Minor (0xMMMMNNNN where MMMM is
- major version and NNNN is minor version).
-
- @retval SMEM_LIB_VERSION Library version number in format 0xMMMMNNNN
- (0x00010001 for version 1.1).
-
- @par Dependencies
- None.
-
- @par Side Effects
- None.
-**/
-UINT32
-EFIAPI
-SmemLibGetVersion (
- VOID
- );
-
-/**
- Initializes the shared memory allocation structures.
-
- @par Dependencies
- Shared memory must have been cleared and initialized by the first system
- bootloader.
-**/
-VOID
-EFIAPI
-SmemInit (
- VOID
- );
-
-/**
- Requests a pointer to a buffer in shared memory.
-
- @param[in] SmemType Type of memory.
- @param[in] BufSize Size of the buffer requested. For pre-allocated
- buffers, a fatal error occurs if the buffer size
- requested does not match the size of the existing
- buffer. If the BufSize is not 64-bit aligned, this
- function increases the size until it is 64-bit aligned.
-
- @retval NULL SMEM is not initialized.
- @retval Other Valid SMEM address to the requested buffer.
-
- @par Side Effects
- This function uses spinlocks for exclusive access to the shared memory heap.
-**/
-VOID *
-EFIAPI
-SmemAlloc (
- IN SMEM_MEM_TYPE SmemType,
- IN UINT32 BufSize
- );
-
-/**
- Requests a pointer to a buffer in shared memory. Upon success, Params.Buffer
- points to the allocation in shared memory.
-
- @param[in, out] Params See definition of SMEM_ALLOC_PARAMS_TYPE for details.
-
- @retval SMEM_STATUS_SUCCESS Allocation was successful,
- or already exists with specified size.
- Pointer to SMEM buffer is saved in
- Params.Buffer.
- Params.Size contains the requested size rounded
- up to 8 bytes.
- Params.Flags contains the status of the cached
- flag, which may not match what was
- requested if the item has been allocated
- previously.
- @retval SMEM_STATUS_SIZE_MISMATCH Allocation exists, but has different size.
- This is possible when another processor has
- already allocated an item with this SMEM ID and
- a different size.
- Pointer to SMEM buffer is saved in Params.Buffer.
- Params.Size contains the originally allocated
- size rounded up to 8 bytes.
- Params.Flags contains the status of the cached
- flag, which may not match what was
- requested if the item has been allocated
- previously.
- @retval SMEM_STATUS_INVALID_PARAM Invalid parameter
- @retval SMEM_STATUS_OUT_OF_RESOURCES Not enough SMEM to allocate this buffer
- @retval SMEM_STATUS_FAILURE General failure
-
- @par Side Effects
- This function uses spinlocks for exclusive access to the shared memory heap.
-**/
-INT32
-EFIAPI
-SmemAllocEx (
- IN OUT SMEM_ALLOC_PARAMS_TYPE *Params
- );
-
-/**
- Requests the address and size of an allocated buffer in shared memory. Newly
- allocated shared memory buffers, which have never been allocated on any
- processor, are guaranteed to be zero-initialized.
-
- @param[in] SmemType Type of memory for which to get a pointer.
- @param[out] BufSize Size of the buffer allocated in shared memory.
-
- @retval Pointer Pointer to the requested buffer.
- @retval NULL Buffer has not been allocated.
-
- @par Dependencies
- The buffer must already have been allocated.
-
- @par Side Effects
- This function uses spinlocks for exclusive access to the shared memory heap.
-**/
-VOID *
-EFIAPI
-SmemGetAddr (
- IN SMEM_MEM_TYPE SmemType,
- OUT UINT32 *BufSize
- );
-
-/**
- Requests the address and size of an allocated buffer in shared memory.
- If found, sets the buffer and size fields of the Params struct.
-
- @param[in, out] Params Params.SmemType must be set to the ID to search for.
- Params.RemoteHost must be set to the ID of the remote
- host of the partition.
- If Params.Flags has the SMEM_ALLOC_FLAG_PARTITION_ONLY
- flag set, then this function will not search the
- default partition for the item. This is useful when
- SMEM item X is possible in both the default partition
- and an edge-pair partition, and the caller wants to
- find out if the item exists in the edge-pair
- partition only.
-
- @retval SMEM_STATUS_SUCCESS Allocated buffer found
- Params.Buffer contains a pointer to the allocation.
- Params.Size contains the size of the allocation
- as originally requested, rounded up to 8 bytes.
- Params.Flags contains the status of the cached
- flag.
- @retval SMEM_STATUS_NOT_FOUND Allocated buffer not found
- @retval SMEM_STATUS_INVALID_PARAM Invalid parameter
- @retval SMEM_STATUS_FAILURE Failure occurred
-
- @par Side Effects
- This function uses spinlocks for exclusive access to the shared memory heap.
- This function updates the SizeRemaining field for the partition.
-**/
-INT32
-EFIAPI
-SmemGetAddrEx (
- IN OUT SMEM_ALLOC_PARAMS_TYPE *Params
- );
-
-/**
- Frees a pointer in shared memory.
-
- @note This function is not actually implemented, but if it were, it would
- allow other functions to reuse the memory previously allocated in shared
- memory.
-
- @param[in] Addr Pointer to the shared memory block to be freed.
-
- @par Dependencies
- SmemInit() must have been called on this processor.
- The pointer must have been allocated using SmemAlloc().
-**/
-VOID
-EFIAPI
-SmemFree (
- IN VOID *Addr
- );
-
-/**
- Sets the version number for this processor and a given object.
-
- The version number is compared to all previously set version numbers for this
- object. The last processor to register checks against all other processors.
-
- @param[in] Type Type of object being version checked. It must be
- between SmemVersionFirst and SmemVersionLast
- in the SMEM_MEM_TYPE enum, unless it is of type
- SmemVersionInfo (for internal use only).
- @param[in] Version Local version number for this memory object.
- @param[in] Mask Bitwise AND mask used to specify either SMEM or PROC_COMM
- version when comparing against other processor version
- numbers. To compare both (all 32 version bits), this
- argument must be 0xFFFFFFFF.
-
- @retval TRUE Version number of the local processor matches all previously
- registered versions for this object type.
- @retval FALSE There is a mismatch.
-
- @par Dependencies
- SmemInit() must have been called on this processor.
-
- @par Side Effects
- This function uses spinlocks for exclusive access to the shared memory heap.
-**/
-BOOLEAN
-EFIAPI
-SmemVersionSet (
- IN SMEM_MEM_TYPE Type,
- IN UINT32 Version,
- IN UINT32 Mask
- );
diff --git a/Silicon/Qualcomm/QualcommSiliconPkg/Include/SmemType.h b/Silicon/Qualcomm/QualcommSiliconPkg/Include/SmemType.h deleted file mode 100644 index 68683908ac..0000000000 --- a/Silicon/Qualcomm/QualcommSiliconPkg/Include/SmemType.h +++ /dev/null @@ -1,261 +0,0 @@ -/** @file
- Public data types for the Qualcomm Shared Memory (SMEM) subsystem.
-
- Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Glossary:
- - ADSP - Audio Digital Signal Processor
- - AARM - Application Processor ARM (Current boot core - akin to BSP in PI spec)
- - BAM - Bus Access Manager
- - CDSP - Compute Digital Signal Processor
- - CPR - Core Power Reduction
- - DAL - Device Abstraction Layer
- - DCP - Data Compression Processor
- - DSP - Digital Signal Processor
- - EFS - Embedded File System
- - GLINK - Generic Link
- - GPDSP - General Purpose DSP
- - HLOS - High Level Operating System
- - IPA - IP Accelerator
- - IPC - Inter-Processor Communication
- - LA - Linux Android
- - LC - Linux Client
- - LPASS - Low Power Audio Sub-System
- - MSS - Modem Sub-System
- - MPROC - Multi-processor
- - NPU - Neural Processing Unit
- - NSP - Network Sub-Processor
- - OOB - Out of Band
- - OSSRRC - ASN.1 RRC decode/encode working memory between the Modem (MPSS) and another processor
- - QECP - Qualcomm Enhanced Compute Processor
- - RPM - Resource Power Manager
- - SEFS - Secure Embedded File System
- - SMEM - Shared Memory
- - SMD - Shared Memory Driver
- - SMP2P - Shared Memory Point to Point
- - SMSM - Shared Memory State Machine
- - SOCCP - System on Chip Compute Processor
- - SPSS - Secure Processor Sub-System
- - SSC - Sensor Sub-System Compute
- - SSR - Sub-System Restart
- - TEE - Trusted Execution Environment
- - TME - Trusted Memory Expansion
- - TZ - TrustZone
- - VM - Virtual Machine
- - WCN - Wireless Connectivity Network
- - WPSS - Wireless Processor Sub-System
- - XBL - eXtensible Boot Loader
-**/
-
-#pragma once
-
-#include <Base.h>
-
-/**
- The most significant two bytes of SMEM_VERSION_ID are the SMEM major version
- and the least significant two bytes are the SMEM minor version. The major
- version must be updated whenever an incompatible change is introduced.
-
- The minor version may track API changes and deprecations that do not affect
- remote processors, including changes to the SMEM_MEM_TYPE enum when
- dependencies have already been satisfied on the relevant processors.
-
- Minor version inconsistencies between processors will not prevent SMEM from
- booting, but major version inconsistencies will.
-**/
-
-#define SMEM_VERSION_ID 0x000C0000
-
-#define SMEM_MAJOR_VERSION_MASK 0xFFFF0000
-#define SMEM_MINOR_VERSION_MASK 0x0000FFFF
-#define SMEM_FULL_VERSION_MASK 0xFFFFFFFF
-
-#define SMEM_NUM_SMD_CHANNELS 64
-#define SMEM_NUM_SMP2P_EDGES 8
-#define SMEM_NUM_VERSION_ENTRIES 24
-
-/** Types of memory that can be requested via SmemAlloc.
-
- SmemVersionFirst and SmemVersionLast are the first and last
- boundaries for external version checking via the SmemVersionSet routine.
-
- SmemVersionLast need not be the last item in the enum.
-**/
-typedef enum {
- SmemMemFirst = 0,
- SmemReservedProcComm = 0, /* SmemMemFirst */
- SmemFirstFixedBuffer = 0, /* SmemReservedProcComm */
- SmemHeapInfo = 1,
- SmemAllocationTable = 2,
- SmemVersionInfo = 3,
- SmemHwResetDetect = 4,
- SmemReservedAarmWarmBoot = 5,
- SmemDiagErrMessage = 6,
- SmemSpinlockArray = 7,
- SmemMemoryBarrierLocation = 8,
- SmemLastFixedBuffer = 8, /* SmemMemoryBarrierLocation */
- SmemAarmPartitionTable = 9,
- SmemAarmBadBlockTable = 10,
- SmemErrCrashLogAdsp = 11,
- SmemBootBoardInfo = 12,
- SmemChannelAllocTbl = 13,
- SmemSmdBaseId = 14,
- SmemSmemLogIdx = SmemSmdBaseId + SMEM_NUM_SMD_CHANNELS,
- SmemSmemLogEvents = 79,
- SmemReservedSmemStaticLogIdx = 80,
- SmemXblLoaderCoreInfo = 80, /* SmemReservedSmemStaticLogIdx */
- SmemReservedSmemStaticLogEvents = 81,
- SmemChargerBatteryInfo = 81, /* SmemReservedSmemStaticLogEvents */
- SmemReservedSmemSlowClockSync = 82,
- SmemWlanConfig = 82, /* SmemReservedSmemSlowClockSync */
- SmemReservedSmemSlowClockValue = 83,
- SmemMePlayback = 83, /* SmemReservedSmemSlowClockValue */
- SmemReservedBioLedBuf = 84,
- SmemSmsmSharedState = 85,
- SmemReservedSmsmIntInfo = 86,
- SmemReservedSmsmSleepDelay = 87,
- SmemReservedSmsmLimitSleep = 88,
- SmemReservedSleepPowerCollapseDisabled = 89,
- SmemReservedKeypadKeysPressed = 90,
- SmemReservedKeypadStateUpdated = 91,
- SmemReservedKeypadStateIdx = 92,
- SmemReservedGpioInt = 93,
- SmemIdSmp2pBaseCdsp = 94,
- SmemReservedSmdProfiles = SmemIdSmp2pBaseCdsp + SMEM_NUM_SMP2P_EDGES,
- SmemReservedTsscBusy = 103,
- SmemReservedHsSuspendFilterInfo = 104,
- SmemReservedBattInfo = 105,
- SmemReservedAppsBootMode = 106,
- SmemVersionFirst = 107,
- SmemVersionSmd = 107, /* SmemVersionFirst */
- SmemVersionSmdBridge = 108,
- SmemVersionSmsm = 109,
- SmemVersionSmdNwayLoop = 110,
- SmemVersionLast = SmemVersionFirst + SMEM_NUM_VERSION_ENTRIES,
- SmemReservedOssRrcasn1Buf1 = 132,
- SmemReservedOssRrcasn1Buf2 = 133,
- SmemIdVendor0 = 134,
- SmemIdVendor1 = 135,
- SmemIdVendor2 = 136,
- SmemHwSwBuildId = 137,
- SmemReservedSmdBlockPortBaseId = 138,
- SmemReservedSmdBlockPortProc0Heap = SmemReservedSmdBlockPortBaseId + SMEM_NUM_SMD_CHANNELS,
- SmemReservedSmdBlockPortProc1Heap = SmemReservedSmdBlockPortProc0Heap + SMEM_NUM_SMD_CHANNELS,
- SmemI2cMutex = SmemReservedSmdBlockPortProc1Heap + SMEM_NUM_SMD_CHANNELS,
- SmemSclkConversion = 331,
- SmemReservedSmdSmsmIntrMux = 332,
- SmemSmsmCpuIntrMask = 333,
- SmemReservedAppsDemSlaveData = 334,
- SmemReservedQdsp6DemSlaveData = 335,
- SmemVsenseData = 336,
- SmemReservedClkregimSources = 337,
- SmemSmdFifoBaseId = 338,
- SmemUsableRamPartitionTable = SmemSmdFifoBaseId + SMEM_NUM_SMD_CHANNELS,
- SmemPowerOnStatusInfo = 403,
- SmemDalArea = 404,
- SmemSmemLogPowerIdx = 405,
- SmemSmemLogPowerWrap = 406,
- SmemSmemLogPowerEvents = 407,
- SmemErrCrashLog = 408,
- SmemErrF3TraceLog = 409,
- SmemSmdBridgeAllocTable = 410,
- SmemSmdFeatureSet = 411,
- SmemReservedSdImgUpgradeStatus = 412,
- SmemSefsInfo = 413,
- SmemReservedResetLog = 414,
- SmemReservedResetLogSymbols = 415,
- SmemModemSwBuildId = 416,
- SmemSmemLogMprocWrap = 417,
- SmemReservedBootInfoForApps = 418,
- SmemSmsmSizeInfo = 419,
- SmemSmdLoopbackRegister = 420,
- SmemSsrReasonMss0 = 421,
- SmemSsrReasonWcnss0 = 422,
- SmemSsrReasonLpass0 = 423,
- SmemSsrReasonDsps0 = 424,
- SmemSsrReasonVcodec0 = 425,
- SmemVoice = 426,
- SmemIdSmp2pBaseApps = 427,
- SmemIdSmp2pBaseModem = SmemIdSmp2pBaseApps + SMEM_NUM_SMP2P_EDGES,
- SmemIdSmp2pBaseAdsp = SmemIdSmp2pBaseModem + SMEM_NUM_SMP2P_EDGES,
- SmemIdSmp2pBaseWcn = SmemIdSmp2pBaseAdsp + SMEM_NUM_SMP2P_EDGES,
- SmemIdSmp2pBaseRpm = SmemIdSmp2pBaseWcn + SMEM_NUM_SMP2P_EDGES,
- SmemFlashDeviceInfo = SmemIdSmp2pBaseRpm + SMEM_NUM_SMP2P_EDGES,
- SmemBamPipeMemory = 468,
- SmemImageVersionTable = 469,
- SmemLcDebugger = 470,
- SmemFlashNandDevInfo = 471,
- SmemA2BamDescriptorFifo = 472,
- SmemCprConfig = 473,
- SmemClockInfo = 474,
- SmemIpcInfo = 475,
- SmemRfEepromData = 476,
- SmemCoexMdmWcn = 477,
- SmemGlinkNativeXportDescriptor = 478,
- SmemGlinkNativeXportFifo0 = 479,
- SmemGlinkNativeXportFifo1 = 480,
- SmemIdSmp2pBaseSsc = 481,
- SmemIdSmp2pBaseTz = SmemIdSmp2pBaseSsc + SMEM_NUM_SMP2P_EDGES,
- SmemIpaFilterTable = SmemIdSmp2pBaseTz + SMEM_NUM_SMP2P_EDGES,
- SmemMemLast = 497, /* SmemIpaFilterTable */
- SmemInvalid = 498
-} SMEM_MEM_TYPE;
-
-/** A list of hosts supported in SMEM */
-typedef enum {
- SmemApps = 0, /**< Apps Processor */
- SmemModem = 1, /**< Modem processor */
- SmemAdsp = 2, /**< ADSP processor */
- SmemSsc = 3, /**< Sensor processor */
- SmemWcn = 4, /**< WCN processor */
- SmemCdsp = 5, /**< CDSP processor */
- SmemRpm = 6, /**< RPM processor */
- SmemTz = 7, /**< TZ processor */
- SmemSpss = 8, /**< Secure processor */
- SmemHyp = 9, /**< Hypervisor */
- SmemNpu = 10, /**< NPU processor */
- SmemSpssSp = 11, /**< SPSS Host that shares partition with TZ */
- SmemNsp1 = 12, /**< NSP1 processor */
- SmemWpss = 13, /**< WPSS processor */
- SmemTme = 14, /**< TME processor */
- SmemAppsVmLa = 15, /**< VM LA Host of Apps processor */
- SmemExtPm = 16, /**< External PM */
- SmemGpdsp0 = 17, /**< General Purpose DSP 0 */
- SmemGpdsp1 = 18, /**< General Purpose DSP 1 */
- SmemSoccp = 19, /**< SOCCP processor */
- SmemOobTee = 20, /**< OOB Secure processor */
- SmemOobNs = 21, /**< OOB Non-Secure processor */
- SmemDcp = 22, /**< DCP processor */
- SmemWm = 23, /**< WM processor */
- SmemAm = 24, /**< AM processor */
- SmemQecp = 25, /**< QECP processor */
- SmemNumHosts = 26, /**< Max number of host in target */
- SmemQ6 = SmemAdsp, /**< Kept for legacy purposes. New code should use SmemAdsp. */
- SmemRiva = SmemWcn, /**< Kept for legacy purposes. New code should use SmemWcn. */
- SmemDsps = SmemSsc, /**< Kept for legacy purposes. New code should use SmemSsc. */
- SmemSpssNonsp = SmemSpss, /**< SPSS Host that shares partition with HLOS */
- SmemNsp = SmemCdsp, /**< Alias for SmemCdsp. Kept for legacy purposes. */
- SmemCmddb = 0xFFFD, /**< Reserved partition for command DB use case */
- SmemCommonHost = 0xFFFE, /**< Common host */
- SmemInvalidHost = 0xFFFF, /**< Invalid processor */
-} SMEM_HOST_TYPE;
-
-/** Hardware reset detection magic value structure */
-typedef struct {
- UINT32 Magic1; ///< Most-significant word of the predefined magic value.
- UINT32 Magic2; ///< Least-significant word of the predefined magic value.
-} SMEM_HW_RESET_ID_TYPE;
-
-/** Parameters structure for SmemAllocEx and SmemGetAddrEx */
-typedef struct {
- SMEM_HOST_TYPE RemoteHost; ///< Remote endpoint with which this SMEM item will be shared.
- ///< Determines which partition to allocate from. If set to
- ///< SmemInvalidHost, the allocation is from the default
- ///< unprotected partition.
- SMEM_MEM_TYPE SmemType; ///< Identifier for the allocation. Allowed types are in SMEM_MEM_TYPE.
- UINT32 Size; ///< Size of the allocation in bytes. Allocated size may be larger
- ///< than requested and is rounded up to 8 bytes.
- VOID *Buffer; ///< Pointer to the allocated buffer in shared memory.
- UINT32 Flags; ///< Allocation flags. See SMEM_ALLOC_FLAG for options.
-} SMEM_ALLOC_PARAMS_TYPE;
diff --git a/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemInternal.h b/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemInternal.h new file mode 100644 index 0000000000..8474b26b27 --- /dev/null +++ b/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemInternal.h @@ -0,0 +1,259 @@ +/** @file
+ Qualcomm Shared Memory (SMEM) - Internal protocol definitions.
+
+ Defines protocol constants, wire-format ABI structures, and the driver
+ state type used exclusively by QualcommSmemLib.c. This header is not part of
+ the public API and must not be included by external code.
+
+ @par Glossary
+ - Smem - Shared Memory
+ - Abi - Application Binary Interface
+ - Toc - Table of Contents
+ - Ipc - Inter-processor Communication
+
+ Copyright (C) Qualcomm Technologies, Inc. and/or its subsidiaries.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#pragma once
+
+#include "QualcommSmemPlatform.h"
+
+// -------------------------------------------------------------------------
+// Protocol constants
+// -------------------------------------------------------------------------
+
+//
+// BOOT info page: the first 4096 bytes of SMEM contain BOOT/static
+// version metadata. This page is mapped read-only during init.
+//
+// Layout of the first 4096 bytes:
+// [0, 64): ProcComm[16] - legacy IPC mechanism (16 x UINT32)
+// [64, 192): Ver[32] - version array (32 x UINT32)
+// [192, 4096): ... - other static metadata
+//
+// The BOOT SMEM version is at Ver[QUALCOMM_SMEM_VERSION_BOOT_OFFSET].
+//
+#define QUALCOMM_SMEM_BOOT_INFO_SIZE 4096U
+
+// TOC page size: the TOC occupies the last 4096 bytes of SMEM.
+#define QUALCOMM_SMEM_TOC_SIZE 4096U
+
+// Supported TOC version.
+#define QUALCOMM_SMEM_TOC_VERSION 1U
+
+// Maximum number of TOC entries processed (bounds the TOC walk).
+#define QUALCOMM_SMEM_TOC_MAX_ENTRIES 40U
+
+//
+// TOC magic: "$TOC" stored as a little-endian UINT32.
+// '$' = 0x24, 'T' = 0x54, 'O' = 0x4F, 'C' = 0x43
+//
+#define QUALCOMM_SMEM_TOC_MAGIC 0x434F5424U
+
+//
+// Partition magic: "$PRT" stored as a little-endian UINT32.
+// '$' = 0x24, 'P' = 0x50, 'R' = 0x52, 'T' = 0x54
+//
+#define QUALCOMM_SMEM_PART_MAGIC 0x54525024U
+
+// Canary value stored in every item header.
+#define QUALCOMM_SMEM_ITEM_CANARY 0xa5a5U
+
+//
+// BOOT SMEM version constants.
+//
+// The BOOT SMEM version word is stored at index QUALCOMM_SMEM_VERSION_BOOT_OFFSET
+// within the Ver[] array of QUALCOMM_SMEM_STATIC_HEADER.
+//
+// Version word format:
+// bits [31:16] = major version
+// bits [15:0] = minor version
+//
+// This driver supports major version 0x000C (12).
+// Minor version differences are accepted if the layout is compatible.
+//
+#define QUALCOMM_SMEM_VERSION_ID 0x000C0001U
+#define QUALCOMM_SMEM_MAJOR_VERSION_MASK 0xffff0000U
+#define QUALCOMM_SMEM_MINOR_VERSION_MASK 0x0000ffffU
+#define QUALCOMM_SMEM_VERSION_BOOT_OFFSET 7U
+
+//
+// QUALCOMM_SMEM_HOST_INVALID sentinel - duplicated here as a UINT16 literal
+// to avoid casting the public macro in internal comparisons.
+//
+#define QUALCOMM_SMEM_HOST_INVALID_U16 0xffffU
+
+//
+// Internal multi-host partition marker.
+// A TOC entry with Host0 == Host1 == QUALCOMM_SMEM_HOST_MULTIHOST describes
+// a multi-host partition whose membership is encoded in HostsBitmap.
+// Not exposed publicly.
+//
+#define QUALCOMM_SMEM_HOST_MULTIHOST 0xfffcU
+
+// -------------------------------------------------------------------------
+// Host-ID encoding
+//
+// A regular host ID is a 16-bit value encoded as:
+//
+// bits [5:0] ProcId (6 bits, values 0-63)
+// bits [9:6] ProcNum (4 bits, values 0-15)
+// bits [12:10] PdNum (3 bits, values 0-7)
+// bits [15:13] Chiplet (3 bits, values 0-7)
+//
+// Special values that must never be produced by QualcommSmemHostId():
+// QUALCOMM_SMEM_HOST_COMMON = 0xfffe
+// QUALCOMM_SMEM_HOST_INVALID = 0xffff
+// QUALCOMM_SMEM_HOST_MULTIHOST = 0xfffc
+// -------------------------------------------------------------------------
+
+#define HOST_PROC_ID_BITS 6U
+#define HOST_PROC_NUM_BITS 4U
+#define HOST_PD_NUM_BITS 3U
+#define HOST_CHIPLET_BITS 3U
+
+#define HOST_PROC_ID_SHIFT 0U
+#define HOST_PROC_NUM_SHIFT 6U
+#define HOST_PD_NUM_SHIFT 10U
+#define HOST_CHIPLET_SHIFT 13U
+
+#define HOST_PROC_ID_MASK ((1U << HOST_PROC_ID_BITS) - 1U)
+#define HOST_PROC_NUM_MASK ((1U << HOST_PROC_NUM_BITS) - 1U)
+#define HOST_PD_NUM_MASK ((1U << HOST_PD_NUM_BITS) - 1U)
+#define HOST_CHIPLET_MASK ((1U << HOST_CHIPLET_BITS) - 1U)
+
+// -------------------------------------------------------------------------
+// Shared-memory ABI structures
+//
+// These structures represent the fixed binary layout of the SMEM protocol.
+// They are internal to the driver and must NOT be exposed in any public header.
+// -------------------------------------------------------------------------
+
+#pragma pack (1)
+
+//
+// QUALCOMM_SMEM_STATIC_HEADER - layout of the first 4096 bytes of SMEM.
+//
+// The Ver[] array at offset 64 contains version words for each SMEM
+// subsystem. Index QUALCOMM_SMEM_VERSION_BOOT_OFFSET (7) holds the BOOT
+// SMEM version that this driver validates during init.
+//
+typedef struct {
+ UINT32 ProcComm[16]; ///< Legacy IPC: 16 x UINT32 = 64 bytes.
+ UINT32 Ver[32]; ///< Version array: 32 x UINT32 = 128 bytes.
+} QUALCOMM_SMEM_STATIC_HEADER;
+
+//
+// QUALCOMM_SMEM_TOC_HEADER - SMEM partition table (TOC) header.
+//
+// Located at: SmemBase + SmemSize - QUALCOMM_SMEM_TOC_SIZE.
+// Immediately followed by an array of QUALCOMM_SMEM_TOC_ENTRY records.
+//
+typedef struct {
+ UINT32 Magic; ///< Must equal QUALCOMM_SMEM_TOC_MAGIC.
+ UINT32 Version; ///< Must equal QUALCOMM_SMEM_TOC_VERSION.
+ UINT32 NumEntries; ///< Number of valid QUALCOMM_SMEM_TOC_ENTRY records.
+ UINT32 MinorVersion; ///< Minor version; informational only.
+ UINT32 Reserved[4]; ///< Reserved; not validated.
+} QUALCOMM_SMEM_TOC_HEADER;
+
+//
+// QUALCOMM_SMEM_TOC_ENTRY - one entry in the SMEM partition table.
+//
+// Entries follow the QUALCOMM_SMEM_TOC_HEADER immediately in memory.
+// Host0 and Host1 use UINT16 to match the SMEM wire format.
+// Do NOT use QUALCOMM_SMEM_HOST here; the ABI layout must remain stable.
+//
+typedef struct {
+ UINT32 Offset; ///< Byte offset of partition from SMEM base.
+ UINT32 Size; ///< Partition size in bytes.
+ UINT32 Flags; ///< Reserved flags.
+ UINT16 Host0; ///< First host identifier (wire UINT16).
+ UINT16 Host1; ///< Second host identifier (wire UINT16).
+ UINT32 SizeCacheline; ///< Cached-item alignment (0 = default).
+ UINT32 Reserved[3]; ///< Reserved; not validated.
+ UINT32 ExclusionSizes[4]; ///< Per-host exclusion region sizes.
+} QUALCOMM_SMEM_TOC_ENTRY;
+
+//
+// QUALCOMM_SMEM_PARTITION_HEADER - header at the start of each partition.
+//
+// Host0 and Host1 use UINT16 to match the SMEM wire format.
+// Do NOT use QUALCOMM_SMEM_HOST here; the ABI layout must remain stable.
+//
+// OffsetFreeUncached: end of the allocated uncached (upward) region.
+// Grows upward from sizeof (QUALCOMM_SMEM_PARTITION_HEADER).
+// OffsetFreeCached: start of the allocated cached (downward) region.
+// Grows downward from partition size.
+//
+typedef struct {
+ UINT32 Magic; ///< Must equal QUALCOMM_SMEM_PART_MAGIC.
+ UINT16 Host0; ///< First host identifier (wire UINT16).
+ UINT16 Host1; ///< Second host identifier (wire UINT16).
+ UINT32 Size; ///< Total partition size in bytes.
+ UINT32 OffsetFreeUncached; ///< End of allocated uncached region.
+ UINT32 OffsetFreeCached; ///< Start of allocated cached region.
+ UINT32 Reserved[3]; ///< Reserved; not validated.
+} QUALCOMM_SMEM_PARTITION_HEADER;
+
+//
+// QUALCOMM_SMEM_ITEM_HEADER - header preceding each allocated SMEM item.
+//
+// Uncached item layout (growing upward from partition header):
+// [QUALCOMM_SMEM_ITEM_HEADER][PaddingHeader bytes][data][PaddingData bytes]
+//
+// Data address: Ptr + sizeof (QUALCOMM_SMEM_ITEM_HEADER) + PaddingHeader
+// Data size: Size - PaddingData
+// Next header: Ptr + sizeof (QUALCOMM_SMEM_ITEM_HEADER) + PaddingHeader + Size
+//
+typedef struct {
+ UINT16 Canary; ///< Must equal QUALCOMM_SMEM_ITEM_CANARY (0xa5a5).
+ UINT16 Item; ///< SMEM item identifier.
+ UINT32 Size; ///< Total rounded size including PaddingData.
+ UINT16 PaddingData; ///< Unused bytes at end of data region.
+ UINT16 PaddingHeader; ///< Alignment gap between header and data.
+ UINT32 Reserved; ///< Reserved; not validated.
+} QUALCOMM_SMEM_ITEM_HEADER;
+
+#pragma pack ()
+
+// Compile-time size assertions - catch layout regressions immediately.
+STATIC_ASSERT (
+ sizeof (QUALCOMM_SMEM_STATIC_HEADER) == 192U,
+ "QUALCOMM_SMEM_STATIC_HEADER size mismatch"
+ );
+STATIC_ASSERT (
+ sizeof (QUALCOMM_SMEM_TOC_HEADER) == 32U,
+ "QUALCOMM_SMEM_TOC_HEADER size mismatch"
+ );
+STATIC_ASSERT (
+ sizeof (QUALCOMM_SMEM_TOC_ENTRY) == 48U,
+ "QUALCOMM_SMEM_TOC_ENTRY size mismatch"
+ );
+STATIC_ASSERT (
+ sizeof (QUALCOMM_SMEM_PARTITION_HEADER) == 32U,
+ "QUALCOMM_SMEM_PARTITION_HEADER size mismatch"
+ );
+STATIC_ASSERT (
+ sizeof (QUALCOMM_SMEM_ITEM_HEADER) == 16U,
+ "QUALCOMM_SMEM_ITEM_HEADER size mismatch"
+ );
+
+// -------------------------------------------------------------------------
+// Driver state
+// -------------------------------------------------------------------------
+
+//
+// QUALCOMM_SMEM_INFO - driver state.
+//
+typedef struct {
+ BOOLEAN Initialized; ///< FALSE = uninitialized, TRUE = initialized.
+ QUALCOMM_SMEM_HOST LocalHost; ///< Local host ID.
+ UINT16 MaxItems; ///< Maximum item ID (exclusive).
+ UINT32 SmemSize; ///< Total SMEM size in bytes.
+ UINT32 TocOffset; ///< Byte offset of TOC from SMEM base.
+ UINT32 NumTocEntries; ///< Validated TOC entry count.
+ UINT32 CommonPartOffset; ///< Common partition offset.
+ UINT32 CommonPartSize; ///< Common partition size.
+} QUALCOMM_SMEM_INFO;
diff --git a/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemLib.c b/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemLib.c new file mode 100644 index 0000000000..1b9dd44a68 --- /dev/null +++ b/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemLib.c @@ -0,0 +1,981 @@ +/** @file
+ Qualcomm Shared Memory (SMEM) - Common Core.
+
+ Implements SMEM initialization, partition mapping, and item lookup.
+ Platform-specific operations are delegated to the interface defined in
+ QualcommSmemPlatform.h. Internal protocol constants, ABI structures, and
+ driver state type are defined in QualcommSmemInternal.h.
+
+ @par Glossary:
+ - Abi - Application Binary Interface
+ - Smem - Shared Memory
+ - Toc - Table of Contents
+
+ Copyright (C) Qualcomm Technologies, Inc. and/or its subsidiaries.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "QualcommSmemInternal.h"
+#include "QualcommSmemLib.h"
+#include "QualcommSmemPlatform.h"
+
+static QUALCOMM_SMEM_INFO mQualcommSmemInfo;
+
+// -------------------------------------------------------------------------
+// Internal helpers
+// -------------------------------------------------------------------------
+
+/**
+ Read a 16-bit value from shared memory.
+
+ Uses CopyMem to avoid undefined behaviour on unaligned reads.
+
+ @param[in] Ptr Pointer to the source location in shared memory.
+
+ @return The 16-bit value at Ptr.
+**/
+static
+UINT16
+SmemRd16 (
+ IN CONST VOID *Ptr
+ )
+{
+ UINT16 Value;
+
+ CopyMem (&Value, Ptr, sizeof (Value));
+ return Value;
+}
+
+/**
+ Read a 32-bit value from shared memory.
+
+ Uses CopyMem to avoid undefined behaviour on unaligned reads.
+
+ @param[in] Ptr Pointer to the source location in shared memory.
+
+ @return The 32-bit value at Ptr.
+**/
+static
+UINT32
+SmemRd32 (
+ IN CONST VOID *Ptr
+ )
+{
+ UINT32 Value;
+
+ CopyMem (&Value, Ptr, sizeof (Value));
+ return Value;
+}
+
+/**
+ Validate a single TOC entry.
+
+ Checks that the partition described by Entry has a non-zero size and
+ lies entirely within the SMEM region.
+
+ @param[in] Entry TOC entry to validate.
+
+ @retval EFI_SUCCESS Entry is valid.
+ @retval EFI_DEVICE_ERROR Entry is malformed.
+**/
+static
+EFI_STATUS
+SmemValidateTocEntry (
+ IN CONST QUALCOMM_SMEM_TOC_ENTRY *Entry
+ )
+{
+ UINT32 Off;
+ UINT32 Size;
+ UINT64 End;
+
+ Off = SmemRd32 (&Entry->Offset);
+ Size = SmemRd32 (&Entry->Size);
+
+ // Partition must be large enough to hold the partition header.
+ if (Size < (UINT32)sizeof (QUALCOMM_SMEM_PARTITION_HEADER)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Offset + Size must not overflow and must lie within SMEM.
+ End = (UINT64)Off + (UINT64)Size;
+ if (End > (UINT64)mQualcommSmemInfo.SmemSize) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Check if a TOC entry involves the local host.
+
+ A partition is relevant to the local host if it is:
+ - the common partition (Host0 == Host1 == QUALCOMM_SMEM_HOST_COMMON), or
+ - an edge-pair partition where LocalHost is one of the endpoints.
+
+ @param[in] Entry TOC entry to test.
+
+ @retval TRUE Partition involves the local host.
+ @retval FALSE Partition does not involve the local host.
+**/
+static
+BOOLEAN
+SmemPartInvolvesLocal (
+ IN CONST QUALCOMM_SMEM_TOC_ENTRY *Entry
+ )
+{
+ UINT16 Lh;
+ UINT16 H0;
+ UINT16 H1;
+
+ Lh = (UINT16)mQualcommSmemInfo.LocalHost;
+ H0 = SmemRd16 (&Entry->Host0);
+ H1 = SmemRd16 (&Entry->Host1);
+
+ // Common partition - accessible to all hosts.
+ if ((H0 == (UINT16)QUALCOMM_SMEM_HOST_COMMON) &&
+ (H1 == (UINT16)QUALCOMM_SMEM_HOST_COMMON))
+ {
+ return TRUE;
+ }
+
+ // Edge-pair partition: local host is one endpoint.
+ return ((H0 == Lh) || (H1 == Lh)) ? TRUE : FALSE;
+}
+
+/**
+ Check if a TOC entry matches the requested host pair.
+
+ - If Host == QUALCOMM_SMEM_HOST_COMMON: match the common partition.
+ - Otherwise: match an edge-pair partition where one endpoint is
+ LocalHost and the other is Host.
+
+ @param[in] Entry TOC entry to test.
+ @param[in] Host Requested remote host.
+
+ @retval TRUE Entry matches the requested host pair.
+ @retval FALSE Entry does not match.
+**/
+static
+BOOLEAN
+SmemPartMatches (
+ IN CONST QUALCOMM_SMEM_TOC_ENTRY *Entry,
+ IN QUALCOMM_SMEM_HOST Host
+ )
+{
+ UINT16 Lh;
+ UINT16 Rh;
+ UINT16 H0;
+ UINT16 H1;
+
+ Lh = (UINT16)mQualcommSmemInfo.LocalHost;
+ Rh = (UINT16)Host;
+ H0 = SmemRd16 (&Entry->Host0);
+ H1 = SmemRd16 (&Entry->Host1);
+
+ // Common partition lookup.
+ if (Host == QUALCOMM_SMEM_HOST_COMMON) {
+ return ((H0 == (UINT16)QUALCOMM_SMEM_HOST_COMMON) &&
+ (H1 == (UINT16)QUALCOMM_SMEM_HOST_COMMON)) ? TRUE : FALSE;
+ }
+
+ // Edge-pair: one endpoint must be local, the other must be remote.
+ return (((H0 == Lh) && (H1 == Rh)) ||
+ ((H0 == Rh) && (H1 == Lh))) ? TRUE : FALSE;
+}
+
+/**
+ Scan the uncached/upward item list in a partition.
+
+ Items are stored sequentially starting immediately after the partition
+ header, growing upward toward ScanLimit. Each item occupies:
+
+ [QUALCOMM_SMEM_ITEM_HEADER][PaddingHeader bytes][data (Size bytes)]
+
+ where the last PaddingData bytes of data are unused padding.
+
+ @param[in] Base Base address of the partition in virtual memory.
+ @param[in] ScanLimit Offset of the first free uncached byte (exclusive).
+ @param[in] ItemId Item identifier to search for.
+ @param[out] Addr Set to the item payload address on success.
+ @param[out] Size Set to the item payload size on success (may be NULL).
+
+ @retval EFI_SUCCESS Item found; Addr and Size (if non-NULL) are set.
+ @retval EFI_NOT_FOUND Item not present in the uncached region.
+ @retval EFI_DEVICE_ERROR Corrupted item metadata detected.
+**/
+static
+EFI_STATUS
+SmemScanUncached (
+ IN CONST UINT8 *Base,
+ IN UINT32 ScanLimit,
+ IN UINT16 ItemId,
+ OUT VOID **Addr,
+ OUT UINTN *Size OPTIONAL
+ )
+{
+ CONST UINT8 *Limit;
+ CONST UINT8 *Ptr;
+ CONST QUALCOMM_SMEM_ITEM_HEADER *Ihdr;
+ UINT32 ItemSize;
+ UINT32 Step;
+
+ // ScanLimit must cover at least the partition header.
+ if (ScanLimit < (UINT32)sizeof (QUALCOMM_SMEM_PARTITION_HEADER)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Limit = Base + ScanLimit;
+ Ptr = Base + sizeof (QUALCOMM_SMEM_PARTITION_HEADER);
+
+ while (Ptr < Limit) {
+ // Ensure there is room for a complete item header.
+ if ((UINTN)Limit - (UINTN)Ptr < sizeof (QUALCOMM_SMEM_ITEM_HEADER)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Ihdr = (CONST QUALCOMM_SMEM_ITEM_HEADER *)(CONST VOID *)Ptr;
+
+ // Validate canary - detects corruption or scan overrun.
+ if (SmemRd16 (&Ihdr->Canary) != (UINT16)QUALCOMM_SMEM_ITEM_CANARY) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ ItemSize = SmemRd32 (&Ihdr->Size);
+
+ // Size must be non-zero; PaddingData must not exceed Size.
+ if (ItemSize == 0U) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ((UINT32)SmemRd16 (&Ihdr->PaddingData) > ItemSize) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Step = sizeof (header) + PaddingHeader + ItemSize.
+ // A wrapped result is always < ItemSize; detect overflow.
+ //
+ Step = (UINT32)sizeof (QUALCOMM_SMEM_ITEM_HEADER) +
+ (UINT32)SmemRd16 (&Ihdr->PaddingHeader) +
+ ItemSize;
+ if (Step < ItemSize) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ((UINTN)Limit - (UINTN)Ptr < (UINTN)Step) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (SmemRd16 (&Ihdr->Item) == ItemId) {
+ //
+ // Found: payload starts after header + PaddingHeader.
+ // Cast away CONST: callers may write to the payload.
+ //
+ *Addr = (VOID *)(Ptr +
+ sizeof (QUALCOMM_SMEM_ITEM_HEADER) +
+ (UINTN)SmemRd16 (&Ihdr->PaddingHeader));
+ if (Size != NULL) {
+ *Size = (UINTN)(ItemSize - (UINTN)SmemRd16 (&Ihdr->PaddingData));
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ Ptr += (UINTN)Step;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Search a single partition for an item.
+
+ Retrieves the partition virtual address, validates the static header
+ fields (magic, size), issues a memory barrier, acquires the HW lock,
+ reads and validates the mutable heap pointers, then delegates to
+ SmemScanUncached().
+
+ The HW lock is released on every return path after a successful acquire.
+
+ @param[in] PartOffset Byte offset of the partition from SMEM base.
+ @param[in] PartSize Partition size in bytes.
+ @param[in] ItemId Item identifier to search for.
+ @param[out] Addr Set to the item payload address on success.
+ @param[out] Size Set to the item payload size on success (may be NULL).
+
+ @retval EFI_SUCCESS Item found.
+ @retval EFI_NOT_FOUND Item not found in uncached region.
+ @retval EFI_DEVICE_ERROR Corrupted partition metadata.
+ @retval EFI_ACCESS_DENIED Partition not mapped.
+**/
+static
+EFI_STATUS
+SmemSearchPartition (
+ IN UINT32 PartOffset,
+ IN UINT32 PartSize,
+ IN UINT16 ItemId,
+ OUT VOID **Addr,
+ OUT UINTN *Size OPTIONAL
+ )
+{
+ CONST QUALCOMM_SMEM_PARTITION_HEADER *Phdr;
+ VOID *Va;
+ EFI_STATUS Status;
+ UINT32 OffsetFreeUncached;
+ UINT32 OffsetFreeCached;
+ UINT32 MinUncached;
+
+ // Validate partition range before any memory access.
+ if (PartSize < (UINT32)sizeof (QUALCOMM_SMEM_PARTITION_HEADER)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ((UINT64)PartOffset + (UINT64)PartSize > (UINT64)mQualcommSmemInfo.SmemSize) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Va = QualcommSmemPlatGetAddr (PartOffset);
+ if (Va == NULL) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ Phdr = (CONST QUALCOMM_SMEM_PARTITION_HEADER *)Va;
+
+ //
+ // Validate static partition fields.
+ // Magic and Size are written once at partition creation time and
+ // never change, so they can be read without the HW lock.
+ //
+ if (SmemRd32 (&Phdr->Magic) != QUALCOMM_SMEM_PART_MAGIC) {
+ QualcommSmemPlatLogErr (
+ "smem: bad partition magic 0x%08x\n",
+ (unsigned int)SmemRd32 (&Phdr->Magic)
+ );
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (SmemRd32 (&Phdr->Size) != PartSize) {
+ QualcommSmemPlatLogErr (
+ "smem: partition size mismatch (header=%u toc=%u)\n",
+ (unsigned int)SmemRd32 (&Phdr->Size),
+ (unsigned int)PartSize
+ );
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Memory barrier before reading mutable partition metadata.
+ // Ensures writes by remote processors are visible on this core.
+ //
+ QualcommSmemPlatMemBarrier ();
+
+ //
+ // Acquire HW lock before reading mutable heap pointers.
+ // Remote processors update OffsetFreeUncached and OffsetFreeCached
+ // when allocating new items.
+ //
+ Status = QualcommSmemPlatHwlockAcquire ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Read mutable heap pointers under lock.
+ OffsetFreeUncached = SmemRd32 (&Phdr->OffsetFreeUncached);
+ OffsetFreeCached = SmemRd32 (&Phdr->OffsetFreeCached);
+
+ //
+ // Validate heap pointers:
+ // OffsetFreeUncached >= sizeof (QUALCOMM_SMEM_PARTITION_HEADER)
+ // OffsetFreeUncached <= OffsetFreeCached
+ // OffsetFreeCached <= PartSize
+ //
+ MinUncached = (UINT32)sizeof (QUALCOMM_SMEM_PARTITION_HEADER);
+ if ((OffsetFreeUncached < MinUncached) ||
+ (OffsetFreeUncached > OffsetFreeCached) ||
+ (OffsetFreeCached > PartSize))
+ {
+ QualcommSmemPlatHwlockRelease ();
+ QualcommSmemPlatLogErr (
+ "smem: invalid partition heap pointers uncached=%u cached=%u size=%u\n",
+ (unsigned int)OffsetFreeUncached,
+ (unsigned int)OffsetFreeCached,
+ (unsigned int)PartSize
+ );
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = SmemScanUncached (
+ (CONST UINT8 *)Va,
+ OffsetFreeUncached,
+ ItemId,
+ Addr,
+ Size
+ );
+
+ // Release HW lock on every return path after successful acquire.
+ QualcommSmemPlatHwlockRelease ();
+ return Status;
+}
+
+/**
+ Validate the BOOT SMEM version word.
+
+ Reads Ver[QUALCOMM_SMEM_VERSION_BOOT_OFFSET] from the static header and
+ checks that the major version matches QUALCOMM_SMEM_VERSION_ID. A minor
+ version mismatch is tolerated with a warning log.
+
+ Called from QualcommSmemInit() after the BOOT info page has been mapped.
+
+ @param[in] StaticHdr Pointer to the mapped BOOT info page.
+
+ @retval EFI_SUCCESS Major version matches.
+ @retval EFI_UNSUPPORTED Major version mismatch; SMEM layout is incompatible.
+**/
+static
+EFI_STATUS
+SmemValidateBootVersion (
+ IN CONST QUALCOMM_SMEM_STATIC_HEADER *StaticHdr
+ )
+{
+ UINT32 BootVersion;
+ UINT32 BootMajor;
+ UINT32 LocalMajor;
+
+ BootVersion = SmemRd32 (&StaticHdr->Ver[QUALCOMM_SMEM_VERSION_BOOT_OFFSET]);
+ BootMajor = BootVersion & QUALCOMM_SMEM_MAJOR_VERSION_MASK;
+ LocalMajor = QUALCOMM_SMEM_VERSION_ID & QUALCOMM_SMEM_MAJOR_VERSION_MASK;
+
+ if (BootMajor != LocalMajor) {
+ QualcommSmemPlatLogErr (
+ "smem: BOOT version major mismatch: got 0x%08x expected 0x%08x\n",
+ (unsigned int)BootVersion,
+ (unsigned int)LocalMajor
+ );
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Validate the TOC header and entry count.
+
+ Checks the TOC magic word, version, and NumEntries field. Writes the
+ validated entry count to *NumEntriesOut on success.
+
+ Called from QualcommSmemInit() after the TOC page has been mapped and a
+ memory barrier has been issued.
+
+ @param[in] Toc Pointer to the mapped TOC header.
+ @param[out] NumEntriesOut Receives the validated entry count.
+
+ @retval EFI_SUCCESS TOC header is valid; *NumEntriesOut is set.
+ @retval EFI_DEVICE_ERROR Bad magic or invalid entry count.
+ @retval EFI_UNSUPPORTED Unsupported TOC version.
+**/
+static
+EFI_STATUS
+SmemValidateTocHeader (
+ IN CONST QUALCOMM_SMEM_TOC_HEADER *Toc,
+ OUT UINT32 *NumEntriesOut
+ )
+{
+ UINT32 NumEntries;
+
+ if (SmemRd32 (&Toc->Magic) != QUALCOMM_SMEM_TOC_MAGIC) {
+ QualcommSmemPlatLogErr (
+ "smem: bad TOC magic 0x%08x\n",
+ (unsigned int)SmemRd32 (&Toc->Magic)
+ );
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (SmemRd32 (&Toc->Version) != QUALCOMM_SMEM_TOC_VERSION) {
+ QualcommSmemPlatLogErr (
+ "smem: unsupported TOC version %u\n",
+ (unsigned int)SmemRd32 (&Toc->Version)
+ );
+ return EFI_UNSUPPORTED;
+ }
+
+ NumEntries = SmemRd32 (&Toc->NumEntries);
+ if ((NumEntries == 0U) || (NumEntries > QUALCOMM_SMEM_TOC_MAX_ENTRIES)) {
+ QualcommSmemPlatLogErr (
+ "smem: invalid TOC NumEntries %u\n",
+ (unsigned int)NumEntries
+ );
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Entries array must fit within the TOC page.
+ if ((UINT32)sizeof (QUALCOMM_SMEM_TOC_HEADER) +
+ NumEntries * (UINT32)sizeof (QUALCOMM_SMEM_TOC_ENTRY) >
+ QUALCOMM_SMEM_TOC_SIZE)
+ {
+ QualcommSmemPlatLogErr ("smem: TOC entries overflow TOC page\n");
+ return EFI_DEVICE_ERROR;
+ }
+
+ *NumEntriesOut = NumEntries;
+ return EFI_SUCCESS;
+}
+
+/**
+ Walk the TOC, map local partitions, and cache the common partition.
+
+ Iterates over all NumEntries TOC entries. For each entry that:
+ - passes SmemValidateTocEntry() (bounds check), and
+ - passes SmemPartInvolvesLocal() (involves the local host),
+ the partition is mapped read-write via QualcommSmemPlatMap().
+
+ Additionally, if the common partition (Host0 == Host1 ==
+ QUALCOMM_SMEM_HOST_COMMON) is found, its offset and size are stored in
+ mQualcommSmemInfo for fast O(1) access by QualcommSmemLookup().
+
+ Unrelated partitions are deliberately not mapped to prevent speculative
+ CPU accesses to regions that may not be accessible from this security
+ domain.
+
+ Called from QualcommSmemInit() after mQualcommSmemInfo.LocalHost,
+ mQualcommSmemInfo.SmemSize, and mQualcommSmemInfo.NumTocEntries have been
+ populated.
+
+ @param[in] Entries Pointer to the first TOC entry.
+ @param[in] NumEntries Number of TOC entries to process.
+
+ @retval EFI_SUCCESS All relevant partitions mapped successfully.
+ @retval other First mapping failure; mQualcommSmemInfo is cleared by caller.
+**/
+static
+EFI_STATUS
+SmemMapPartitions (
+ IN CONST QUALCOMM_SMEM_TOC_ENTRY *Entries,
+ IN UINT32 NumEntries
+ )
+{
+ UINT32 Index;
+ EFI_STATUS Status;
+ CONST QUALCOMM_SMEM_TOC_ENTRY *Entry;
+
+ for (Index = 0U; Index < NumEntries; Index++) {
+ Entry = &Entries[Index];
+
+ if (EFI_ERROR (SmemValidateTocEntry (Entry))) {
+ continue; // skip malformed entries silently
+ }
+
+ if (!SmemPartInvolvesLocal (Entry)) {
+ continue; // not relevant partition - do not map
+ }
+
+ Status = QualcommSmemPlatMap (
+ SmemRd32 (&Entry->Offset),
+ (UINTN)SmemRd32 (&Entry->Size),
+ QUALCOMM_SMEM_PLAT_MAP_RW
+ );
+
+ if (EFI_ERROR (Status)) {
+ QualcommSmemPlatLogErr (
+ "smem: failed to map partition host0=%u host1=%u offset=%u: 0x%lx\n",
+ (unsigned int)SmemRd16 (&Entry->Host0),
+ (unsigned int)SmemRd16 (&Entry->Host1),
+ (unsigned int)SmemRd32 (&Entry->Offset),
+ (unsigned long)(UINTN)Status
+ );
+ return Status;
+ }
+
+ if ((SmemRd16 (&Entry->Host0) == (UINT16)QUALCOMM_SMEM_HOST_COMMON) &&
+ (SmemRd16 (&Entry->Host1) == (UINT16)QUALCOMM_SMEM_HOST_COMMON) &&
+ (mQualcommSmemInfo.CommonPartOffset == 0U))
+ {
+ mQualcommSmemInfo.CommonPartOffset = SmemRd32 (&Entry->Offset);
+ mQualcommSmemInfo.CommonPartSize = SmemRd32 (&Entry->Size);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+// -------------------------------------------------------------------------
+// Public API
+// -------------------------------------------------------------------------
+
+/**
+ Construct a SMEM host identifier.
+
+ Constructs a valid SMEM host identifier from the given parameters.
+ The internal bit encoding is an implementation detail; callers must
+ use this function rather than constructing host values directly.
+
+ @param[in] ProcId Processor ID (use QUALCOMM_SMEM_PROC_* macros).
+ @param[in] ProcNum Processor instance number.
+ @param[in] PdNum Protection-domain number.
+ @param[in] Chiplet Chiplet identifier.
+ @param[out] Host Output host identifier (must not be NULL).
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Host is NULL, any parameter is out of range,
+ or the encoded value would collide with a
+ reserved host identifier.
+**/
+EFI_STATUS
+EFIAPI
+QualcommSmemHostId (
+ IN UINT16 ProcId,
+ IN UINT16 ProcNum,
+ IN UINT16 PdNum,
+ IN UINT16 Chiplet,
+ OUT QUALCOMM_SMEM_HOST *Host
+ )
+{
+ UINT16 Encoded;
+
+ if (Host == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Range checks: each field must fit in its allocated bit-width.
+ if ((UINT32)ProcId > HOST_PROC_ID_MASK) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((UINT32)ProcNum > HOST_PROC_NUM_MASK) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((UINT32)PdNum > HOST_PD_NUM_MASK) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((UINT32)Chiplet > HOST_CHIPLET_MASK) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Encoded = (UINT16)(
+ ((UINT16)ProcId << HOST_PROC_ID_SHIFT) |
+ ((UINT16)ProcNum << HOST_PROC_NUM_SHIFT) |
+ ((UINT16)PdNum << HOST_PD_NUM_SHIFT) |
+ ((UINT16)Chiplet << HOST_CHIPLET_SHIFT));
+
+ //
+ // Reject any encoding that collides with a reserved/special host.
+ // These checks protect against accidental construction of reserved
+ // values even when the individual field ranges permit it.
+ //
+ if (Encoded == (UINT16)QUALCOMM_SMEM_HOST_COMMON) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Encoded == (UINT16)QUALCOMM_SMEM_HOST_INVALID) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Encoded == (UINT16)QUALCOMM_SMEM_HOST_MULTIHOST) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Host = (QUALCOMM_SMEM_HOST)Encoded;
+ return EFI_SUCCESS;
+}
+
+/**
+ Initialize the SMEM common core.
+
+ Performs the following steps:
+ 1. Calls QualcommSmemPlatInit() to obtain platform target parameters.
+ 2. Validates PlatInfo fields.
+ 3. Maps the first 4 KiB BOOT/static metadata page read-only.
+ 4. Calls SmemValidateBootVersion() to check the BOOT SMEM version.
+ 5. Maps the TOC page (last 4 KiB) read-only.
+ 6. Calls SmemValidateTocHeader() to check TOC magic/version/count.
+ 7. Calls SmemMapPartitions() to map local partitions and cache common.
+ 8. Marks the driver as initialized.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_ALREADY_STARTED Already initialized.
+ @retval other EFI_STATUS error code on failure.
+**/
+EFI_STATUS
+EFIAPI
+QualcommSmemInit (
+ VOID
+ )
+{
+ QUALCOMM_SMEM_PLAT_INFO PlatInfo;
+ CONST QUALCOMM_SMEM_STATIC_HEADER *StaticHdr;
+ CONST QUALCOMM_SMEM_TOC_HEADER *Toc;
+ CONST QUALCOMM_SMEM_TOC_ENTRY *Entries;
+ VOID *Va;
+ UINT32 SmemSize;
+ UINT32 TocOffset;
+ UINT32 NumEntries;
+ EFI_STATUS Status;
+
+ if (mQualcommSmemInfo.Initialized) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ // Step 1: obtain platform target parameters.
+ Status = QualcommSmemPlatInit (&PlatInfo);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Step 2: validate PlatInfo fields.
+ if (PlatInfo.LocalHost == (QUALCOMM_SMEM_HOST)QUALCOMM_SMEM_HOST_INVALID) {
+ QualcommSmemPlatLogErr ("smem: invalid LocalHost\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // SmemSize must hold at least the BOOT info page and the TOC page
+ // without overlap. The constant sum cannot overflow UINTN.
+ //
+ if (PlatInfo.SmemSize <
+ (UINTN)(QUALCOMM_SMEM_BOOT_INFO_SIZE + QUALCOMM_SMEM_TOC_SIZE))
+ {
+ QualcommSmemPlatLogErr ("smem: SmemSize too small\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // SmemSize must fit in UINT32 (offsets are UINT32).
+ if (PlatInfo.SmemSize > (UINTN)(UINT32)(-1)) {
+ QualcommSmemPlatLogErr ("smem: SmemSize exceeds UINT32\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (PlatInfo.MaxItems == 0U) {
+ QualcommSmemPlatLogErr ("smem: MaxItems is zero\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SmemSize = (UINT32)PlatInfo.SmemSize;
+ TocOffset = SmemSize - QUALCOMM_SMEM_TOC_SIZE;
+
+ // Step 3: map the BOOT/static metadata page read-only.
+ Status = QualcommSmemPlatMap (
+ 0U,
+ QUALCOMM_SMEM_BOOT_INFO_SIZE,
+ QUALCOMM_SMEM_PLAT_MAP_RO
+ );
+
+ if (EFI_ERROR (Status)) {
+ QualcommSmemPlatLogErr (
+ "smem: failed to map BOOT info: 0x%lx\n",
+ (unsigned long)(UINTN)Status
+ );
+ return Status;
+ }
+
+ Va = QualcommSmemPlatGetAddr (0U);
+ if (Va == NULL) {
+ QualcommSmemPlatLogErr ("smem: BOOT info not mapped\n");
+ return EFI_DEVICE_ERROR;
+ }
+
+ StaticHdr = (CONST QUALCOMM_SMEM_STATIC_HEADER *)Va;
+
+ // Step 4: validate the BOOT SMEM version.
+ Status = SmemValidateBootVersion (StaticHdr);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Step 5: map the TOC page read-only.
+ Status = QualcommSmemPlatMap (
+ TocOffset,
+ QUALCOMM_SMEM_TOC_SIZE,
+ QUALCOMM_SMEM_PLAT_MAP_RO
+ );
+
+ if (EFI_ERROR (Status)) {
+ QualcommSmemPlatLogErr (
+ "smem: failed to map TOC: 0x%lx\n",
+ (unsigned long)(UINTN)Status
+ );
+ return Status;
+ }
+
+ Va = QualcommSmemPlatGetAddr (TocOffset);
+ if (Va == NULL) {
+ QualcommSmemPlatLogErr ("smem: TOC not mapped\n");
+ return EFI_DEVICE_ERROR;
+ }
+
+ Toc = (CONST QUALCOMM_SMEM_TOC_HEADER *)Va;
+ Entries = (CONST QUALCOMM_SMEM_TOC_ENTRY *)
+ ((CONST UINT8 *)Va + sizeof (QUALCOMM_SMEM_TOC_HEADER));
+
+ // Memory barrier before reading shared-memory metadata.
+ QualcommSmemPlatMemBarrier ();
+
+ // Step 6: validate the TOC header.
+ Status = SmemValidateTocHeader (Toc, &NumEntries);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Populate mQualcommSmemInfo fields needed by SmemValidateTocEntry(),
+ // SmemPartInvolvesLocal(), and SmemMapPartitions() before calling them.
+ //
+ mQualcommSmemInfo.LocalHost = PlatInfo.LocalHost;
+ mQualcommSmemInfo.MaxItems = PlatInfo.MaxItems;
+ mQualcommSmemInfo.SmemSize = SmemSize;
+ mQualcommSmemInfo.TocOffset = TocOffset;
+ mQualcommSmemInfo.NumTocEntries = NumEntries;
+
+ //
+ // Step 7: map local partitions and cache the common partition.
+ //
+ // SmemMapPartitions() walks the TOC, maps every partition that
+ // involves the local host, and stores the common partition offset
+ // and size in mQualcommSmemInfo for fast O(1) access.
+ //
+ Status = SmemMapPartitions (Entries, NumEntries);
+ if (EFI_ERROR (Status)) {
+ // Roll back partially populated state.
+ ZeroMem (&mQualcommSmemInfo, sizeof (mQualcommSmemInfo));
+ return Status;
+ }
+
+ // Step 8: mark driver as initialized.
+ mQualcommSmemInfo.Initialized = TRUE;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Look up an existing SMEM item.
+
+ Fast path (QUALCOMM_SMEM_HOST_COMMON):
+ Uses the cached CommonPartOffset / CommonPartSize from mQualcommSmemInfo
+ to call SmemSearchPartition() directly, bypassing the TOC walk.
+
+ Slow path (edge-pair host):
+ Walks the TOC to find a partition matching the requested host pair,
+ then calls SmemSearchPartition() for the first matching entry.
+
+ @param[in] RemoteHost Remote host for a host-pair partition, or
+ QUALCOMM_SMEM_HOST_COMMON for the common partition.
+ @param[in] Item SMEM item ID.
+ @param[in] Flags Must be QUALCOMM_SMEM_FLAG_NONE.
+ @param[out] ItemPtr Pointer to item payload (must not be NULL).
+ @param[out] ItemSize Size of item payload in bytes (may be NULL).
+
+ @retval EFI_SUCCESS ItemPtr points to item payload.
+ @retval EFI_INVALID_PARAMETER Invalid argument.
+ @retval EFI_NOT_STARTED Driver not initialized.
+ @retval EFI_NOT_FOUND Item or partition not found.
+ @retval EFI_ACCESS_DENIED Partition not mapped.
+ @retval EFI_DEVICE_ERROR Corrupted shared-memory metadata.
+**/
+EFI_STATUS
+EFIAPI
+QualcommSmemLookup (
+ IN QUALCOMM_SMEM_HOST RemoteHost,
+ IN UINT16 Item,
+ IN UINT32 Flags,
+ OUT VOID **ItemPtr,
+ OUT UINTN *ItemSize OPTIONAL
+ )
+{
+ CONST QUALCOMM_SMEM_TOC_ENTRY *Entries;
+ CONST QUALCOMM_SMEM_TOC_ENTRY *Entry;
+ VOID *TocVa;
+ UINT32 Index;
+ EFI_STATUS Status;
+
+ // Validate arguments.
+ if (ItemPtr == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (RemoteHost == QUALCOMM_SMEM_HOST_INVALID) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Flags != 0U) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!mQualcommSmemInfo.Initialized) {
+ return EFI_NOT_STARTED;
+ }
+
+ if ((UINT32)Item >= (UINT32)mQualcommSmemInfo.MaxItems) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Fast path: common partition lookup.
+ //
+ // The common partition offset and size were cached during
+ // QualcommSmemInit() by SmemMapPartitions(). Use them directly
+ // to avoid walking the TOC on every common-partition lookup.
+ //
+ // If no common partition was found during init (CommonPartOffset == 0
+ // and CommonPartSize == 0), fall through to the TOC walk which will
+ // also return EFI_NOT_FOUND.
+ //
+ if (RemoteHost == QUALCOMM_SMEM_HOST_COMMON) {
+ if ((mQualcommSmemInfo.CommonPartOffset != 0U) ||
+ (mQualcommSmemInfo.CommonPartSize != 0U))
+ {
+ return SmemSearchPartition (
+ mQualcommSmemInfo.CommonPartOffset,
+ mQualcommSmemInfo.CommonPartSize,
+ Item,
+ ItemPtr,
+ ItemSize
+ );
+ }
+
+ // No common partition mapped - item cannot exist.
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Slow path: edge-pair partition lookup.
+ //
+ // Walk the TOC looking for a partition matching {LocalHost, RemoteHost}.
+ // First matching valid partition wins.
+ //
+ TocVa = QualcommSmemPlatGetAddr (mQualcommSmemInfo.TocOffset);
+ if (TocVa == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Entries = (CONST QUALCOMM_SMEM_TOC_ENTRY *)
+ ((CONST UINT8 *)TocVa + sizeof (QUALCOMM_SMEM_TOC_HEADER));
+
+ // Memory barrier before reading TOC metadata.
+ QualcommSmemPlatMemBarrier ();
+
+ for (Index = 0U; Index < mQualcommSmemInfo.NumTocEntries; Index++) {
+ Entry = &Entries[Index];
+
+ if (EFI_ERROR (SmemValidateTocEntry (Entry))) {
+ continue;
+ }
+
+ if (!SmemPartMatches (Entry, RemoteHost)) {
+ continue;
+ }
+
+ Status = SmemSearchPartition (
+ SmemRd32 (&Entry->Offset),
+ SmemRd32 (&Entry->Size),
+ Item,
+ ItemPtr,
+ ItemSize
+ );
+
+ if (Status != EFI_NOT_FOUND) {
+ return Status; // found, or hard error
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
diff --git a/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemLib.inf b/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemLib.inf new file mode 100644 index 0000000000..08d2056995 --- /dev/null +++ b/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemLib.inf @@ -0,0 +1,41 @@ +## @file +# Qualcomm Shared memory (SMEM) library for UEFI. +# +# This library provides shared memory management functionality for UEFI +# firmware, including allocation, retrieval, and partition management. +# +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# @par Glossary: +# - SMEM - Shared Memory +## + +[Defines] + INF_VERSION = 1.30 + BASE_NAME = QualcommSmemLib + FILE_GUID = 9568C37C-9CAD-4B5F-8B3E-83CDCCF4057E + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = QualcommSmemLib + +# +# VALID_ARCHITECTURES = AARCH64 +# +[Sources.common] + QualcommSmemLib.c + QualcommSmemPlatform.c + +[LibraryClasses] + BaseLib + PcdLib + QualcommSmemLib + +[Packages] + MdePkg/MdePkg.dec + QualcommSiliconPkg/QualcommSiliconPkg.dec + +[FixedPcd] + gQualcommSiliconPkgTokenSpaceGuid.PcdSmemBaseAddress + gQualcommSiliconPkgTokenSpaceGuid.PcdSmemSize + gQualcommSiliconPkgTokenSpaceGuid.PcdSmemMaxItems diff --git a/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemLibNull.c b/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemLibNull.c new file mode 100644 index 0000000000..5fa6c50450 --- /dev/null +++ b/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemLibNull.c @@ -0,0 +1,77 @@ +/** @file
+ NULL implementation of the Qualcomm Shared Memory (SMEM) library.
+
+ All functions return safe default values suitable for platforms
+ where SMEM is not available.
+
+ Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - SMEM - Shared Memory
+**/
+
+#include <Library/QualcommSmemLib.h>
+
+/**
+ Construct a SMEM host identifier.
+
+ @param[in] ProcId Processor ID (use QUALCOMM_SMEM_PROC_* macros).
+ @param[in] ProcNum Processor instance number.
+ @param[in] PdNum Protection-domain number.
+ @param[in] Chiplet Chiplet identifier.
+ @param[out] Host Output host identifier (must not be NULL).
+
+ @retval EFI_UNSUPPORTED Always returns unsupported in this NULL implementation.
+**/
+EFI_STATUS
+EFIAPI
+QualcommSmemHostId (
+ IN UINT16 ProcId,
+ IN UINT16 ProcNum,
+ IN UINT16 PdNum,
+ IN UINT16 Chiplet,
+ OUT QUALCOMM_SMEM_HOST *Host
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Initialize the SMEM common core.
+
+ @retval EFI_SUCCESS Always returns success in this NULL implementation.
+**/
+EFI_STATUS
+EFIAPI
+QualcommSmemInit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ Look up an existing SMEM item.
+
+ @param[in] RemoteHost Remote host for a host-pair partition, or
+ QUALCOMM_SMEM_HOST_COMMON for the common partition.
+ @param[in] Item SMEM item ID.
+ @param[in] Flags Must be QUALCOMM_SMEM_FLAG_NONE.
+ @param[out] ItemPtr Pointer to item payload (must not be NULL).
+ @param[out] ItemSize Size of item payload in bytes (may be NULL).
+
+ @retval EFI_NOT_FOUND Always returns not found in this NULL implementation.
+**/
+EFI_STATUS
+EFIAPI
+QualcommSmemLookup (
+ IN QUALCOMM_SMEM_HOST RemoteHost,
+ IN UINT16 Item,
+ IN UINT32 Flags,
+ OUT VOID **ItemPtr,
+ OUT UINTN *ItemSize OPTIONAL
+ )
+{
+ return EFI_NOT_FOUND;
+}
diff --git a/Silicon/Qualcomm/QualcommSiliconPkg/Library/SmemLib/SmemLibNull.inf b/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemLibNull.inf index 4eacbab569..88386be762 100644 --- a/Silicon/Qualcomm/QualcommSiliconPkg/Library/SmemLib/SmemLibNull.inf +++ b/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemLibNull.inf @@ -1,33 +1,33 @@ -## @file
-# Qualcomm Shared memory (SMEM) library for UEFI.
-#
-# This library provides shared memory management functionality for UEFI
-# firmware, including allocation, retrieval, and partition management.
-#
-# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved.
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-# @par Glossary:
-# - SMEM - Shared Memory
-##
-
-[Defines]
- INF_VERSION = 1.30
- BASE_NAME = SmemLib
- FILE_GUID = 9568C37C-9CAD-4B5F-8B3E-83CDCCF4057E
- MODULE_TYPE = BASE
- VERSION_STRING = 1.0
- LIBRARY_CLASS = SmemLib
-
-#
-# VALID_ARCHITECTURES = AARCH64
-#
-[Sources.common]
- SmemLibNull.c
-
-[LibraryClasses]
- BaseLib
-
-[Packages]
- MdePkg/MdePkg.dec
- Silicon/Qualcomm/QualcommSiliconPkg/QualcommSiliconPkg.dec
+## @file +# Qualcomm Shared memory (SMEM) library for UEFI. +# +# This library provides shared memory management functionality for UEFI +# firmware, including allocation, retrieval, and partition management. +# +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# @par Glossary: +# - SMEM - Shared Memory +## + +[Defines] + INF_VERSION = 1.30 + BASE_NAME = QualcommSmemLibNull + FILE_GUID = 9568C37C-9CAD-4B5F-8B3E-83CDCCF4057E + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = QualcommSmemLib + +# +# VALID_ARCHITECTURES = AARCH64 +# +[Sources.common] + QualcommSmemLibNull.c + +[LibraryClasses] + BaseLib + +[Packages] + MdePkg/MdePkg.dec + QualcommSiliconPkg/QualcommSiliconPkg.dec diff --git a/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemPlatform.c b/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemPlatform.c new file mode 100644 index 0000000000..aec942f884 --- /dev/null +++ b/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemPlatform.c @@ -0,0 +1,187 @@ +/** @file
+ Qualcomm Shared Memory (SMEM) - UEFI platform integration layer.
+
+ Implements the platform abstraction interface declared in QualcommSmemPlatform.h for
+ UEFI environments. SMEM is statically mapped as part of the QTI device
+ region; physical and virtual addresses are identical (1:1 mapping).
+
+ @par Glossary
+ - SMEM - Shared Memory
+ - Pa - Physical Address
+ - Va - Virtual Address
+ - Toc - Table of Contents
+
+ Copyright (C) Qualcomm Technologies, Inc. and/or its subsidiaries.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/ArmLib.h>
+#include <Library/PcdLib.h>
+#include "QualcommSmemLib.h"
+#include "QualcommSmemPlatform.h"
+
+/**
+ Map a region of SMEM into the virtual address space.
+
+ SMEM is statically mapped as part of the QTI device region; no additional
+ mapping is required. Validates that Offset + Size does not exceed the SMEM
+ region size.
+
+ @param[in] Offset Byte offset from the SMEM physical base.
+ @param[in] Size Number of bytes to map.
+ @param[in] Flags QUALCOMM_SMEM_PLAT_MAP_RO or QUALCOMM_SMEM_PLAT_MAP_RW.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Offset + Size exceeds the SMEM region.
+**/
+EFI_STATUS
+EFIAPI
+QualcommSmemPlatMap (
+ IN UINT32 Offset,
+ IN UINTN Size,
+ IN UINT32 Flags
+ )
+{
+ if ((UINT64)Offset + (UINT64)Size > FixedPcdGet32 (PcdSmemSize)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Translate an SMEM offset to a virtual address.
+
+ SMEM is statically mapped with a 1:1 physical-to-virtual mapping, so the
+ virtual address is computed directly from the physical base and offset.
+
+ @param[in] Offset Byte offset from the SMEM physical base.
+
+ @return Virtual address corresponding to Offset; NULL if Offset is invalid.
+**/
+VOID *
+EFIAPI
+QualcommSmemPlatGetAddr (
+ IN UINT32 Offset
+ )
+{
+ if ((UINTN)Offset >= (UINTN)FixedPcdGet32 (PcdSmemSize)) {
+ return NULL;
+ }
+
+ return (VOID *)(UINTN)(FixedPcdGet64 (PcdSmemBaseAddress) + (UINT64)Offset);
+}
+
+/**
+ Platform entry point for SMEM initialization.
+
+ Discovers SMEM target parameters and writes them into PlatInfo. The local
+ host is set to the Trust-Zone processor identity; MaxItems and SmemSize are
+ taken from the platform's fixed-at-build PCDs.
+
+ @param[out] PlatInfo Caller-allocated struct to fill with parameters.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER PlatInfo is NULL.
+ @retval EFI_DEVICE_ERROR Host identifier construction failed.
+**/
+EFI_STATUS
+EFIAPI
+QualcommSmemPlatInit (
+ OUT QUALCOMM_SMEM_PLAT_INFO *PlatInfo
+ )
+{
+ EFI_STATUS Status;
+
+ if (PlatInfo == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = QualcommSmemHostId (
+ QUALCOMM_SMEM_PROC_TZ,
+ 0U,
+ 0U,
+ 0U,
+ &PlatInfo->LocalHost
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ PlatInfo->MaxItems = FixedPcdGet16 (PcdSmemMaxItems);
+ PlatInfo->SmemSize = FixedPcdGet32 (PcdSmemSize);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Full memory barrier.
+
+ Issues a data memory barrier to ensure that all preceding memory accesses
+ are globally visible before any subsequent accesses.
+**/
+VOID
+EFIAPI
+QualcommSmemPlatMemBarrier (
+ VOID
+ )
+{
+ ArmDataMemoryBarrier ();
+}
+
+/**
+ Acquire the SMEM serialisation lock.
+
+ In this stub implementation the lock is always immediately available.
+
+ @retval EFI_SUCCESS Always.
+**/
+EFI_STATUS
+EFIAPI
+QualcommSmemPlatHwlockAcquire (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ Release the SMEM serialisation lock.
+**/
+VOID
+EFIAPI
+QualcommSmemPlatHwlockRelease (
+ VOID
+ )
+{
+}
+
+/**
+ Log an error-level message.
+
+ @param[in] Fmt printf-style format string.
+ @param[in] ... Variadic arguments.
+**/
+VOID
+EFIAPI
+QualcommSmemPlatLogErr (
+ IN CONST CHAR8 *Fmt,
+ ...
+ )
+{
+}
+
+/**
+ Log a debug-level message.
+
+ @param[in] Fmt printf-style format string.
+ @param[in] ... Variadic arguments.
+**/
+VOID
+EFIAPI
+QualcommSmemPlatLogDbg (
+ IN CONST CHAR8 *Fmt,
+ ...
+ )
+{
+}
diff --git a/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemPlatform.h b/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemPlatform.h new file mode 100644 index 0000000000..cd89ace580 --- /dev/null +++ b/Silicon/Qualcomm/QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemPlatform.h @@ -0,0 +1,225 @@ +/** @file
+ Qualcomm Shared Memory (SMEM) - Internal platform abstraction interface.
+
+ Mapping contract
+ ----------------
+ The platform must reserve a contiguous virtual-address window for the
+ entire SMEM physical range before QualcommSmemInit() is called. The
+ window is reserved but not backed by page-table entries.
+
+ QualcommSmemPlatMap() is called by the SMEM core to install page-table
+ entries for specific sub-ranges (BOOT info page, TOC page, individual
+ partitions). The virtual address returned by QualcommSmemPlatGetAddr()
+ must satisfy:
+
+ VA(Offset) == SmemReservedVaBase + Offset
+
+ so that the core can compute partition VAs from offsets without any
+ additional translation.
+
+ Successful mappings are kept alive for the lifetime of the driver.
+ There is no unmap path in the common core.
+
+ @par Glossary
+ - Smem - Shared Memory
+ - Toc - Table of Contents
+ - Va - Virtual Address
+ - Pa - Physical Address
+ - Abi - Application Binary Interface
+
+ Copyright (C) Qualcomm Technologies, Inc. and/or its subsidiaries.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#pragma once
+
+#include <Library/BaseMemoryLib.h>
+#include "QualcommSmemLib.h"
+
+// -------------------------------------------------------------------------
+// Mapping attribute flags passed to QualcommSmemPlatMap().
+// -------------------------------------------------------------------------
+
+/// Install a read-only mapping.
+#define QUALCOMM_SMEM_PLAT_MAP_RO 0x1U
+
+/// Install a read-write mapping.
+#define QUALCOMM_SMEM_PLAT_MAP_RW 0x2U
+
+// -------------------------------------------------------------------------
+// Platform target information
+// -------------------------------------------------------------------------
+
+//
+// QUALCOMM_SMEM_PLAT_INFO - platform-supplied SMEM target parameters.
+//
+typedef struct {
+ QUALCOMM_SMEM_HOST LocalHost; ///< Local processor host ID.
+ UINT16 MaxItems; ///< Exclusive upper bound for item IDs.
+ UINTN SmemSize; ///< Total SMEM region size in bytes.
+} QUALCOMM_SMEM_PLAT_INFO;
+
+// -------------------------------------------------------------------------
+// Internal init API (not exposed in the public header)
+// -------------------------------------------------------------------------
+
+/**
+ Initialize the SMEM common core.
+
+ Called by platform boot integration code after the platform has
+ reserved the SMEM virtual address window. Internally calls
+ QualcommSmemPlatInit() to obtain platform target parameters, then
+ maps and validates the BOOT info page, TOC, and relevant partitions.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_ALREADY_STARTED Already initialized.
+ @retval other EFI_STATUS error code on failure.
+**/
+EFI_STATUS
+EFIAPI
+QualcommSmemInit (
+ VOID
+ );
+
+// -------------------------------------------------------------------------
+// Platform operation interface
+//
+// Implemented once per platform in QualcommSmemPlatform.c.
+// The common core calls these; it does not know PA/VA/MMU details.
+// -------------------------------------------------------------------------
+
+/**
+ Platform entry point for SMEM initialization.
+
+ Discovers SMEM target parameters (PA base, size, MaxItems, local host)
+ from WONCE registers or device tree and writes them into PlatInfo.
+
+ PA base and VA base are stored in platform-private state only.
+
+ @param[out] PlatInfo Caller-allocated struct to fill with parameters.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER PlatInfo is NULL.
+ @retval EFI_DEVICE_ERROR Target info is unavailable or corrupted.
+**/
+EFI_STATUS
+EFIAPI
+QualcommSmemPlatInit (
+ OUT QUALCOMM_SMEM_PLAT_INFO *PlatInfo
+ );
+
+/**
+ Map a region of SMEM into the virtual address space.
+
+ The platform converts the offset to physical and virtual addresses:
+ PA = SmemPaBase + Offset
+ VA = SmemReservedVaBase + Offset
+
+ Must be idempotent: if the range is already mapped with compatible
+ permissions, return EFI_SUCCESS without error.
+
+ Must validate that Offset + Size does not exceed SmemSize.
+
+ @param[in] Offset Byte offset from the SMEM physical base.
+ @param[in] Size Number of bytes to map.
+ @param[in] Flags QUALCOMM_SMEM_PLAT_MAP_RO or QUALCOMM_SMEM_PLAT_MAP_RW.
+
+ @retval EFI_SUCCESS Success.
+ @retval other EFI_STATUS error code on failure.
+**/
+EFI_STATUS
+EFIAPI
+QualcommSmemPlatMap (
+ IN UINT32 Offset,
+ IN UINTN Size,
+ IN UINT32 Flags
+ );
+
+/**
+ Translate an SMEM offset to a virtual address.
+
+ Returns the virtual address corresponding to the given offset within
+ the pre-reserved SMEM virtual address window. Must not perform any
+ new mapping; the region must have been mapped by QualcommSmemPlatMap()
+ before this function is called.
+
+ @param[in] Offset Byte offset from the SMEM physical base.
+
+ @return Virtual address on success; NULL if the offset is invalid or
+ the region has not been mapped.
+**/
+VOID *
+EFIAPI
+QualcommSmemPlatGetAddr (
+ IN UINT32 Offset
+ );
+
+/**
+ Full memory barrier.
+
+ Ensures that all preceding memory accesses are globally visible before
+ any subsequent accesses. Used before reading mutable shared-memory
+ metadata that may have been written by a remote processor.
+**/
+VOID
+EFIAPI
+QualcommSmemPlatMemBarrier (
+ VOID
+ );
+
+/**
+ Acquire the SMEM serialisation lock.
+
+ Must serialise concurrent calls to QualcommSmemLookup() on the local
+ processor. Production ports should also acquire the SMEM hardware
+ spinlock to serialise against remote writers that update partition
+ heap pointers when allocating new items.
+
+ Do NOT hold this lock during MMU mapping operations.
+
+ @retval EFI_SUCCESS Success.
+ @retval other EFI_STATUS error code on failure.
+**/
+EFI_STATUS
+EFIAPI
+QualcommSmemPlatHwlockAcquire (
+ VOID
+ );
+
+/**
+ Release the SMEM serialisation lock.
+
+ Must be called on every return path after a successful
+ QualcommSmemPlatHwlockAcquire().
+**/
+VOID
+EFIAPI
+QualcommSmemPlatHwlockRelease (
+ VOID
+ );
+
+/**
+ Log an error-level message.
+
+ @param[in] Fmt printf-style format string.
+ @param[in] ... Variadic arguments.
+**/
+VOID
+EFIAPI
+QualcommSmemPlatLogErr (
+ IN CONST CHAR8 *Fmt,
+ ...
+ );
+
+/**
+ Log a debug-level message.
+
+ @param[in] Fmt printf-style format string.
+ @param[in] ... Variadic arguments.
+**/
+VOID
+EFIAPI
+QualcommSmemPlatLogDbg (
+ IN CONST CHAR8 *Fmt,
+ ...
+ );
diff --git a/Silicon/Qualcomm/QualcommSiliconPkg/Library/SmemLib/SmemLibNull.c b/Silicon/Qualcomm/QualcommSiliconPkg/Library/SmemLib/SmemLibNull.c deleted file mode 100644 index e1ee18ede1..0000000000 --- a/Silicon/Qualcomm/QualcommSiliconPkg/Library/SmemLib/SmemLibNull.c +++ /dev/null @@ -1,145 +0,0 @@ -/** @file
- NULL implementation of the Qualcomm Shared Memory (SMEM) library.
-
- All functions return safe default values suitable for platforms
- where SMEM is not available.
-
- Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Glossary:
- - SMEM - Shared Memory
-**/
-
-#include <Base.h>
-#include <Library/SmemLib.h>
-
-/**
- Get SMEM library version.
-
- @retval SMEM_LIB_VERSION_NULL Always returns the NULL instance version.
-**/
-UINT32
-EFIAPI
-SmemLibGetVersion (
- VOID
- )
-{
- return SMEM_LIB_VERSION_NULL;
-}
-
-/**
- Initializes the shared memory allocation structures.
-
- @par Dependencies
- Shared memory must have been cleared and initialized by the first system
- bootloader before calling this function.
-**/
-VOID
-EFIAPI
-SmemInit (
- VOID
- )
-{
-}
-
-/**
- Requests a pointer to a buffer in shared memory.
-
- @param[in] SmemType Type of memory.
- @param[in] BufSize Size of the buffer requested.
-
- @retval NULL Always returns NULL in this NULL implementation.
-**/
-VOID *
-EFIAPI
-SmemAlloc (
- IN SMEM_MEM_TYPE SmemType,
- IN UINT32 BufSize
- )
-{
- return NULL;
-}
-
-/**
- Requests a pointer to a buffer in shared memory.
-
- @param[in, out] Params See definition of SMEM_ALLOC_PARAMS_TYPE for details.
-
- @retval SMEM_STATUS_FAILURE Always returns failure in this NULL implementation.
-**/
-INT32
-EFIAPI
-SmemAllocEx (
- IN OUT SMEM_ALLOC_PARAMS_TYPE *Params
- )
-{
- return SMEM_STATUS_FAILURE;
-}
-
-/**
- Requests the address of an allocated buffer in shared memory.
-
- @param[in] SmemType Type of memory to get a pointer for.
- @param[out] BufSize Size of buffer allocated in shared memory.
-
- @retval NULL Always returns NULL in this NULL implementation.
-**/
-VOID *
-EFIAPI
-SmemGetAddr (
- IN SMEM_MEM_TYPE SmemType,
- OUT UINT32 *BufSize
- )
-{
- return NULL;
-}
-
-/**
- Requests the address and size of an allocated buffer in shared memory.
-
- @param[in, out] Params See definition of SMEM_ALLOC_PARAMS_TYPE for details.
-
- @retval SMEM_STATUS_FAILURE Always returns failure in this NULL implementation.
-**/
-INT32
-EFIAPI
-SmemGetAddrEx (
- IN OUT SMEM_ALLOC_PARAMS_TYPE *Params
- )
-{
- return SMEM_STATUS_FAILURE;
-}
-
-/**
- Frees a pointer in shared memory.
-
- @param[in] Addr Pointer to the shared memory block to be freed.
-**/
-VOID
-EFIAPI
-SmemFree (
- IN VOID *Addr
- )
-{
-}
-
-/**
- Sets the version number for this processor and a given object.
-
- @param[in] Type Type of object being version checked.
- @param[in] Version Local version number for this memory object.
- @param[in] Mask Bitwise AND mask for version comparison.
-
- @retval TRUE Always returns TRUE in this NULL implementation.
-**/
-BOOLEAN
-EFIAPI
-SmemVersionSet (
- IN SMEM_MEM_TYPE Type,
- IN UINT32 Version,
- IN UINT32 Mask
- )
-{
- return TRUE;
-}
diff --git a/Silicon/Qualcomm/QualcommSiliconPkg/QualcommSiliconPkg.dec b/Silicon/Qualcomm/QualcommSiliconPkg/QualcommSiliconPkg.dec index 6e38478ae1..473c0d8445 100644 --- a/Silicon/Qualcomm/QualcommSiliconPkg/QualcommSiliconPkg.dec +++ b/Silicon/Qualcomm/QualcommSiliconPkg/QualcommSiliconPkg.dec @@ -24,6 +24,10 @@ [Includes.common]
Include
+ Include/Library
+
+[LibraryClasses]
+ QualcommSmemLib|Include/Library/QualcommSmemLib.h
[Guids]
gQualcommSiliconPkgTokenSpaceGuid = {0x648ed5f4, 0x6e90, 0x11f1, {0xad, 0xee, 0x5b, 0x58, 0x90, 0x85, 0x09, 0x0b}}
@@ -51,19 +55,3 @@ ## Maximum number of SMEM items that can be allocated.
# @Prompt SMEM Maximum Items
gQualcommSiliconPkgTokenSpaceGuid.PcdSmemMaxItems | 0 | UINT16 | 0xA1000003
-
- ## Base address of Top-Level Control and Status Register (TCSR).
- # @Prompt SMEM TCSR Base Address
- gQualcommSiliconPkgTokenSpaceGuid.PcdSmemTcsrBase | 0x0 | UINT32 | 0xA1000004
-
- ## Base address of hardware mutex registers for SMEM synchronization.
- # @Prompt SMEM Mutex Register Base
- gQualcommSiliconPkgTokenSpaceGuid.PcdSmemMutexRegBase | 0x0 | UINT32 | 0xA1000005
-
- ## Base address of Write-Once (WONCE) registers.
- # @Prompt SMEM WONCE Register Base
- gQualcommSiliconPkgTokenSpaceGuid.PcdSmemWonceRegBase | 0x0 | UINT32 | 0xA1000006
-
- ## Offset of target information register within WONCE space.
- # @Prompt SMEM Target Info WONCE Register
- gQualcommSiliconPkgTokenSpaceGuid.PcdSmemTargetInfoWonceReg | 0x0 | UINT32 | 0xA1000007
diff --git a/Silicon/Qualcomm/QualcommSiliconPkg/QualcommSiliconPkg.dsc.inc b/Silicon/Qualcomm/QualcommSiliconPkg/QualcommSiliconPkg.dsc.inc index 84d55a3cfd..20117c3465 100644 --- a/Silicon/Qualcomm/QualcommSiliconPkg/QualcommSiliconPkg.dsc.inc +++ b/Silicon/Qualcomm/QualcommSiliconPkg/QualcommSiliconPkg.dsc.inc @@ -8,4 +8,4 @@ ##
[LibraryClasses.common]
- SmemLib|QualcommSiliconPkg/Library/SmemLib/SmemLibNull.inf
+ QualcommSmemLib|QualcommSiliconPkg/Library/QualcommSmemLib/QualcommSmemLib.inf
|
