sdhci_write(SDHCIState *s, unsigned int offset, uint32_t value, unsigned size)

{

    unsigned shift =  8 * (offset & 0x3);

    uint32_t mask = ~(((1ULL << (size * 8)) - 1) << shift);

    value <<= shift;



    switch (offset & ~0x3) {

    case SDHC_SYSAD:

        s->sdmasysad = (s->sdmasysad & mask) | value;

        MASKED_WRITE(s->sdmasysad, mask, value);

        /* Writing to last byte of sdmasysad might trigger transfer */

        if (!(mask & 0xFF000000) && TRANSFERRING_DATA(s->prnsts) && s->blkcnt &&

                s->blksize && SDHC_DMA_TYPE(s->hostctl) == SDHC_CTRL_SDMA) {

            SDHCI_GET_CLASS(s)->do_sdma_multi(s);

        }

        break;

    case SDHC_BLKSIZE:

        if (!TRANSFERRING_DATA(s->prnsts)) {

            MASKED_WRITE(s->blksize, mask, value);

            MASKED_WRITE(s->blkcnt, mask >> 16, value >> 16);

        }

        break;

    case SDHC_ARGUMENT:

        MASKED_WRITE(s->argument, mask, value);

        break;

    case SDHC_TRNMOD:

        /* DMA can be enabled only if it is supported as indicated by

         * capabilities register */

        if (!(s->capareg & SDHC_CAN_DO_DMA)) {

            value &= ~SDHC_TRNS_DMA;

        }

        MASKED_WRITE(s->trnmod, mask, value);

        MASKED_WRITE(s->cmdreg, mask >> 16, value >> 16);



        /* Writing to the upper byte of CMDREG triggers SD command generation */

        if ((mask & 0xFF000000) || !SDHCI_GET_CLASS(s)->can_issue_command(s)) {

            break;

        }



        SDHCI_GET_CLASS(s)->send_command(s);

        break;

    case  SDHC_BDATA:

        if (sdhci_buff_access_is_sequential(s, offset - SDHC_BDATA)) {

            SDHCI_GET_CLASS(s)->bdata_write(s, value >> shift, size);

        }

        break;

    case SDHC_HOSTCTL:

        if (!(mask & 0xFF0000)) {

            sdhci_blkgap_write(s, value >> 16);

        }

        MASKED_WRITE(s->hostctl, mask, value);

        MASKED_WRITE(s->pwrcon, mask >> 8, value >> 8);

        MASKED_WRITE(s->wakcon, mask >> 24, value >> 24);

        if (!(s->prnsts & SDHC_CARD_PRESENT) || ((s->pwrcon >> 1) & 0x7) < 5 ||

                !(s->capareg & (1 << (31 - ((s->pwrcon >> 1) & 0x7))))) {

            s->pwrcon &= ~SDHC_POWER_ON;

        }

        break;

    case SDHC_CLKCON:

        if (!(mask & 0xFF000000)) {

            sdhci_reset_write(s, value >> 24);

        }

        MASKED_WRITE(s->clkcon, mask, value);

        MASKED_WRITE(s->timeoutcon, mask >> 16, value >> 16);

        if (s->clkcon & SDHC_CLOCK_INT_EN) {

            s->clkcon |= SDHC_CLOCK_INT_STABLE;

        } else {

            s->clkcon &= ~SDHC_CLOCK_INT_STABLE;

        }

        break;

    case SDHC_NORINTSTS:

        if (s->norintstsen & SDHC_NISEN_CARDINT) {

            value &= ~SDHC_NIS_CARDINT;

        }

        s->norintsts &= mask | ~value;

        s->errintsts &= (mask >> 16) | ~(value >> 16);

        if (s->errintsts) {

            s->norintsts |= SDHC_NIS_ERR;

        } else {

            s->norintsts &= ~SDHC_NIS_ERR;

        }

        sdhci_update_irq(s);

        break;

    case SDHC_NORINTSTSEN:

        MASKED_WRITE(s->norintstsen, mask, value);

        MASKED_WRITE(s->errintstsen, mask >> 16, value >> 16);

        s->norintsts &= s->norintstsen;

        s->errintsts &= s->errintstsen;

        if (s->errintsts) {

            s->norintsts |= SDHC_NIS_ERR;

        } else {

            s->norintsts &= ~SDHC_NIS_ERR;

        }

        sdhci_update_irq(s);

        break;

    case SDHC_NORINTSIGEN:

        MASKED_WRITE(s->norintsigen, mask, value);

        MASKED_WRITE(s->errintsigen, mask >> 16, value >> 16);

        sdhci_update_irq(s);

        break;

    case SDHC_ADMAERR:

        MASKED_WRITE(s->admaerr, mask, value);

        break;

    case SDHC_ADMASYSADDR:

        s->admasysaddr = (s->admasysaddr & (0xFFFFFFFF00000000ULL |

                (uint64_t)mask)) | (uint64_t)value;

        break;

    case SDHC_ADMASYSADDR + 4:

        s->admasysaddr = (s->admasysaddr & (0x00000000FFFFFFFFULL |

                ((uint64_t)mask << 32))) | ((uint64_t)value << 32);

        break;

    case SDHC_FEAER:

        s->acmd12errsts |= value;

        s->errintsts |= (value >> 16) & s->errintstsen;

        if (s->acmd12errsts) {

            s->errintsts |= SDHC_EIS_CMD12ERR;

        }

        if (s->errintsts) {

            s->norintsts |= SDHC_NIS_ERR;

        }

        sdhci_update_irq(s);

        break;

    default:

        ERRPRINT("bad %ub write offset: addr[0x%04x] <- %u(0x%x)\n",

                size, offset, value >> shift, value >> shift);

        break;

    }

    DPRINT_L2("write %ub: addr[0x%04x] <- %u(0x%x)\n",

            size, offset, value >> shift, value >> shift);

}

