/**
* @file PcRtc.h
*
* @brief PcRtc - PC-AT Real-Time Clock Runtime DXE Driver
*
* UEFI Runtime DXE driver that implements the EFI RealTimeClock services
* (GetTime, SetTime, GetWakeupTime, SetWakeupTime) by accessing the
* CMOS RTC hardware via legacy I/O ports 0x70/0x71.
*
* Source: PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/
* Files: PcRtcEntry.c, PcRtc.c, AutoGen.c
*
* This driver is part of the HR650X BIOS PcRtc module (index 0034).
*/
#ifndef PC_RTC_H_
#define PC_RTC_H_
#include "../uefi_headers/Uefi.h"
// =========================================================================
// GUID Definitions
// =========================================================================
// -------------------------------------------------------------------------
// DebugLib Protocol GUID (UBA Platform Debug Library)
// 36232936-0E76-31C8-A13A-3AF2FC1C3932
// Located at .data +0x0000 (VA 0x5000)
// -------------------------------------------------------------------------
#define DEBUGLIB_PROTOCOL_GUID \
{ 0x36232936, 0x0E76, 0x31C8, \
{ 0xA1, 0x3A, 0x3A, 0xF2, 0xFC, 0x1C, 0x39, 0x32 } }
// -------------------------------------------------------------------------
// HOB List GUID (Standard UEFI Hand-Off Block list)
// 7739F24C-93D7-11D4-9A3A-0090273FC14D
// Located at .data +0x0050 (VA 0x5050)
// -------------------------------------------------------------------------
#define HOB_LIST_GUID \
{ 0x7739F24C, 0x93D7, 0x11D4, \
{ 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }
// -------------------------------------------------------------------------
// Real-Time Clock Architecture Protocol GUID (customized variant)
// NOTE: Standard UEFI spec defines this as 27CFAC88-..., but this binary
// has 27CFAC87-... (one bit difference in Data1). This may be a
// vendor-customized GUID.
// 27CFAC87-46CC-11D4-9A38-0090273FC14D
// Located at .data +0x0060 (VA 0x5060)
// -------------------------------------------------------------------------
#define RTC_ARCH_PROTOCOL_GUID \
{ 0x27CFAC87, 0x46CC, 0x11D4, \
{ 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }
// -------------------------------------------------------------------------
// Unknown Protocol GUID 1
// 11B34006-D85B-4D0A-A290-D5A571310EF7
// Located at .data +0x0020 (VA 0x5020)
// -------------------------------------------------------------------------
#define UNKNOWN_PROTOCOL_1_GUID \
{ 0x11B34006, 0xD85B, 0x4D0A, \
{ 0xA2, 0x90, 0xD5, 0xA5, 0x71, 0x31, 0x0E, 0xF7 } }
// -------------------------------------------------------------------------
// Unknown Protocol GUID 2
// 27ABF055-B1B8-4C26-8048-748F37BAA2DF
// Located at .data +0x0070 (VA 0x5070)
// -------------------------------------------------------------------------
#define UNKNOWN_PROTOCOL_2_GUID \
{ 0x27ABF055, 0xB1B8, 0x4C26, \
{ 0x80, 0x48, 0x74, 0x8F, 0x37, 0xBA, 0xA2, 0xDF } }
// -------------------------------------------------------------------------
// Unknown Protocol GUID 3
// 13FA7698-C831-49C7-87EA-8F43FCC25196
// Located at .data +0x0080 (VA 0x5080)
// -------------------------------------------------------------------------
#define UNKNOWN_PROTOCOL_3_GUID \
{ 0x13FA7698, 0xC831, 0x49C7, \
{ 0x87, 0xEA, 0x8F, 0x43, 0xFC, 0xC2, 0x51, 0x96 } }
// -------------------------------------------------------------------------
// DXE Services Table GUID (Standard UEFI)
// 05AD34BA-6F02-4214-952E-4DA0398E2BB9
// Located at .data +0x0090 (VA 0x5090)
// -------------------------------------------------------------------------
#define DXE_SERVICES_TABLE_GUID \
{ 0x05AD34BA, 0x6F02, 0x4214, \
{ 0x95, 0x2E, 0x4D, 0xA0, 0x39, 0x8E, 0x2B, 0xB9 } }
// -------------------------------------------------------------------------
// Unknown Protocol GUID 4
// 378D7B65-8DA9-4773-B6E4-A47826A833E1
// Located at .data +0x00A0 (VA 0x50A0)
// -------------------------------------------------------------------------
#define UNKNOWN_PROTOCOL_4_GUID \
{ 0x378D7B65, 0x8DA9, 0x4773, \
{ 0xB6, 0xE4, 0xA4, 0x78, 0x26, 0xA8, 0x33, 0xE1 } }
// =========================================================================
// CMOS RTC Register Map
// =========================================================================
/// CMOS I/O port to select register index (NMI enable in bit 7)
#define RTC_INDEX_PORT 0x70
/// CMOS I/O port to read/write data
#define RTC_DATA_PORT 0x71
/// NMI enable bit mask -- must be ORed into index port value
#define RTC_NMI_ENABLE 0x80
/// CMOS register addresses for time/date
#define RTC_REG_SECONDS 0x00
#define RTC_REG_SECONDS_ALARM 0x01
#define RTC_REG_MINUTES 0x02
#define RTC_REG_MINUTES_ALARM 0x03
#define RTC_REG_HOURS 0x04
#define RTC_REG_HOURS_ALARM 0x05
#define RTC_REG_DAY_OF_WEEK 0x06
#define RTC_REG_DAY_OF_MONTH 0x07
#define RTC_REG_MONTH 0x08
#define RTC_REG_YEAR 0x09
/// CMOS register addresses for RTC status
#define RTC_REG_STATUS_A 0x0A
#define RTC_REG_STATUS_B 0x0B
#define RTC_REG_STATUS_C 0x0C
#define RTC_REG_STATUS_D 0x0D
/// Century byte offset (configurable via PCD, default = 0x55)
#define RTC_REG_CENTURY_DEFAULT 0x55
// -------------------------------------------------------------------------
// Register A bits
// -------------------------------------------------------------------------
#define RTC_REG_A_UIP BIT7 ///< Update In Progress -- 1 = time update active
#define RTC_REG_A_DV_SHIFT 4 ///< Divider chain setting
#define RTC_REG_A_DV_MASK 0x70 ///< DV0-DV2 divider bits
#define RTC_REG_A_RATE_MASK 0x0F ///< Rate selection bits
// -------------------------------------------------------------------------
// Register B bits
// -------------------------------------------------------------------------
#define RTC_REG_B_SET BIT7 ///< 1 = inhibit updates (for writing time)
#define RTC_REG_B_PIE BIT6 ///< Periodic Interrupt Enable
#define RTC_REG_B_AIE BIT5 ///< Alarm Interrupt Enable
#define RTC_REG_B_UIE BIT4 ///< Update Interrupt Enable
#define RTC_REG_B_SQWE BIT3 ///< Square Wave Enable
#define RTC_REG_B_DM BIT2 ///< Data Mode: 0=BCD, 1=Binary
#define RTC_REG_B_24H BIT1 ///< Hour Format: 0=12h, 1=24h
#define RTC_REG_B_DSE BIT0 ///< Daylight Savings Enable
// -------------------------------------------------------------------------
// Register C bits
// -------------------------------------------------------------------------
#define RTC_REG_C_IRQF BIT7 ///< Interrupt Request Flag (any IRQ)
#define RTC_REG_C_PF BIT6 ///< Periodic Interrupt Flag
#define RTC_REG_C_AF BIT5 ///< Alarm Interrupt Flag
#define RTC_REG_C_UF BIT4 ///< Update Interrupt Flag
// -------------------------------------------------------------------------
// Register D bits
// -------------------------------------------------------------------------
#define RTC_REG_D_VRT BIT7 ///< Valid RAM and Time (battery status)
// =========================================================================
// Alarm "Don't Care" Values
// =========================================================================
/// When an alarm register reads 0xC0-0xFF, the field is "don't care"
#define RTC_ALARM_DONT_CARE_MIN 0xC0
// =========================================================================
// Time Conversion Constants
// =========================================================================
/// Maximum BCD byte value for decimal tens digit
#define BCD_TENS_MAX 0x09
/// Maximum valid binary year value for validation (year <= 2099 typically)
#define MAX_VALID_YEAR 2099
// =========================================================================
// EFI_TIME Default Values (used when RTC battery is dead)
// =========================================================================
/// Default year when RTC time is invalid
#define RTC_DEFAULT_YEAR 2000
/// Default month when RTC time is invalid
#define RTC_DEFAULT_MONTH 1
/// Default day when RTC time is invalid
#define RTC_DEFAULT_DAY 1
/// Default hour when RTC time is invalid
#define RTC_DEFAULT_HOUR 0
/// Default minute when RTC time is invalid
#define RTC_DEFAULT_MINUTE 0
/// Default second when RTC time is invalid
#define RTC_DEFAULT_SECOND 0
// =========================================================================
// RTC Lock States
// =========================================================================
#define RTC_LOCK_INITIALIZER { EFI_TPL_APPLICATION }
// =========================================================================
// Function Prototypes - PcRtcEntry.c
// =========================================================================
/**
* @brief UEFI Driver Entry Point
*
* Called by the DXE Core dispatcher. Saves global UEFI table pointers
* (gImageHandle, gST, gBS, gRT) and initializes the RTC driver.
* Entry point address: 0x1114.
*
* The entry point performs:
* 1. Cache ImageHandle, SystemTable, BootServices, RuntimeServices
* in global variables
* 2. Call PcRtcEntryInit() to initialize RTC hardware and install
* runtime services
* 3. Return EFI_SUCCESS or error code from PcRtcEntryInit()
*
* @param[in] ImageHandle UEFI image handle for this driver
* @param[in] SystemTable Pointer to EFI System Table
*
* @return EFI_STATUS
* @retval EFI_SUCCESS RTC driver initialized successfully
* @retval other Error from PcRtcEntryInit() (asserts on error)
*/
EFI_STATUS
EFIAPI
ModuleEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
// =========================================================================
// Function Prototypes - PcRtc.c (provided by EDK2)
//
// These are the standard PcAtChipsetPkg RTC functions. Their exact
// addresses in the binary require IDA-based disassembly to determine
// (listed as approximate VA ranges for the .text section).
// =========================================================================
/**
* @brief Initialize the RTC driver and register runtime services
*
* Main initialization function (called from ModuleEntryPoint).
* Performs the following:
* 1. Get HOB list via GetHobList()
* 2. Verify RTC hardware is functional (check Registers A, D)
* 3. Read current time, validate, default if invalid
* 4. Register SetVirtualAddressMap event for runtime pointer conversion
* 5. Install EFI RealTimeClock services in gRT->GetTime/SetTime/
* GetWakeupTime/SetWakeupTime
*
* Located in PcRtcEntry.c (~0x113C in .text or nearby)
*
* @return EFI_STATUS
* @retval EFI_SUCCESS RTC driver ready
* @retval EFI_INVALID_PARAMETER Could not validate time
*/
EFI_STATUS
PcRtcEntryInit (
VOID
);
/**
* @brief Read current time from CMOS RTC
*
* Implements EFI_RUNTIME_SERVICES.GetTime.
* Reading flow:
* 1. Acquire RTC lock (raise TPL to TPL_HIGH_LEVEL)
* 2. Wait for update cycle to complete (UIP bit clears)
* 3. Read all time registers (seconds, minutes, hours, day-of-week,
* day-of-month, month, year, century)
* 4. Convert BCD to binary if needed (check Register B bit 2)
* 5. Convert 12h to 24h if needed (check Register B bit 1)
* 6. Release lock
* 7. Return time (and capabilities if requested)
*
* Address: ~0x... in .text section
*
* @param[out] Time Pointer to EFI_TIME to receive current time
* @param[out] Capabilities Optional pointer to EFI_TIME_CAPABILITIES
*
* @return EFI_STATUS
* @retval EFI_SUCCESS Time read successfully
* @retval EFI_INVALID_PARAMETER Time is NULL
* @retval EFI_DEVICE_ERROR RTC hardware error (Register D VRT bit cleared)
*/
EFI_STATUS
EFIAPI
PcRtcGetTime (
OUT EFI_TIME *Time,
OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL
);
/**
* @brief Set current time in CMOS RTC
*
* Implements EFI_RUNTIME_SERVICES.SetTime.
* Writing flow:
* 1. Validate Time fields (year, month, day, hour, minute, second)
* 2. Acquire RTC lock
* 3. Set Register B SET bit (inhibit updates)
* 4. Write all time registers (seconds, minutes, hours, day-of-week,
* day-of-month, month, year, century)
* 5. Ensure 24h mode is set (Register B bit 1)
* 6. Clear SET bit (re-enable updates)
* 7. Release lock
*
* Address: ~0x... in .text section
*
* @param[in] Time Pointer to EFI_TIME to set
*
* @return EFI_STATUS
* @retval EFI_SUCCESS Time set successfully
* @retval EFI_INVALID_PARAMETER Time fields are invalid
* @retval EFI_DEVICE_ERROR RTC hardware error
*/
EFI_STATUS
EFIAPI
PcRtcSetTime (
IN EFI_TIME *Time
);
/**
* @brief Read RTC alarm time (wakeup time)
*
* Implements EFI_RUNTIME_SERVICES.GetWakeupTime.
* Reads CMOS alarm registers (0x01, 0x03, 0x05) and checks if
* AIE (Alarm Interrupt Enable) is set in Register B.
* Values of 0xC0-0xFF in alarm registers indicate "don't care"
* fields (per RTC specification).
*
* Address: ~0x... in .text section
*
* @param[out] Enabled TRUE if alarm is enabled (Register B AIE bit set)
* @param[out] Pending TRUE if alarm interrupt is pending (Register C AF bit)
* @param[out] Time Current alarm time (enabled fields only)
*
* @return EFI_STATUS
* @retval EFI_SUCCESS Alarm read successfully
* @retval EFI_INVALID_PARAMETER Time or Enabled is NULL
* @retval EFI_UNSUPPORTED Alarm not supported or no interrupt connected
*/
EFI_STATUS
EFIAPI
PcRtcGetWakeupTime (
OUT BOOLEAN *Enabled,
OUT BOOLEAN *Pending,
OUT EFI_TIME *Time
);
/**
* @brief Set RTC alarm time (wakeup time)
*
* Implements EFI_RUNTIME_SERVICES.SetWakeupTime.
* Writing flow:
* 1. Acquire RTC lock
* 2. Clear AIE bit in Register B (disable alarm)
* 3. Write alarm registers: second (0x01), minute (0x03), hour (0x05)
* With Enabled=FALSE, writes 0xC0 to all (= don't care = disabled)
* 4. Read Register C to clear any pending alarm IRQ
* 5. If Enabled=TRUE, set AIE bit in Register B
* 6. Release lock
*
* Address: ~0x... in .text section
*
* @param[in] Enabled TRUE to enable alarm, FALSE to disable
* @param[in] Time Alarm time (ignored if Enabled=FALSE)
* @return EFI_STATUS
* @retval EFI_SUCCESS Alarm set successfully
* @retval EFI_INVALID_PARAMETER Time is NULL with Enabled=TRUE
* @retval EFI_DEVICE_ERROR RTC hardware error
*/
EFI_STATUS
EFIAPI
PcRtcSetWakeupTime (
IN BOOLEAN Enabled,
IN EFI_TIME *Time OPTIONAL
);
/**
* @brief Read a byte from CMOS RAM
*
* Selects the CMOS register via port 0x70 and reads it via port 0x71.
* Preserves the NMI enable bit (bit 7) in the index register.
*
* @param[in] Address CMOS register address (0x00-0x7F typically)
*
* @return UINT8 The data byte read from the selected CMOS register
*/
UINT8
PcRtcRead (
IN UINT8 Address
);
/**
* @brief Write a byte to CMOS RAM
*
* Selects the CMOS register via port 0x70 and writes data via port 0x71.
* Preserves the NMI enable bit (bit 7) in the index register.
*
* @param[in] Address CMOS register address (0x00-0x7F typically)
* @param[in] Data The data byte to write
*/
VOID
PcRtcWrite (
IN UINT8 Address,
IN UINT8 Data
);
/**
* @brief Wait for RTC update cycle to complete
*
* Polls Register A bit 7 (UIP = Update In Progress) until it clears.
* When UIP is 1, the RTC is updating its time registers and reading
* them would return inconsistent data.
*
* After UIP clears, reading the time registers must complete within
* 244 microseconds (one update cycle at 4.096 kHz) to avoid reading
* during the next update.
*
* @retval EFI_SUCCESS Update completed, safe to read time
* @retval EFI_TIMEOUT Update did not complete (hardware error)
*/
EFI_STATUS
PcRtcWaitForUpdate (
VOID
);
/**
* @brief Validate all time fields
*
* Checks EFI_TIME fields:
* - Year: >= 1998 (typical, may vary by PCD)
* - Month: 1-12
* - Day: 1-max_days_in_month (validates against month/year)
* - Hour: 0-23
* - Minute: 0-59
* - Second: 0-59
* - Nanosecond: 0-999999999 (if checked)
* - Timezone: valid range or EFI_UNSPECIFIED_TIMEZONE
* - Daylight: valid flags
*
* @param[in] Time Pointer to EFI_TIME to validate
*
* @return BOOLEAN
* @retval TRUE All time fields are within valid ranges
* @retval FALSE One or more time fields are invalid
*/
BOOLEAN
PcRtcValidateTime (
IN EFI_TIME *Time
);
/**
* @brief Validate the Day field against the month/year
*
* Returns the maximum day number in the specified month,
* accounting for leap years (Gregorian calendar rules).
* February in a leap year returns 29.
*
* @param[in] Month Month (1-12)
* @param[in] Year Full year (e.g., 2024)
*
* @return UINT8 Maximum number of days in the given month/year
*/
UINT8
PcRtcValidateDay (
IN UINT8 Month,
IN UINT16 Year
);
/**
* @brief Check if an EFI_TIME structure has all fields valid
*
* Quick validation of time fields without detailed error reporting.
* Used internally before writing to CMOS.
*
* @param[in] Time Pointer to EFI_TIME to check
*
* @return BOOLEAN
* @retval TRUE All fields valid
* @retval FALSE Invalid fields
*/
BOOLEAN
PcRtcTimeFieldsValid (
IN EFI_TIME *Time
);
/**
* @brief Convert time fields between BCD and Binary formats
*
* Checks Register B bit 2 (DM = Data Mode):
* - If DM=0 (BCD), converts BCD time registers to binary EFI_TIME
* - If DM=1 (Binary), leaves time values as-is
*
* Also handles 12h-to-24h conversion by checking Register B bit 1:
* - If bit 1=0 (12h mode), checks PM bit (bit 7 of hour register)
* and converts to 24h format
*
* @param[in,out] Time EFI_TIME structure to convert
* @param[in] RegisterB Current value of CMOS Register B
*/
VOID
PcRtcConvertTimeFields (
IN OUT EFI_TIME *Time,
IN UINT8 RegisterB
);
/**
* @brief Convert BCD-encoded byte to binary
*
* Example: 0x59 BCD -> 59 binary
* Asserts: Value < 0xA0, (Value & 0xF) < 0xA
*
* @param[in] BcdValue BCD-encoded byte (e.g., 0x59 for 59)
*
* @return UINT8 Binary value (e.g., 59)
*/
UINT8
PcRtcBcdToBinary (
IN UINT8 BcdValue
);
/**
* @brief Convert binary value to BCD-encoded byte
*
* Example: 59 binary -> 0x59 BCD
* Asserts: Value < 100
*
* @param[in] BinaryValue Binary value (0-99)
*
* @return UINT8 BCD-encoded byte (e.g., 0x59)
*/
UINT8
PcRtcBinaryToBcd (
IN UINT8 BinaryValue
);
/**
* @brief Set RTC time in hardware (internal, locked)
*
* Writes all time registers to CMOS:
* - Sets Register B SET bit (bit 7) to freeze time during write
* - Writes seconds (0x00), minutes (0x02), hours (0x04)
* - Writes day-of-week (0x06), day-of-month (0x07), month (0x08), year (0x09)
* - Writes century byte to PCD-configured CMOS offset
* - Ensures 24h mode in Register B bit 1
* - Clears SET bit to resume updates
*
* Caller must hold RTC lock before calling.
*
* @param[in] Time EFI_TIME structure to write
*
* @return EFI_STATUS
* @retval EFI_SUCCESS Time written to CMOS successfully
*/
EFI_STATUS
PcRtcSetTimeInternal (
IN EFI_TIME *Time
);
/**
* @brief Get RTC time from hardware (internal, locked)
*
* Reads all time registers from CMOS:
* - Waits for UIP bit to clear
* - Reads seconds (0x00), minutes (0x02), hours (0x04)
* - Reads day-of-week (0x06), day-of-month (0x07), month (0x08), year (0x09)
* - Reads century from PCD-configured CMOS offset
* - Converts BCD/binary and 12h/24h as needed
*
* Caller must hold RTC lock before calling.
*
* @param[out] Time EFI_TIME structure to fill
*
* @return EFI_STATUS
* @retval EFI_SUCCESS Time read from CMOS successfully
*/
EFI_STATUS
PcRtcGetTimeInternal (
OUT EFI_TIME *Time
);
/**
* @brief Acquire the RTC lock
*
* Raises TPL to TPL_HIGH_LEVEL and acquires the RTC spin lock
* to prevent interrupt reentrancy during RTC register access.
* This is critical because RTC reads require atomic access to
* multiple registers (seconds, minutes, hours, etc.) and
* must not be interrupted.
*
* @param[out] OldTpl Receives the previous TPL to restore later
*/
VOID
PcRtcLockRtc (
OUT EFI_TPL *OldTpl
);
/**
* @brief Release the RTC lock
*
* Restores TPL to the value saved by PcRtcLockRtc().
*
* @param[in] OldTpl TPL value to restore (from PcRtcLockRtc)
*/
VOID
PcRtcUnlockRtc (
IN EFI_TPL OldTpl
);
// =========================================================================
// Library Function Prototypes (standard EDK2 BaseLib/BootService wrappers)
// =========================================================================
/**
* @brief Locate and cache the DebugLib Protocol
*
* Searches for the platform DebugLib protocol by GUID
* (36232936-0E76-31C8-A13A-3AF2FC1C3932) via gBS->LocateProtocol().
* Caches the result globally for use by DebugPrint and DebugAssert.
*
* @return VOID* Pointer to DebugLib protocol interface, or NULL if not found
*/
VOID *
GetDebugProtocol (
VOID
);
/**
* @brief Debug output through platform DebugLib protocol
*
* Formats and outputs a debug message. Checks the debug level
* mask from CMOS register 0x4B or MMIO fallback to determine
* which error levels are enabled for this platform.
*
* @param[in] ErrorLevel Debug message severity (EFI_D_* bitmask)
* @param[in] Format Format string (printf-style)
* @param[in] ... Variable arguments for format string
*/
VOID
DebugPrint (
IN UINTN ErrorLevel,
IN CHAR8 *Format,
...
);
/**
* @brief Assertion handler through platform DebugLib protocol
*
* Called by ASSERT() macro when a condition fails.
* Delegates to the DebugLib protocol's assertion handler.
*
* @param[in] FileName Source file name where assertion failed
* @param[in] LineNumber Source line number where assertion failed
* @param[in] Expression Text of the assertion expression
*/
VOID
DebugAssert (
IN CHAR8 *FileName,
IN UINTN LineNumber,
IN CHAR8 *Expression
);
/**
* @brief Locate the HOB (Hand-Off Block) list
*
* Scans gST->ConfigurationTable[] for the entry with VendorGuid
* matching gEfiHobListGuid (7739F24C-93D7-11D4-9A3A-0090273FC14D).
* Caches the result globally.
*
* Each configuration table entry is 24 bytes:
* +0x00: EFI_GUID VendorGuid (16 bytes)
* +0x10: VOID* VendorTable (8 bytes)
*
* @return VOID* Pointer to HOB list start, or NULL if not found
*/
VOID *
GetHobList (
VOID
);
/**
* @brief Read UINT64 from unaligned address
*
* Performs a 64-bit read from a potentially unaligned memory address.
* Asserts that Buffer is not NULL.
*
* Standard implementation from MdePkg BaseLib Unaligned.c
*
* @param[in] Buffer Pointer to read from (may be unaligned)
*
* @return UINT64 Value read
*/
UINT64
ReadUnaligned64 (
IN CONST VOID *Buffer
);
/**
* @brief Write UINT64 to unaligned address
*
* Performs a 64-bit write to a potentially unaligned memory address.
* Asserts that Buffer is not NULL.
*
* Standard implementation from MdePkg BaseLib Unaligned.c
*
* @param[out] Buffer Pointer to write to (may be unaligned)
* @param[in] Value Value to write
*/
VOID
WriteUnaligned64 (
OUT VOID *Buffer,
IN UINT64 Value
);
/**
* @brief Compare two GUIDs for equality
*
* Compares GUIDs by reading their first 8 bytes and second 8 bytes
* as UINT64 values via ReadUnaligned64.
*
* Standard implementation from MdePkg BaseLib
*
* @param[in] Guid1 First GUID to compare
* @param[in] Guid2 Second GUID to compare
*
* @return BOOLEAN
* @retval TRUE GUIDs are identical
* @retval FALSE GUIDs differ
*/
BOOLEAN
CompareGuid (
IN CONST EFI_GUID *Guid1,
IN CONST EFI_GUID *Guid2
);
#endif /* PC_RTC_H_ */