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