1af7b0868SMatt Evans #include "kvm/ioport.h" 2af7b0868SMatt Evans 3af7b0868SMatt Evans #include <stdlib.h> 4ce08f2afSPekka Enberg #include <stdio.h> 5af7b0868SMatt Evans 64123ca55SMarc Zyngier static bool debug_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) 7af7b0868SMatt Evans { 8b0822113SSasha Levin return 0; 9af7b0868SMatt Evans } 10af7b0868SMatt Evans 11af7b0868SMatt Evans static struct ioport_operations debug_ops = { 12af7b0868SMatt Evans .io_out = debug_io_out, 13af7b0868SMatt Evans }; 14af7b0868SMatt Evans 154123ca55SMarc Zyngier static bool seabios_debug_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) 16ce08f2afSPekka Enberg { 17ce08f2afSPekka Enberg char ch; 18ce08f2afSPekka Enberg 19ce08f2afSPekka Enberg ch = ioport__read8(data); 20ce08f2afSPekka Enberg 21ce08f2afSPekka Enberg putchar(ch); 22ce08f2afSPekka Enberg 23ce08f2afSPekka Enberg return true; 24ce08f2afSPekka Enberg } 25ce08f2afSPekka Enberg 26ce08f2afSPekka Enberg static struct ioport_operations seabios_debug_ops = { 27ce08f2afSPekka Enberg .io_out = seabios_debug_io_out, 28ce08f2afSPekka Enberg }; 29ce08f2afSPekka Enberg 304123ca55SMarc Zyngier static bool dummy_io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) 31af7b0868SMatt Evans { 32af7b0868SMatt Evans return true; 33af7b0868SMatt Evans } 34af7b0868SMatt Evans 354123ca55SMarc Zyngier static bool dummy_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) 36af7b0868SMatt Evans { 37af7b0868SMatt Evans return true; 38af7b0868SMatt Evans } 39af7b0868SMatt Evans 40af7b0868SMatt Evans static struct ioport_operations dummy_read_write_ioport_ops = { 41af7b0868SMatt Evans .io_in = dummy_io_in, 42af7b0868SMatt Evans .io_out = dummy_io_out, 43af7b0868SMatt Evans }; 44af7b0868SMatt Evans 45af7b0868SMatt Evans static struct ioport_operations dummy_write_only_ioport_ops = { 46af7b0868SMatt Evans .io_out = dummy_io_out, 47af7b0868SMatt Evans }; 48af7b0868SMatt Evans 4960e1cb55SPekka Enberg /* 5060e1cb55SPekka Enberg * The "fast A20 gate" 5160e1cb55SPekka Enberg */ 5260e1cb55SPekka Enberg 534123ca55SMarc Zyngier static bool ps2_control_a_io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) 5460e1cb55SPekka Enberg { 5560e1cb55SPekka Enberg /* 5660e1cb55SPekka Enberg * A20 is always enabled. 5760e1cb55SPekka Enberg */ 5860e1cb55SPekka Enberg ioport__write8(data, 0x02); 5960e1cb55SPekka Enberg 6060e1cb55SPekka Enberg return true; 6160e1cb55SPekka Enberg } 6260e1cb55SPekka Enberg 6360e1cb55SPekka Enberg static struct ioport_operations ps2_control_a_ops = { 6460e1cb55SPekka Enberg .io_in = ps2_control_a_io_in, 6560e1cb55SPekka Enberg .io_out = dummy_io_out, 6660e1cb55SPekka Enberg }; 6760e1cb55SPekka Enberg 68206c41f4SWill Deacon void ioport__map_irq(u8 *irq) 69206c41f4SWill Deacon { 70206c41f4SWill Deacon } 71206c41f4SWill Deacon 72*97531eb2SAndre Przywara static int ioport__setup_arch(struct kvm *kvm) 73af7b0868SMatt Evans { 748f160708SAlexandru Elisei int r; 758f160708SAlexandru Elisei 76af7b0868SMatt Evans /* Legacy ioport setup */ 77af7b0868SMatt Evans 7848bed025SPekka Enberg /* 0000 - 001F - DMA1 controller */ 798f160708SAlexandru Elisei r = ioport__register(kvm, 0x0000, &dummy_read_write_ioport_ops, 32, NULL); 808f160708SAlexandru Elisei if (r < 0) 818f160708SAlexandru Elisei return r; 8248bed025SPekka Enberg 83af7b0868SMatt Evans /* 0x0020 - 0x003F - 8259A PIC 1 */ 848f160708SAlexandru Elisei r = ioport__register(kvm, 0x0020, &dummy_read_write_ioport_ops, 2, NULL); 858f160708SAlexandru Elisei if (r < 0) 868f160708SAlexandru Elisei return r; 87af7b0868SMatt Evans 88af7b0868SMatt Evans /* PORT 0040-005F - PIT - PROGRAMMABLE INTERVAL TIMER (8253, 8254) */ 898f160708SAlexandru Elisei r = ioport__register(kvm, 0x0040, &dummy_read_write_ioport_ops, 4, NULL); 908f160708SAlexandru Elisei if (r < 0) 918f160708SAlexandru Elisei return r; 92af7b0868SMatt Evans 9360e1cb55SPekka Enberg /* 0092 - PS/2 system control port A */ 948f160708SAlexandru Elisei r = ioport__register(kvm, 0x0092, &ps2_control_a_ops, 1, NULL); 958f160708SAlexandru Elisei if (r < 0) 968f160708SAlexandru Elisei return r; 9760e1cb55SPekka Enberg 98af7b0868SMatt Evans /* 0x00A0 - 0x00AF - 8259A PIC 2 */ 998f160708SAlexandru Elisei r = ioport__register(kvm, 0x00A0, &dummy_read_write_ioport_ops, 2, NULL); 1008f160708SAlexandru Elisei if (r < 0) 1018f160708SAlexandru Elisei return r; 102af7b0868SMatt Evans 10348bed025SPekka Enberg /* 00C0 - 001F - DMA2 controller */ 1048f160708SAlexandru Elisei r = ioport__register(kvm, 0x00C0, &dummy_read_write_ioport_ops, 32, NULL); 1058f160708SAlexandru Elisei if (r < 0) 1068f160708SAlexandru Elisei return r; 10748bed025SPekka Enberg 108af7b0868SMatt Evans /* PORT 00E0-00EF are 'motherboard specific' so we use them for our 109af7b0868SMatt Evans internal debugging purposes. */ 1108f160708SAlexandru Elisei r = ioport__register(kvm, IOPORT_DBG, &debug_ops, 1, NULL); 1118f160708SAlexandru Elisei if (r < 0) 1128f160708SAlexandru Elisei return r; 113af7b0868SMatt Evans 114af7b0868SMatt Evans /* PORT 00ED - DUMMY PORT FOR DELAY??? */ 1158f160708SAlexandru Elisei r = ioport__register(kvm, 0x00ED, &dummy_write_only_ioport_ops, 1, NULL); 1168f160708SAlexandru Elisei if (r < 0) 1178f160708SAlexandru Elisei return r; 118af7b0868SMatt Evans 119af7b0868SMatt Evans /* 0x00F0 - 0x00FF - Math co-processor */ 1208f160708SAlexandru Elisei r = ioport__register(kvm, 0x00F0, &dummy_write_only_ioport_ops, 2, NULL); 1218f160708SAlexandru Elisei if (r < 0) 1228f160708SAlexandru Elisei return r; 123af7b0868SMatt Evans 12448bed025SPekka Enberg /* PORT 0278-027A - PARALLEL PRINTER PORT (usually LPT1, sometimes LPT2) */ 1258f160708SAlexandru Elisei r = ioport__register(kvm, 0x0278, &dummy_read_write_ioport_ops, 3, NULL); 1268f160708SAlexandru Elisei if (r < 0) 1278f160708SAlexandru Elisei return r; 12848bed025SPekka Enberg 12948bed025SPekka Enberg /* PORT 0378-037A - PARALLEL PRINTER PORT (usually LPT2, sometimes LPT3) */ 1308f160708SAlexandru Elisei r = ioport__register(kvm, 0x0378, &dummy_read_write_ioport_ops, 3, NULL); 1318f160708SAlexandru Elisei if (r < 0) 1328f160708SAlexandru Elisei return r; 13348bed025SPekka Enberg 134af7b0868SMatt Evans /* PORT 03D4-03D5 - COLOR VIDEO - CRT CONTROL REGISTERS */ 1358f160708SAlexandru Elisei r = ioport__register(kvm, 0x03D4, &dummy_read_write_ioport_ops, 1, NULL); 1368f160708SAlexandru Elisei if (r < 0) 1378f160708SAlexandru Elisei return r; 1388f160708SAlexandru Elisei r = ioport__register(kvm, 0x03D5, &dummy_write_only_ioport_ops, 1, NULL); 1398f160708SAlexandru Elisei if (r < 0) 1408f160708SAlexandru Elisei return r; 141ce08f2afSPekka Enberg 1428f160708SAlexandru Elisei r = ioport__register(kvm, 0x402, &seabios_debug_ops, 1, NULL); 1438f160708SAlexandru Elisei if (r < 0) 1448f160708SAlexandru Elisei return r; 14548bed025SPekka Enberg 14648bed025SPekka Enberg /* 0510 - QEMU BIOS configuration register */ 1478f160708SAlexandru Elisei r = ioport__register(kvm, 0x510, &dummy_read_write_ioport_ops, 2, NULL); 1488f160708SAlexandru Elisei if (r < 0) 1498f160708SAlexandru Elisei return r; 1508f160708SAlexandru Elisei 1518f160708SAlexandru Elisei return 0; 152af7b0868SMatt Evans } 153*97531eb2SAndre Przywara dev_base_init(ioport__setup_arch); 154