static void iotkit_sysctl_write()

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;
    }
}