Patrick Georgi | ac95903 | 2020-05-05 22:49:26 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
Arthur Heymans | c4772b9 | 2019-04-14 18:38:35 +0200 | [diff] [blame] | 2 | |
| 3 | /* |
| 4 | * input %esp: return address (not pointer to return address!) |
| 5 | * clobber the content of eax, ecx, edx |
| 6 | */ |
| 7 | |
| 8 | #include <cpu/x86/mtrr.h> |
| 9 | |
Patrick Rudolph | 429c77a | 2020-11-30 13:35:43 +0100 | [diff] [blame] | 10 | .code32 |
Arthur Heymans | c4772b9 | 2019-04-14 18:38:35 +0200 | [diff] [blame] | 11 | .section .text |
| 12 | .global check_mtrr |
| 13 | |
| 14 | check_mtrr: |
| 15 | /* Use the MTRR default type MSR as a proxy for detecting INIT#. |
| 16 | * Reset the system if any known bits are set in that MSR. That is |
| 17 | * an indication of the CPU not being properly reset. */ |
| 18 | |
| 19 | check_for_clean_reset: |
| 20 | movl $MTRR_DEF_TYPE_MSR, %ecx |
| 21 | rdmsr |
| 22 | andl $(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN), %eax |
| 23 | cmp $0, %eax |
| 24 | jnz warm_reset |
| 25 | jmp *%esp |
| 26 | /* perform warm reset */ |
| 27 | warm_reset: |
| 28 | movw $0xcf9, %dx |
| 29 | movb $0x06, %al |
| 30 | outb %al, %dx |
| 31 | /* Should not reach this*/ |
| 32 | .Lhlt: |
| 33 | hlt |
| 34 | jmp .Lhlt |