sdhci_write(SDHCIState *s, unsigned int offset, uint32_t value, unsigned size)

{

    unsigned shift =  8 * (offset & 0x3);

    uint32_t mask = ~(((1ULL << (size * 8)) - 1) << shift);

    value <<= shift;



    switch (offset & ~0x3) {

    case SDHC_SYSAD:

        s->sdmasysad = (s->sdmasysad & mask) | value;

        MASKED_WRITE(s->sdmasysad, mask, value);

        

        if (!(mask & 0xFF000000) && TRANSFERRING_DATA(s->prnsts) && s->blkcnt &&

                s->blksize && SDHC_DMA_TYPE(s->hostctl) == SDHC_CTRL_SDMA) {

            SDHCI_GET_CLASS(s)->do_sdma_multi(s);

        }

        break;

    case SDHC_BLKSIZE:

        if (!TRANSFERRING_DATA(s->prnsts)) {

            MASKED_WRITE(s->blksize, mask, value);

            MASKED_WRITE(s->blkcnt, mask >> 16, value >> 16);

        }

        break;

    case SDHC_ARGUMENT:

        MASKED_WRITE(s->argument, mask, value);

        break;

    case SDHC_TRNMOD:

        



        if (!(s->capareg & SDHC_CAN_DO_DMA)) {

            value &= ~SDHC_TRNS_DMA;

        }

        MASKED_WRITE(s->trnmod, mask, value);

        MASKED_WRITE(s->cmdreg, mask >> 16, value >> 16);



        

        if ((mask & 0xFF000000) || !SDHCI_GET_CLASS(s)->can_issue_command(s)) {

            break;

        }



        SDHCI_GET_CLASS(s)->send_command(s);

        break;

    case  SDHC_BDATA:

        if (sdhci_buff_access_is_sequential(s, offset - SDHC_BDATA)) {

            SDHCI_GET_CLASS(s)->bdata_write(s, value >> shift, size);

        }

        break;

    case SDHC_HOSTCTL:

        if (!(mask & 0xFF0000)) {

            sdhci_blkgap_write(s, value >> 16);

        }

        MASKED_WRITE(s->hostctl, mask, value);

        MASKED_WRITE(s->pwrcon, mask >> 8, value >> 8);

        MASKED_WRITE(s->wakcon, mask >> 24, value >> 24);

        if (!(s->prnsts & SDHC_CARD_PRESENT) || ((s->pwrcon >> 1) & 0x7) < 5 ||

                !(s->capareg & (1 << (31 - ((s->pwrcon >> 1) & 0x7))))) {

            s->pwrcon &= ~SDHC_POWER_ON;

        }

        break;

    case SDHC_CLKCON:

        if (!(mask & 0xFF000000)) {

            sdhci_reset_write(s, value >> 24);

        }

        MASKED_WRITE(s->clkcon, mask, value);

        MASKED_WRITE(s->timeoutcon, mask >> 16, value >> 16);

        if (s->clkcon & SDHC_CLOCK_INT_EN) {

            s->clkcon |= SDHC_CLOCK_INT_STABLE;

        } else {

            s->clkcon &= ~SDHC_CLOCK_INT_STABLE;

        }

        break;

    case SDHC_NORINTSTS:

        if (s->norintstsen & SDHC_NISEN_CARDINT) {

            value &= ~SDHC_NIS_CARDINT;

        }

        s->norintsts &= mask | ~value;

        s->errintsts &= (mask >> 16) | ~(value >> 16);

        if (s->errintsts) {

            s->norintsts |= SDHC_NIS_ERR;

        } else {

            s->norintsts &= ~SDHC_NIS_ERR;

        }

        sdhci_update_irq(s);

        break;

    case SDHC_NORINTSTSEN:

        MASKED_WRITE(s->norintstsen, mask, value);

        MASKED_WRITE(s->errintstsen, mask >> 16, value >> 16);

        s->norintsts &= s->norintstsen;

        s->errintsts &= s->errintstsen;

        if (s->errintsts) {

            s->norintsts |= SDHC_NIS_ERR;

        } else {

            s->norintsts &= ~SDHC_NIS_ERR;

        }

        sdhci_update_irq(s);

        break;

    case SDHC_NORINTSIGEN:

        MASKED_WRITE(s->norintsigen, mask, value);

        MASKED_WRITE(s->errintsigen, mask >> 16, value >> 16);

        sdhci_update_irq(s);

        break;

    case SDHC_ADMAERR:

        MASKED_WRITE(s->admaerr, mask, value);

        break;

    case SDHC_ADMASYSADDR:

        s->admasysaddr = (s->admasysaddr & (0xFFFFFFFF00000000ULL |

                (uint64_t)mask)) | (uint64_t)value;

        break;

    case SDHC_ADMASYSADDR + 4:

        s->admasysaddr = (s->admasysaddr & (0x00000000FFFFFFFFULL |

                ((uint64_t)mask << 32))) | ((uint64_t)value << 32);

        break;

    case SDHC_FEAER:

        s->acmd12errsts |= value;

        s->errintsts |= (value >> 16) & s->errintstsen;

        if (s->acmd12errsts) {

            s->errintsts |= SDHC_EIS_CMD12ERR;

        }

        if (s->errintsts) {

            s->norintsts |= SDHC_NIS_ERR;

        }

        sdhci_update_irq(s);

        break;

    default:

        ERRPRINT("bad %ub write offset: addr[0x%04x] <- %u(0x%x)\n",

                size, offset, value >> shift, value >> shift);

        break;

    }

    DPRINT_L2("write %ub: addr[0x%04x] <- %u(0x%x)\n",

            size, offset, value >> shift, value >> shift);

}

