static void zynq_xadc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) { ZynqXADCState *s = (ZynqXADCState *)opaque; int reg = offset / 4; int xadc_reg; int xadc_cmd; int xadc_data; if (!zynq_xadc_check_offset(reg, false)) { qemu_log_mask(LOG_GUEST_ERROR, "zynq_xadc: Invalid write access " "to addr %" HWADDR_PRIx "\n", offset); return; } switch (reg) { case CFG: s->regs[CFG] = val; break; case INT_STS: s->regs[INT_STS] &= ~val; break; case INT_MASK: s->regs[INT_MASK] = val & INT_ALL; break; case CMDFIFO: xadc_cmd = extract32(val, 26, 4); xadc_reg = extract32(val, 16, 10); xadc_data = extract32(val, 0, 16); if (s->regs[MCTL] & MCTL_RESET) { qemu_log_mask(LOG_GUEST_ERROR, "zynq_xadc: Sending command " "while comm channel held in reset: %" PRIx32 "\n", (uint32_t) val); break; } if (xadc_reg > ZYNQ_XADC_NUM_ADC_REGS && xadc_cmd != CMD_NOP) { qemu_log_mask(LOG_GUEST_ERROR, "read/write op to invalid xadc " "reg 0x%x\n", xadc_reg); break; } switch (xadc_cmd) { case CMD_READ: xadc_push_dfifo(s, s->xadc_regs[xadc_reg]); break; case CMD_WRITE: s->xadc_regs[xadc_reg] = xadc_data; /* fallthrough */ case CMD_NOP: xadc_push_dfifo(s, 0); break; } break; case MCTL: s->regs[MCTL] = val & 0x00fffeff; break; } zynq_xadc_update_ints(s); }