113a7760fSPekka Enberg #include "kvm/early_printk.h" 213a7760fSPekka Enberg 313a7760fSPekka Enberg #include "kvm/ioport.h" 413a7760fSPekka Enberg 513a7760fSPekka Enberg #include <stdio.h> 613a7760fSPekka Enberg 73f55f3acSPekka Enberg static int early_serial_base = 0x3f8; /* ttyS0 */ 83f55f3acSPekka Enberg 93f55f3acSPekka Enberg #define XMTRDY 0x20 103f55f3acSPekka Enberg 113f55f3acSPekka Enberg #define TXR 0 /* Transmit register (WRITE) */ 123f55f3acSPekka Enberg #define LSR 5 /* Line Status */ 13a93ec68bSPekka Enberg #define MSR 6 /* Modem Status */ 143f55f3acSPekka Enberg 1513a7760fSPekka Enberg static bool early_serial_txr_out(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 1613a7760fSPekka Enberg { 1713a7760fSPekka Enberg char *p = data; 18f2d8dc88SCyrill Gorcunov int i; 1913a7760fSPekka Enberg 20f2d8dc88SCyrill Gorcunov while (count--) { 21f2d8dc88SCyrill Gorcunov for (i = 0; i < size; i++) 22*b7475544SPekka Enberg fprintf(stdout, "%c", *p++); 235b9d0b58SAsias He } 24*b7475544SPekka Enberg fflush(stdout); 2513a7760fSPekka Enberg 2613a7760fSPekka Enberg return true; 2713a7760fSPekka Enberg } 2813a7760fSPekka Enberg 2925af6674SPekka Enberg static bool early_serial_rxr_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 3025af6674SPekka Enberg { 3125af6674SPekka Enberg return true; 3225af6674SPekka Enberg } 3325af6674SPekka Enberg 3425af6674SPekka Enberg static struct ioport_operations early_serial_txr_rxr_ops = { 3513a7760fSPekka Enberg .io_out = early_serial_txr_out, 3625af6674SPekka Enberg .io_in = early_serial_rxr_in, 3713a7760fSPekka Enberg }; 3813a7760fSPekka Enberg 3913a7760fSPekka Enberg static bool early_serial_lsr_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 4013a7760fSPekka Enberg { 4113a7760fSPekka Enberg uint8_t *p = data; 4213a7760fSPekka Enberg 433f55f3acSPekka Enberg *p = XMTRDY; 4413a7760fSPekka Enberg 4513a7760fSPekka Enberg return true; 4613a7760fSPekka Enberg } 4713a7760fSPekka Enberg 4813a7760fSPekka Enberg static struct ioport_operations early_serial_lsr_ops = { 4913a7760fSPekka Enberg .io_in = early_serial_lsr_in, 5013a7760fSPekka Enberg }; 5113a7760fSPekka Enberg 52a93ec68bSPekka Enberg static bool early_serial_msr_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 53a93ec68bSPekka Enberg { 54a93ec68bSPekka Enberg return true; 55a93ec68bSPekka Enberg } 56a93ec68bSPekka Enberg 57a93ec68bSPekka Enberg static struct ioport_operations early_serial_msr_ops = { 58a93ec68bSPekka Enberg .io_in = early_serial_msr_in, 59a93ec68bSPekka Enberg }; 60a93ec68bSPekka Enberg 6113a7760fSPekka Enberg void early_printk__init(void) 6213a7760fSPekka Enberg { 633e553514SPekka Enberg ioport__register(early_serial_base + TXR, &early_serial_txr_rxr_ops, 1); 643e553514SPekka Enberg ioport__register(early_serial_base + LSR, &early_serial_lsr_ops, 1); 65a93ec68bSPekka Enberg ioport__register(early_serial_base + MSR, &early_serial_msr_ops, 1); 6613a7760fSPekka Enberg } 67