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