diff options
author | Jarkko Sakkinen <jarkko.sakkinen@intel.com> | 2012-05-08 21:22:42 +0300 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2012-05-08 11:48:45 -0700 |
commit | c4845474a01f699966272536e8416222e3f2d2cb (patch) | |
tree | 8d590924f5ab164981368822f7534f42eaabae30 /arch/x86/realmode/rm/wakemain.c | |
parent | b429dbf6e866bd6dadb56fae66f61f611cde57ff (diff) | |
download | linux-stable-c4845474a01f699966272536e8416222e3f2d2cb.tar.gz linux-stable-c4845474a01f699966272536e8416222e3f2d2cb.tar.bz2 linux-stable-c4845474a01f699966272536e8416222e3f2d2cb.zip |
x86, realmode: flattened rm hierachy
Simplified hierarchy under rm directory to a flat
directory because it is not anymore really justified
to have own directory for wakeup code. It only adds
more complexity.
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@intel.com>
Link: http://lkml.kernel.org/r/1336501366-28617-20-git-send-email-jarkko.sakkinen@intel.com
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/realmode/rm/wakemain.c')
-rw-r--r-- | arch/x86/realmode/rm/wakemain.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/arch/x86/realmode/rm/wakemain.c b/arch/x86/realmode/rm/wakemain.c new file mode 100644 index 000000000000..91405d515ec6 --- /dev/null +++ b/arch/x86/realmode/rm/wakemain.c @@ -0,0 +1,82 @@ +#include "wakeup.h" +#include "boot.h" + +static void udelay(int loops) +{ + while (loops--) + io_delay(); /* Approximately 1 us */ +} + +static void beep(unsigned int hz) +{ + u8 enable; + + if (!hz) { + enable = 0x00; /* Turn off speaker */ + } else { + u16 div = 1193181/hz; + + outb(0xb6, 0x43); /* Ctr 2, squarewave, load, binary */ + io_delay(); + outb(div, 0x42); /* LSB of counter */ + io_delay(); + outb(div >> 8, 0x42); /* MSB of counter */ + io_delay(); + + enable = 0x03; /* Turn on speaker */ + } + inb(0x61); /* Dummy read of System Control Port B */ + io_delay(); + outb(enable, 0x61); /* Enable timer 2 output to speaker */ + io_delay(); +} + +#define DOT_HZ 880 +#define DASH_HZ 587 +#define US_PER_DOT 125000 + +/* Okay, this is totally silly, but it's kind of fun. */ +static void send_morse(const char *pattern) +{ + char s; + + while ((s = *pattern++)) { + switch (s) { + case '.': + beep(DOT_HZ); + udelay(US_PER_DOT); + beep(0); + udelay(US_PER_DOT); + break; + case '-': + beep(DASH_HZ); + udelay(US_PER_DOT * 3); + beep(0); + udelay(US_PER_DOT); + break; + default: /* Assume it's a space */ + udelay(US_PER_DOT * 3); + break; + } + } +} + +void main(void) +{ + /* Kill machine if structures are wrong */ + if (wakeup_header.real_magic != 0x12345678) + while (1) + ; + + if (wakeup_header.realmode_flags & 4) + send_morse("...-"); + + if (wakeup_header.realmode_flags & 1) + asm volatile("lcallw $0xc000,$3"); + + if (wakeup_header.realmode_flags & 2) { + /* Need to call BIOS */ + probe_cards(0); + set_mode(wakeup_header.video_mode); + } +} |