From ec444f9da2e33aff154ee00f085d79dd624f2167 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sun, 11 Apr 2010 20:42:10 +0300 Subject: [PATCH] kvm: Add support for early serial printk Signed-off-by: Pekka Enberg --- tools/kvm/Makefile | 1 + tools/kvm/early_printk.c | 37 ++++++++++++++++++++++++++++ tools/kvm/include/kvm/early_printk.h | 6 +++++ tools/kvm/include/kvm/ioport.h | 16 ++++++++++++ tools/kvm/ioport.c | 19 ++++++++++---- tools/kvm/main.c | 3 +++ 6 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 tools/kvm/early_printk.c create mode 100644 tools/kvm/include/kvm/early_printk.h create mode 100644 tools/kvm/include/kvm/ioport.h diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile index 1846f3c4f7e7..8db8548cf031 100644 --- a/tools/kvm/Makefile +++ b/tools/kvm/Makefile @@ -10,6 +10,7 @@ export E Q PROGRAM = kvm OBJS += cpuid.o +OBJS += early_printk.o OBJS += interrupt.o OBJS += ioport.o OBJS += kvm.o diff --git a/tools/kvm/early_printk.c b/tools/kvm/early_printk.c new file mode 100644 index 000000000000..026ab7895209 --- /dev/null +++ b/tools/kvm/early_printk.c @@ -0,0 +1,37 @@ +#include "kvm/early_printk.h" + +#include "kvm/ioport.h" + +#include + +static bool early_serial_txr_out(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) +{ + char *p = data; + + printf("%c", *p); + + return true; +} + +static struct ioport_operations early_serial_txr_ops = { + .io_out = early_serial_txr_out, +}; + +static bool early_serial_lsr_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) +{ + uint8_t *p = data; + + *p = 0x20; /* xmtrdy */ + + return true; +} + +static struct ioport_operations early_serial_lsr_ops = { + .io_in = early_serial_lsr_in, +}; + +void early_printk__init(void) +{ + ioport__register(0x03F8, &early_serial_txr_ops); + ioport__register(0x03FD, &early_serial_lsr_ops); +} diff --git a/tools/kvm/include/kvm/early_printk.h b/tools/kvm/include/kvm/early_printk.h new file mode 100644 index 000000000000..3ff49c0ee9aa --- /dev/null +++ b/tools/kvm/include/kvm/early_printk.h @@ -0,0 +1,6 @@ +#ifndef KVM__EARLY_PRINTK_H +#define KVM__EARLY_PRINTK_H + +void early_printk__init(void); + +#endif /* KVM__EARLY_PRINTK_H */ diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h new file mode 100644 index 000000000000..3721910f4af8 --- /dev/null +++ b/tools/kvm/include/kvm/ioport.h @@ -0,0 +1,16 @@ +#ifndef KVM__IOPORT_H +#define KVM__IOPORT_H + +#include +#include + +struct kvm; + +struct ioport_operations { + bool (*io_in)(struct kvm *self, uint16_t port, void *data, int size, uint32_t count); + bool (*io_out)(struct kvm *self, uint16_t port, void *data, int size, uint32_t count); +}; + +void ioport__register(uint16_t port, struct ioport_operations *ops); + +#endif /* KVM__IOPORT_H */ diff --git a/tools/kvm/ioport.c b/tools/kvm/ioport.c index 31324b3fe477..8930ccb0f61a 100644 --- a/tools/kvm/ioport.c +++ b/tools/kvm/ioport.c @@ -1,13 +1,11 @@ +#include "kvm/ioport.h" + #include "kvm/kvm.h" +#include #include #include -struct ioport_operations { - bool (*io_in)(struct kvm *self, uint16_t port, void *data, int size, uint32_t count); - bool (*io_out)(struct kvm *self, uint16_t port, void *data, int size, uint32_t count); -}; - static uint8_t ioport_to_uint8(void *data) { uint8_t *p = data; @@ -81,12 +79,23 @@ static struct ioport_operations *ioport_ops[USHRT_MAX] = { [0x3D4] = &dummy_read_write_ioport_ops, [0x3D5] = &dummy_write_only_ioport_ops, + /* PORT 03F8-03FF - Serial port (8250,8250A,8251,16450,16550,16550A,etc.) COM1 */ + [0x03F9] = &dummy_read_write_ioport_ops, + [0x03FA] = &dummy_read_write_ioport_ops, + [0x03FB] = &dummy_read_write_ioport_ops, + [0x03FC] = &dummy_read_write_ioport_ops, + /* PORT 0CF8-0CFF - PCI Configuration Mechanism 1 - Configuration Registers */ [0x0CF8] = &dummy_write_only_ioport_ops, [0x0CFC] = &dummy_read_write_ioport_ops, [0x0CFE] = &dummy_read_write_ioport_ops, }; +void ioport__register(uint16_t port, struct ioport_operations *ops) +{ + ioport_ops[port] = ops; +} + static const char *to_direction(int direction) { if (direction == KVM_EXIT_IO_IN) diff --git a/tools/kvm/main.c b/tools/kvm/main.c index b6414e77f474..61253fdecd04 100644 --- a/tools/kvm/main.c +++ b/tools/kvm/main.c @@ -1,5 +1,6 @@ #include "kvm/kvm.h" +#include "kvm/early_printk.h" #include "kvm/util.h" #include @@ -58,6 +59,8 @@ int main(int argc, char *argv[]) if (single_step) kvm__enable_singlestep(kvm); + early_printk__init(); + for (;;) { kvm__run(kvm); -- 2.39.5