kvm: Add support for early serial printk

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
This commit is contained in:
Pekka Enberg
2015-06-01 16:39:39 +01:00
committed by Will Deacon
parent 2dd4a4ed1e
commit 13a7760f97
6 changed files with 77 additions and 5 deletions
+1
View File
@@ -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
+37
View File
@@ -0,0 +1,37 @@
#include "kvm/early_printk.h"
#include "kvm/ioport.h"
#include <stdio.h>
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);
}
+6
View File
@@ -0,0 +1,6 @@
#ifndef KVM__EARLY_PRINTK_H
#define KVM__EARLY_PRINTK_H
void early_printk__init(void);
#endif /* KVM__EARLY_PRINTK_H */
+16
View File
@@ -0,0 +1,16 @@
#ifndef KVM__IOPORT_H
#define KVM__IOPORT_H
#include <stdbool.h>
#include <stdint.h>
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 */
+14 -5
View File
@@ -1,13 +1,11 @@
#include "kvm/ioport.h"
#include "kvm/kvm.h"
#include <assert.h>
#include <limits.h>
#include <stdio.h>
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)
+3
View File
@@ -1,5 +1,6 @@
#include "kvm/kvm.h"
#include "kvm/early_printk.h"
#include "kvm/util.h"
#include <inttypes.h>
@@ -58,6 +59,8 @@ int main(int argc, char *argv[])
if (single_step)
kvm__enable_singlestep(kvm);
early_printk__init();
for (;;) {
kvm__run(kvm);