summaryrefslogtreecommitdiff
path: root/ChvRefCodePkg
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-06-02 13:35:49 +0800
committerHao Wu <hao.a.wu@intel.com>2016-06-07 09:55:26 +0800
commitdad0b0a63c85b47075b1b9c1054ca33f14bb85d0 (patch)
treef1fc5c9791c577769a90ced2c2416a554fecf742 /ChvRefCodePkg
parente53f60302eb2449e230a6a42049718b5d32da2f0 (diff)
downloadedk2-platforms-dad0b0a63c85b47075b1b9c1054ca33f14bb85d0.tar.xz
ChvRefCodePkg: Add CPU SampleCode
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'ChvRefCodePkg')
-rw-r--r--ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Library/DTSHookLib.h43
-rw-r--r--ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Library/KscLib.h238
-rw-r--r--ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Library/SmmIoLib.h190
-rw-r--r--ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Include/Protocol/GenericMemoryTest.h124
-rw-r--r--ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.c102
-rw-r--r--ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/DTSHookLib/Smm/DTSHookLib.inf29
-rw-r--r--ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/Ksc/Smm/SmmKscLib.c218
-rw-r--r--ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/Ksc/Smm/SmmKscLib.inf29
-rw-r--r--ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/SmmIo/SmmIo.c236
-rw-r--r--ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/SmmIo/SmmIo.inf38
-rw-r--r--ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/Library/SmmIo/SmmPciIo.c164
-rw-r--r--ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/SampleCode.dec26
-rw-r--r--ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.c196
-rw-r--r--ChvRefCodePkg/CherryViewSoc/CPU/SampleCode/SmramSaveInfoHandlerSmm/SmramSaveInfoHandlerSmm.inf65
14 files changed, 1698 insertions, 0 deletions
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.<BR>
+
+ 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 <Library/KscLib.h>
+
+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.<BR>
+
+ 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.<BR>
+
+ 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 <PiSmm.h>
+#include <Base.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/SmmServicesTableLib.h>
+
+//
+// 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.<BR>
+
+ 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.<BR>
+
+ 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/DTSHookLib.h>
+
+/**
+ 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.<BR>
+#
+# 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.<BR>
+
+ 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.<BR>
+#
+# 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.<BR>
+
+ 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 <Library/SmmIoLib.h>
+#include <Library/IoLib.h>
+#include "PchAccess.h"
+#include <Protocol/SmmBase2.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+/**
+ 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.<BR>
+#
+# 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.<BR>
+
+ 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/SmmIoLib.h>
+#include <Protocol/SmmBase2.h>
+#include <Library/DebugLib.h>
+
+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.<BR>
+#
+# 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.<BR>
+
+ 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 <PiSmm.h>
+#include <PchRegs.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Protocol/SmmSwDispatch2.h>
+#include <Protocol/SmmReadyToLock.h>
+#include <Protocol/SmmControl2.h>
+
+#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.<BR>
+#
+# 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
+