#include "kvm/ioport.h" #include #include static void dummy_io(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, u8 is_write, void *ptr) { } static void debug_io(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, u8 is_write, void *ptr) { if (!vcpu->kvm->cfg.ioport_debug) return; fprintf(stderr, "debug port %s from VCPU%lu: port=0x%lx, size=%u", is_write ? "write" : "read", vcpu->cpu_id, (unsigned long)addr, len); if (is_write) { u32 value; switch (len) { case 1: value = ioport__read8(data); break; case 2: value = ioport__read16((u16*)data); break; case 4: value = ioport__read32((u32*)data); break; default: value = 0; break; } fprintf(stderr, ", data: 0x%x\n", value); } else { fprintf(stderr, "\n"); } } static void seabios_debug_io(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, u8 is_write, void *ptr) { char ch; if (!is_write) return; ch = ioport__read8(data); putchar(ch); } /* * The "fast A20 gate" */ static void ps2_control_io(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, u8 is_write, void *ptr) { /* * A20 is always enabled. */ if (!is_write) ioport__write8(data, 0x02); } void ioport__map_irq(u8 *irq) { } static int ioport__setup_arch(struct kvm *kvm) { int r; /* Legacy ioport setup */ /* 0000 - 001F - DMA1 controller */ r = kvm__register_pio(kvm, 0x0000, 32, dummy_io, NULL); if (r < 0) return r; /* 0x0020 - 0x003F - 8259A PIC 1 */ r = kvm__register_pio(kvm, 0x0020, 2, dummy_io, NULL); if (r < 0) return r; /* PORT 0040-005F - PIT - PROGRAMMABLE INTERVAL TIMER (8253, 8254) */ r = kvm__register_pio(kvm, 0x0040, 4, dummy_io, NULL); if (r < 0) return r; /* 0092 - PS/2 system control port A */ r = kvm__register_pio(kvm, 0x0092, 1, ps2_control_io, NULL); if (r < 0) return r; /* 0x00A0 - 0x00AF - 8259A PIC 2 */ r = kvm__register_pio(kvm, 0x00A0, 2, dummy_io, NULL); if (r < 0) return r; /* 00C0 - 001F - DMA2 controller */ r = kvm__register_pio(kvm, 0x00c0, 32, dummy_io, NULL); if (r < 0) return r; /* PORT 00E0-00EF are 'motherboard specific' so we use them for our internal debugging purposes. */ r = kvm__register_pio(kvm, IOPORT_DBG, 1, debug_io, NULL); if (r < 0) return r; /* PORT 00ED - DUMMY PORT FOR DELAY??? */ r = kvm__register_pio(kvm, 0x00ed, 1, dummy_io, NULL); if (r < 0) return r; /* 0x00F0 - 0x00FF - Math co-processor */ r = kvm__register_pio(kvm, 0x00f0, 2, dummy_io, NULL); if (r < 0) return r; /* PORT 0278-027A - PARALLEL PRINTER PORT (usually LPT1, sometimes LPT2) */ r = kvm__register_pio(kvm, 0x0278, 3, dummy_io, NULL); if (r < 0) return r; /* PORT 0378-037A - PARALLEL PRINTER PORT (usually LPT2, sometimes LPT3) */ r = kvm__register_pio(kvm, 0x0378, 3, dummy_io, NULL); if (r < 0) return r; /* PORT 03D4-03D5 - COLOR VIDEO - CRT CONTROL REGISTERS */ r = kvm__register_pio(kvm, 0x03d4, 1, dummy_io, NULL); if (r < 0) return r; r = kvm__register_pio(kvm, 0x03d5, 1, dummy_io, NULL); if (r < 0) return r; r = kvm__register_pio(kvm, 0x0402, 1, seabios_debug_io, NULL); if (r < 0) return r; /* 0510 - QEMU BIOS configuration register */ r = kvm__register_pio(kvm, 0x0510, 2, dummy_io, NULL); if (r < 0) return r; return 0; } dev_base_init(ioport__setup_arch);