Martin Roth | 7687e77 | 2023-08-22 16:32:20 -0600 | [diff] [blame^] | 1 | /* SPDX-License-Identifier: BSD-3-Clause */ |
| 2 | |
Marc Jones | 0b11bd0 | 2015-07-19 15:20:17 -0600 | [diff] [blame] | 3 | /* $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 | */ |
| 122 | typedef VOID (*PF_AP_TASK) (AMD_CONFIG_PARAMS *StdHeader); |
| 123 | typedef VOID (*PF_AP_TASK_I) (VOID *, AMD_CONFIG_PARAMS *StdHeader); |
| 124 | typedef VOID (*PF_AP_TASK_C) (AMD_CONFIG_PARAMS *StdHeader, AMD_CPU_EARLY_PARAMS *); |
| 125 | typedef VOID (*PF_AP_TASK_IC) (VOID *, AMD_CONFIG_PARAMS *StdHeader, AMD_CPU_EARLY_PARAMS *); |
| 126 | typedef UINT32 (*PF_AP_TASK_O) (AMD_CONFIG_PARAMS *StdHeader); |
| 127 | typedef UINT32 (*PF_AP_TASK_IO) (VOID *, AMD_CONFIG_PARAMS *StdHeader); |
| 128 | typedef UINT32 (*PF_AP_TASK_OC) (AMD_CONFIG_PARAMS *StdHeader, AMD_CPU_EARLY_PARAMS *); |
| 129 | typedef 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. |
| 133 | typedef 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. |
| 147 | typedef 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. |
| 154 | typedef 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. |
| 161 | typedef 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 |
| 169 | typedef 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 |
| 180 | typedef 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 |
| 197 | UINT8 |
| 198 | ApUtilReadRemoteControlByte ( |
| 199 | IN UINT32 TargetApicId, |
| 200 | IN AMD_CONFIG_PARAMS *StdHeader |
| 201 | ); |
| 202 | |
| 203 | VOID |
| 204 | ApUtilWriteControlByte ( |
| 205 | IN UINT8 Value, |
| 206 | IN AMD_CONFIG_PARAMS *StdHeader |
| 207 | ); |
| 208 | |
| 209 | UINT32 |
| 210 | ApUtilReadRemoteDataDword ( |
| 211 | IN UINT32 TargetApicId, |
| 212 | IN AMD_CONFIG_PARAMS *StdHeader |
| 213 | ); |
| 214 | |
| 215 | VOID |
| 216 | ApUtilWriteDataDword ( |
| 217 | IN UINT32 Value, |
| 218 | IN AMD_CONFIG_PARAMS *StdHeader |
| 219 | ); |
| 220 | |
| 221 | UINT32 |
| 222 | ApUtilRunCodeOnSocketCore ( |
| 223 | IN UINT8 Socket, |
| 224 | IN UINT8 Core, |
| 225 | IN AP_TASK *TaskPtr, |
| 226 | IN AMD_CONFIG_PARAMS *StdHeader |
| 227 | ); |
| 228 | |
| 229 | UINT8 |
| 230 | ApUtilWaitForCoreStatus ( |
| 231 | IN UINT32 TargetApicId, |
| 232 | IN AP_WAIT_FOR_STATUS *WaitParamsPtr, |
| 233 | IN AMD_CONFIG_PARAMS *StdHeader |
| 234 | ); |
| 235 | |
| 236 | VOID |
| 237 | ApEntry ( |
| 238 | IN AMD_CONFIG_PARAMS *StdHeader, |
| 239 | IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams |
| 240 | ); |
| 241 | |
| 242 | UINT32 |
| 243 | ApUtilTaskOnExecutingCore ( |
| 244 | IN AP_TASK *TaskPtr, |
| 245 | IN AMD_CONFIG_PARAMS *StdHeader, |
| 246 | IN VOID *ConfigParams |
| 247 | ); |
| 248 | |
| 249 | VOID |
| 250 | ApUtilTransmitBuffer ( |
| 251 | IN UINT8 Socket, |
| 252 | IN UINT8 Core, |
| 253 | IN AP_DATA_TRANSFER *BufferInfo, |
| 254 | IN AMD_CONFIG_PARAMS *StdHeader |
| 255 | ); |
| 256 | |
| 257 | AGESA_STATUS |
| 258 | ApUtilReceiveBuffer ( |
| 259 | IN UINT8 Socket, |
| 260 | IN UINT8 Core, |
| 261 | IN OUT AP_DATA_TRANSFER *BufferInfo, |
| 262 | IN AMD_CONFIG_PARAMS *StdHeader |
| 263 | ); |
| 264 | |
| 265 | VOID |
| 266 | GetLocalApicIdForCore ( |
| 267 | IN UINT32 TargetSocket, |
| 268 | IN UINT32 TargetCore, |
| 269 | OUT UINT32 *LocalApicId, |
| 270 | IN AMD_CONFIG_PARAMS *StdHeader |
| 271 | ); |
| 272 | |
| 273 | VOID |
| 274 | ApUtilRunCodeOnAllLocalCoresAtEarly ( |
| 275 | IN AP_TASK *TaskPtr, |
| 276 | IN AMD_CONFIG_PARAMS *StdHeader, |
| 277 | IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr |
| 278 | ); |
| 279 | |
| 280 | VOID |
| 281 | RelinquishControlOfAllAPs ( |
| 282 | IN AMD_CONFIG_PARAMS *StdHeader |
| 283 | ); |
| 284 | |
| 285 | VOID |
| 286 | GetCsSelector ( |
| 287 | IN UINT16 *Selector, |
| 288 | IN AMD_CONFIG_PARAMS *StdHeader |
| 289 | ); |
| 290 | |
| 291 | VOID |
| 292 | SetIdtr ( |
| 293 | IN IDT_BASE_LIMIT *IdtInfo, |
| 294 | IN AMD_CONFIG_PARAMS *StdHeader |
| 295 | ); |
| 296 | |
| 297 | VOID |
| 298 | GetIdtr ( |
| 299 | IN IDT_BASE_LIMIT *IdtInfo, |
| 300 | IN AMD_CONFIG_PARAMS *StdHeader |
| 301 | ); |
| 302 | |
| 303 | #endif /* _CPU_APIC_UTILITIES_H_ */ |
| 304 | |