From dad0b0a63c85b47075b1b9c1054ca33f14bb85d0 Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Thu, 2 Jun 2016 13:35:49 +0800 Subject: ChvRefCodePkg: Add CPU SampleCode Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- .../CPU/SampleCode/Include/Library/DTSHookLib.h | 43 ++++ .../CPU/SampleCode/Include/Library/KscLib.h | 238 +++++++++++++++++++++ .../CPU/SampleCode/Include/Library/SmmIoLib.h | 190 ++++++++++++++++ .../Include/Protocol/GenericMemoryTest.h | 124 +++++++++++ .../SampleCode/Library/DTSHookLib/Smm/DTSHookLib.c | 102 +++++++++ .../Library/DTSHookLib/Smm/DTSHookLib.inf | 29 +++ .../CPU/SampleCode/Library/Ksc/Smm/SmmKscLib.c | 218 +++++++++++++++++++ .../CPU/SampleCode/Library/Ksc/Smm/SmmKscLib.inf | 29 +++ .../CPU/SampleCode/Library/SmmIo/SmmIo.c | 236 ++++++++++++++++++++ .../CPU/SampleCode/Library/SmmIo/SmmIo.inf | 38 ++++ .../CPU/SampleCode/Library/SmmIo/SmmPciIo.c | 164 ++++++++++++++ .../CherryViewSoc/CPU/SampleCode/SampleCode.dec | 26 +++ .../SmramSaveInfoHandlerSmm.c | 196 +++++++++++++++++ .../SmramSaveInfoHandlerSmm.inf | 65 ++++++ 14 files changed, 1698 insertions(+) create mode 100644 ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Library/DTSHookLib.h create mode 100644 ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Library/KscLib.h create mode 100644 ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Library/SmmIoLib.h create mode 100644 ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Protocol/GenericMemoryTest.h create mode 100644 ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.c create mode 100644 ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.inf create mode 100644 ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/Ksc/Smm/SmmKscLib.c create mode 100644 ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/Ksc/Smm/SmmKscLib.inf create mode 100644 ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/SmmIo/SmmIo.c create mode 100644 ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/SmmIo/SmmIo.inf create mode 100644 ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/SmmIo/SmmPciIo.c create mode 100644 ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/SampleCode.dec create mode 100644 ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.c create mode 100644 ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.inf diff --git a/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Library/DTSHookLib.h b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Library/DTSHookLib.h new file mode 100644 index 0000000000..a677288995 --- /dev/null +++ b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Library/DTSHookLib.h @@ -0,0 +1,43 @@ +/** @file + Defines and prototypes for the DigitalThermalSensor SMM driver + + Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _DTS_LIB_H_ +#define _DTS_LIB_H_ +// +// Include files +// +#include + +EFI_STATUS +InitializeDtsHookLib ( + VOID +); + +VOID +PlatformHookBeforeGenerateSCI ( + VOID +); + +UINT8 +ReadPlatformThermalDiode ( + VOID +); + +VOID +PlatformEventOutOfSpec ( + VOID +); + +#endif diff --git a/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Library/KscLib.h b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Library/KscLib.h new file mode 100644 index 0000000000..57d0affd7e --- /dev/null +++ b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Library/KscLib.h @@ -0,0 +1,238 @@ +/** @file + KSC library functions and definitions. + + This library provides basic KSC interface. It is deemed simple enough and uses in + so few cases that there is not currently benefit to implementing a protocol. + If more consumers are added, it may be benefitial to implement as a protocol. + + There may be different libraries for different environments (PEI, BS, RT, SMM). + Make sure you meet the requirements for the library (protocol dependencies, use + restrictions, etc). + + Copyright (c) 1996 - 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _KSC_LIB_H_ +#define _KSC_LIB_H_ + +// +// Include files +// + +// +// Timeout if KSC command/data fails +// +#define KSC_TIME_OUT 0x20000 + +// +// The Keyboard and System management Controller (KSC) implements a standard 8042 keyboard +// controller interface at ports 0x60/0x64 and a ACPI compliant system management controller +// at ports 0x62/0x66. Port 0x66 is the command and status port, port 0x62 is the data port. +// +#define KSC_D_PORT 0x62 +#define KSC_C_PORT 0x66 + +// +// Status Port 0x62 +// +#define KSC_S_OVR_TMP 0x80 // Current CPU temperature exceeds the threshold +#define KSC_S_SMI_EVT 0x40 // SMI event is pending +#define KSC_S_SCI_EVT 0x20 // SCI event is pending +#define KSC_S_BURST 0x10 // KSC is in burst mode or normal mode +#define KSC_S_CMD 0x08 // Byte in data register is command/data +#define KSC_S_IGN 0x04 // Ignored +#define KSC_S_IBF 0x02 // Input buffer is full/empty +#define KSC_S_OBF 0x01 // Output buffer is full/empty + +// +// KSC commands that are issued to the KSC through the command port (0x66). +// New commands and command parameters should only be written by the host when IBF=0. +// Data read from the KSC data port is valid only when OBF=1. +// +#define KSC_C_SMI_NOTIFY_ENABLE 0x04 // Enable SMI notifications to the host +#define KSC_C_SMI_NOTIFY_DISABLE 0x05 // SMI notifications are disabled and pending notifications cleared +#define KSC_C_QUERY_SYS_STATUS 0x06 // Returns 1 byte of information about the system status +#define KSC_B_SYS_STATUS_FAN 0x40 // Fan status (1 = ON) +#define KSC_B_SYS_STATUS_DOCK 0x20 // Dock status (1 = Docked) +#define KSC_B_SYS_STATUS_AC 0x10 // AC power (1 = AC powered) +#define KSC_B_SYS_STATUS_THERMAL 0x0F // CPU thermal state (0 ~ 9) +#define KSC_C_FAB_ID 0x0D // Get the board fab ID in the lower 3 bits +#define KSC_C_SYSTEM_POWER_OFF 0x22 // Turn off the system power +#define KSC_C_LAN_ON 0x46 // Turn on the power to LAN through EC/KSC +#define KSC_C_LAN_OFF 0x47 // Turn off the power to LAN through EC/KSC +#define KSC_C_GET_DTEMP 0x50 // Returns the CPU temperature as read from the SMBus thermal sensor. +#define KSC_C_SET_CTEMP 0x58 // The next byte written to the data port will be the shutdown temperature +#define KSC_C_EN_DTEMP 0x5E // Commands KSC to begin reading Thermal Diode and comparing to Critical Temperature +#define KSC_C_DIS_DTEMP 0x5F // Commands KSC to stop reading Thermal Diode +#define KSC_C_SMI_QUERY 0x70 // The host reads the data port to retrieve the notifications +#define KSC_C_SMI_TIMER 0x71 // Commands the KSC to generate a periodic SMI to the host +#define KSC_C_SMI_HOTKEY 0x72 // Get the scan code of hotkey pressed (CTRL + ALT + SHIFT + key) +#define KSC_C_READ_MEM 0x80 // Read the KSC memory +#define KSC_C_WRITE_MEM 0x81 // Write the KSC memory +#define KSC_C_DOCK_STATUS 0x8A // Get the dock status +#define KSC_B_DOCK_STATUS_ATTACH 0x01 // Dock status (1 = Attach) +#define KSC_C_KSC_REVISION 0x90 // Get the revision for the KSC +#define KSC_C_SMI_INJECT 0xBA // The next byte written to the data port will generate an immediate SMI +#define KSC_C_SMI_DISABLE 0xBC // SMI generation by the KSC is disabled +#define KSC_C_SMI_ENABLE 0xBD // SMI generation by the KSC is enabled +#define KSC_C_ACPI_ENABLE 0xAA // Enable ACPI mode +#define KSC_C_ACPI_DISABLE 0xAB // Disable ACPI mode + +// +// KSC commands that are only valid if the EC has ACPI mode enabled. +// Note that capacity and voltage are 16 bit values, thus you need to read them from +// ACPI space with two reads (little Endian). +// +#define KSC_VIRTUAL_BAT_STATUS 48 // Status of the virtual battery (present) +#define KSC_VIRTUAL_BAT_PRESENT_MASK 0x10 // Bit 4 is the indicator + +#define KSC_REAL_BAT1_STATUS 50 // Status of the first real battery (present, charging) +#define KSC_REAL_BAT1_REMAINING_CAPACITY 89 // Remaining capacity in mWh +#define KSC_REAL_BAT1_RESOLUTION_VOLTAGE 93 // Full resolution voltage in mV + +#define KSC_REAL_BAT2_STATUS 54 // Status of the second real battery (present, charging) +#define KSC_REAL_BAT2_REMAINING_CAPACITY 99 // Remaining capacity in mWh +#define KSC_REAL_BAT2_RESOLUTION_VOLTAGE 103 // Full resolution voltage in mV + +#define KSC_REAL_BAT_PRESENT_MASK 0x8 // Bit 3 is the indicator +#define KSC_REAL_BAT_CHARGING_MASK 0x1 // Bit 1 is the indicator + +// +// SMI notification code table, read through command KSC_C_SMI_QUERY +// +#define KSC_N_SMI_NULL 0x00 // Null marks the end of the SMI notification queue +#define KSC_N_SMI_HOTKEY 0x20 // Hotkey pressed SMI +#define KSC_N_SMI_ACINSERTION 0x30 // AC insertion SMI +#define KSC_N_SMI_ACREMOVAL 0x31 // AC removal SMI +#define KSC_N_SMI_PWRSW 0x32 // Power switch press SMI +#define KSC_N_SMI_LID 0x33 // Lid switch change SMI +#define KSC_N_SMI_VB 0x34 // Virtual battery switch change SMI +#define KSC_N_SMI_THERM_0 0x60 // Thermal state 0 SMI +#define KSC_N_SMI_THERM_1 0x61 // Thermal state 1 SMI +#define KSC_N_SMI_THERM_2 0x62 // Thermal state 2 SMI +#define KSC_N_SMI_THERM_3 0x63 // Thermal state 3 SMI +#define KSC_N_SMI_THERM_4 0x64 // Thermal state 4 SMI +#define KSC_N_SMI_THERM_5 0x65 // Thermal state 5 SMI +#define KSC_N_SMI_THERM_6 0x66 // Thermal state 6 SMI +#define KSC_N_SMI_THERM_7 0x67 // Thermal state 7 SMI +#define KSC_N_SMI_THERM_8 0x68 // Thermal state 8 SMI +#define KSC_N_SMI_DOCKED 0x70 // Dock complete SMI +#define KSC_N_SMI_UNDOCKED 0x71 // Undock complete SMI +#define KSC_N_SMI_UNDOCKREQUEST 0x72 // Undocking request SMI +#define KSC_N_SMI_TIMER 0x80 // Timer wakeup SMI + +// +// Hotkey scan code (CTRL + ALT + SHIFT + key) +// +#define KSC_HK_ESC 0x01 // ESC +#define KSC_HK_1 0x02 // 1 ! +#define KSC_HK_2 0x03 // 2 @ +#define KSC_HK_3 0x04 // 3 # +#define KSC_HK_4 0x05 // 4 $ +#define KSC_HK_5 0x06 // 5 % +#define KSC_HK_6 0x07 // 6 ^ +#define KSC_HK_7 0x08 // 7 & +#define KSC_HK_8 0x09 // 8 * +#define KSC_HK_9 0x0A // 9 ( +#define KSC_HK_0 0x0B // 0 ) +#define KSC_HK_MINUS 0x0C // - _ +#define KSC_HK_ADD 0x0D // = + +#define KSC_HK_F1 0x3B // F1 +#define KSC_HK_F2 0x3C // F2 +#define KSC_HK_F3 0x3D // F3 +#define KSC_HK_F4 0x3E // F4 +#define KSC_HK_F5 0x3F // F5 +#define KSC_HK_F6 0x40 // F6 +#define KSC_HK_F7 0x41 // F7 +#define KSC_HK_F8 0x42 // F8 +#define KSC_HK_F9 0x43 // F9 +#define KSC_HK_F10 0x44 // F10 +#define KSC_HK_F11 0x57 // F11 +#define KSC_HK_F12 0x58 // F12 + +// +// Function declarations +// +/** + This function initializes the KSC library. + It must be called before using any of the other KSC library functions. + + @param[in] None + + @retval EFI_SUCCESS KscLib is successfully initialized. + +**/ +EFI_STATUS +InitializeKscLib ( + VOID + ); + +/** + Send a command to the Keyboard System Controller. + + @param[in] Command Command byte to send + + @retval EFI_SUCCESS Command success + @retval EFI_TIMEOUT Command timeout + @retval Other Command failed + +**/ +EFI_STATUS +SendKscCommand ( + UINT8 Command + ); + +/** + Sends data to Keyboard System Controller. + + @param[in] Data Data byte to send + + @retval EFI_SUCCESS Success + @retval EFI_TIMEOUT Timeout + @retval Other Failed + +**/ +EFI_STATUS +SendKscData ( + UINT8 Data + ); + +/** + Receives data from Keyboard System Controller. + + @param[in] Data Data byte received + + @retval EFI_SUCCESS Read success + @retval EFI_TIMEOUT Read timeout + @retval Other Read failed + +**/ +EFI_STATUS +ReceiveKscData ( + UINT8 *Data + ); + +/** + Receives status from Keyboard System Controller. + + @param[in] Status Status byte to receive + + @retval EFI_SUCCESS Success + @retval Other Failed + +**/ +EFI_STATUS +ReceiveKscStatus ( + UINT8 *KscStatus + ); + +#endif diff --git a/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Library/SmmIoLib.h b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Library/SmmIoLib.h new file mode 100644 index 0000000000..ec1e24b821 --- /dev/null +++ b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Library/SmmIoLib.h @@ -0,0 +1,190 @@ +/** @file + This library provides SMM functions for IO and PCI IO access. + These can be used to save size and simplify code. + All contents must be runtime and SMM safe. + + Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _SMM_IO_LIB_H_ +#define _SMM_IO_LIB_H_ + +#include +#include +#include +#include + +// +// Utility consumed protocols +// + +// +// Definitions +// +#define ICH_ACPI_TIMER_MAX_VALUE 0x1000000 // The timer is 24 bit overflow + +// +// Pci I/O related data structure deifinition +// +typedef enum { + SmmPciWidthUint8 = 0, + SmmPciWidthUint16 = 1, + SmmPciWidthUint32 = 2, + SmmPciWidthUint64 = 3, + SmmPciWidthMaximum +} SMM_PCI_IO_WIDTH; + +#define SMM_PCI_ADDRESS(bus,dev,func,reg) \ + ((UINT64) ( (((UINT32)bus) << 24) + \ + (((UINT32)dev) << 16) + \ + (((UINT32)func) << 8) + \ + ( (UINT32)reg)) ) + +typedef struct { + UINT8 Register; + UINT8 Function; + UINT8 Device; + UINT8 Bus; + UINT32 ExtendedRegister; +} SMM_PCI_IO_ADDRESS; + +// +// CPU I/O Access Functions +// + +UINT8 +SmmIoRead8 ( + IN UINT16 Address + ); + +VOID +SmmIoWrite8 ( + IN UINT16 Address, + IN UINT8 Data + ); + +UINT16 +SmmIoRead16 ( + IN UINT16 Address + ); + +VOID +SmmIoWrite16 ( + IN UINT16 Address, + IN UINT16 Data + ); + +UINT32 +SmmIoRead32 ( + IN UINT16 Address + ); + +VOID +SmmIoWrite32 ( + IN UINT16 Address, + IN UINT32 Data + ); + +VOID +SmmMemWrite8 ( + IN UINT64 Dest, + IN UINT8 Data + ); + +UINT8 +SmmMemRead8 ( + IN UINT64 Dest + ); + +VOID +SmmMemWrite16 ( + IN UINT64 Dest, + IN UINT16 Data + ); + +UINT16 +SmmMemRead16 ( + IN UINT64 Dest + ); + +VOID +SmmMemWrite32 ( + IN UINT64 Dest, + IN UINT32 Data + ); + +UINT32 +SmmMemRead32 ( + IN UINT64 Dest + ); + +VOID +SmmMemAnd32 ( + IN UINT64 Dest, + IN UINT32 Data + ); +// +// Pci Configuration Space access functions definition +// + +/** + Read value from the specified PCI config space register + + @param[in] Width The width (8, 16 or 32 bits) of accessed pci config space register + @param[in] Address The address of the accessed pci register (bus, dev, func, offset) + @param[in] Buffer The returned value + + @retval EFI_SUCCESS All operations successfully + @retval EFI_INVALID_PARAMETER Width is not valid or dosn't match register address + @retval Other error code If any error occured when calling libiary functions + +**/ +EFI_STATUS +SmmPciCfgRead ( + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ); + +/** + Write value into the specified PCI config space register + + @param[in] Width The width (8, 16 or 32 bits) of accessed pci config space register + @param[in] Address The address of the accessed pci register (bus, dev, func, offset) + @param[in] Buffer The returned value + + @retval EFI_SUCCESS All operations successfully + @retval EFI_INVALID_PARAMETER Width is not valid or dosn't match register address + @retval Other error code If any error occured when calling libiary functions + +**/ +EFI_STATUS +SmmPciCfgWrite ( + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ); + +/** + Delay for at least the request number of microseconds + + @param[in] Microseconds Number of microseconds to delay. + + @retval None + +**/ +VOID +SmmStall ( + IN UINTN Microseconds + ); + +#endif diff --git a/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Protocol/GenericMemoryTest.h b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Protocol/GenericMemoryTest.h new file mode 100644 index 0000000000..507a3673e0 --- /dev/null +++ b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Protocol/GenericMemoryTest.h @@ -0,0 +1,124 @@ +/** @file + This protocol defines the generic memory test interfaces in Dxe phase. + + Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __GENERIC_MEMORY_TEST_H__ +#define __GENERIC_MEMORY_TEST_H__ + +#define EFI_GENERIC_MEMORY_TEST_PROTOCOL_GUID \ + { 0x309de7f1, 0x7f5e, 0x4ace, {0xb4, 0x9c, 0x53, 0x1b, 0xe5, 0xaa, 0x95, 0xef} } + +typedef struct _EFI_GENERIC_MEMORY_TEST_PROTOCOL EFI_GENERIC_MEMORY_TEST_PROTOCOL; + +/// +/// Memory test coverage level. +/// Ignore chooses not to test memory. Quick and Sparse test some memory, and Extensive performs a detailed memory test. +/// +typedef enum { + IGNORE, + QUICK, + SPARSE, + EXTENSIVE, + MAXLEVEL +} EXTENDMEM_COVERAGE_LEVEL; + +/** + Initialize the generic memory test. + + @param[in] This The protocol instance pointer. + @param[in] Level The coverage level of the memory test. + @param[in] RequireSoftECCInit Indicate if the memory need software ECC init. + + @retval EFI_SUCCESS The generic memory test is initialized correctly. + @retval EFI_NO_MEDIA The system had no memory to be tested. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MEMORY_TEST_INIT) ( + IN EFI_GENERIC_MEMORY_TEST_PROTOCOL *This, + IN EXTENDMEM_COVERAGE_LEVEL Level, + OUT BOOLEAN *RequireSoftECCInit + ); + +/** + Perform the memory test. + + @param[in] This The protocol instance pointer. + @param[in] TestedMemorySize Return the tested extended memory size. + @param[in] TotalMemorySize Return the whole system physical memory size. + The total memory size does not include memory in a slot with a disabled DIMM. + @param[in] ErrorOut TRUE if the memory error occured. + @param[in] IfTestAbort Indicates that the user pressed "ESC" to skip the memory test. + + @retval EFI_SUCCESS One block of memory passed the test. + @retval EFI_NOT_FOUND All memory blocks have already been tested. + @retval EFI_DEVICE_ERROR Memory device error occured, and no agent can handle it. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PERFORM_MEMORY_TEST) ( + IN EFI_GENERIC_MEMORY_TEST_PROTOCOL *This, + OUT UINT64 *TestedMemorySize, + OUT UINT64 *TotalMemorySize, + OUT BOOLEAN *ErrorOut, + IN BOOLEAN IfTestAbort + ); + +/** + Finish the memory test. + + @param[in] This The protocol instance pointer. + + @retval EFI_SUCCESS Success. All resources used in the memory test are freed. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MEMORY_TEST_FINISHED) ( + IN EFI_GENERIC_MEMORY_TEST_PROTOCOL *This + ); + +/** + Provides the capability to test the compatible range used by some special drivers. + + @param[in] This The protocol instance pointer. + @param[in] StartAddress The start address of the compatible memory range that + must be below 16M. + @param[in] Length The compatible memory range's length. + + @retval EFI_SUCCESS The compatible memory range pass the memory test. + @retval EFI_INVALID_PARAMETER The compatible memory range are not below Low 16M. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MEMORY_TEST_COMPATIBLE_RANGE) ( + IN EFI_GENERIC_MEMORY_TEST_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS StartAddress, + IN UINT64 Length + ); + +struct _EFI_GENERIC_MEMORY_TEST_PROTOCOL { + EFI_MEMORY_TEST_INIT MemoryTestInit; + EFI_PERFORM_MEMORY_TEST PerformMemoryTest; + EFI_MEMORY_TEST_FINISHED Finished; + EFI_MEMORY_TEST_COMPATIBLE_RANGE CompatibleRangeTest; +}; + +extern EFI_GUID gEfiGenericMemTestProtocolGuid; + +#endif + diff --git a/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.c b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.c new file mode 100644 index 0000000000..0e68d407ef --- /dev/null +++ b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.c @@ -0,0 +1,102 @@ +/** @file + Digital Thermal Sensor (DTS) SMM Library. + This SMM Library configures and supports the DigitalThermalSensor features + for the platform. + + Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +/** + Prepare data and protocol for Dts Hooe Lib + + @retval EFI_SUCCESS - Initialize complete + +**/ +EFI_STATUS +InitializeDtsHookLib ( + VOID +) + +{ + // + //Nothing to do on CRB. + // + return EFI_SUCCESS; +} + +/** + Platform may need to register some data to private data structure before generate + software SMI or SCI. + +**/ +VOID +PlatformHookBeforeGenerateSCI ( + VOID +) + +{ + // + //Nothing to do on CRB. + // +} + +/** + Read CPU temperature from platform diode + + @retval TemperatureOfDiode - Return the CPU temperature of platform diode + +**/ +UINT8 +ReadPlatformThermalDiode( + VOID +) + +{ + UINT8 CurrentTemperatureOfDiode=0; + EFI_STATUS Status; + + // + // Call KSC to get Diode Temperature + // + + while (CurrentTemperatureOfDiode == 0) { + Status = SendKscCommand (KSC_C_GET_DTEMP); + if (Status == EFI_SUCCESS) { + ReceiveKscData ((UINT8 *)&CurrentTemperatureOfDiode); + } + } + return CurrentTemperatureOfDiode; + +} +/** + When system temperature out of specification, do platform specific programming to prevent + system damage. + +**/ +VOID +PlatformEventOutOfSpec ( + VOID +) + +{ + EFI_STATUS Status; + // + // Handle critical event by shutting down via EC + // + Status = InitializeKscLib (); + if (Status == EFI_SUCCESS) { + SendKscCommand (KSC_C_SYSTEM_POWER_OFF); + } +} + diff --git a/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.inf b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.inf new file mode 100644 index 0000000000..8b107ee310 --- /dev/null +++ b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.inf @@ -0,0 +1,29 @@ +## @file +# Component description file. +# +# Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[defines] + INF_VERSION = 0x00010005 + BASE_NAME = DTSHookLib2s + FILE_GUID = DC8447E9-7C9D-4eac-A774-173E84A63FC4 + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = DTSHookLib + +[sources] + DTSHookLib.c + +[Packages] + MdePkg/MdePkg.dec + ChvRefCodePkg/ChvRefCodePkg.dec diff --git a/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/Ksc/Smm/SmmKscLib.c b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/Ksc/Smm/SmmKscLib.c new file mode 100644 index 0000000000..b2ea8ac110 --- /dev/null +++ b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/Ksc/Smm/SmmKscLib.c @@ -0,0 +1,218 @@ +/** @file + SMM KSC library implementation. + These functions need to be SMM safe. + These functions require the SMM IO library (SmmIoLib) to be present. + Caller must link those libraries and have the proper include path. + + Copyright (c) 1996 - 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "Library/KscLib.h" +#include "Library/SmmIoLib.h" + +BOOLEAN mSmmKscLibInitialized = FALSE; + +/** + Initialize the library. + The SMM library only requires SMM IO library and has no initialization. + However, this must be called prior to use of any other KSC library functions + for future compatibility. + + @retval EFI_SUCCESS - KscLib is successfully initialized. + +**/ +EFI_STATUS +InitializeKscLib ( + VOID + ) +{ + // + // Fail if EC doesn't exist. + // + if (SmmIoRead8(KSC_C_PORT) == 0xff) { + mSmmKscLibInitialized = FALSE; + return EFI_DEVICE_ERROR; + } + + mSmmKscLibInitialized = TRUE; + + return EFI_SUCCESS; +} + +/** + Sends command to Keyboard System Controller. + + @param[in] Command - Command byte to send + + @retval EFI_SUCCESS - Command success + @retval EFI_DEVICE_ERROR - Command error + +**/ +EFI_STATUS +SendKscCommand ( + UINT8 Command + ) +{ + UINTN Index; + UINT8 KscStatus = 0; + + // + // Verify if KscLib has been initialized, NOT if EC dose not exist. + // + if (mSmmKscLibInitialized == FALSE) { + return EFI_DEVICE_ERROR; + } + + Index = 0; + + // + // Wait for KSC to be ready (with a timeout) + // + ReceiveKscStatus (&KscStatus); + while (((KscStatus & KSC_S_IBF) != 0) && (Index < KSC_TIME_OUT)) { + SmmStall (15); + ReceiveKscStatus (&KscStatus); + Index++; + } + if (Index >= KSC_TIME_OUT) { + return EFI_DEVICE_ERROR; + } + + // + // Send the KSC command + // + SmmIoWrite8 (KSC_C_PORT, Command); + + return EFI_SUCCESS; +} + +/** + Receives status from Keyboard System Controller. + + @param[in] KscStatus - Status byte to receive + + @retval EFI_SUCCESS - Always success + +**/ +EFI_STATUS +ReceiveKscStatus ( + UINT8 *KscStatus + ) +{ + // + // Verify if KscLib has been initialized, NOT if EC dose not exist. + // + if (mSmmKscLibInitialized == FALSE) { + return EFI_DEVICE_ERROR; + } + + // + // Read and return the status + // + *KscStatus = SmmIoRead8 (KSC_C_PORT); + + return EFI_SUCCESS; +} + +/** + Sends data to Keyboard System Controller. + + @param[in] Data - Data byte to send + + @retval EFI_SUCCESS - Success + @retval EFI_DEVICE_ERROR - Error + +**/ +EFI_STATUS +SendKscData ( + UINT8 Data + ) +{ + UINTN Index; + UINT8 KscStatus; + + // + // Verify if KscLib has been initialized, NOT if EC dose not exist. + // + if (mSmmKscLibInitialized == FALSE) { + return EFI_DEVICE_ERROR; + } + + Index = 0; + + // + // Wait for KSC to be ready (with a timeout) + // + ReceiveKscStatus (&KscStatus); + while (((KscStatus & KSC_S_IBF) != 0) && (Index < KSC_TIME_OUT)) { + SmmStall (15); + ReceiveKscStatus (&KscStatus); + Index++; + } + if (Index >= KSC_TIME_OUT) { + return EFI_DEVICE_ERROR; + } + + // + // Send the data and return + // + SmmIoWrite8 (KSC_D_PORT, Data); + + return EFI_SUCCESS; +} + +/** + Receives data from Keyboard System Controller. + + @param[in] Data - Data byte received + + @retval EFI_SUCCESS - Read success + @retval EFI_DEVICE_ERROR - Read error + +**/ +EFI_STATUS +ReceiveKscData ( + UINT8 *Data + ) +{ + UINTN Index; + UINT8 KscStatus; + + // + // Verify if KscLib has been initialized, NOT if EC dose not exist. + // + if (mSmmKscLibInitialized == FALSE) { + return EFI_DEVICE_ERROR; + } + + Index = 0; + + // + // Wait for KSC to be ready (with a timeout) + // + ReceiveKscStatus (&KscStatus); + while (((KscStatus & KSC_S_OBF) == 0) && (Index < KSC_TIME_OUT)) { + SmmStall (15); + ReceiveKscStatus (&KscStatus); + Index++; + } + if (Index >= KSC_TIME_OUT) { + return EFI_DEVICE_ERROR; + } + + // + // Read KSC data and return + // + *Data = SmmIoRead8 (KSC_D_PORT); + + return EFI_SUCCESS; +} diff --git a/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/Ksc/Smm/SmmKscLib.inf b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/Ksc/Smm/SmmKscLib.inf new file mode 100644 index 0000000000..f971295eeb --- /dev/null +++ b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/Ksc/Smm/SmmKscLib.inf @@ -0,0 +1,29 @@ +## @file +# Component description file. +# +# Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[defines] + INF_VERSION = 0x00010005 + BASE_NAME = SmmKscLib2 + FILE_GUID = 5C4A5CA1-66E2-4a42-A29E-2D7738112CDE + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = SmmKscLib + +[sources] + SmmKscLib.c + +[Packages] + MdePkg/MdePkg.dec + ChvRefCodePkg/ChvRefCodePkg.dec diff --git a/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/SmmIo/SmmIo.c b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/SmmIo/SmmIo.c new file mode 100644 index 0000000000..2962aa2646 --- /dev/null +++ b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/SmmIo/SmmIo.c @@ -0,0 +1,236 @@ +/** @file + SMM I/O access utility implementation file, for Ia32 + + Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +// +// Include files +// +#include +#include +#include "PchAccess.h" +#include +#include +#include + +/** + Do a one byte IO read + + @param[in] Address - IO address to read + + @retval Data read + +**/ +UINT8 +SmmIoRead8 ( + IN UINT16 Address + ) +{ + UINT8 Buffer; + + ASSERT (gSmst); + + gSmst->SmmIo.Io.Read ( + &gSmst->SmmIo, + SMM_IO_UINT8, + Address, + 1, + &Buffer + ); + return Buffer; +} + +/** + Do a one byte IO write + + @param[in] Address - IO address to write + @param[in] Data - Data to write + +**/ +VOID +SmmIoWrite8 ( + IN UINT16 Address, + IN UINT8 Data + ) +{ + ASSERT (gSmst); + + gSmst->SmmIo.Io.Write ( + &gSmst->SmmIo, + SMM_IO_UINT8, + Address, + 1, + &Data + ); +} + +/** + Do a two byte IO read + + @param[in] Address - IO address to read + + @retval Data read + +**/ +UINT16 +SmmIoRead16 ( + IN UINT16 Address + ) +{ + UINT16 Buffer; + + ASSERT (gSmst); + + gSmst->SmmIo.Io.Read ( + &gSmst->SmmIo, + SMM_IO_UINT16, + Address, + 1, + &Buffer + ); + return Buffer; +} + +/** + Do a two byte IO write + + @param[in] Address - IO address to write + @param[in] Data - Data to write + +**/ +VOID +SmmIoWrite16 ( + IN UINT16 Address, + IN UINT16 Data + ) +{ + ASSERT (gSmst); + + gSmst->SmmIo.Io.Write ( + &gSmst->SmmIo, + SMM_IO_UINT16, + Address, + 1, + &Data + ); +} + +/** + Do a four byte IO read + + @param[in] Address - IO address to read + + @retval Data read + +**/ +UINT32 +SmmIoRead32 ( + IN UINT16 Address + ) +{ + UINT32 Buffer; + + ASSERT (gSmst); + + gSmst->SmmIo.Io.Read ( + &gSmst->SmmIo, + SMM_IO_UINT32, + Address, + 1, + &Buffer + ); + return Buffer; +} + +/** + Do a four byte IO write + + @param[in] Address - IO address to write + @param[in] Data - Data to write + +**/ +VOID +SmmIoWrite32 ( + IN UINT16 Address, + IN UINT32 Data + ) +{ + ASSERT (gSmst); + + gSmst->SmmIo.Io.Write ( + &gSmst->SmmIo, + SMM_IO_UINT32, + Address, + 1, + &Data + ); +} + +/** + Delay for at least the request number of microseconds. + Timer used is ACPI time counter, which has 1us granularity. + + @param[in] Microseconds - Number of microseconds to delay. + +**/ +VOID +SmmStall ( + IN UINTN Microseconds + ) +{ + UINTN Ticks; + UINTN Counts; + UINTN CurrentTick; + UINTN OriginalTick; + UINTN RemainingTick; + UINT16 mAcpiBaseAddr; + + if (Microseconds == 0) { + return; + } + + mAcpiBaseAddr = PchLpcPciCfg16 (R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR; + + OriginalTick = SmmIoRead32 (mAcpiBaseAddr + R_PCH_ACPI_PM1_TMR); + CurrentTick = OriginalTick; + + // + // The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks + // + Ticks = Microseconds * 358 / 100 + OriginalTick + 1; + + // + // The loops needed by timer overflow + // + Counts = Ticks / ICH_ACPI_TIMER_MAX_VALUE; + + // + // Remaining clocks within one loop + // + RemainingTick = Ticks % ICH_ACPI_TIMER_MAX_VALUE; + + // + // not intend to use TMROF_STS bit of register PM1_STS, because this adds extra + // one I/O operation, and maybe generate SMI + // + while ((Counts != 0) || (RemainingTick > CurrentTick)) { + CurrentTick = SmmIoRead32 (mAcpiBaseAddr + R_PCH_ACPI_PM1_TMR); + // + // Check if timer overflow + // + if (CurrentTick < OriginalTick) { + Counts--; + } + OriginalTick = CurrentTick; + } +} diff --git a/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/SmmIo/SmmIo.inf b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/SmmIo/SmmIo.inf new file mode 100644 index 0000000000..b679ba24b5 --- /dev/null +++ b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/SmmIo/SmmIo.inf @@ -0,0 +1,38 @@ +## @file +# Component description file. +# +# Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SmmIoLib2 + FILE_GUID = 8B7B3CFB-5592-4a9d-8FEE-EE0BA9CF2623 + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = SmmIoLib + +[sources] + SmmIo.c + SmmPciIo.c + +[Packages] + MdePkg/MdePkg.dec + ChvRefCodePkg/ChvRefCodePkg.dec + +[LibraryClasses] + PcdLib + DebugLib + IoLib + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress diff --git a/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/SmmIo/SmmPciIo.c b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/SmmIo/SmmPciIo.c new file mode 100644 index 0000000000..3c822e91c0 --- /dev/null +++ b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/SmmIo/SmmPciIo.c @@ -0,0 +1,164 @@ +/** @file + SMM PCI config space I/O access utility implementation file, for Ia32 + + Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +STATIC +EFI_STATUS +SmmSingleSegmentPciAccess ( + IN EFI_SMM_CPU_IO2_PROTOCOL *CpuIo, + IN BOOLEAN IsWrite, + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ); + +/** + Read value from the specified PCI config space register + + @param[in] Width - The width (8, 16 or 32 bits) of accessed pci config space register + @param[in] Address - The address of the accessed pci register (bus, dev, func, offset) + @param[in] Buffer - The returned value + + @retval EFI_SUCCESS - All operations successfully + @retval EFI_INVALID_PARAMETER - Width is not valid or dosn't match register address + @retval Other error code - If any error occured when calling libiary functions + +**/ +EFI_STATUS +SmmPciCfgRead ( + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ) +{ + EFI_SMM_CPU_IO2_PROTOCOL *SmmCpuIo; + + ASSERT (gSmst); + + SmmCpuIo = &(gSmst->SmmIo); + + return SmmSingleSegmentPciAccess (SmmCpuIo, FALSE, Width, Address, Buffer); +} + +/** + Write value into the specified PCI config space register + + @param[in] Width - The width (8, 16 or 32 bits) of accessed pci config space register + @param[in] Address - The address of the accessed pci register (bus, dev, func, offset) + @param[in] Buffer - The returned value + + @retval EFI_SUCCESS - All operations successfully + @retval EFI_INVALID_PARAMETER - Width is not valid or dosn't match register address + @retval Other error code - If any error occured when calling libiary functions + +**/ +EFI_STATUS +SmmPciCfgWrite ( + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ) +{ + EFI_SMM_CPU_IO2_PROTOCOL *SmmCpuIo; + + ASSERT (gSmst); + + SmmCpuIo = &(gSmst->SmmIo); + + return SmmSingleSegmentPciAccess (SmmCpuIo, TRUE, Width, Address, Buffer); +} + +/** + Access a PCI config space address, including read and write + + @param[in] CpuIo - The cpu I/O accessing interface provided by EFI runtime sys table + @param[in] IsWrite - Indicates whether this operation is a write access or read + @param[in] Width - The width (8, 16 or 32 bits) of accessed pci config space register + @param[in] Address - The address of the accessed pci register (bus, dev, func, offset) + @param[in] Buffer - The returned value when this is a reading operation or the data + to be written when this is a writing one + + @retval EFI_SUCCESS - All operations successfully + @retval EFI_INVALID_PARAMETER - Width is not valid or dosn't match register address + @retval Other error code - If any error occured when calling libiary functions + +**/ +STATIC +EFI_STATUS +SmmSingleSegmentPciAccess ( + IN EFI_SMM_CPU_IO2_PROTOCOL *CpuIo, + IN BOOLEAN IsWrite, + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + PCI_CONFIG_ACCESS_CF8 PciCf8Data; + UINT64 PciDataReg; + + // + // PCI Config access are all 32-bit alligned, but by accessing the + // CONFIG_DATA_REGISTER (0xcfc) with different widths more cycle types + // are possible on PCI. + // + // To read a byte of PCI config space you load 0xcf8 and + // read 0xcfc, 0xcfd, 0xcfe, 0xcff + // + // The validation of passed in arguments "Address" will be checked in the + // CPU IO functions, so we don't check them here + // + + if (Width >= SmmPciWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + PciCf8Data.Bits.Reg = Address->Register & 0xfc; + PciCf8Data.Bits.Func = Address->Function; + PciCf8Data.Bits.Dev = Address->Device; + PciCf8Data.Bits.Bus = Address->Bus; + PciCf8Data.Bits.Reserved = 0; + PciCf8Data.Bits.Enable = 1; + + Status = CpuIo->Io.Write (CpuIo, SmmPciWidthUint32, 0xcf8, 1, &PciCf8Data); + if (EFI_ERROR(Status)) { + return Status; + } + + PciDataReg = 0xcfc + (Address->Register & 0x03); + + if (IsWrite) { + // + // This is a Pci write operation, write data into (0xcfc + offset) + // + Status = CpuIo->Io.Write (CpuIo, Width, PciDataReg, 1, Buffer); + if (EFI_ERROR(Status)) { + return Status; + } + } else { + // + // This is a Pci Read operation, read returned data from (0xcfc + offset) + // + Status = CpuIo->Io.Read (CpuIo, Width, PciDataReg, 1, Buffer); + if (EFI_ERROR(Status)) { + return Status; + } + } + + return EFI_SUCCESS; +} diff --git a/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/SampleCode.dec b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/SampleCode.dec new file mode 100644 index 0000000000..7841782b5d --- /dev/null +++ b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/SampleCode.dec @@ -0,0 +1,26 @@ +## @file +# +# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + DEC_SPECIFICATION = 0x00010005 + PACKAGE_NAME = SampleCode + PACKAGE_GUID = 10A1278E-07CA-4a19-BC6E-BCD81C865C22 + PACKAGE_VERSION = 0.1 + +[Includes] + Include + +[Protocols] + +[Ppis] diff --git a/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.c b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.c new file mode 100644 index 0000000000..722e386bf4 --- /dev/null +++ b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.c @@ -0,0 +1,196 @@ +/** @file + A helper driver to save information to SMRAM after SMRR is enabled. + + Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SMM_FROM_SMBASE_DRIVER 0x55 +#define SMM_FROM_CPU_DRIVER_SAVE_INFO 0x81 + +#define EFI_SMRAM_CPU_NVS_HEADER_GUID \ + { \ + 0x429501d9, 0xe447, 0x40f4, 0x86, 0x7b, 0x75, 0xc9, 0x3a, 0x1d, 0xb5, 0x4e \ + } + +UINT8 mSmiDataRegister; +BOOLEAN mLocked = FALSE; +EFI_GUID mSmramCpuNvsHeaderGuid = EFI_SMRAM_CPU_NVS_HEADER_GUID; + +/** + Dispatch function for a Software SMI handler. + + @param[in] DispatchHandle The handle of this dispatch function. + @param[in] DispatchContext The pointer to the dispatch function's context. + The SwSmiInputValue field is filled in + by the software dispatch driver prior to + invoking this dispatch function. + The dispatch function will only be called + for input values for which it is registered. + + @return None + +**/ +EFI_STATUS +SmramSaveInfoHandler ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_SW_REGISTER_CONTEXT *DispatchContext + ) +{ + EFI_STATUS Status; + UINT64 VarData[3]; + EFI_PHYSICAL_ADDRESS SmramDataAddress; + UINTN VarSize; + + if (DispatchContext == NULL) { + ASSERT(DispatchContext != NULL); + return EFI_UNSUPPORTED; + } + ASSERT (DispatchContext->SwSmiInputValue == SMM_FROM_SMBASE_DRIVER); + + if (!mLocked && IoRead8 (mSmiDataRegister) == SMM_FROM_CPU_DRIVER_SAVE_INFO) { + VarSize = sizeof (VarData); + Status = gRT->GetVariable ( + L"SmramCpuNvs", + &mSmramCpuNvsHeaderGuid, + NULL, + &VarSize, + VarData + ); + if (!EFI_ERROR (Status) && VarSize == sizeof (VarData)) { + Status = gSmst->SmmAllocatePages ( + AllocateAnyPages, + EfiRuntimeServicesData, + #if (defined X64_BUILD_SUPPORT) && (X64_BUILD_SUPPORT == 1) + EFI_SIZE_TO_PAGES (VarData[2]), + #else + EFI_SIZE_TO_PAGES ((UINT32)VarData[2]), + #endif + &SmramDataAddress + ); + ASSERT_EFI_ERROR (Status); + DEBUG ((EFI_D_ERROR, "CPU SMRAM NVS Data - %x\n", SmramDataAddress)); + DEBUG ((EFI_D_ERROR, "CPU SMRAM NVS Data size - %x\n", VarData[2])); + VarData[0] = (UINT64)SmramDataAddress; + CopyMem ( + (VOID *)(UINTN)(VarData[0]), + (VOID *)(UINTN)(VarData[1]), + (UINTN)(VarData[2]) + ); + Status = gRT->SetVariable ( + L"SmramCpuNvs", + &mSmramCpuNvsHeaderGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS, + VarSize, + &VarData + ); + } + } + + return EFI_SUCCESS; +} + +/** + Smm Ready To Lock event notification handler. + + It sets a flag indicating that SMRAM has been locked. + + @param[in] Protocol Points to the protocol's unique identifier. + @param[in] Interface Points to the interface instance. + @param[in] Handle The handle on which the interface was installed. + + @retval EFI_SUCCESS Notification handler runs successfully. +**/ +EFI_STATUS +EFIAPI +SmmReadyToLockEventNotify ( + IN CONST EFI_GUID *Protocol, + IN VOID *Interface, + IN EFI_HANDLE Handle + ) +{ + mLocked = TRUE; + return EFI_SUCCESS; +} + +/** + Entry point function of this driver. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. +**/ +EFI_STATUS +EFIAPI +SmramSaveInfoHandlerSmmMain ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + VOID *Registration; + EFI_SMM_SW_DISPATCH2_PROTOCOL *SmmSwDispatch; + EFI_SMM_SW_REGISTER_CONTEXT SmmSwDispatchContext; + EFI_HANDLE DispatchHandle; + + // + // Get SMI data register + // + mSmiDataRegister = R_PCH_APM_STS; + + // + // Register software SMI handler + // + + Status = gSmst->SmmLocateProtocol ( + &gEfiSmmSwDispatch2ProtocolGuid, + NULL, + (VOID **) &SmmSwDispatch + ); + ASSERT_EFI_ERROR (Status); + + SmmSwDispatchContext.SwSmiInputValue = SMM_FROM_SMBASE_DRIVER; + Status = SmmSwDispatch->Register ( + SmmSwDispatch, + (EFI_SMM_HANDLER_ENTRY_POINT2)&SmramSaveInfoHandler, + &SmmSwDispatchContext, + &DispatchHandle + ); + ASSERT_EFI_ERROR (Status); + + // + // Register SMM Ready To Lock Protocol notification + // + Status = gSmst->SmmRegisterProtocolNotify ( + &gEfiSmmReadyToLockProtocolGuid, + SmmReadyToLockEventNotify, + &Registration + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + diff --git a/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.inf b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.inf new file mode 100644 index 0000000000..edfa1cd3fe --- /dev/null +++ b/ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.inf @@ -0,0 +1,65 @@ +## @file +# Smram Save Information SMM Module +# +# This driver provides smi handler for storing information into smram. +# +# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SmramSaveInfoHandlerSmm + FILE_GUID = C95DC4A9-3EED-4DAD-AC31-A5CF5E61F6B1 + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x0001000A + + ENTRY_POINT = SmramSaveInfoHandlerSmmMain + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.common] + SmramSaveInfoHandlerSmm.c + +[Packages] + MdePkg/MdePkg.dec + ChvRefCodePkg/ChvRefCodePkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiRuntimeServicesTableLib + SmmServicesTableLib + BaseLib + BaseMemoryLib + IoLib + +[Protocols] + ## CONSUMES + gEfiSmmSwDispatch2ProtocolGuid + + ## CONSUMES + gEfiSmmControl2ProtocolGuid + + ## NOTIFY + gEfiSmmReadyToLockProtocolGuid + +[Depex] + gEfiSmmSwDispatch2ProtocolGuid AND + gEfiSmmControl2ProtocolGuid + +[BuildOptions] + *_*_X64_CC_FLAGS = -D X64_BUILD_SUPPORT=1 + -- cgit v1.2.3