Don't include etherboot.h; we get a circular dependency
[people/xl0/gpxe.git] / src / core / console.c
1 /*
2  * Central console switch.  Various console devices can be selected
3  * via the build options CONSOLE_FIRMWARE, CONSOLE_SERIAL etc.
4  * config.c picks up on these definitions and drags in the relevant
5  * objects.  The linker compiles the console_drivers table for us; we
6  * simply delegate to each console_driver that we find in the table.
7  *
8  * Doing it this way allows for changing CONSOLE_XXX without
9  * rebuilding anything other than config.o.  This is extremely useful
10  * for rom-o-matic.
11  */
12
13 #include "stddef.h"
14 #include "console.h"
15
16 /* FIXME: we need a cleaner way to pick up cpu_nap().  It makes a
17  * real-mode call, and so we don't want to use it with LinuxBIOS.
18  */
19 #include "bios.h"
20
21 static struct console_driver console_drivers[0] __table_start ( console );
22 static struct console_driver console_drivers_end[0] __table_end ( console );
23
24 /*****************************************************************************
25  * putchar : write a single character to each console
26  *****************************************************************************
27  */
28
29 void putchar ( int character ) {
30         struct console_driver *console;
31
32         /* Automatic LF -> CR,LF translation */
33         if ( character == '\n' )
34                 putchar ( '\r' );
35
36         for ( console = console_drivers; console < console_drivers_end ;
37               console++ ) {
38                 if ( ( ! console->disabled ) && console->putchar )
39                         console->putchar ( character );
40         }
41 }
42
43 /*****************************************************************************
44  * has_input : check to see if any input is available on any console,
45  * and return a pointer to the console device if so
46  *****************************************************************************
47  */
48 static struct console_driver * has_input ( void ) {
49         struct console_driver *console;
50
51         for ( console = console_drivers; console < console_drivers_end ;
52               console++ ) {
53                 if ( ( ! console->disabled ) && console->iskey ) {
54                         if ( console->iskey () )
55                                 return console;
56                 }
57         }
58         return NULL;
59 }
60
61 /*****************************************************************************
62  * getchar : read a single character from any console
63  *
64  * NOTE : this function does not echo the character, and it does block
65  *****************************************************************************
66  */
67
68 int getchar ( void ) {
69         struct console_driver *console;
70         int character = 256;
71
72         while ( character == 256 ) {
73                 /* Doze for a while (until the next interrupt).  This works
74                  * fine, because the keyboard is interrupt-driven, and the
75                  * timer interrupt (approx. every 50msec) takes care of the
76                  * serial port, which is read by polling.  This reduces the
77                  * power dissipation of a modern CPU considerably, and also
78                  * makes Etherboot waiting for user interaction waste a lot
79                  * less CPU time in a VMware session.
80                  */
81                 cpu_nap();
82                 
83                 console = has_input();
84                 if ( console && console->getchar )
85                         character = console->getchar ();
86         }
87
88         /* CR -> LF translation */
89         if ( character == '\r' )
90                 character = '\n';
91
92         return character;
93 }
94
95 /*****************************************************************************
96  * iskey : check to see if any input is available on any console
97  *****************************************************************************
98  */
99
100 int iskey ( void ) {
101         return has_input() ? 1 : 0;
102 }