Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
wakemain.c
Go to the documentation of this file.
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);
48  beep(0);
50  break;
51  case '-':
52  beep(DASH_HZ);
53  udelay(US_PER_DOT * 3);
54  beep(0);
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 
72  send_morse("...-");
73 
75  asm volatile("lcallw $0xc000,$3");
76 
77  if (wakeup_header.realmode_flags & 2) {
78  /* Need to call BIOS */
79  probe_cards(0);
81  }
82 }