1 /*++
2 
3   Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
4 
5 
6   This program and the accompanying materials are licensed and made available under
7 
8   the terms and conditions of the BSD License that accompanies this distribution.
9 
10   The full text of the license may be found at
11 
12   http://opensource.org/licenses/bsd-license.php.
13 
14 
15 
16   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
17 
18   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 
20 
21 
22 
23 
24 Module Name:
25 
26   EfiRegTableLib.h
27 
28 Abstract:
29 
30   Definitions and macros for building register tables for chipset
31   initialization..
32 
33   Components linking this lib must include CpuIo, PciRootBridgeIo, and
34   BootScriptSave protocols in their DPX.
35 
36 
37 
38 --*/
39 
40 #ifndef EFI_REG_TABLE_H
41 #define EFI_REG_TABLE_H
42 
43 
44 #include <PiDxe.h>
45 #include <Library/BaseLib.h>
46 #include <Library/DebugLib.h>
47 #include <Library/UefiLib.h>
48 #include <Library/UefiDriverEntryPoint.h>
49 #include <Protocol/CpuIo.h>
50 #include <Protocol/BootScriptSave.h>
51 #include <Framework/BootScript.h>
52 #include <Protocol/PciRootBridgeIo.h>
53 
54 
55 #define OPCODE_BASE(OpCode)       ((UINT8)((OpCode) & 0xFF))
56 #define OPCODE_FLAGS(OpCode)      ((UINT8)(((OpCode) >> 8) & 0xFF))
57 #define OPCODE_EXTRA_DATA(OpCode) ((UINT16)((OpCode) >> 16))
58 
59 //
60 // RegTable Base OpCodes
61 //
62 #define OP_TERMINATE_TABLE                0
63 #define OP_MEM_WRITE                      1
64 #define OP_MEM_READ_MODIFY_WRITE          2
65 #define OP_IO_WRITE                       3
66 #define OP_IO_READ_MODIFY_WRITE           4
67 #define OP_PCI_WRITE                      5
68 #define OP_PCI_READ_MODIFY_WRITE          6
69 #define OP_STALL                          7
70 
71 //
72 // RegTable OpCode Flags
73 //
74 #define OPCODE_FLAG_S3SAVE                1
75 
76 
77 #define TERMINATE_TABLE { (UINT32) OP_TERMINATE_TABLE, (UINT32) 0, (UINT32) 0 }
78 
79 
80 //
81 // REG_TABLE_ENTRY_PCI_WRITE encodes the width in the upper bits of the OpCode
82 // as one of the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH values
83 //
84 typedef struct {
85   UINT32                                OpCode;
86   UINT32                                PciAddress;
87   UINT32                                Data;
88 } EFI_REG_TABLE_PCI_WRITE;
89 
90 #define PCI_WRITE(Bus, Dev, Fnc, Reg, Width, Data, S3Flag)                    \
91   {                                                                           \
92     (UINT32) (OP_PCI_WRITE | ((S3Flag) << 8) | ((Width) << 16)),              \
93     (UINT32) (EFI_PCI_ADDRESS ((Bus), (Dev), (Fnc), (Reg))),                  \
94     (UINT32) (Data),                                                          \
95     (UINT32) (0)                                                              \
96   }
97 
98 typedef struct {
99   UINT32                                OpCode;
100   UINT32                                MemAddress;
101   UINT32                                Data;
102 } EFI_REG_TABLE_MEM_WRITE;
103 
104 typedef struct {
105   UINT32                                OpCode;
106   UINT32                                PciAddress;
107   UINT32                                OrMask;
108   UINT32                                AndMask;
109 } EFI_REG_TABLE_PCI_READ_MODIFY_WRITE;
110 
111 #define PCI_READ_MODIFY_WRITE(Bus, Dev, Fnc, Reg, Width, OrMask, AndMask, S3Flag)  \
112   {                                                                           \
113     (UINT32) (OP_PCI_READ_MODIFY_WRITE | ((S3Flag) << 8) | ((Width) << 16)),  \
114     (UINT32) (EFI_PCI_ADDRESS ((Bus), (Dev), (Fnc), (Reg))),                  \
115     (UINT32) (OrMask),                                                        \
116     (UINT32) (AndMask)                                                        \
117   }
118 
119 typedef struct {
120   UINT32                                OpCode;
121   UINT32                                MemAddress;
122   UINT32                                OrMask;
123   UINT32                                AndMask;
124 } EFI_REG_TABLE_MEM_READ_MODIFY_WRITE;
125 
126 #define MEM_READ_MODIFY_WRITE(Address, Width, OrMask, AndMask, S3Flag)  \
127   {                                                                           \
128     (UINT32) (OP_MEM_READ_MODIFY_WRITE | ((S3Flag) << 8) | ((Width) << 16)),  \
129     (UINT32) (Address),                  \
130     (UINT32) (OrMask),                                                        \
131     (UINT32) (AndMask)                                                        \
132   }
133 
134 typedef struct {
135   UINT32                                OpCode;
136   UINT32                                Field2;
137   UINT32                                Field3;
138   UINT32                                Field4;
139 } EFI_REG_TABLE_GENERIC;
140 
141 typedef union {
142   EFI_REG_TABLE_GENERIC                 Generic;
143   EFI_REG_TABLE_PCI_WRITE               PciWrite;
144   EFI_REG_TABLE_PCI_READ_MODIFY_WRITE   PciReadModifyWrite;
145   EFI_REG_TABLE_MEM_READ_MODIFY_WRITE   MemReadModifyWrite;
146 } EFI_REG_TABLE;
147 
148 /**
149   Processes register table assuming which may contain PCI, IO, MEM, and STALL
150   entries.
151 
152   No parameter checking is done so the caller must be careful about omitting
153   values for PciRootBridgeIo or CpuIo parameters.  If the regtable does
154   not contain any PCI accesses, it is safe to omit the PciRootBridgeIo (supply
155   NULL).  If the regtable does not contain any IO or Mem entries, it is safe to
156   omit the CpuIo (supply NULL).
157 
158   The RegTableEntry parameter is not checked, but is required.
159 
160   gBS is assumed to have been defined and is used when processing stalls.
161 
162   The function processes each entry sequentially until an OP_TERMINATE_TABLE
163   entry is encountered.
164 
165   @param[in] RegTableEntry    A pointer to the register table to process
166 
167   @param[in] PciRootBridgeIo  A pointer to the instance of PciRootBridgeIo that is used
168                               when processing PCI table entries
169 
170   @param[in] CpuIo            A pointer to the instance of CpuIo that is used when processing IO and
171                               MEM table entries
172 
173   @retval Nothing.
174 
175 **/
176 VOID
177 ProcessRegTablePci (
178   EFI_REG_TABLE                   * RegTableEntry,
179   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * PciRootBridgeIo,
180   EFI_CPU_IO_PROTOCOL             * CpuIo
181   );
182 
183 /**
184   Processes register table assuming which may contain IO, MEM, and STALL
185   entries, but must NOT contain any PCI entries.  Any PCI entries cause an
186   ASSERT in a DEBUG build and are skipped in a free build.
187 
188   No parameter checking is done.  Both RegTableEntry and CpuIo parameters are
189   required.
190 
191   gBS is assumed to have been defined and is used when processing stalls.
192 
193   The function processes each entry sequentially until an OP_TERMINATE_TABLE
194   entry is encountered.
195 
196   @param[in] RegTableEntry - A pointer to the register table to process
197 
198   @param[in] CpuIo - A pointer to the instance of CpuIo that is used when processing IO and
199                   MEM table entries
200 
201   @retval Nothing.
202 
203 **/
204 VOID
205 ProcessRegTableCpu (
206   EFI_REG_TABLE                   * RegTableEntry,
207   EFI_CPU_IO_PROTOCOL             * CpuIo
208   );
209 
210 #endif
211