void registers_update() { struct Node *n = IExec->GetSucc(registers_node); char tempstr[256]; n = IExec->GetSucc(n); sprintf(tempstr, "0x%x", context_copy.msr); update_register(n, tempstr); n = IExec->GetSucc(n); sprintf(tempstr, "0x%x", context_copy.ip); update_register (n, tempstr); n = IExec->GetSucc(n); sprintf(tempstr, "0x%x", context_copy.cr); update_register (n, tempstr); n = IExec->GetSucc(n); sprintf(tempstr, "0x%x", context_copy.xer); update_register (n, tempstr); n = IExec->GetSucc(n); sprintf(tempstr, "0x%x", context_copy.ctr); update_register (n, tempstr); n = IExec->GetSucc(n); sprintf(tempstr, "0x%x", context_copy.lr); update_register (n, tempstr); n = IExec->GetSucc(n); n = IExec->GetSucc(n); int i; for (i = 0; i < 32; i++) { sprintf(tempstr, "0x%x", context_copy.gpr[i]); update_register (n, tempstr); n = IExec->GetSucc(n); } n = IExec->GetSucc(n); for (i = 0; i < 32; i++) { sprintf(tempstr, "%e", context_copy.fpr[i]); update_register (n, tempstr); n = IExec->GetSucc(n); } }
void ds1307_start(i2c_dev_t *dev, bool start) { update_register(dev, TIME_REG, CH_MASK, start ? 0 : CH_BIT); }
void ds1307_set_output(i2c_dev_t *dev, bool value) { update_register(dev, CONTROL_REG, OUT_MASK, value ? OUT_BIT : 0); }
void ds1307_set_squarewave_freq(i2c_dev_t *dev, ds1307_squarewave_freq_t freq) { update_register(dev, CONTROL_REG, SQWEF_MASK, (uint8_t)freq); }
void ds1307_enable_squarewave(i2c_dev_t *dev, bool enable) { update_register(dev, CONTROL_REG, SQWE_MASK, enable ? SQWE_BIT : 0); }
int emulate_inout(int vcpu, struct vm_exit *vmexit, int strict) { int addrsize, bytes, flags, in, port, prot, rep; uint32_t eax, val; inout_func_t handler; void *arg; int error, fault, retval; enum vm_reg_name idxreg; uint64_t gla, index, iterations, count; struct vm_inout_str *vis; struct iovec iov[2]; bytes = vmexit->u.inout.bytes; in = vmexit->u.inout.in; port = vmexit->u.inout.port; assert(port < MAX_IOPORTS); assert(bytes == 1 || bytes == 2 || bytes == 4); handler = inout_handlers[port].handler; if (strict && handler == default_inout) return (-1); flags = inout_handlers[port].flags; arg = inout_handlers[port].arg; if (in) { if (!(flags & IOPORT_F_IN)) return (-1); } else { if (!(flags & IOPORT_F_OUT)) return (-1); } retval = 0; if (vmexit->u.inout.string) { vis = &vmexit->u.inout_str; rep = vis->inout.rep; addrsize = vis->addrsize; prot = in ? XHYVE_PROT_WRITE : XHYVE_PROT_READ; assert(addrsize == 2 || addrsize == 4 || addrsize == 8); /* Index register */ idxreg = in ? VM_REG_GUEST_RDI : VM_REG_GUEST_RSI; index = vis->index & vie_size2mask(addrsize); /* Count register */ count = vis->count & vie_size2mask(addrsize); /* Limit number of back-to-back in/out emulations to 16 */ iterations = min(count, 16); while (iterations > 0) { assert(retval == 0); if (vie_calculate_gla(vis->paging.cpu_mode, vis->seg_name, &vis->seg_desc, index, bytes, addrsize, prot, &gla)) { vm_inject_gp(vcpu); break; } error = xh_vm_copy_setup(vcpu, &vis->paging, gla, ((size_t) bytes), prot, iov, nitems(iov), &fault); if (error) { retval = -1; /* Unrecoverable error */ break; } else if (fault) { retval = 0; /* Resume guest to handle fault */ break; } if (vie_alignment_check(vis->paging.cpl, bytes, vis->cr0, vis->rflags, gla)) { vm_inject_ac(vcpu, 0); break; } val = 0; if (!in) xh_vm_copyin(iov, &val, ((size_t) bytes)); retval = handler(vcpu, in, port, bytes, &val, arg); if (retval != 0) break; if (in) xh_vm_copyout(&val, iov, ((size_t) bytes)); /* Update index */ if (vis->rflags & PSL_D) index -= ((uint64_t) bytes); else index += ((uint64_t) bytes); count--; iterations--; } /* Update index register */ error = update_register(vcpu, idxreg, index, addrsize); assert(error == 0); /* * Update count register only if the instruction had a repeat * prefix. */ if (rep) { error = update_register(vcpu, VM_REG_GUEST_RCX, count, addrsize); assert(error == 0); } /* Restart the instruction if more iterations remain */ if (retval == 0 && count != 0) { error = xh_vm_restart_instruction(vcpu); assert(error == 0); } } else { eax = vmexit->u.inout.eax; val = eax & vie_size2mask(bytes); retval = handler(vcpu, in, port, bytes, &val, arg); if (retval == 0 && in) { eax &= ~vie_size2mask(bytes); eax |= val & vie_size2mask(bytes); error = xh_vm_set_register(vcpu, VM_REG_GUEST_RAX, eax); assert(error == 0); } } return (retval); }