Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/x86/kernel/acpi/realmode/wakemain.c
10821 views
1
#include "wakeup.h"
2
#include "boot.h"
3
4
static void udelay(int loops)
5
{
6
while (loops--)
7
io_delay(); /* Approximately 1 us */
8
}
9
10
static void beep(unsigned int hz)
11
{
12
u8 enable;
13
14
if (!hz) {
15
enable = 0x00; /* Turn off speaker */
16
} else {
17
u16 div = 1193181/hz;
18
19
outb(0xb6, 0x43); /* Ctr 2, squarewave, load, binary */
20
io_delay();
21
outb(div, 0x42); /* LSB of counter */
22
io_delay();
23
outb(div >> 8, 0x42); /* MSB of counter */
24
io_delay();
25
26
enable = 0x03; /* Turn on speaker */
27
}
28
inb(0x61); /* Dummy read of System Control Port B */
29
io_delay();
30
outb(enable, 0x61); /* Enable timer 2 output to speaker */
31
io_delay();
32
}
33
34
#define DOT_HZ 880
35
#define DASH_HZ 587
36
#define US_PER_DOT 125000
37
38
/* Okay, this is totally silly, but it's kind of fun. */
39
static void send_morse(const char *pattern)
40
{
41
char s;
42
43
while ((s = *pattern++)) {
44
switch (s) {
45
case '.':
46
beep(DOT_HZ);
47
udelay(US_PER_DOT);
48
beep(0);
49
udelay(US_PER_DOT);
50
break;
51
case '-':
52
beep(DASH_HZ);
53
udelay(US_PER_DOT * 3);
54
beep(0);
55
udelay(US_PER_DOT);
56
break;
57
default: /* Assume it's a space */
58
udelay(US_PER_DOT * 3);
59
break;
60
}
61
}
62
}
63
64
void main(void)
65
{
66
/* Kill machine if structures are wrong */
67
if (wakeup_header.real_magic != 0x12345678)
68
while (1);
69
70
if (wakeup_header.realmode_flags & 4)
71
send_morse("...-");
72
73
if (wakeup_header.realmode_flags & 1)
74
asm volatile("lcallw $0xc000,$3");
75
76
if (wakeup_header.realmode_flags & 2) {
77
/* Need to call BIOS */
78
probe_cards(0);
79
set_mode(wakeup_header.video_mode);
80
}
81
}
82
83