Stefan Reinauer | debb11f | 2008-10-29 04:46:52 +0000 | [diff] [blame] | 1 | /* |
| 2 | * This file is part of the coreboot project. |
| 3 | * |
Stefan Reinauer | 36c8340 | 2009-03-01 10:16:01 +0000 | [diff] [blame] | 4 | * Copyright (C) 2008-2009 coresystems GmbH |
Stefan Reinauer | debb11f | 2008-10-29 04:46:52 +0000 | [diff] [blame] | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License as published by |
| 8 | * the Free Software Foundation; version 2 of the License. |
| 9 | * |
| 10 | * This program is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | * GNU General Public License for more details. |
Stefan Reinauer | debb11f | 2008-10-29 04:46:52 +0000 | [diff] [blame] | 14 | */ |
| 15 | |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 16 | /* AMD64 SMM State-Save Area |
Stefan Reinauer | debb11f | 2008-10-29 04:46:52 +0000 | [diff] [blame] | 17 | * starts @ 0x7e00 |
| 18 | */ |
Sven Schnelle | 180f81e | 2011-06-28 08:06:18 +0200 | [diff] [blame] | 19 | |
| 20 | #ifndef CPU_X86_SMM_H |
| 21 | #define CPU_X86_SMM_H |
| 22 | |
Edward O'Callaghan | c4561e2 | 2014-06-26 15:02:40 +1000 | [diff] [blame] | 23 | #include <arch/cpu.h> |
| 24 | #include <types.h> |
| 25 | |
Aaron Durbin | 1fef1f5 | 2012-12-19 17:15:43 -0600 | [diff] [blame] | 26 | #define SMM_DEFAULT_BASE 0x30000 |
| 27 | #define SMM_DEFAULT_SIZE 0x10000 |
| 28 | |
Rudolf Marek | b5b3b3b | 2011-07-02 16:36:17 +0200 | [diff] [blame] | 29 | /* used only by C programs so far */ |
| 30 | #define SMM_BASE 0xa0000 |
| 31 | |
Aaron Durbin | 62f100b | 2012-11-07 12:27:29 -0600 | [diff] [blame] | 32 | #define SMM_ENTRY_OFFSET 0x8000 |
| 33 | #define SMM_SAVE_STATE_BEGIN(x) (SMM_ENTRY_OFFSET + (x)) |
| 34 | |
Stefan Reinauer | debb11f | 2008-10-29 04:46:52 +0000 | [diff] [blame] | 35 | typedef struct { |
| 36 | u16 es_selector; |
| 37 | u16 es_attributes; |
| 38 | u32 es_limit; |
| 39 | u64 es_base; |
| 40 | |
| 41 | u16 cs_selector; |
| 42 | u16 cs_attributcs; |
| 43 | u32 cs_limit; |
| 44 | u64 cs_base; |
| 45 | |
| 46 | u16 ss_selector; |
| 47 | u16 ss_attributss; |
| 48 | u32 ss_limit; |
| 49 | u64 ss_base; |
| 50 | |
| 51 | u16 ds_selector; |
| 52 | u16 ds_attributds; |
| 53 | u32 ds_limit; |
| 54 | u64 ds_base; |
| 55 | |
| 56 | u16 fs_selector; |
| 57 | u16 fs_attributfs; |
| 58 | u32 fs_limit; |
| 59 | u64 fs_base; |
| 60 | |
| 61 | u16 gs_selector; |
| 62 | u16 gs_attributgs; |
| 63 | u32 gs_limit; |
| 64 | u64 gs_base; |
| 65 | |
| 66 | u8 reserved0[4]; |
| 67 | u16 gdtr_limit; |
| 68 | u8 reserved1[2]; |
| 69 | u64 gdtr_base; |
| 70 | |
| 71 | u16 ldtr_selector; |
| 72 | u16 ldtr_attributes; |
| 73 | u32 ldtr_limit; |
| 74 | u64 ldtr_base; |
| 75 | |
| 76 | u8 reserved2[4]; |
| 77 | u16 idtr_limit; |
| 78 | u8 reserved3[2]; |
| 79 | u64 idtr_base; |
| 80 | |
| 81 | u16 tr_selector; |
| 82 | u16 tr_attributes; |
| 83 | u32 tr_limit; |
| 84 | u64 tr_base; |
| 85 | |
| 86 | u8 reserved4[40]; |
| 87 | |
| 88 | u8 io_restart; |
| 89 | u8 autohalt_restart; |
| 90 | |
| 91 | u8 reserved5[6]; |
| 92 | |
| 93 | u64 efer; |
| 94 | |
| 95 | u8 reserved6[36]; |
| 96 | |
| 97 | u32 smm_revision; |
| 98 | u32 smbase; |
| 99 | |
| 100 | u8 reserved7[68]; |
| 101 | |
| 102 | u64 cr4; |
| 103 | u64 cr3; |
| 104 | u64 cr0; |
| 105 | u64 dr7; |
| 106 | u64 dr6; |
| 107 | |
| 108 | u64 rflags; |
| 109 | u64 rip; |
| 110 | u64 r15; |
| 111 | u64 r14; |
| 112 | u64 r13; |
| 113 | u64 r12; |
| 114 | u64 r11; |
| 115 | u64 r10; |
| 116 | u64 r9; |
| 117 | u64 r8; |
| 118 | |
| 119 | u64 rdi; |
| 120 | u64 rsi; |
| 121 | u64 rpb; |
| 122 | u64 rsp; |
| 123 | u64 rbx; |
| 124 | u64 rdx; |
| 125 | u64 rcx; |
| 126 | u64 rax; |
| 127 | } __attribute__((packed)) amd64_smm_state_save_area_t; |
| 128 | |
| 129 | |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 130 | /* Intel Core 2 (EM64T) SMM State-Save Area |
Stefan Reinauer | debb11f | 2008-10-29 04:46:52 +0000 | [diff] [blame] | 131 | * starts @ 0x7d00 |
| 132 | */ |
| 133 | typedef struct { |
| 134 | u8 reserved0[208]; |
| 135 | |
| 136 | u32 gdtr_upper_base; |
| 137 | u32 ldtr_upper_base; |
| 138 | u32 idtr_upper_base; |
| 139 | |
| 140 | u8 reserved1[4]; |
| 141 | |
| 142 | u64 io_rdi; |
| 143 | u64 io_rip; |
| 144 | u64 io_rcx; |
| 145 | u64 io_rsi; |
| 146 | u64 cr4; |
| 147 | |
| 148 | u8 reserved2[68]; |
| 149 | |
| 150 | u64 gdtr_base; |
| 151 | u64 idtr_base; |
| 152 | u64 ldtr_base; |
| 153 | |
| 154 | u8 reserved3[84]; |
| 155 | |
| 156 | u32 smm_revision; |
| 157 | u32 smbase; |
| 158 | |
| 159 | u16 io_restart; |
| 160 | u16 autohalt_restart; |
| 161 | |
| 162 | u8 reserved4[24]; |
| 163 | |
| 164 | u64 r15; |
| 165 | u64 r14; |
| 166 | u64 r13; |
| 167 | u64 r12; |
| 168 | u64 r11; |
| 169 | u64 r10; |
| 170 | u64 r9; |
| 171 | u64 r8; |
| 172 | |
| 173 | u64 rax; |
| 174 | u64 rcx; |
| 175 | u64 rdx; |
| 176 | u64 rbx; |
| 177 | |
| 178 | u64 rsp; |
| 179 | u64 rbp; |
| 180 | u64 rsi; |
| 181 | u64 rdi; |
| 182 | |
| 183 | |
| 184 | u64 io_mem_addr; |
| 185 | u32 io_misc_info; |
| 186 | |
| 187 | u32 es_sel; |
| 188 | u32 cs_sel; |
| 189 | u32 ss_sel; |
| 190 | u32 ds_sel; |
| 191 | u32 fs_sel; |
| 192 | u32 gs_sel; |
| 193 | |
| 194 | u32 ldtr_sel; |
| 195 | u32 tr_sel; |
| 196 | |
| 197 | u64 dr7; |
| 198 | u64 dr6; |
| 199 | u64 rip; |
| 200 | u64 efer; |
| 201 | u64 rflags; |
| 202 | |
| 203 | u64 cr3; |
| 204 | u64 cr0; |
| 205 | } __attribute__((packed)) em64t_smm_state_save_area_t; |
| 206 | |
| 207 | |
Aaron Durbin | d052040 | 2013-10-21 22:21:12 -0500 | [diff] [blame] | 208 | /* Intel Revision 30100 SMM State-Save Area |
| 209 | * The following processor architectures use this: |
| 210 | * - Bay Trail |
| 211 | */ |
| 212 | #define SMM_EM64T100_ARCH_OFFSET 0x7c00 |
| 213 | #define SMM_EM64T100_SAVE_STATE_OFFSET \ |
| 214 | SMM_SAVE_STATE_BEGIN(SMM_EM64T100_ARCH_OFFSET) |
| 215 | typedef struct { |
| 216 | u8 reserved0[256]; |
| 217 | u8 reserved1[208]; |
| 218 | |
| 219 | u32 gdtr_upper_base; |
| 220 | u32 ldtr_upper_base; |
| 221 | u32 idtr_upper_base; |
| 222 | |
| 223 | u8 reserved2[4]; |
| 224 | |
| 225 | u64 io_rdi; |
| 226 | u64 io_rip; |
| 227 | u64 io_rcx; |
| 228 | u64 io_rsi; |
| 229 | |
| 230 | u8 reserved3[64]; |
| 231 | u32 cr4; |
| 232 | |
| 233 | u8 reserved4[72]; |
| 234 | |
| 235 | u32 gdtr_base; |
| 236 | u8 reserved5[4]; |
| 237 | u32 idtr_base; |
| 238 | u8 reserved6[4]; |
| 239 | u32 ldtr_base; |
| 240 | |
| 241 | u8 reserved7[88]; |
| 242 | |
| 243 | u32 smbase; |
| 244 | u32 smm_revision; |
| 245 | |
| 246 | u16 io_restart; |
| 247 | u16 autohalt_restart; |
| 248 | |
| 249 | u8 reserved8[24]; |
| 250 | |
| 251 | u64 r15; |
| 252 | u64 r14; |
| 253 | u64 r13; |
| 254 | u64 r12; |
| 255 | u64 r11; |
| 256 | u64 r10; |
| 257 | u64 r9; |
| 258 | u64 r8; |
| 259 | |
| 260 | u64 rax; |
| 261 | u64 rcx; |
| 262 | u64 rdx; |
| 263 | u64 rbx; |
| 264 | |
| 265 | u64 rsp; |
| 266 | u64 rbp; |
| 267 | u64 rsi; |
| 268 | u64 rdi; |
| 269 | |
| 270 | |
| 271 | u64 io_mem_addr; |
| 272 | u32 io_misc_info; |
| 273 | |
| 274 | u32 es_sel; |
| 275 | u32 cs_sel; |
| 276 | u32 ss_sel; |
| 277 | u32 ds_sel; |
| 278 | u32 fs_sel; |
| 279 | u32 gs_sel; |
| 280 | |
| 281 | u32 ldtr_sel; |
| 282 | u32 tr_sel; |
| 283 | |
| 284 | u64 dr7; |
| 285 | u64 dr6; |
| 286 | u64 rip; |
| 287 | u64 efer; |
| 288 | u64 rflags; |
| 289 | |
| 290 | u64 cr3; |
| 291 | u64 cr0; |
| 292 | } __attribute__((packed)) em64t100_smm_state_save_area_t; |
| 293 | |
Duncan Laurie | 51cb26d | 2012-06-23 15:22:43 -0700 | [diff] [blame] | 294 | /* Intel Revision 30101 SMM State-Save Area |
Aaron Durbin | 62f100b | 2012-11-07 12:27:29 -0600 | [diff] [blame] | 295 | * The following processor architectures use this: |
| 296 | * - SandyBridge |
| 297 | * - IvyBridge |
| 298 | * - Haswell |
Duncan Laurie | 51cb26d | 2012-06-23 15:22:43 -0700 | [diff] [blame] | 299 | */ |
Aaron Durbin | 62f100b | 2012-11-07 12:27:29 -0600 | [diff] [blame] | 300 | #define SMM_EM64T101_ARCH_OFFSET 0x7c00 |
| 301 | #define SMM_EM64T101_SAVE_STATE_OFFSET \ |
| 302 | SMM_SAVE_STATE_BEGIN(SMM_EM64T101_ARCH_OFFSET) |
Duncan Laurie | 51cb26d | 2012-06-23 15:22:43 -0700 | [diff] [blame] | 303 | typedef struct { |
Aaron Durbin | 62f100b | 2012-11-07 12:27:29 -0600 | [diff] [blame] | 304 | u8 reserved0[256]; |
| 305 | u8 reserved1[208]; |
Duncan Laurie | 51cb26d | 2012-06-23 15:22:43 -0700 | [diff] [blame] | 306 | |
| 307 | u32 gdtr_upper_base; |
| 308 | u32 ldtr_upper_base; |
| 309 | u32 idtr_upper_base; |
| 310 | |
| 311 | u32 io_cf8; |
| 312 | |
| 313 | u64 io_rdi; |
| 314 | u64 io_rip; |
| 315 | u64 io_rcx; |
| 316 | u64 io_rsi; |
| 317 | |
Aaron Durbin | 62f100b | 2012-11-07 12:27:29 -0600 | [diff] [blame] | 318 | u8 reserved2[52]; |
Duncan Laurie | 51cb26d | 2012-06-23 15:22:43 -0700 | [diff] [blame] | 319 | u32 shutdown_auto_restart; |
Aaron Durbin | 62f100b | 2012-11-07 12:27:29 -0600 | [diff] [blame] | 320 | u8 reserved3[8]; |
Duncan Laurie | 51cb26d | 2012-06-23 15:22:43 -0700 | [diff] [blame] | 321 | u32 cr4; |
| 322 | |
Aaron Durbin | 62f100b | 2012-11-07 12:27:29 -0600 | [diff] [blame] | 323 | u8 reserved4[72]; |
Duncan Laurie | 51cb26d | 2012-06-23 15:22:43 -0700 | [diff] [blame] | 324 | |
| 325 | u32 gdtr_base; |
Duncan Laurie | 51cb26d | 2012-06-23 15:22:43 -0700 | [diff] [blame] | 326 | u8 reserved5[4]; |
Aaron Durbin | 62f100b | 2012-11-07 12:27:29 -0600 | [diff] [blame] | 327 | u32 idtr_base; |
| 328 | u8 reserved6[4]; |
Duncan Laurie | 51cb26d | 2012-06-23 15:22:43 -0700 | [diff] [blame] | 329 | u32 ldtr_base; |
| 330 | |
Aaron Durbin | 62f100b | 2012-11-07 12:27:29 -0600 | [diff] [blame] | 331 | u8 reserved7[56]; |
| 332 | /* EPTP fields are only on Haswell according to BWGs, but Intel was |
| 333 | * wise and reused the same revision number. */ |
| 334 | u64 eptp; |
| 335 | u32 eptp_en; |
Duncan Laurie | 51cb26d | 2012-06-23 15:22:43 -0700 | [diff] [blame] | 336 | u32 cs_base; |
Aaron Durbin | 62f100b | 2012-11-07 12:27:29 -0600 | [diff] [blame] | 337 | u8 reserved8[4]; |
Duncan Laurie | 51cb26d | 2012-06-23 15:22:43 -0700 | [diff] [blame] | 338 | u32 iedbase; |
| 339 | |
Aaron Durbin | 62f100b | 2012-11-07 12:27:29 -0600 | [diff] [blame] | 340 | u8 reserved9[8]; |
Duncan Laurie | 51cb26d | 2012-06-23 15:22:43 -0700 | [diff] [blame] | 341 | |
| 342 | u32 smbase; |
| 343 | u32 smm_revision; |
| 344 | |
| 345 | u16 io_restart; |
| 346 | u16 autohalt_restart; |
| 347 | |
Aaron Durbin | 62f100b | 2012-11-07 12:27:29 -0600 | [diff] [blame] | 348 | u8 reserved10[24]; |
Duncan Laurie | 51cb26d | 2012-06-23 15:22:43 -0700 | [diff] [blame] | 349 | |
| 350 | u64 r15; |
| 351 | u64 r14; |
| 352 | u64 r13; |
| 353 | u64 r12; |
| 354 | u64 r11; |
| 355 | u64 r10; |
| 356 | u64 r9; |
| 357 | u64 r8; |
| 358 | |
| 359 | u64 rax; |
| 360 | u64 rcx; |
| 361 | u64 rdx; |
| 362 | u64 rbx; |
| 363 | |
| 364 | u64 rsp; |
| 365 | u64 rbp; |
| 366 | u64 rsi; |
| 367 | u64 rdi; |
| 368 | |
| 369 | |
| 370 | u64 io_mem_addr; |
| 371 | u32 io_misc_info; |
| 372 | |
| 373 | u32 es_sel; |
| 374 | u32 cs_sel; |
| 375 | u32 ss_sel; |
| 376 | u32 ds_sel; |
| 377 | u32 fs_sel; |
| 378 | u32 gs_sel; |
| 379 | |
| 380 | u32 ldtr_sel; |
| 381 | u32 tr_sel; |
| 382 | |
| 383 | u64 dr7; |
| 384 | u64 dr6; |
| 385 | u64 rip; |
| 386 | u64 efer; |
| 387 | u64 rflags; |
| 388 | |
| 389 | u64 cr3; |
| 390 | u64 cr0; |
| 391 | } __attribute__((packed)) em64t101_smm_state_save_area_t; |
| 392 | |
| 393 | |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 394 | /* Legacy x86 SMM State-Save Area |
Stefan Reinauer | debb11f | 2008-10-29 04:46:52 +0000 | [diff] [blame] | 395 | * starts @ 0x7e00 |
| 396 | */ |
| 397 | |
| 398 | typedef struct { |
| 399 | u8 reserved0[248]; |
| 400 | u32 smbase; |
| 401 | u32 smm_revision; |
| 402 | u16 io_restart; |
| 403 | u16 autohalt_restart; |
| 404 | u8 reserved1[132]; |
| 405 | u32 gdtbase; |
| 406 | u8 reserved2[8]; |
| 407 | u32 idtbase; |
| 408 | u8 reserved3[16]; |
| 409 | u32 es; |
| 410 | u32 cs; |
| 411 | u32 ss; |
| 412 | u32 ds; |
| 413 | u32 fs; |
| 414 | u32 gs; |
| 415 | u32 ldtbase; |
| 416 | u32 tr; |
| 417 | u32 dr7; |
| 418 | u32 dr6; |
| 419 | u32 eax; |
| 420 | u32 ecx; |
| 421 | u32 edx; |
| 422 | u32 ebx; |
| 423 | u32 esp; |
| 424 | u32 ebp; |
| 425 | u32 esi; |
| 426 | u32 edi; |
| 427 | u32 eip; |
| 428 | u32 eflags; |
| 429 | u32 cr3; |
| 430 | u32 cr0; |
| 431 | } __attribute__((packed)) legacy_smm_state_save_area_t; |
| 432 | |
| 433 | typedef enum { |
| 434 | AMD64, |
| 435 | EM64T, |
Duncan Laurie | 51cb26d | 2012-06-23 15:22:43 -0700 | [diff] [blame] | 436 | EM64T101, |
Stefan Reinauer | debb11f | 2008-10-29 04:46:52 +0000 | [diff] [blame] | 437 | LEGACY |
| 438 | } save_state_type_t; |
| 439 | |
| 440 | |
| 441 | typedef struct { |
| 442 | save_state_type_t type; |
| 443 | union { |
| 444 | amd64_smm_state_save_area_t *amd64_state_save; |
| 445 | em64t_smm_state_save_area_t *em64t_state_save; |
Duncan Laurie | 51cb26d | 2012-06-23 15:22:43 -0700 | [diff] [blame] | 446 | em64t101_smm_state_save_area_t *em64t101_state_save; |
Stefan Reinauer | debb11f | 2008-10-29 04:46:52 +0000 | [diff] [blame] | 447 | legacy_smm_state_save_area_t *legacy_state_save; |
| 448 | }; |
| 449 | } smm_state_save_area_t; |
| 450 | |
Sven Schnelle | f4dc1a7 | 2011-06-05 11:33:41 +0200 | [diff] [blame] | 451 | #define APM_CNT 0xb2 |
| 452 | #define APM_CNT_CST_CONTROL 0x85 |
| 453 | #define APM_CNT_PST_CONTROL 0x80 |
| 454 | #define APM_CNT_ACPI_DISABLE 0x1e |
| 455 | #define APM_CNT_ACPI_ENABLE 0xe1 |
| 456 | #define APM_CNT_MBI_UPDATE 0xeb |
| 457 | #define APM_CNT_GNVS_UPDATE 0xea |
Duncan Laurie | 911cedf | 2013-07-30 16:05:55 -0700 | [diff] [blame] | 458 | #define APM_CNT_FINALIZE 0xcb |
Marc Jones | 9afc5c0 | 2014-09-24 10:53:48 -0600 | [diff] [blame] | 459 | #define APM_CNT_LEGACY 0xcc |
Sven Schnelle | f4dc1a7 | 2011-06-05 11:33:41 +0200 | [diff] [blame] | 460 | #define APM_STS 0xb3 |
Stefan Reinauer | 3b38745 | 2009-03-06 19:52:36 +0000 | [diff] [blame] | 461 | |
| 462 | /* SMI handler function prototypes */ |
Stefan Reinauer | 348a1ba | 2010-03-17 01:51:11 +0000 | [diff] [blame] | 463 | void smi_handler(u32 smm_revision); |
| 464 | |
Stefan Reinauer | be7f798 | 2009-03-13 15:42:27 +0000 | [diff] [blame] | 465 | void io_trap_handler(int smif); |
Stefan Reinauer | 3b38745 | 2009-03-06 19:52:36 +0000 | [diff] [blame] | 466 | int southbridge_io_trap_handler(int smif); |
Kyösti Mälkki | 48b3dbc | 2014-12-29 19:36:50 +0200 | [diff] [blame] | 467 | int mainboard_io_trap_handler(int smif); |
Stefan Reinauer | 3b38745 | 2009-03-06 19:52:36 +0000 | [diff] [blame] | 468 | |
Stefan Reinauer | 348a1ba | 2010-03-17 01:51:11 +0000 | [diff] [blame] | 469 | void southbridge_smi_set_eos(void); |
| 470 | |
Vladimir Serbinenko | 44cbe10 | 2015-05-28 21:09:31 +0200 | [diff] [blame] | 471 | #if CONFIG_SMM_TSEG |
Aaron Durbin | 50a3464 | 2013-01-03 17:38:47 -0600 | [diff] [blame] | 472 | void cpu_smi_handler(void); |
| 473 | void northbridge_smi_handler(void); |
| 474 | void southbridge_smi_handler(void); |
Kyösti Mälkki | 48b3dbc | 2014-12-29 19:36:50 +0200 | [diff] [blame] | 475 | #else |
| 476 | void cpu_smi_handler(unsigned int node, smm_state_save_area_t *state_save); |
| 477 | void northbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save); |
| 478 | void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save); |
Vladimir Serbinenko | 44cbe10 | 2015-05-28 21:09:31 +0200 | [diff] [blame] | 479 | #endif /* CONFIG_SMM_TSEG */ |
Duncan Laurie | 0edc224 | 2013-04-29 15:04:30 -0700 | [diff] [blame] | 480 | void mainboard_smi_gpi(u32 gpi_sts); |
Aaron Durbin | 50a3464 | 2013-01-03 17:38:47 -0600 | [diff] [blame] | 481 | int mainboard_smi_apmc(u8 data); |
| 482 | void mainboard_smi_sleep(u8 slp_typ); |
Stefan Reinauer | bf34e94 | 2012-04-27 00:44:04 +0200 | [diff] [blame] | 483 | |
Stefan Reinauer | 3aa067f | 2012-04-02 13:24:04 -0700 | [diff] [blame] | 484 | #if !CONFIG_SMM_TSEG |
Sven Schnelle | bfe8e51 | 2011-06-14 20:55:54 +0200 | [diff] [blame] | 485 | void smi_release_lock(void); |
Stefan Reinauer | 3aa067f | 2012-04-02 13:24:04 -0700 | [diff] [blame] | 486 | #endif |
Sven Schnelle | 180f81e | 2011-06-28 08:06:18 +0200 | [diff] [blame] | 487 | |
Duncan Laurie | 7f3d442 | 2012-10-03 19:01:57 -0700 | [diff] [blame] | 488 | /* Get PMBASE address */ |
| 489 | u16 smm_get_pmbase(void); |
| 490 | |
Vladimir Serbinenko | 44cbe10 | 2015-05-28 21:09:31 +0200 | [diff] [blame] | 491 | #if CONFIG_SMM_TSEG |
Aaron Durbin | 50a3464 | 2013-01-03 17:38:47 -0600 | [diff] [blame] | 492 | |
| 493 | struct smm_runtime { |
| 494 | u32 smbase; |
| 495 | u32 save_state_size; |
| 496 | /* The apic_id_to_cpu provides a mapping from APIC id to cpu number. |
| 497 | * The cpu number is indicated by the index into the array by matching |
Martin Roth | 0cb07e3 | 2013-07-09 21:46:01 -0600 | [diff] [blame] | 498 | * the default APIC id and value at the index. The stub loader |
Aaron Durbin | 50a3464 | 2013-01-03 17:38:47 -0600 | [diff] [blame] | 499 | * initializes this array with a 1:1 mapping. If the APIC ids are not |
| 500 | * contiguous like the 1:1 mapping it is up to the caller of the stub |
| 501 | * loader to adjust this mapping. */ |
| 502 | u8 apic_id_to_cpu[CONFIG_MAX_CPUS]; |
| 503 | } __attribute__ ((packed)); |
| 504 | |
Aaron Durbin | 3eb8eb7 | 2014-03-10 16:13:58 -0500 | [diff] [blame] | 505 | struct smm_module_params { |
| 506 | void *arg; |
| 507 | int cpu; |
| 508 | const struct smm_runtime *runtime; |
| 509 | }; |
| 510 | |
| 511 | /* smm_handler_t is called with arg of smm_module_params pointer. */ |
| 512 | typedef void asmlinkage (*smm_handler_t)(void *); |
Aaron Durbin | 50a3464 | 2013-01-03 17:38:47 -0600 | [diff] [blame] | 513 | |
| 514 | #ifdef __SMM__ |
| 515 | /* SMM Runtime helpers. */ |
| 516 | |
| 517 | /* Entry point for SMM modules. */ |
Aaron Durbin | 3eb8eb7 | 2014-03-10 16:13:58 -0500 | [diff] [blame] | 518 | void asmlinkage smm_handler_start(void *params); |
Aaron Durbin | 50a3464 | 2013-01-03 17:38:47 -0600 | [diff] [blame] | 519 | |
| 520 | /* Retrieve SMM save state for a given CPU. WARNING: This does not take into |
| 521 | * account CPUs which are configured to not save their state to RAM. */ |
| 522 | void *smm_get_save_state(int cpu); |
| 523 | |
| 524 | #else |
| 525 | /* SMM Module Loading API */ |
| 526 | |
Martin Roth | 0cb07e3 | 2013-07-09 21:46:01 -0600 | [diff] [blame] | 527 | /* The smm_loader_params structure provides direction to the SMM loader: |
Aaron Durbin | 50a3464 | 2013-01-03 17:38:47 -0600 | [diff] [blame] | 528 | * - stack_top - optional external stack provided to loader. It must be at |
| 529 | * least per_cpu_stack_size * num_concurrent_stacks in size. |
| 530 | * - per_cpu_stack_size - stack size per cpu for smm modules. |
| 531 | * - num_concurrent_stacks - number of concurrent cpus in handler needing stack |
| 532 | * optional for setting up relocation handler. |
| 533 | * - per_cpu_save_state_size - the smm save state size per cpu |
| 534 | * - num_concurrent_save_states - number of concurrent cpus needing save state |
| 535 | * space |
| 536 | * - handler - optional handler to call. Only used during SMM relocation setup. |
| 537 | * - handler_arg - optional argument to handler for SMM relocation setup. For |
| 538 | * loading the SMM module, the handler_arg is filled in with |
| 539 | * the address of the module's parameters (if present). |
| 540 | * - runtime - this field is a result only. The SMM runtime location is filled |
| 541 | * into this field so the code doing the loading can manipulate the |
| 542 | * runtime's assumptions. e.g. updating the apic id to cpu map to |
| 543 | * handle sparse apic id space. |
| 544 | */ |
| 545 | struct smm_loader_params { |
| 546 | void *stack_top; |
| 547 | int per_cpu_stack_size; |
| 548 | int num_concurrent_stacks; |
| 549 | |
| 550 | int per_cpu_save_state_size; |
| 551 | int num_concurrent_save_states; |
| 552 | |
| 553 | smm_handler_t handler; |
| 554 | void *handler_arg; |
| 555 | |
| 556 | struct smm_runtime *runtime; |
| 557 | }; |
| 558 | |
| 559 | /* Both of these return 0 on success, < 0 on failure. */ |
| 560 | int smm_setup_relocation_handler(struct smm_loader_params *params); |
| 561 | int smm_load_module(void *smram, int size, struct smm_loader_params *params); |
| 562 | #endif /* __SMM__ */ |
Vladimir Serbinenko | 44cbe10 | 2015-05-28 21:09:31 +0200 | [diff] [blame] | 563 | #endif /* CONFIG_SMM_TSEG */ |
Aaron Durbin | 50a3464 | 2013-01-03 17:38:47 -0600 | [diff] [blame] | 564 | |
Aaron Durbin | b4b9eb3 | 2014-02-13 10:26:18 -0600 | [diff] [blame] | 565 | /* Backup and restore default SMM region. */ |
| 566 | void *backup_default_smm_area(void); |
| 567 | void restore_default_smm_area(void *smm_save_area); |
| 568 | |
Edward O'Callaghan | c4561e2 | 2014-06-26 15:02:40 +1000 | [diff] [blame] | 569 | #endif /* CPU_X86_SMM_H */ |