mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-07 22:34:18 +08:00
eb4ea1ae8f
Port I/O instructions trigger #VE in the TDX environment. In response to the exception, kernel emulates these instructions using hypercalls. But during early boot, on the decompression stage, it is cumbersome to deal with #VE. It is cleaner to go to hypercalls directly, bypassing #VE handling. Add a way to hook up alternative port I/O helpers in the boot stub with a new pio_ops structure. For now, set the ops structure to just call the normal I/O operation functions. out*()/in*() macros redefined to use pio_ops callbacks. It eliminates need in changing call sites. io_delay() changed to use port I/O helper instead of inline assembly. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com> Link: https://lkml.kernel.org/r/20220405232939.73860-16-kirill.shutemov@linux.intel.com
88 lines
1.6 KiB
C
88 lines
1.6 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
#include "wakeup.h"
|
|
#include "boot.h"
|
|
|
|
static void udelay(int loops)
|
|
{
|
|
while (loops--)
|
|
io_delay(); /* Approximately 1 us */
|
|
}
|
|
|
|
static void beep(unsigned int hz)
|
|
{
|
|
u8 enable;
|
|
|
|
if (!hz) {
|
|
enable = 0x00; /* Turn off speaker */
|
|
} else {
|
|
u16 div = 1193181/hz;
|
|
|
|
outb(0xb6, 0x43); /* Ctr 2, squarewave, load, binary */
|
|
io_delay();
|
|
outb(div, 0x42); /* LSB of counter */
|
|
io_delay();
|
|
outb(div >> 8, 0x42); /* MSB of counter */
|
|
io_delay();
|
|
|
|
enable = 0x03; /* Turn on speaker */
|
|
}
|
|
inb(0x61); /* Dummy read of System Control Port B */
|
|
io_delay();
|
|
outb(enable, 0x61); /* Enable timer 2 output to speaker */
|
|
io_delay();
|
|
}
|
|
|
|
#define DOT_HZ 880
|
|
#define DASH_HZ 587
|
|
#define US_PER_DOT 125000
|
|
|
|
/* Okay, this is totally silly, but it's kind of fun. */
|
|
static void send_morse(const char *pattern)
|
|
{
|
|
char s;
|
|
|
|
while ((s = *pattern++)) {
|
|
switch (s) {
|
|
case '.':
|
|
beep(DOT_HZ);
|
|
udelay(US_PER_DOT);
|
|
beep(0);
|
|
udelay(US_PER_DOT);
|
|
break;
|
|
case '-':
|
|
beep(DASH_HZ);
|
|
udelay(US_PER_DOT * 3);
|
|
beep(0);
|
|
udelay(US_PER_DOT);
|
|
break;
|
|
default: /* Assume it's a space */
|
|
udelay(US_PER_DOT * 3);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
struct port_io_ops pio_ops;
|
|
|
|
void main(void)
|
|
{
|
|
init_default_io_ops();
|
|
|
|
/* Kill machine if structures are wrong */
|
|
if (wakeup_header.real_magic != 0x12345678)
|
|
while (1)
|
|
;
|
|
|
|
if (wakeup_header.realmode_flags & 4)
|
|
send_morse("...-");
|
|
|
|
if (wakeup_header.realmode_flags & 1)
|
|
asm volatile("lcallw $0xc000,$3");
|
|
|
|
if (wakeup_header.realmode_flags & 2) {
|
|
/* Need to call BIOS */
|
|
probe_cards(0);
|
|
set_mode(wakeup_header.video_mode);
|
|
}
|
|
}
|