linux/arch/x86/realmode/rm/wakemain.c
<<
>>
Prefs
   1#include "wakeup.h"
   2#include "boot.h"
   3
   4static void udelay(int loops)
   5{
   6        while (loops--)
   7                io_delay();     /* Approximately 1 us */
   8}
   9
  10static 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. */
  39static 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
  64void main(void)
  65{
  66        /* Kill machine if structures are wrong */
  67        if (wakeup_header.real_magic != 0x12345678)
  68                while (1)
  69                        ;
  70
  71        if (wakeup_header.realmode_flags & 4)
  72                send_morse("...-");
  73
  74        if (wakeup_header.realmode_flags & 1)
  75                asm volatile("lcallw   $0xc000,$3");
  76
  77        if (wakeup_header.realmode_flags & 2) {
  78                /* Need to call BIOS */
  79                probe_cards(0);
  80                set_mode(wakeup_header.video_mode);
  81        }
  82}
  83