int __dev_pic_status(pic_t *pic, io_insn_t *io) { uint8_t *target; io_size_t sz = { .available = 1 }; if((io->port & 1) == 0) { if(pic->ocw3.poll) target = &pic->poll; else if(pic->ocw3.reg == 2) target = &pic->irr; else if(pic->ocw3.reg == 3) target = &pic->isr; else { debug(DEV_PIC, "read status from bad register (0x%x) !\n", pic->ocw3.reg); return VM_FAIL; } *target = in(io->port); /* XXX: never signal interrupt for uart1 */ if(pic->base == PIC1 && !pic->ocw3.poll) *target &= ~(1<<PIC_UART1_IRQ); } else target = &pic->imr.raw; return dev_io_insn(io, target, &sz); } int __dev_pic_ocw3(pic_t *pic, uint8_t data) { pic->ocw3.raw = data; debug(DEV_PIC, "@0x%x ocw3 0x%x\n", __rip.low, data); if(pic->ocw3.smm == PIC_OCW3_SPECIAL_MASK_MODE_ENABLED) { debug(DEV_PIC, "special mask mode not supported !\n"); return VM_FAIL; } out(data, PIC_OCW3(pic->base)); if(pic->ocw3.poll) debug(DEV_PIC, "poll command\n"); return VM_DONE; }
static int __dev_ata_device(ata_t *ata, io_insn_t *io) { ata_dev_reg_t dev; int rc; io_size_t sz = {.available = sizeof(ata_dev_reg_t)}; if(io->in) return dev_io_proxify(io); else { /* check crazy io (should not happen) */ if((io->sz * io->cnt) > sizeof(ata_dev_reg_t)) { debug(DEV_ATA, "unsupported ata dev access\n"); return VM_FAIL; } rc = dev_io_insn(io, (void*)&dev.raw, &sz); if(rc != VM_DONE) return rc; ata->dev_head = dev; debug(DEV_ATA, "ata device [%s]\n", dev.dev ? "SLAVE":"MASTER"); return dev_io_native(io, &dev.raw); } } static int __fake_ata_status(ata_t *ata) { if(ata->last_out == ATA_CMD_REG(ata->base)) info->vm.cpu.gpr->rax.blow = 1; else if(ata->last_out == ATA_DEVICE_REG(ata->base)) info->vm.cpu.gpr->rax.blow = 0; else { debug(DEV_ATA, "can't fake status for previous out(0x%x)\n", ata->last_out); return VM_FAIL; } return VM_DONE; } static int __dev_ata_status(ata_t *ata, io_insn_t *io) { if(!__rmode() && __ata_guest_want_slave(ata)) { debug(DEV_ATA, "ata fake status\n"); return __fake_ata_status(ata); } debug(DEV_ATA, "ata status\n"); return dev_io_proxify(io); } static int __dev_ata_alt_status(ata_t *ata, io_insn_t *io) { if(!__rmode() && __ata_guest_want_slave(ata)) { debug(DEV_ATA, "ata fake ALT status\n"); return __fake_ata_status(ata); } debug(DEV_ATA, "ata ALT status\n"); return dev_io_proxify(io); } static int __dev_ata_lba_filter(void *device, void *arg) { ata_t *ata = (ata_t*)arg; ata_dev_t *disk = &ata->devices[0]; uint8_t lba = *(uint8_t*)device; uint8_t idx = ata->last_out - ATA_LBA_LOW_REG(ata->base); if(idx > 2) { debug(DEV_ATA, "unknown (internal) LBA index access (%d)\n", idx); return VM_FAIL; } disk->lba_r[idx] = lba; debug(DEV_ATA, "ata lba[%d] = 0x%x\n", idx, lba); return VM_DONE; }
** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program; if not, write to the Free Software Foundation, Inc., ** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include <dev_ps2.h> #include <info_data.h> #include <debug.h> extern info_data_t *info; int dev_ps2(ps2_t *ps2, io_insn_t *io) { io_size_t sz = { .available = 1 }; int rc = dev_io_insn(io, &ps2->raw, &sz); if(rc != VM_DONE) return rc; if(ps2->fast_reset) panic("ps2 fast reset !"); dev_a20_set((uint8_t)ps2->enabled_a20); return VM_DONE; }