diff options
Diffstat (limited to 'arch/x86/kernel/acpi/realmode/wakemain.c')
-rw-r--r-- | arch/x86/kernel/acpi/realmode/wakemain.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/arch/x86/kernel/acpi/realmode/wakemain.c b/arch/x86/kernel/acpi/realmode/wakemain.c new file mode 100644 index 000000000000..883962d9eef2 --- /dev/null +++ b/arch/x86/kernel/acpi/realmode/wakemain.c | |||
@@ -0,0 +1,81 @@ | |||
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 | } | ||