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 void pl022_write(void *opaque, target_phys_addr_t offset, uint32_t value) { pl022_state *s = (pl022_state *)opaque; offset -= s->base; 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", 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) cpu_abort (cpu_single_env, "pl022: DMA not implemented\n"); break; default: cpu_abort (cpu_single_env, "pl022_write: Bad offset %x\n", (int)offset); } }
static uint64_t pl022_read(void *opaque, hwaddr offset, unsigned size) { pl022_state *s = (pl022_state *)opaque; int val; if (offset >= 0xfe0 && offset < 0x1000) { return pl022_id[(offset - 0xfe0) >> 2]; } switch (offset) { case 0x00: /* CR0 */ return s->cr0; case 0x04: /* CR1 */ return s->cr1; case 0x08: /* DR */ if (s->rx_fifo_len) { val = s->rx_fifo[(s->rx_fifo_head - s->rx_fifo_len) & 7]; DPRINTF("RX %02x\n", val); s->rx_fifo_len--; pl022_xfer(s); } else { val = 0; } return val; case 0x0c: /* SR */ return s->sr; case 0x10: /* CPSR */ return s->cpsr; case 0x14: /* IMSC */ return s->im; case 0x18: /* RIS */ return s->is; case 0x1c: /* MIS */ return s->im & s->is; case 0x20: /* DMACR */ /* Not implemented. */ return 0; default: qemu_log_mask(LOG_GUEST_ERROR, "pl022_read: Bad offset %x\n", (int)offset); return 0; } }
static uint32_t pl022_read(void *opaque, target_phys_addr_t offset) { pl022_state *s = (pl022_state *)opaque; int val; offset -= s->base; if (offset >= 0xfe0 && offset < 0x1000) { return pl022_id[(offset - 0xfe0) >> 2]; } switch (offset) { case 0x00: /* CR0 */ return s->cr0; case 0x04: /* CR1 */ return s->cr1; case 0x08: /* DR */ if (s->rx_fifo_len) { val = s->rx_fifo[(s->rx_fifo_head - s->rx_fifo_len) & 7]; DPRINTF("RX %02x\n", val); s->rx_fifo_len--; pl022_xfer(s); } else { val = 0; } return val; case 0x0c: /* SR */ return s->sr; case 0x10: /* CPSR */ return s->cpsr; case 0x14: /* IMSC */ return s->im; case 0x18: /* RIS */ return s->is; case 0x1c: /* MIS */ return s->im & s->is; case 0x20: /* DMACR */ /* Not implemented. */ return 0; default: cpu_abort (cpu_single_env, "pl022_read: Bad offset %x\n", (int)offset); return 0; } }