blob: 16f4657dd4faf0860378b4b0778f89a6e3ef8ec7 [file] [log] [blame]
Martin Roth7687e772023-08-22 16:32:20 -06001/* SPDX-License-Identifier: BSD-3-Clause */
2
Marc Jones0b11bd02015-07-19 15:20:17 -06003/* $NoKeywords:$ */
4/**
5 * @file
6 *
7 * AMD CPU APIC related utility functions and structures
8 *
9 * Contains code that provides mechanism to invoke and control APIC communication.
10 *
11 * @xrefitem bom "File Content Label" "Release Content"
12 * @e project: AGESA
13 * @e sub-project: CPU
14 * @e \$Revision: 281178 $ @e \$Date: 2013-12-18 02:14:15 -0600 (Wed, 18 Dec 2013) $
15 *
16 */
17/*****************************************************************************
18 *
19 * Copyright (c) 2008 - 2014, Advanced Micro Devices, Inc.
20 * All rights reserved.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions are met:
24 * * Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * * Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
30 * its contributors may be used to endorse or promote products derived
31 * from this software without specific prior written permission.
32 *
33 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
37 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
40 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 *
44 ***************************************************************************/
45
46#ifndef _CPU_APIC_UTILITIES_H_
47#define _CPU_APIC_UTILITIES_H_
48
49
50/*---------------------------------------------------------------------------------------
51 * M I X E D (Definitions And Macros / Typedefs, Structures, Enums)
52 *---------------------------------------------------------------------------------------
53 */
54
55
56/*---------------------------------------------------------------------------------------
57 * D E F I N I T I O N S A N D M A C R O S
58 *---------------------------------------------------------------------------------------
59 */
60#define APIC_CTRL_DWORD 0xF
61#define APIC_CTRL_REG (APIC_CTRL_DWORD << 4)
62#define APIC_CTRL_MASK 0xFF
63#define APIC_CTRL_SHIFT 0
64
65#define APIC_DATA_DWORD 0x38
66#define APIC_DATA_REG (APIC_DATA_DWORD << 4)
67
68#define APIC_REMOTE_READ_REG 0xC0
69#define APIC_CMD_LO_REG 0x300
70#define APIC_CMD_HI_REG 0x310
71
72// APIC_CMD_LO_REG bits
73#define CMD_REG_DELIVERY_STATUS 0x1000
74#define CMD_REG_TO_READ 0x300
75#define CMD_REG_REMOTE_RD_STS_MSK 0x30000ul
76#define CMD_REG_REMOTE_DELIVERY_PENDING 0x10000ul
77#define CMD_REG_REMOTE_DELIVERY_DONE 0x20000ul
78#define CMD_REG_TO_NMI 0x400
79
80// ExeFlags bits
81#define WAIT_FOR_CORE 0x00000001ul
82#define TASK_HAS_OUTPUT 0x00000002ul
83#define RETURN_PARAMS 0x00000004ul
84#define END_AT_HLT 0x00000008ul
85#define PASS_EARLY_PARAMS 0x00000010ul
86
87// Control Byte Values
88// bit 7 indicates the type of message
89// 1 - control message
90// 0 - launch + APIC ID = message to go
91//
92#define CORE_UNAVAILABLE 0xFF
93#define CORE_IDLE 0xFE
94#define CORE_IDLE_HLT 0xFD
95#define CORE_ACTIVE 0xFC
96#define CORE_NEEDS_PTR 0xFB
97#define CORE_NEEDS_DATA_SIZE 0xFA
98#define CORE_STS_DATA_READY_1 0xF9
99#define CORE_STS_DATA_READY_0 0xF8
100#define CORE_DATA_FLAGS_READY 0xF7
101#define CORE_DATA_FLAGS_ACKNOWLEDGE 0xF6
102#define CORE_DATA_PTR_READY 0xF5
103
104// Macro used to determine the number of dwords to transmit to the AP as input
105#define SIZE_IN_DWORDS(sInput) ((UINT32) (((sizeof (sInput)) + 3) >> 2))
106
107// IDT table
108#define IDT_DESC_PRESENT 0x80
109
110#define IDT_DESC_TYPE_LDT 0x02
111#define IDT_DESC_TYPE_CALL16 0x04
112#define IDT_DESC_TYPE_TASK 0x05
113#define IDT_DESC_TYPE_INT16 0x06
114#define IDT_DESC_TYPE_TRAP16 0x07
115#define IDT_DESC_TYPE_CALL32 0x0C
116#define IDT_DESC_TYPE_INT32 0x0E
117#define IDT_DESC_TYPE_TRAP32 0x0F
118/*---------------------------------------------------------------------------------------
119 * T Y P E D E F S, S T R U C T U R E S, E N U M S
120 *---------------------------------------------------------------------------------------
121 */
122typedef VOID (*PF_AP_TASK) (AMD_CONFIG_PARAMS *StdHeader);
123typedef VOID (*PF_AP_TASK_I) (VOID *, AMD_CONFIG_PARAMS *StdHeader);
124typedef VOID (*PF_AP_TASK_C) (AMD_CONFIG_PARAMS *StdHeader, AMD_CPU_EARLY_PARAMS *);
125typedef VOID (*PF_AP_TASK_IC) (VOID *, AMD_CONFIG_PARAMS *StdHeader, AMD_CPU_EARLY_PARAMS *);
126typedef UINT32 (*PF_AP_TASK_O) (AMD_CONFIG_PARAMS *StdHeader);
127typedef UINT32 (*PF_AP_TASK_IO) (VOID *, AMD_CONFIG_PARAMS *StdHeader);
128typedef UINT32 (*PF_AP_TASK_OC) (AMD_CONFIG_PARAMS *StdHeader, AMD_CPU_EARLY_PARAMS *);
129typedef UINT32 (*PF_AP_TASK_IOC) (VOID *, AMD_CONFIG_PARAMS *StdHeader, AMD_CPU_EARLY_PARAMS *);
130
131/// Function pointer union representing the eight different
132/// types of functions that an AP can be asked to perform.
133typedef union {
134 PF_AP_TASK PfApTask; ///< AMD_CONFIG_PARAMS * input with no output
135 PF_AP_TASK_I PfApTaskI; ///< VOID * + AMD_CONFIG_PARAMS * input with no output
136 PF_AP_TASK_C PfApTaskC; ///< AMD_CONFIG_PARAMS * + AMD_CPU_EARLY_PARAMS * input with no output
137 PF_AP_TASK_IC PfApTaskIC; ///< VOID * + AMD_CONFIG_PARAMS * + AMD_CPU_EARLY_PARAMS * input with no output
138 PF_AP_TASK_O PfApTaskO; ///< AMD_CONFIG_PARAMS * input with UINT32 output
139 PF_AP_TASK_IO PfApTaskIO; ///< VOID * + AMD_CONFIG_PARAMS * input with UINT32 output
140 PF_AP_TASK_OC PfApTaskOC; ///< AMD_CONFIG_PARAMS * + AMD_CPU_EARLY_PARAMS * input with UINT32 output
141 PF_AP_TASK_IOC PfApTaskIOC; ///< VOID * + AMD_CONFIG_PARAMS * + AMD_CPU_EARLY_PARAMS * input with UINT32 output
142} AP_FUNCTION_PTR;
143
144/// Input structure for ApUtilTransmitBuffer and ApUtilReceiveBuffer
145/// containing information about the data transfer from one core
146/// to another.
147typedef struct {
148 IN OUT UINT16 DataSizeInDwords; ///< Size of the data to be transferred rounded up to the nearest dword
149 IN OUT VOID *DataPtr; ///< Pointer to the data
150 IN UINT32 DataTransferFlags; ///< Flags dictating certain aspects of the data transfer
151} AP_DATA_TRANSFER;
152
153/// Input structure for ApUtilRunCodeOnSocketCore.
154typedef struct _AP_TASK {
155 AP_FUNCTION_PTR FuncAddress; ///< Pointer to the function that the AP will run
156 AP_DATA_TRANSFER DataTransfer; ///< Data transfer struct for optionally passing data that the AP should use as input to the function
157 UINT32 ExeFlags; ///< Flags dictating certain aspects of the AP tasking sequence
158} AP_TASK;
159
160/// Input structure for ApUtilWaitForCoreStatus.
161typedef struct {
162 IN UINT8 *Status; ///< Pointer to the 1st element of an array of values to wait for
163 IN UINT8 NumberOfElements; ///< Number of elements in the array
164 IN UINT32 RetryCount; ///< Number of remote read cycles to complete before quitting
165 IN UINT32 WaitForStatusFlags; ///< Flags dictating certain aspects of ApUtilWaitForCoreStatus
166} AP_WAIT_FOR_STATUS;
167
168/// Interrupt Descriptor Table entry
169typedef struct {
170 UINT16 OffsetLo; ///< Lower 16 bits of the interrupt handler routine's offset
171 UINT16 Selector; ///< Interrupt handler routine's selector
172 UINT8 Rsvd; ///< Reserved
173 UINT8 Flags; ///< Interrupt flags
174 UINT16 OffsetHi; ///< Upper 16 bits of the interrupt handler routine's offset
175 UINT32 Offset64; ///< High order 32 bits of the handler's offset needed when in 64 bit mode
176 UINT32 Rsvd64; ///< Reserved
177} IDT_DESCRIPTOR;
178
179/// Structure needed to load the IDTR using the lidt instruction
180typedef struct {
181 UINT16 Limit; ///< Interrupt Descriptor Table size
182 UINT64 Base; ///< Interrupt Descriptor Table base address
183} IDT_BASE_LIMIT;
184
185#define WAIT_STATUS_EQUALITY 0x00000001ul
186#define WAIT_INFINITELY 0
187
188// Data Transfer Flags
189#define DATA_IN_MEMORY 0x00000001ul
190
191
192/*---------------------------------------------------------------------------------------
193 * F U N C T I O N P R O T O T Y P E
194 *---------------------------------------------------------------------------------------
195 */
196// These are P U B L I C functions, used by AGESA
197UINT8
198ApUtilReadRemoteControlByte (
199 IN UINT32 TargetApicId,
200 IN AMD_CONFIG_PARAMS *StdHeader
201 );
202
203VOID
204ApUtilWriteControlByte (
205 IN UINT8 Value,
206 IN AMD_CONFIG_PARAMS *StdHeader
207 );
208
209UINT32
210ApUtilReadRemoteDataDword (
211 IN UINT32 TargetApicId,
212 IN AMD_CONFIG_PARAMS *StdHeader
213 );
214
215VOID
216ApUtilWriteDataDword (
217 IN UINT32 Value,
218 IN AMD_CONFIG_PARAMS *StdHeader
219 );
220
221UINT32
222ApUtilRunCodeOnSocketCore (
223 IN UINT8 Socket,
224 IN UINT8 Core,
225 IN AP_TASK *TaskPtr,
226 IN AMD_CONFIG_PARAMS *StdHeader
227 );
228
229UINT8
230ApUtilWaitForCoreStatus (
231 IN UINT32 TargetApicId,
232 IN AP_WAIT_FOR_STATUS *WaitParamsPtr,
233 IN AMD_CONFIG_PARAMS *StdHeader
234 );
235
236VOID
237ApEntry (
238 IN AMD_CONFIG_PARAMS *StdHeader,
239 IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams
240 );
241
242UINT32
243ApUtilTaskOnExecutingCore (
244 IN AP_TASK *TaskPtr,
245 IN AMD_CONFIG_PARAMS *StdHeader,
246 IN VOID *ConfigParams
247 );
248
249VOID
250ApUtilTransmitBuffer (
251 IN UINT8 Socket,
252 IN UINT8 Core,
253 IN AP_DATA_TRANSFER *BufferInfo,
254 IN AMD_CONFIG_PARAMS *StdHeader
255 );
256
257AGESA_STATUS
258ApUtilReceiveBuffer (
259 IN UINT8 Socket,
260 IN UINT8 Core,
261 IN OUT AP_DATA_TRANSFER *BufferInfo,
262 IN AMD_CONFIG_PARAMS *StdHeader
263 );
264
265VOID
266GetLocalApicIdForCore (
267 IN UINT32 TargetSocket,
268 IN UINT32 TargetCore,
269 OUT UINT32 *LocalApicId,
270 IN AMD_CONFIG_PARAMS *StdHeader
271 );
272
273VOID
274ApUtilRunCodeOnAllLocalCoresAtEarly (
275 IN AP_TASK *TaskPtr,
276 IN AMD_CONFIG_PARAMS *StdHeader,
277 IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr
278 );
279
280VOID
281RelinquishControlOfAllAPs (
282 IN AMD_CONFIG_PARAMS *StdHeader
283 );
284
285VOID
286GetCsSelector (
287 IN UINT16 *Selector,
288 IN AMD_CONFIG_PARAMS *StdHeader
289 );
290
291VOID
292SetIdtr (
293 IN IDT_BASE_LIMIT *IdtInfo,
294 IN AMD_CONFIG_PARAMS *StdHeader
295 );
296
297VOID
298GetIdtr (
299 IN IDT_BASE_LIMIT *IdtInfo,
300 IN AMD_CONFIG_PARAMS *StdHeader
301 );
302
303#endif /* _CPU_APIC_UTILITIES_H_ */
304