1 /** @file
2   SMM STM support functions
3 
4   Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
5   This program and the accompanying materials
6   are licensed and made available under the terms and conditions of the BSD License
7   which accompanies this distribution.  The full text of the license may be found at
8   http://opensource.org/licenses/bsd-license.php.
9 
10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 #include <PiSmm.h>
16 #include <Library/DebugLib.h>
17 
18 #include "SmmStm.h"
19 
20 ///
21 /// Page Table Entry
22 ///
23 #define IA32_PG_P                   BIT0
24 #define IA32_PG_RW                  BIT1
25 #define IA32_PG_PS                  BIT7
26 
27 /**
28 
29   Create 4G page table for STM.
30   2M PAE page table in X64 version.
31 
32   @param PageTableBase        The page table base in MSEG
33 
34 **/
35 VOID
StmGen4GPageTable(IN UINTN PageTableBase)36 StmGen4GPageTable (
37   IN UINTN              PageTableBase
38   )
39 {
40   UINTN                             Index;
41   UINTN                             SubIndex;
42   UINT64                            *Pde;
43   UINT64                            *Pte;
44   UINT64                            *Pml4;
45 
46   Pml4 = (UINT64*)(UINTN)PageTableBase;
47   PageTableBase += SIZE_4KB;
48   *Pml4 = PageTableBase | IA32_PG_RW | IA32_PG_P;
49 
50   Pde = (UINT64*)(UINTN)PageTableBase;
51   PageTableBase += SIZE_4KB;
52   Pte = (UINT64 *)(UINTN)PageTableBase;
53 
54   for (Index = 0; Index < 4; Index++) {
55     *Pde = PageTableBase | IA32_PG_RW | IA32_PG_P;
56     Pde++;
57     PageTableBase += SIZE_4KB;
58 
59     for (SubIndex = 0; SubIndex < SIZE_4KB / sizeof (*Pte); SubIndex++) {
60       *Pte = (((Index << 9) + SubIndex) << 21) | IA32_PG_PS | IA32_PG_RW | IA32_PG_P;
61       Pte++;
62     }
63   }
64 }
65 
66 /**
67   This is SMM exception handle.
68   Consumed by STM when exception happen.
69 
70   @param Context  STM protection exception stack frame
71 
72   @return the EBX value for STM reference.
73           EBX = 0: resume SMM guest using register state found on exception stack.
74           EBX = 1 to 0x0F: EBX contains a BIOS error code which the STM must record in the
75                            TXT.ERRORCODE register and subsequently reset the system via
76                            TXT.CMD.SYS_RESET. The value of the TXT.ERRORCODE register is calculated as
77                            follows: TXT.ERRORCODE = (EBX & 0x0F) | STM_CRASH_BIOS_PANIC
78           EBX = 0x10 to 0xFFFFFFFF - reserved, do not use.
79 
80 **/
81 UINT32
82 EFIAPI
SmmStmExceptionHandler(IN OUT STM_PROTECTION_EXCEPTION_STACK_FRAME Context)83 SmmStmExceptionHandler (
84   IN OUT STM_PROTECTION_EXCEPTION_STACK_FRAME Context
85   )
86 {
87   // TBD - SmmStmExceptionHandler, record information
88   DEBUG ((DEBUG_ERROR, "SmmStmExceptionHandler ...\n"));
89   //
90   // Skip this instruction and continue;
91   //
92   Context.X64StackFrame->Rip += Context.X64StackFrame->VmcsExitInstructionLength;
93 
94   return 0;
95 }
96