FUNC_0(SDHCIState *VAR_0, unsigned int VAR_1, uint32_t VAR_2, unsigned VAR_3)

{

    unsigned VAR_4 =  8 * (VAR_1 & 0x3);

    uint32_t mask = ~(((1ULL << (VAR_3 * 8)) - 1) << VAR_4);

    VAR_2 <<= VAR_4;



    switch (VAR_1 & ~0x3) {

    case SDHC_SYSAD:

        VAR_0->sdmasysad = (VAR_0->sdmasysad & mask) | VAR_2;

        MASKED_WRITE(VAR_0->sdmasysad, mask, VAR_2);

        

        if (!(mask & 0xFF000000) && TRANSFERRING_DATA(VAR_0->prnsts) && VAR_0->blkcnt &&

                VAR_0->blksize && SDHC_DMA_TYPE(VAR_0->hostctl) == SDHC_CTRL_SDMA) {

            SDHCI_GET_CLASS(VAR_0)->do_sdma_multi(VAR_0);

        }

        break;

    case SDHC_BLKSIZE:

        if (!TRANSFERRING_DATA(VAR_0->prnsts)) {

            MASKED_WRITE(VAR_0->blksize, mask, VAR_2);

            MASKED_WRITE(VAR_0->blkcnt, mask >> 16, VAR_2 >> 16);

        }

        break;

    case SDHC_ARGUMENT:

        MASKED_WRITE(VAR_0->argument, mask, VAR_2);

        break;

    case SDHC_TRNMOD:

        



        if (!(VAR_0->capareg & SDHC_CAN_DO_DMA)) {

            VAR_2 &= ~SDHC_TRNS_DMA;

        }

        MASKED_WRITE(VAR_0->trnmod, mask, VAR_2);

        MASKED_WRITE(VAR_0->cmdreg, mask >> 16, VAR_2 >> 16);



        

        if ((mask & 0xFF000000) || !SDHCI_GET_CLASS(VAR_0)->can_issue_command(VAR_0)) {

            break;

        }



        SDHCI_GET_CLASS(VAR_0)->send_command(VAR_0);

        break;

    case  SDHC_BDATA:

        if (sdhci_buff_access_is_sequential(VAR_0, VAR_1 - SDHC_BDATA)) {

            SDHCI_GET_CLASS(VAR_0)->bdata_write(VAR_0, VAR_2 >> VAR_4, VAR_3);

        }

        break;

    case SDHC_HOSTCTL:

        if (!(mask & 0xFF0000)) {

            sdhci_blkgap_write(VAR_0, VAR_2 >> 16);

        }

        MASKED_WRITE(VAR_0->hostctl, mask, VAR_2);

        MASKED_WRITE(VAR_0->pwrcon, mask >> 8, VAR_2 >> 8);

        MASKED_WRITE(VAR_0->wakcon, mask >> 24, VAR_2 >> 24);

        if (!(VAR_0->prnsts & SDHC_CARD_PRESENT) || ((VAR_0->pwrcon >> 1) & 0x7) < 5 ||

                !(VAR_0->capareg & (1 << (31 - ((VAR_0->pwrcon >> 1) & 0x7))))) {

            VAR_0->pwrcon &= ~SDHC_POWER_ON;

        }

        break;

    case SDHC_CLKCON:

        if (!(mask & 0xFF000000)) {

            sdhci_reset_write(VAR_0, VAR_2 >> 24);

        }

        MASKED_WRITE(VAR_0->clkcon, mask, VAR_2);

        MASKED_WRITE(VAR_0->timeoutcon, mask >> 16, VAR_2 >> 16);

        if (VAR_0->clkcon & SDHC_CLOCK_INT_EN) {

            VAR_0->clkcon |= SDHC_CLOCK_INT_STABLE;

        } else {

            VAR_0->clkcon &= ~SDHC_CLOCK_INT_STABLE;

        }

        break;

    case SDHC_NORINTSTS:

        if (VAR_0->norintstsen & SDHC_NISEN_CARDINT) {

            VAR_2 &= ~SDHC_NIS_CARDINT;

        }

        VAR_0->norintsts &= mask | ~VAR_2;

        VAR_0->errintsts &= (mask >> 16) | ~(VAR_2 >> 16);

        if (VAR_0->errintsts) {

            VAR_0->norintsts |= SDHC_NIS_ERR;

        } else {

            VAR_0->norintsts &= ~SDHC_NIS_ERR;

        }

        sdhci_update_irq(VAR_0);

        break;

    case SDHC_NORINTSTSEN:

        MASKED_WRITE(VAR_0->norintstsen, mask, VAR_2);

        MASKED_WRITE(VAR_0->errintstsen, mask >> 16, VAR_2 >> 16);

        VAR_0->norintsts &= VAR_0->norintstsen;

        VAR_0->errintsts &= VAR_0->errintstsen;

        if (VAR_0->errintsts) {

            VAR_0->norintsts |= SDHC_NIS_ERR;

        } else {

            VAR_0->norintsts &= ~SDHC_NIS_ERR;

        }

        sdhci_update_irq(VAR_0);

        break;

    case SDHC_NORINTSIGEN:

        MASKED_WRITE(VAR_0->norintsigen, mask, VAR_2);

        MASKED_WRITE(VAR_0->errintsigen, mask >> 16, VAR_2 >> 16);

        sdhci_update_irq(VAR_0);

        break;

    case SDHC_ADMAERR:

        MASKED_WRITE(VAR_0->admaerr, mask, VAR_2);

        break;

    case SDHC_ADMASYSADDR:

        VAR_0->admasysaddr = (VAR_0->admasysaddr & (0xFFFFFFFF00000000ULL |

                (uint64_t)mask)) | (uint64_t)VAR_2;

        break;

    case SDHC_ADMASYSADDR + 4:

        VAR_0->admasysaddr = (VAR_0->admasysaddr & (0x00000000FFFFFFFFULL |

                ((uint64_t)mask << 32))) | ((uint64_t)VAR_2 << 32);

        break;

    case SDHC_FEAER:

        VAR_0->acmd12errsts |= VAR_2;

        VAR_0->errintsts |= (VAR_2 >> 16) & VAR_0->errintstsen;

        if (VAR_0->acmd12errsts) {

            VAR_0->errintsts |= SDHC_EIS_CMD12ERR;

        }

        if (VAR_0->errintsts) {

            VAR_0->norintsts |= SDHC_NIS_ERR;

        }

        sdhci_update_irq(VAR_0);

        break;

    default:

        ERRPRINT("bad %ub write VAR_1: addr[0x%04x] <- %u(0x%x)\n",

                VAR_3, VAR_1, VAR_2 >> VAR_4, VAR_2 >> VAR_4);

        break;

    }

    DPRINT_L2("write %ub: addr[0x%04x] <- %u(0x%x)\n",

            VAR_3, VAR_1, VAR_2 >> VAR_4, VAR_2 >> VAR_4);

}

