summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--payloads/libpayload/drivers/keyboard.c7
-rw-r--r--payloads/libpayload/drivers/serial.c14
-rw-r--r--payloads/libpayload/drivers/usb/usbhid.c11
-rw-r--r--payloads/libpayload/drivers/video/video.c11
-rw-r--r--payloads/libpayload/include/libpayload.h20
-rw-r--r--payloads/libpayload/libc/console.c58
6 files changed, 89 insertions, 32 deletions
diff --git a/payloads/libpayload/drivers/keyboard.c b/payloads/libpayload/drivers/keyboard.c
index 95827463ca..0d8f72b32e 100644
--- a/payloads/libpayload/drivers/keyboard.c
+++ b/payloads/libpayload/drivers/keyboard.c
@@ -326,6 +326,11 @@ int keyboard_add_reset_handler(void (*new_handler)(void))
return 0;
}
+static struct console_input_driver cons = {
+ .havekey = keyboard_havechar,
+ .getchar = keyboard_getchar
+};
+
void keyboard_init(void)
{
u8 mode;
@@ -350,5 +355,7 @@ void keyboard_init(void)
/* Write the new mode */
keyboard_set_mode(mode);
+
+ console_add_input_driver(&cons);
}
diff --git a/payloads/libpayload/drivers/serial.c b/payloads/libpayload/drivers/serial.c
index 95f5b4855e..7a6590cb16 100644
--- a/payloads/libpayload/drivers/serial.c
+++ b/payloads/libpayload/drivers/serial.c
@@ -58,15 +58,27 @@ void serial_hardware_init(int port, int speed, int word_bits, int parity, int st
outb(reg &= ~0x80, port + 0x03);
}
+static struct console_input_driver consin = {
+ .havekey = serial_havechar,
+ .getchar = serial_getchar
+};
+
+static struct console_output_driver consout = {
+ .putchar = serial_putchar
+};
+
void serial_init(void)
{
#ifdef CONFIG_SERIAL_SET_SPEED
serial_hardware_init(IOBASE, CONFIG_SERIAL_BAUD_RATE, 8, 0, 1);
#endif
+ console_add_input_driver(&consin);
+ console_add_output_driver(&consout);
}
-void serial_putchar(unsigned char c)
+void serial_putchar(unsigned int c)
{
+ c &= 0xff;
while ((inb(IOBASE + 0x05) & 0x20) == 0) ;
outb(c, IOBASE);
}
diff --git a/payloads/libpayload/drivers/usb/usbhid.c b/payloads/libpayload/drivers/usb/usbhid.c
index 8713cf48c8..b96bfe63f5 100644
--- a/payloads/libpayload/drivers/usb/usbhid.c
+++ b/payloads/libpayload/drivers/usb/usbhid.c
@@ -145,10 +145,21 @@ usb_hid_set_protocol (usbdev_t *dev, interface_descriptor_t *interface, hid_prot
dev->controller->control (dev, OUT, sizeof (dev_req_t), &dr, 0, 0);
}
+static struct console_input_driver cons = {
+ .havekey = usbhid_havechar,
+ .getchar = usbhid_getchar
+};
+
void
usb_hid_init (usbdev_t *dev)
{
+ static int installed = 0;
+ if (!installed) {
+ installed = 1;
+ console_add_input_driver (&cons);
+ }
+
configuration_descriptor_t *cd = (configuration_descriptor_t*)dev->configuration;
interface_descriptor_t *interface = (interface_descriptor_t*)(((char *) cd) + cd->bLength);
diff --git a/payloads/libpayload/drivers/video/video.c b/payloads/libpayload/drivers/video/video.c
index 6ebc0f8ab6..83c393b4db 100644
--- a/payloads/libpayload/drivers/video/video.c
+++ b/payloads/libpayload/drivers/video/video.c
@@ -111,6 +111,11 @@ void video_console_putc(u8 row, u8 col, unsigned int ch)
void video_console_putchar(unsigned int ch)
{
+ /* replace black-on-black with light-gray-on-black.
+ do it here, instead of in libc/console.c */
+ if ((ch & 0xFF00) == 0) {
+ ch |= 0x0700;
+ }
switch(ch & 0xFF) {
case '\r':
cursorx = 0;
@@ -165,6 +170,10 @@ void video_console_set_cursor(unsigned int x, unsigned int y)
video_console_fixup_cursor();
}
+static struct console_output_driver cons = {
+ .putchar = video_console_putchar
+};
+
int video_console_init(void)
{
int i;
@@ -187,6 +196,8 @@ int video_console_init(void)
return 0;
}
+ console_add_output_driver(&cons);
+
return 0;
}
diff --git a/payloads/libpayload/include/libpayload.h b/payloads/libpayload/include/libpayload.h
index a098f0cc21..66d114e8f1 100644
--- a/payloads/libpayload/include/libpayload.h
+++ b/payloads/libpayload/include/libpayload.h
@@ -145,7 +145,7 @@ int keyboard_add_reset_handler(void (*new_handler)(void));
*/
void serial_init(void);
void serial_hardware_init(int port, int speed, int word_bits, int parity, int stop_bits);
-void serial_putchar(unsigned char c);
+void serial_putchar(unsigned int c);
int serial_havechar(void);
int serial_getchar(void);
void serial_clear(void);
@@ -192,7 +192,7 @@ int get_option(void *dest, char *name);
* @{
*/
void console_init(void);
-int putchar(int c);
+int putchar(unsigned int c);
int puts(const char *s);
int havekey(void);
int getchar(void);
@@ -200,6 +200,22 @@ int getchar_timeout(int *ms);
extern int last_putchar;
+struct console_input_driver;
+struct console_input_driver {
+ struct console_input_driver *next;
+ int (*havekey) (void);
+ int (*getchar) (void);
+};
+
+struct console_output_driver;
+struct console_output_driver {
+ struct console_output_driver *next;
+ void (*putchar) (unsigned int);
+};
+
+void console_add_output_driver(struct console_output_driver *out);
+void console_add_input_driver(struct console_input_driver *in);
+
#define havechar havekey
/** @} */
diff --git a/payloads/libpayload/libc/console.c b/payloads/libpayload/libc/console.c
index ff6fc13e8e..8b09c44d51 100644
--- a/payloads/libpayload/libc/console.c
+++ b/payloads/libpayload/libc/console.c
@@ -31,6 +31,21 @@
#include <libpayload.h>
#include <usb/usb.h>
+struct console_output_driver *console_out;
+struct console_input_driver *console_in;
+
+void console_add_output_driver(struct console_output_driver *out)
+{
+ out->next = console_out;
+ console_out = out;
+}
+
+void console_add_input_driver(struct console_input_driver *in)
+{
+ in->next = console_in;
+ console_in = in;
+}
+
void console_init(void)
{
#ifdef CONFIG_VIDEO_CONSOLE
@@ -46,15 +61,12 @@ void console_init(void)
static void device_putchar(unsigned char c)
{
-#ifdef CONFIG_VIDEO_CONSOLE
- video_console_putchar(0x700| c);
-#endif
-#ifdef CONFIG_SERIAL_CONSOLE
- serial_putchar(c);
-#endif
+ struct console_output_driver *out;
+ for (out = console_out; out != 0; out = out->next)
+ out->putchar(c);
}
-int putchar(int c)
+int putchar(unsigned int c)
{
c &= 0xff;
if (c == '\n')
@@ -78,19 +90,13 @@ int puts(const char *s)
int havekey(void)
{
-#ifdef CONFIG_USB_HID
+#ifdef CONFIG_USB
usb_poll();
- if (usbhid_havechar())
- return 1;
-#endif
-#ifdef CONFIG_SERIAL_CONSOLE
- if (serial_havechar())
- return 1;
-#endif
-#ifdef CONFIG_PC_KEYBOARD
- if (keyboard_havechar())
- return 1;
#endif
+ struct console_input_driver *in;
+ for (in = console_in; in != 0; in = in->next)
+ if (in->havekey())
+ return 1;
return 0;
}
@@ -101,19 +107,13 @@ int havekey(void)
int getchar(void)
{
while (1) {
-#ifdef CONFIG_USB_HID
+#ifdef CONFIG_USB
usb_poll();
- if (usbhid_havechar())
- return usbhid_getchar();
-#endif
-#ifdef CONFIG_SERIAL_CONSOLE
- if (serial_havechar())
- return serial_getchar();
-#endif
-#ifdef CONFIG_PC_KEYBOARD
- if (keyboard_havechar())
- return keyboard_getchar();
#endif
+ struct console_input_driver *in = console_in;
+ for (in = console_in; in != 0; in = in->next)
+ if (in->havechar())
+ return in->getchar();
}
}