static void digic_uart_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { DigicUartState *s = opaque; unsigned char ch = value; addr >>= 2; switch (addr) { case R_TX: if (s->chr) { qemu_chr_fe_write_all(s->chr, &ch, 1); } break; case R_ST: /* * Ignore write to R_ST. * * The point is that this register is actively used * during receiving and transmitting symbols, * but we don't know the function of most of bits. * * Ignoring writes to R_ST is only a simplification * of the model. It has no perceptible side effects * for existing guests. */ break; default: qemu_log_mask(LOG_UNIMP, "digic-uart: write access to unknown register 0x" TARGET_FMT_plx, addr << 2); } }
static void bcm2835_ic_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) { BCM2835ICState *s = opaque; switch (offset) { case FIQ_CONTROL: s->fiq_select = extract32(val, 0, 7); s->fiq_enable = extract32(val, 7, 1); break; case IRQ_ENABLE_1: s->gpu_irq_enable |= val; break; case IRQ_ENABLE_2: s->gpu_irq_enable |= val << 32; break; case IRQ_ENABLE_BASIC: s->arm_irq_enable |= val & 0xff; break; case IRQ_DISABLE_1: s->gpu_irq_enable &= ~val; break; case IRQ_DISABLE_2: s->gpu_irq_enable &= ~(val << 32); break; case IRQ_DISABLE_BASIC: s->arm_irq_enable &= ~val & 0xff; break; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n", __func__, offset); return; } bcm2835_ic_update(s); }
static uint64_t digic_uart_read(void *opaque, hwaddr addr, unsigned size) { DigicUartState *s = opaque; uint64_t ret = 0; addr >>= 2; switch (addr) { case R_RX: s->reg_st &= ~(ST_RX_RDY); ret = s->reg_rx; break; case R_ST: ret = s->reg_st; break; default: qemu_log_mask(LOG_UNIMP, "digic-uart: read access to unknown register 0x" TARGET_FMT_plx, addr << 2); } return ret; }
static void iom_pit_ps_hit_in(void *opaque, int n, int level) { XilinxPIT *s = XILINX_IO_MODULE_PIT(opaque); if (!(s->regs[R_IOM_PIT_CONTROL] & IOM_PIT_CONTROL_EN)) { /* PIT disabled */ qemu_log_mask(LOG_GUEST_ERROR, "%s: Received pre-scalar hit when pit is\ Disabled. PIT is in One-shot mode or not enabled\n",\ s->prefix); return; } /* Count only on positive edge */ if (!s->ps_level && level) { s->ps_counter--; s->ps_level = level; } else { /* Not pos edge */ s->ps_level = level; return; } /* If timer expires, try to preload or stop */ if (s->ps_counter == 0) { pit_timer_hit(opaque); /* Check for pit preload/one-shot mode */ if (s->regs[R_IOM_PIT_CONTROL] & IOM_PIT_CONTROL_PRELOAD) { /* Preload Mode, Reload the ps_counter */ s->ps_counter = s->regs[R_IOM_PIT_PRELOAD]; } else { /* One-Shot mode, turn off the timer */ s->regs[R_IOM_PIT_CONTROL] &= ~IOM_PIT_CONTROL_EN; } } }
void program_interrupt(CPUS390XState *env, uint32_t code, int ilen) { S390CPU *cpu = s390_env_get_cpu(env); qemu_log_mask(CPU_LOG_INT, "program interrupt at %#" PRIx64 "\n", env->psw.addr); if (kvm_enabled()) { #ifdef CONFIG_KVM struct kvm_s390_irq irq = { .type = KVM_S390_PROGRAM_INT, .u.pgm.code = code, }; kvm_s390_vcpu_interrupt(cpu, &irq); #endif } else { CPUState *cs = CPU(cpu); env->int_pgm_code = code; env->int_pgm_ilen = ilen; cs->exception_index = EXCP_PGM; cpu_loop_exit(cs); } }
static uint64_t pci_vpb_reg_read(void *opaque, hwaddr addr, unsigned size) { PCIVPBState *s = opaque; switch (addr) { case PCI_IMAP0: case PCI_IMAP1: case PCI_IMAP2: { int win = (addr - PCI_IMAP0) >> 2; return s->imap[win]; } case PCI_SELFID: return s->selfid; case PCI_FLAGS: return s->flags; case PCI_SMAP0: case PCI_SMAP1: case PCI_SMAP2: { int win = (addr - PCI_SMAP0) >> 2; return s->smap[win]; } default: qemu_log_mask(LOG_GUEST_ERROR, "pci_vpb_reg_read: Bad offset %x\n", (int)addr); return 0; } }
static void gptm_reload(gptm_state *s, int n, int reset) { int64_t tick; if (reset) tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); else tick = s->tick[n]; if (s->config == 0) { /* 32-bit CountDown. */ uint32_t count; count = s->load[0] | (s->load[1] << 16); tick += (int64_t)count * system_clock_scale; } else if (s->config == 1) { /* 32-bit RTC. 1Hz tick. */ tick += NANOSECONDS_PER_SECOND; } else if (s->mode[n] == 0xa) { /* PWM mode. Not implemented. */ } else { qemu_log_mask(LOG_UNIMP, "GPTM: 16-bit timer mode unimplemented: 0x%x\n", s->mode[n]); return; } s->tick[n] = tick; timer_mod(s->timer[n], tick); }
static uint64_t vmport_ioport_read(void *opaque, hwaddr addr, unsigned size) { VMPortState *s = opaque; CPUState *cs = current_cpu; X86CPU *cpu = X86_CPU(cs); CPUX86State *env = &cpu->env; unsigned char command; uint32_t eax; cpu_synchronize_state(cs); eax = env->regs[R_EAX]; if (eax != VMPORT_MAGIC) { return eax; } command = env->regs[R_ECX]; trace_vmport_command(command); if (command >= VMPORT_ENTRIES || !s->func[command]) { qemu_log_mask(LOG_UNIMP, "vmport: unknown command %x\n", command); return eax; } return s->func[command](s->opaque[command], addr); }
static void pci_vpb_reg_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { PCIVPBState *s = opaque; switch (addr) { case PCI_IMAP0: case PCI_IMAP1: case PCI_IMAP2: { int win = (addr - PCI_IMAP0) >> 2; s->imap[win] = val; pci_vpb_update_window(s, win); break; } case PCI_SELFID: s->selfid = val; break; case PCI_FLAGS: s->flags = val; break; case PCI_SMAP0: case PCI_SMAP1: case PCI_SMAP2: { int win = (addr - PCI_SMAP0) >> 2; s->smap[win] = val; break; } default: qemu_log_mask(LOG_GUEST_ERROR, "pci_vpb_reg_write: Bad offset %x\n", (int)addr); break; } }
static uint64_t zynq_xadc_read(void *opaque, hwaddr offset, unsigned size) { ZynqXADCState *s = opaque; int reg = offset / 4; uint32_t rv = 0; if (!zynq_xadc_check_offset(reg, true)) { qemu_log_mask(LOG_GUEST_ERROR, "zynq_xadc: Invalid read access to " "addr %" HWADDR_PRIx "\n", offset); return 0; } switch (reg) { case CFG: case INT_MASK: case INT_STS: case MCTL: rv = s->regs[reg]; break; case MSTS: rv = MSTS_CFIFOE; rv |= s->xadc_dfifo_entries << MSTS_DFIFO_LVL_SHIFT; if (!s->xadc_dfifo_entries) { rv |= MSTS_DFIFOE; } else if (s->xadc_dfifo_entries == ZYNQ_XADC_FIFO_DEPTH) { rv |= MSTS_DFIFOF; } break; case RDFIFO: rv = xadc_pop_dfifo(s); break; } return rv; }
void cpu_unassigned_access(CPUState *env1, target_phys_addr_t addr, int is_write, int is_exec, int is_asi, int size) { CPUState *saved_env; saved_env = env; env = env1; qemu_log_mask(CPU_LOG_INT, "Unassigned " TARGET_FMT_plx " wr=%d exe=%d\n", addr, is_write, is_exec); if (!(env->sregs[SR_MSR] & MSR_EE)) { env = saved_env; return; } env->sregs[SR_EAR] = addr; if (is_exec) { if ((env->pvr.regs[2] & PVR2_IOPB_BUS_EXC_MASK)) { env->sregs[SR_ESR] = ESR_EC_INSN_BUS; helper_raise_exception(EXCP_HW_EXCP); } } else { if ((env->pvr.regs[2] & PVR2_DOPB_BUS_EXC_MASK)) { env->sregs[SR_ESR] = ESR_EC_DATA_BUS; helper_raise_exception(EXCP_HW_EXCP); } } env = saved_env; }
/* Read GCR registers */ static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size) { MIPSGCRState *gcr = (MIPSGCRState *) opaque; switch (addr) { /* Global Control Block Register */ case GCR_CONFIG_OFS: /* Set PCORES to 0 */ return 0; case GCR_BASE_OFS: return gcr->gcr_base; case GCR_REV_OFS: return gcr->gcr_rev; case GCR_CPC_BASE_OFS: return gcr->cpc_base; case GCR_CPC_STATUS_OFS: return is_cpc_connected(gcr); case GCR_L2_CONFIG_OFS: /* L2 BYPASS */ return GCR_L2_CONFIG_BYPASS_MSK; /* Core-Local and Core-Other Control Blocks */ case MIPS_CLCB_OFS + GCR_CL_CONFIG_OFS: case MIPS_COCB_OFS + GCR_CL_CONFIG_OFS: /* Set PVP to # of VPs - 1 */ return gcr->num_vps - 1; case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS: return 0; default: qemu_log_mask(LOG_UNIMP, "Read %d bytes at GCR offset 0x%" HWADDR_PRIx "\n", size, addr); return 0; } return 0; }
uint64_t register_read(RegisterInfo *reg, uint64_t re, const char* prefix, bool debug) { uint64_t ret; const RegisterAccessInfo *ac; assert(reg); ac = reg->access; if (!ac || !ac->name) { qemu_log_mask(LOG_GUEST_ERROR, "%s: read from undefined device state\n", prefix); return 0; } ret = reg->data ? register_read_val(reg) : ac->reset; register_write_val(reg, ret & ~(ac->cor & re)); /* Mask based on the read enable size */ ret &= re; if (ac->post_read) { ret = ac->post_read(reg, ret); } if (debug) { qemu_log("%s:%s: read of value %#" PRIx64 "\n", prefix, ac->name, ret); } return ret; }
void register_write_memory(void *opaque, hwaddr addr, uint64_t value, unsigned size) { RegisterInfoArray *reg_array = opaque; RegisterInfo *reg = NULL; uint64_t we; int i; for (i = 0; i < reg_array->num_elements; i++) { if (reg_array->r[i]->access->addr == addr) { reg = reg_array->r[i]; break; } } if (!reg) { qemu_log_mask(LOG_GUEST_ERROR, "%s: write to unimplemented register " \ "at address: %#" PRIx64 "\n", reg_array->prefix, addr); return; } /* Generate appropriate write enable mask */ we = register_enabled_mask(reg->data_size, size); register_write(reg, value, we, reg_array->prefix, reg_array->debug); }
static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset, unsigned size) { AspeedI2CBus *bus = opaque; switch (offset) { case I2CD_FUN_CTRL_REG: return bus->ctrl; case I2CD_AC_TIMING_REG1: return bus->timing[0]; case I2CD_AC_TIMING_REG2: return bus->timing[1]; case I2CD_INTR_CTRL_REG: return bus->intr_ctrl; case I2CD_INTR_STS_REG: return bus->intr_status; case I2CD_BYTE_BUF_REG: return bus->buf; case I2CD_CMD_REG: return bus->cmd | (i2c_bus_busy(bus->bus) << 16); default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset); return -1; } }
static uint64_t aspeed_timer_read(void *opaque, hwaddr offset, unsigned size) { AspeedTimerCtrlState *s = opaque; const int reg = (offset & 0xf) / 4; uint64_t value; switch (offset) { case 0x30: /* Control Register */ value = s->ctrl; break; case 0x34: /* Control Register 2 */ value = s->ctrl2; break; case 0x00 ... 0x2c: /* Timers 1 - 4 */ value = aspeed_timer_get_value(&s->timers[(offset >> 4)], reg); break; case 0x40 ... 0x8c: /* Timers 5 - 8 */ value = aspeed_timer_get_value(&s->timers[(offset >> 4) - 1], reg); break; /* Illegal */ case 0x38: case 0x3C: default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset); value = 0; break; } trace_aspeed_timer_read(offset, size, value); return value; }
static uint64_t rtt_read(void *opaque, hwaddr offset, unsigned size) { rtt_state *s = (rtt_state *)opaque; int val; if (offset >= 0xfe0 && offset < 0x1000) { return rtt_id[(offset - 0xfe0) >> 2]; } switch (offset) { case 0x00: // MR return s->mr; case 0x04: // AR return s->ar; case 0x08: // VR return s->vr; case 0x0c: // SR val = s->sr; s->sr = 0; return val; default: qemu_log_mask(LOG_GUEST_ERROR, "rtt_read: Bad offset %x\n", (int)offset); return 0; } }
static void pic_ioport_write(void *opaque, hwaddr addr64, uint64_t val64, unsigned size) { PICCommonState *s = opaque; uint32_t addr = addr64; uint32_t val = val64; int priority, cmd, irq; DPRINTF("write: addr=0x%02x val=0x%02x\n", addr, val); if (addr == 0) { if (val & 0x10) { pic_init_reset(s); s->init_state = 1; s->init4 = val & 1; s->single_mode = val & 2; if (val & 0x08) { qemu_log_mask(LOG_UNIMP, "i8259: level sensitive irq not supported\n"); } } else if (val & 0x08) { if (val & 0x04) { s->poll = 1; } if (val & 0x02) { s->read_reg_select = val & 1; } if (val & 0x40) { s->special_mask = (val >> 5) & 1; } } else {
static uint64_t cg3_reg_read(void *opaque, hwaddr addr, unsigned size) { CG3State *s = opaque; int val; switch (addr) { case CG3_REG_BT458_ADDR: case CG3_REG_BT458_COLMAP: val = 0; break; case CG3_REG_FBC_CTRL: val = s->regs[0]; break; case CG3_REG_FBC_STATUS: /* monitor ID 6, board type = 1 (color) */ val = s->regs[1] | CG3_SR_1152_900_76_B | CG3_SR_ID_COLOR; break; case CG3_REG_FBC_CURSTART ... CG3_REG_SIZE - 1: val = s->regs[addr - 0x10]; break; default: qemu_log_mask(LOG_UNIMP, "cg3: Unimplemented register read " "reg 0x%" HWADDR_PRIx " size 0x%x\n", addr, size); val = 0; break; } DPRINTF("read %02x from reg %" HWADDR_PRIx "\n", val, addr); return val; }
static void itc_tag_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) { MIPSITUState *tag = (MIPSITUState *)opaque; uint64_t *am = &tag->ITCAddressMap[0]; uint64_t am_old, mask; uint64_t index = addr >> 3; switch (index) { case 0: mask = ITC_AM0_BASE_ADDRESS_MASK | ITC_AM0_EN_MASK; break; case 1: mask = ITC_AM1_ADDR_MASK_MASK | ITC_AM1_ENTRY_GRAIN_MASK; break; default: qemu_log_mask(LOG_GUEST_ERROR, "Bad write 0x%" PRIx64 "\n", addr); return; } am_old = am[index]; am[index] = (data & mask) | (am_old & ~mask); if (am_old != am[index]) { itc_reconfigure(tag); } }
void mb_cpu_unassigned_access(CPUState *cs, hwaddr addr, bool is_write, bool is_exec, int is_asi, unsigned size) { MicroBlazeCPU *cpu; CPUMBState *env; qemu_log_mask(CPU_LOG_INT, "Unassigned " TARGET_FMT_plx " wr=%d exe=%d\n", addr, is_write ? 1 : 0, is_exec ? 1 : 0); if (cs == NULL) { return; } cpu = MICROBLAZE_CPU(cs); env = &cpu->env; if (!(env->sregs[SR_MSR] & MSR_EE)) { return; } env->sregs[SR_EAR] = addr; if (is_exec) { if ((env->pvr.regs[2] & PVR2_IOPB_BUS_EXC_MASK)) { env->sregs[SR_ESR] = ESR_EC_INSN_BUS; helper_raise_exception(env, EXCP_HW_EXCP); } } else { if ((env->pvr.regs[2] & PVR2_DOPB_BUS_EXC_MASK)) { env->sregs[SR_ESR] = ESR_EC_DATA_BUS; helper_raise_exception(env, EXCP_HW_EXCP); } } }
uint64_t register_read_memory(void *opaque, hwaddr addr, unsigned size) { RegisterInfoArray *reg_array = opaque; RegisterInfo *reg = NULL; uint64_t read_val; uint64_t re; int i; for (i = 0; i < reg_array->num_elements; i++) { if (reg_array->r[i]->access->addr == addr) { reg = reg_array->r[i]; break; } } if (!reg) { qemu_log_mask(LOG_GUEST_ERROR, "%s: read to unimplemented register " \ "at address: %#" PRIx64 "\n", reg_array->prefix, addr); return 0; } /* Generate appropriate read enable mask */ re = register_enabled_mask(reg->data_size, size); read_val = register_read(reg, re, reg_array->prefix, reg_array->debug); return extract64(read_val, 0, size * 8); }
static void pl031_write(void * opaque, hwaddr offset, uint64_t value, unsigned size) { PL031State *s = (PL031State *)opaque; switch (offset) { case RTC_LR: s->tick_offset += value - pl031_get_count(s); pl031_set_alarm(s); break; case RTC_MR: s->mr = value; pl031_set_alarm(s); break; case RTC_IMSC: s->im = value & 1; DPRINTF("Interrupt mask %d\n", s->im); pl031_update(s); break; case RTC_ICR: /* The PL031 documentation (DDI0224B) states that the interrupt is cleared when bit 0 of the written value is set. However the arm926e documentation (DDI0287B) states that the interrupt is cleared when any value is written. */ DPRINTF("Interrupt cleared"); s->is = 0; pl031_update(s); break; case RTC_CR: /* Written value is ignored. */ break; case RTC_DR: case RTC_MIS: case RTC_RIS: qemu_log_mask(LOG_GUEST_ERROR, "pl031: write to read-only register at offset 0x%x\n", (int)offset); break; default: qemu_log_mask(LOG_GUEST_ERROR, "pl031_write: Bad offset 0x%x\n", (int)offset); break; } }
static uint64_t pl011_read(void *opaque, hwaddr offset, unsigned size) { PL011State *s = (PL011State *)opaque; uint32_t c; if (offset >= 0xfe0 && offset < 0x1000) { return s->id[(offset - 0xfe0) >> 2]; } switch (offset >> 2) { case 0: /* UARTDR */ s->flags &= ~PL011_FLAG_RXFF; c = s->read_fifo[s->read_pos]; if (s->read_count > 0) { s->read_count--; if (++s->read_pos == 16) s->read_pos = 0; } if (s->read_count == 0) { s->flags |= PL011_FLAG_RXFE; } if (s->read_count == s->read_trigger - 1) s->int_level &= ~ PL011_INT_RX; s->rsr = c >> 8; pl011_update(s); if (s->chr) { qemu_chr_accept_input(s->chr); } return c; case 1: /* UARTRSR */ return s->rsr; case 6: /* UARTFR */ return s->flags; case 8: /* UARTILPR */ return s->ilpr; case 9: /* UARTIBRD */ return s->ibrd; case 10: /* UARTFBRD */ return s->fbrd; case 11: /* UARTLCR_H */ return s->lcr; case 12: /* UARTCR */ return s->cr; case 13: /* UARTIFLS */ return s->ifl; case 14: /* UARTIMSC */ return s->int_enabled; case 15: /* UARTRIS */ return s->int_level; case 16: /* UARTMIS */ return s->int_level & s->int_enabled; case 18: /* UARTDMACR */ return s->dmacr; default: qemu_log_mask(LOG_GUEST_ERROR, "pl011_read: Bad offset %x\n", (int)offset); return 0; } }
/* * The state machine needs some refinement. It is only used to track * invalid STOP commands for the moment. */ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value) { bus->cmd &= ~0xFFFF; bus->cmd |= value & 0xFFFF; if (bus->cmd & I2CD_M_START_CMD) { uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ? I2CD_MSTARTR : I2CD_MSTART; aspeed_i2c_set_state(bus, state); if (i2c_start_transfer(bus->bus, extract32(bus->buf, 1, 7), extract32(bus->buf, 0, 1))) { bus->intr_status |= I2CD_INTR_TX_NAK; } else { bus->intr_status |= I2CD_INTR_TX_ACK; } /* START command is also a TX command, as the slave address is * sent on the bus */ bus->cmd &= ~(I2CD_M_START_CMD | I2CD_M_TX_CMD); /* No slave found */ if (!i2c_bus_busy(bus->bus)) { return; } aspeed_i2c_set_state(bus, I2CD_MACTIVE); } if (bus->cmd & I2CD_M_TX_CMD) { aspeed_i2c_set_state(bus, I2CD_MTXD); if (i2c_send(bus->bus, bus->buf)) { bus->intr_status |= (I2CD_INTR_TX_NAK); i2c_end_transfer(bus->bus); } else { bus->intr_status |= I2CD_INTR_TX_ACK; } bus->cmd &= ~I2CD_M_TX_CMD; aspeed_i2c_set_state(bus, I2CD_MACTIVE); } if ((bus->cmd & (I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST)) && !(bus->intr_status & I2CD_INTR_RX_DONE)) { aspeed_i2c_handle_rx_cmd(bus); } if (bus->cmd & I2CD_M_STOP_CMD) { if (!(aspeed_i2c_get_state(bus) & I2CD_MACTIVE)) { qemu_log_mask(LOG_GUEST_ERROR, "%s: abnormal stop\n", __func__); bus->intr_status |= I2CD_INTR_ABNORMAL; } else { aspeed_i2c_set_state(bus, I2CD_MSTOP); i2c_end_transfer(bus->bus); bus->intr_status |= I2CD_INTR_NORMAL_STOP; } bus->cmd &= ~I2CD_M_STOP_CMD; aspeed_i2c_set_state(bus, I2CD_IDLE); } }
static void pl022_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { pl022_state *s = (pl022_state *)opaque; switch (offset) { case 0x00: /* CR0 */ s->cr0 = value; /* Clock rate and format are ignored. */ s->bitmask = (1 << ((value & 15) + 1)) - 1; break; case 0x04: /* CR1 */ s->cr1 = value; if ((s->cr1 & (PL022_CR1_MS | PL022_CR1_SSE)) == (PL022_CR1_MS | PL022_CR1_SSE)) { BADF("SPI slave mode not implemented\n"); } pl022_xfer(s); break; case 0x08: /* DR */ if (s->tx_fifo_len < 8) { DPRINTF("TX %02x\n", (unsigned)value); s->tx_fifo[s->tx_fifo_head] = value & s->bitmask; s->tx_fifo_head = (s->tx_fifo_head + 1) & 7; s->tx_fifo_len++; pl022_xfer(s); } break; case 0x10: /* CPSR */ /* Prescaler. Ignored. */ s->cpsr = value & 0xff; break; case 0x14: /* IMSC */ s->im = value; pl022_update(s); break; case 0x20: /* DMACR */ if (value) { qemu_log_mask(LOG_UNIMP, "pl022: DMA not implemented\n"); } break; default: qemu_log_mask(LOG_GUEST_ERROR, "pl022_write: Bad offset %x\n", (int)offset); } }
static MemTxResult gicv3_its_trans_read(void *opaque, hwaddr offset, uint64_t *data, unsigned size, MemTxAttrs attrs) { qemu_log_mask(LOG_GUEST_ERROR, "ITS read at offset 0x%"PRIx64"\n", offset); *data = 0; return MEMTX_OK; }
static void aspeed_wdt_timer_expired(void *dev) { AspeedWDTState *s = ASPEED_WDT(dev); qemu_log_mask(CPU_LOG_RESET, "Watchdog timer expired.\n"); watchdog_perform_action(); timer_del(s->timer); }
/** * Analyze the info request message sent by the client to see what data it * provided and what it wants to have. The information is gathered in the * "requested_infos" struct. Note that client_id (if provided) points into * the odata region, thus the caller must keep odata valid as long as it * needs to access the requested_infos struct. */ static int dhcpv6_parse_info_request(uint8_t *odata, int olen, struct requested_infos *ri) { int i, req_opt; while (olen > 4) { /* Parse one option */ int option = odata[0] << 8 | odata[1]; int len = odata[2] << 8 | odata[3]; if (len + 4 > olen) { qemu_log_mask(LOG_GUEST_ERROR, "Guest sent bad DHCPv6 packet!\n"); return -E2BIG; } switch (option) { case OPTION_IAADDR: /* According to RFC3315, we must discard requests with IA option */ return -EINVAL; case OPTION_CLIENTID: if (len > 256) { /* Avoid very long IDs which could cause problems later */ return -E2BIG; } ri->client_id = odata + 4; ri->client_id_len = len; break; case OPTION_ORO: /* Option request option */ if (len & 1) { return -EINVAL; } /* Check which options the client wants to have */ for (i = 0; i < len; i += 2) { req_opt = odata[4 + i] << 8 | odata[4 + i + 1]; switch (req_opt) { case OPTION_DNS_SERVERS: ri->want_dns = true; break; case OPTION_BOOTFILE_URL: ri->want_boot_url = true; break; default: DEBUG_MISC((dfd, "dhcpv6: Unsupported option request %d\n", req_opt)); } } break; default: DEBUG_MISC((dfd, "dhcpv6 info req: Unsupported option %d, len=%d\n", option, len)); } odata += len + 4; olen -= len + 4; } return 0; }
static uint64_t a10_pit_read(void *opaque, hwaddr offset, unsigned size) { AwA10PITState *s = AW_A10_PIT(opaque); uint8_t index; switch (offset) { case AW_A10_PIT_TIMER_IRQ_EN: return s->irq_enable; case AW_A10_PIT_TIMER_IRQ_ST: return s->irq_status; case AW_A10_PIT_TIMER_BASE ... AW_A10_PIT_TIMER_BASE_END: index = offset & 0xf0; index >>= 4; index -= 1; switch (offset & 0x0f) { case AW_A10_PIT_TIMER_CONTROL: return s->control[index]; case AW_A10_PIT_TIMER_INTERVAL: return s->interval[index]; case AW_A10_PIT_TIMER_COUNT: s->count[index] = ptimer_get_count(s->timer[index]); return s->count[index]; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%x\n", __func__, (int)offset); break; } case AW_A10_PIT_WDOG_CONTROL: break; case AW_A10_PIT_WDOG_MODE: break; case AW_A10_PIT_COUNT_LO: return s->count_lo; case AW_A10_PIT_COUNT_HI: return s->count_hi; case AW_A10_PIT_COUNT_CTL: return s->count_ctl; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%x\n", __func__, (int)offset); break; } return 0; }