| ;------------------------------------------------------------------------------ ; | |
| ; Copyright (c) 2022, 9elements GmbH. All rights reserved.<BR> | |
| ; SPDX-License-Identifier: BSD-2-Clause-Patent | |
| ; | |
| ;------------------------------------------------------------------------------- | |
| %include "Nasm.inc" | |
| DEFAULT REL | |
| SECTION .text | |
| ;UINTN | |
| ;EFIAPI | |
| ;TriggerSmi ( | |
| ; UINTN Cmd, | |
| ; UINTN Arg, | |
| ; UINTN Retry | |
| ; ) | |
| global ASM_PFX(TriggerSmi) | |
| ASM_PFX(TriggerSmi): | |
| push rbx | |
| mov rax, rcx ; Smi handler expect Cmd in RAX | |
| mov rbx, rdx ; Smi handler expect Argument in RBX | |
| @Trigger: | |
| out 0b2h, al ; write to APM port to trigger SMI | |
| ; There might be a delay between writing the Smi trigger register and | |
| ; entering SMM, in which case the Smi handler will do nothing as only | |
| ; synchronous Smis are handled. In addition when there's no Smi handler | |
| ; or the SmmStore feature isn't compiled in, no register will be modified. | |
| ; As there's no livesign from SMM, just wait a bit for the handler to fire, | |
| ; and then try again. | |
| cmp rax, rcx ; Check if rax was modified by SMM | |
| jne @Return ; SMM modified rax, return now | |
| push rcx ; save rcx to stack | |
| mov rcx, 10000 | |
| rep pause ; add a small delay | |
| pop rcx ; restore rcx | |
| cmp r8, 0 | |
| je @Return | |
| dec r8 | |
| jmp @Trigger | |
| @Return: | |
| pop rbx | |
| ret |