in hw/misc/iotkit-sysctl.c [384:706]
static void iotkit_sysctl_write(void *opaque, hwaddr offset,
uint64_t value, unsigned size)
{
IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
trace_iotkit_sysctl_write(offset, value, size);
/*
* Most of the state here has to do with control of reset and
* similar kinds of power up -- for instance the guest can ask
* what the reason for the last reset was, or forbid reset for
* some causes (like the non-secure watchdog). Most of this is
* not relevant to QEMU, which doesn't really model anything other
* than a full power-on reset.
* We just model the registers as reads-as-written.
*/
switch (offset) {
case A_RESET_SYNDROME:
qemu_log_mask(LOG_UNIMP,
"IoTKit SysCtl RESET_SYNDROME unimplemented\n");
s->reset_syndrome = value;
break;
case A_RESET_MASK:
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl RESET_MASK unimplemented\n");
s->reset_mask = value;
break;
case A_GRETREG:
/*
* General retention register, which is only reset by a power-on
* reset. Technically this implementation is complete, since
* QEMU only supports power-on resets...
*/
s->gretreg = value;
break;
case A_INITSVTOR0:
switch (s->sse_version) {
case ARMSSE_SSE300:
/* SSE300 has a LOCK bit which prevents further writes when set */
if (s->initsvtor0 & R_INITSVTOR0_LOCK_MASK) {
qemu_log_mask(LOG_GUEST_ERROR,
"IoTKit INITSVTOR0 write when register locked\n");
break;
}
s->initsvtor0 = value;
set_init_vtor(0, s->initsvtor0 & R_INITSVTOR0_VTOR_MASK);
break;
case ARMSSE_IOTKIT:
case ARMSSE_SSE200:
s->initsvtor0 = value;
set_init_vtor(0, s->initsvtor0);
break;
default:
g_assert_not_reached();
}
break;
case A_CPUWAIT:
switch (s->sse_version) {
case ARMSSE_IOTKIT:
case ARMSSE_SSE200:
cpuwait_write(s, value);
break;
case ARMSSE_SSE300:
/* In SSE300 this is reserved (for INITSVTOR2) */
goto bad_offset;
default:
g_assert_not_reached();
}
break;
case A_WICCTRL:
switch (s->sse_version) {
case ARMSSE_IOTKIT:
case ARMSSE_SSE200:
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
s->wicctrl = value;
break;
case ARMSSE_SSE300:
/* In SSE300 this offset is CPUWAIT */
cpuwait_write(s, value);
break;
default:
g_assert_not_reached();
}
break;
case A_SECDBGSET:
/* write-1-to-set */
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SECDBGSET unimplemented\n");
s->secure_debug |= value;
break;
case A_SECDBGCLR:
/* write-1-to-clear */
s->secure_debug &= ~value;
break;
case A_SWRESET:
/* One w/o bit to request a reset; all other bits reserved */
if (value & R_SWRESET_SWRESETREQ_MASK) {
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
}
break;
case A_SCSECCTRL:
switch (s->sse_version) {
case ARMSSE_IOTKIT:
goto bad_offset;
case ARMSSE_SSE200:
case ARMSSE_SSE300:
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
s->scsecctrl = value;
break;
default:
g_assert_not_reached();
}
break;
case A_FCLK_DIV:
switch (s->sse_version) {
case ARMSSE_IOTKIT:
goto bad_offset;
case ARMSSE_SSE200:
case ARMSSE_SSE300:
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
s->fclk_div = value;
break;
default:
g_assert_not_reached();
}
break;
case A_SYSCLK_DIV:
switch (s->sse_version) {
case ARMSSE_IOTKIT:
goto bad_offset;
case ARMSSE_SSE200:
case ARMSSE_SSE300:
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
s->sysclk_div = value;
break;
default:
g_assert_not_reached();
}
break;
case A_CLOCK_FORCE:
switch (s->sse_version) {
case ARMSSE_IOTKIT:
goto bad_offset;
case ARMSSE_SSE200:
case ARMSSE_SSE300:
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
s->clock_force = value;
break;
default:
g_assert_not_reached();
}
break;
case A_INITSVTOR1:
switch (s->sse_version) {
case ARMSSE_IOTKIT:
goto bad_offset;
case ARMSSE_SSE200:
s->initsvtor1 = value;
set_init_vtor(1, s->initsvtor1);
break;
case ARMSSE_SSE300:
goto bad_offset;
default:
g_assert_not_reached();
}
break;
case A_EWCTRL:
switch (s->sse_version) {
case ARMSSE_IOTKIT:
goto bad_offset;
case ARMSSE_SSE200:
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
s->ewctrl = value;
break;
case ARMSSE_SSE300:
/* In SSE300 this offset is is NMI_ENABLE */
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
s->nmi_enable = value;
break;
default:
g_assert_not_reached();
}
break;
case A_PWRCTRL:
switch (s->sse_version) {
case ARMSSE_IOTKIT:
case ARMSSE_SSE200:
goto bad_offset;
case ARMSSE_SSE300:
if (!(s->pwrctrl & R_PWRCTRL_PPU_ACCESS_UNLOCK_MASK)) {
qemu_log_mask(LOG_GUEST_ERROR,
"IoTKit PWRCTRL write when register locked\n");
break;
}
s->pwrctrl = value;
break;
default:
g_assert_not_reached();
}
break;
case A_PDCM_PD_SYS_SENSE:
switch (s->sse_version) {
case ARMSSE_IOTKIT:
goto bad_offset;
case ARMSSE_SSE200:
case ARMSSE_SSE300:
qemu_log_mask(LOG_UNIMP,
"IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
s->pdcm_pd_sys_sense = value;
break;
default:
g_assert_not_reached();
}
break;
case A_PDCM_PD_CPU0_SENSE:
switch (s->sse_version) {
case ARMSSE_IOTKIT:
case ARMSSE_SSE200:
goto bad_offset;
case ARMSSE_SSE300:
qemu_log_mask(LOG_UNIMP,
"IoTKit SysCtl PDCM_PD_CPU0_SENSE unimplemented\n");
s->pdcm_pd_cpu0_sense = value;
break;
default:
g_assert_not_reached();
}
break;
case A_PDCM_PD_SRAM0_SENSE:
switch (s->sse_version) {
case ARMSSE_IOTKIT:
goto bad_offset;
case ARMSSE_SSE200:
qemu_log_mask(LOG_UNIMP,
"IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
s->pdcm_pd_sram0_sense = value;
break;
case ARMSSE_SSE300:
goto bad_offset;
default:
g_assert_not_reached();
}
break;
case A_PDCM_PD_SRAM1_SENSE:
switch (s->sse_version) {
case ARMSSE_IOTKIT:
goto bad_offset;
case ARMSSE_SSE200:
qemu_log_mask(LOG_UNIMP,
"IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
s->pdcm_pd_sram1_sense = value;
break;
case ARMSSE_SSE300:
goto bad_offset;
default:
g_assert_not_reached();
}
break;
case A_PDCM_PD_SRAM2_SENSE:
switch (s->sse_version) {
case ARMSSE_IOTKIT:
goto bad_offset;
case ARMSSE_SSE200:
qemu_log_mask(LOG_UNIMP,
"IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
s->pdcm_pd_sram2_sense = value;
break;
case ARMSSE_SSE300:
qemu_log_mask(LOG_UNIMP,
"IoTKit SysCtl PDCM_PD_VMR0_SENSE unimplemented\n");
s->pdcm_pd_vmr0_sense = value;
break;
default:
g_assert_not_reached();
}
break;
case A_PDCM_PD_SRAM3_SENSE:
switch (s->sse_version) {
case ARMSSE_IOTKIT:
goto bad_offset;
case ARMSSE_SSE200:
qemu_log_mask(LOG_UNIMP,
"IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
s->pdcm_pd_sram3_sense = value;
break;
case ARMSSE_SSE300:
qemu_log_mask(LOG_UNIMP,
"IoTKit SysCtl PDCM_PD_VMR1_SENSE unimplemented\n");
s->pdcm_pd_vmr1_sense = value;
break;
default:
g_assert_not_reached();
}
break;
case A_NMI_ENABLE:
/* In IoTKit this is BUSWAIT: reserved, R/O, zero */
switch (s->sse_version) {
case ARMSSE_IOTKIT:
goto ro_offset;
case ARMSSE_SSE200:
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
s->nmi_enable = value;
break;
case ARMSSE_SSE300:
/* In SSE300 this is reserved (for INITSVTOR3) */
goto bad_offset;
default:
g_assert_not_reached();
}
break;
case A_SECDBGSTAT:
case A_PID4 ... A_CID3:
ro_offset:
qemu_log_mask(LOG_GUEST_ERROR,
"IoTKit SysCtl write: write of RO offset %x\n",
(int)offset);
break;
default:
bad_offset:
qemu_log_mask(LOG_GUEST_ERROR,
"IoTKit SysCtl write: bad offset %x\n", (int)offset);
break;
}
}