FUNC_0(SDHCIState *VAR_0, unsigned int VAR_1, uint32_t VAR_2, unsigned VAR_3)
{ unsigned VAR_4 =  8 * (VAR_1 & 0x3); uint32_t mask = ~(((1ULL << (VAR_3 * 8)) - 1) << VAR_4); VAR_2 <<= VAR_4; switch (VAR_1 & ~0x3) { case SDHC_SYSAD:
VAR_0->sdmasysad = (VAR_0->sdmasysad & mask) | VAR_2; MASKED_WRITE(VAR_0->sdmasysad, mask, VAR_2); if (!(mask & 0xFF000000) && TRANSFERRING_DATA(VAR_0->prnsts) && VAR_0->blkcnt &&
VAR_0->blksize && SDHC_DMA_TYPE(VAR_0->hostctl) == SDHC_CTRL_SDMA) { SDHCI_GET_CLASS(VAR_0)->do_sdma_multi(VAR_0); } break; case SDHC_BLKSIZE:
if (!TRANSFERRING_DATA(VAR_0->prnsts)) { MASKED_WRITE(VAR_0->blksize, mask, VAR_2); MASKED_WRITE(VAR_0->blkcnt, mask >> 16, VAR_2 >> 16); } break; case SDHC_ARGUMENT:
MASKED_WRITE(VAR_0->argument, mask, VAR_2); break; case SDHC_TRNMOD:
if (!(VAR_0->capareg & SDHC_CAN_DO_DMA)) { VAR_2 &= ~SDHC_TRNS_DMA; } MASKED_WRITE(VAR_0->trnmod, mask, VAR_2); MASKED_WRITE(VAR_0->cmdreg, mask >> 16, VAR_2 >> 16); if ((mask & 0xFF000000) || !SDHCI_GET_CLASS(VAR_0)->can_issue_command(VAR_0)) { break; } SDHCI_GET_CLASS(VAR_0)->send_command(VAR_0); break; case  SDHC_BDATA:
if (sdhci_buff_access_is_sequential(VAR_0, VAR_1 - SDHC_BDATA)) { SDHCI_GET_CLASS(VAR_0)->bdata_write(VAR_0, VAR_2 >> VAR_4, VAR_3); } break; case SDHC_HOSTCTL:
if (!(mask & 0xFF0000)) { sdhci_blkgap_write(VAR_0, VAR_2 >> 16); } MASKED_WRITE(VAR_0->hostctl, mask, VAR_2); MASKED_WRITE(VAR_0->pwrcon, mask >> 8, VAR_2 >> 8); MASKED_WRITE(VAR_0->wakcon, mask >> 24, VAR_2 >> 24); if (!(VAR_0->prnsts & SDHC_CARD_PRESENT) || ((VAR_0->pwrcon >> 1) & 0x7) < 5 ||
!(VAR_0->capareg & (1 << (31 - ((VAR_0->pwrcon >> 1) & 0x7))))) { VAR_0->pwrcon &= ~SDHC_POWER_ON; } break; case SDHC_CLKCON:
if (!(mask & 0xFF000000)) { sdhci_reset_write(VAR_0, VAR_2 >> 24); } MASKED_WRITE(VAR_0->clkcon, mask, VAR_2); MASKED_WRITE(VAR_0->timeoutcon, mask >> 16, VAR_2 >> 16); if (VAR_0->clkcon & SDHC_CLOCK_INT_EN) { VAR_0->clkcon |= SDHC_CLOCK_INT_STABLE; } else { VAR_0->clkcon &= ~SDHC_CLOCK_INT_STABLE; } break; case SDHC_NORINTSTS:
if (VAR_0->norintstsen & SDHC_NISEN_CARDINT) { VAR_2 &= ~SDHC_NIS_CARDINT; } VAR_0->norintsts &= mask | ~VAR_2; VAR_0->errintsts &= (mask >> 16) | ~(VAR_2 >> 16); if (VAR_0->errintsts) { VAR_0->norintsts |= SDHC_NIS_ERR; } else { VAR_0->norintsts &= ~SDHC_NIS_ERR; } sdhci_update_irq(VAR_0); break; case SDHC_NORINTSTSEN:
MASKED_WRITE(VAR_0->norintstsen, mask, VAR_2); MASKED_WRITE(VAR_0->errintstsen, mask >> 16, VAR_2 >> 16); VAR_0->norintsts &= VAR_0->norintstsen; VAR_0->errintsts &= VAR_0->errintstsen; if (VAR_0->errintsts) { VAR_0->norintsts |= SDHC_NIS_ERR; } else { VAR_0->norintsts &= ~SDHC_NIS_ERR; } sdhci_update_irq(VAR_0); break; case SDHC_NORINTSIGEN:
MASKED_WRITE(VAR_0->norintsigen, mask, VAR_2); MASKED_WRITE(VAR_0->errintsigen, mask >> 16, VAR_2 >> 16); sdhci_update_irq(VAR_0); break; case SDHC_ADMAERR:
MASKED_WRITE(VAR_0->admaerr, mask, VAR_2); break; case SDHC_ADMASYSADDR:
VAR_0->admasysaddr = (VAR_0->admasysaddr & (0xFFFFFFFF00000000ULL |
(uint64_t)mask)) | (uint64_t)VAR_2; break; case SDHC_ADMASYSADDR + 4:
VAR_0->admasysaddr = (VAR_0->admasysaddr & (0x00000000FFFFFFFFULL |
((uint64_t)mask << 32))) | ((uint64_t)VAR_2 << 32); break; case SDHC_FEAER:
VAR_0->acmd12errsts |= VAR_2; VAR_0->errintsts |= (VAR_2 >> 16) & VAR_0->errintstsen; if (VAR_0->acmd12errsts) { VAR_0->errintsts |= SDHC_EIS_CMD12ERR; } if (VAR_0->errintsts) { VAR_0->norintsts |= SDHC_NIS_ERR; } sdhci_update_irq(VAR_0); break; default:
ERRPRINT("bad %ub write VAR_1: addr[0x%04x] <- %u(0x%x)\n",
VAR_3, VAR_1, VAR_2 >> VAR_4, VAR_2 >> VAR_4); break; } DPRINT_L2("write %ub: addr[0x%04x] <- %u(0x%x)\n",
VAR_3, VAR_1, VAR_2 >> VAR_4, VAR_2 >> VAR_4); }