xref: /kvmtool/hw/serial.c (revision b74755443fc96c72c897f21d3cde702a702ceb44)
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