コード例 #1
0
ファイル: pl181.c プロジェクト: AmesianX/winkvm
static void pl181_fifo_run(pl181_state *s)
{
    uint32_t bits;
    uint32_t value;
    int n;
    int limit;
    int is_read;

    is_read = (s->datactrl & PL181_DATA_DIRECTION) != 0;
    if (s->datacnt != 0 && (!is_read || sd_data_ready(s->card))
            && !s->linux_hack) {
        limit = is_read ? PL181_FIFO_LEN : 0;
        n = 0;
        value = 0;
        while (s->datacnt && s->fifo_len != limit) {
            if (is_read) {
                value |= (uint32_t)sd_read_data(s->card) << (n * 8);
                n++;
                if (n == 4) {
                    pl181_fifo_push(s, value);
                    value = 0;
                    n = 0;
                }
            } else {
                if (n == 0) {
                    value = pl181_fifo_pop(s);
                    n = 4;
                }
                sd_write_data(s->card, value & 0xff);
                value >>= 8;
                n--;
            }
            s->datacnt--;
        }
        if (n && is_read) {
            pl181_fifo_push(s, value);
        }
    }
コード例 #2
0
ファイル: pl181.c プロジェクト: poblces/qemu
static void pl181_fifo_run(pl181_state *s)
{
    uint32_t bits;
    uint32_t value = 0;
    int n;
    int is_read;

    is_read = (s->datactrl & PL181_DATA_DIRECTION) != 0;
    if (s->datacnt != 0 && (!is_read || sd_data_ready(s->card))
            && !s->linux_hack) {
        if (is_read) {
            n = 0;
            while (s->datacnt && s->fifo_len < PL181_FIFO_LEN) {
                value |= (uint32_t)sd_read_data(s->card) << (n * 8);
                s->datacnt--;
                n++;
                if (n == 4) {
                    pl181_fifo_push(s, value);
                    n = 0;
                    value = 0;
                }
            }
            if (n != 0) {
                pl181_fifo_push(s, value);
            }
        } else { /* write */
            n = 0;
            while (s->datacnt > 0 && (s->fifo_len > 0 || n > 0)) {
                if (n == 0) {
                    value = pl181_fifo_pop(s);
                    n = 4;
                }
                n--;
                s->datacnt--;
                sd_write_data(s->card, value & 0xff);
                value >>= 8;
            }
        }
    }
    s->status &= ~(PL181_STATUS_RX_FIFO | PL181_STATUS_TX_FIFO);
    if (s->datacnt == 0) {
        s->status |= PL181_STATUS_DATAEND;
        /* HACK: */
        s->status |= PL181_STATUS_DATABLOCKEND;
        DPRINTF("Transfer Complete\n");
    }
    if (s->datacnt == 0 && s->fifo_len == 0) {
        s->datactrl &= ~PL181_DATA_ENABLE;
        DPRINTF("Data engine idle\n");
    } else {
        /* Update FIFO bits.  */
        bits = PL181_STATUS_TXACTIVE | PL181_STATUS_RXACTIVE;
        if (s->fifo_len == 0) {
            bits |= PL181_STATUS_TXFIFOEMPTY;
            bits |= PL181_STATUS_RXFIFOEMPTY;
        } else {
            bits |= PL181_STATUS_TXDATAAVLBL;
            bits |= PL181_STATUS_RXDATAAVLBL;
        }
        if (s->fifo_len == 16) {
            bits |= PL181_STATUS_TXFIFOFULL;
            bits |= PL181_STATUS_RXFIFOFULL;
        }
        if (s->fifo_len <= 8) {
            bits |= PL181_STATUS_TXFIFOHALFEMPTY;
        }
        if (s->fifo_len >= 8) {
            bits |= PL181_STATUS_RXFIFOHALFFULL;
        }
        if (s->datactrl & PL181_DATA_DIRECTION) {
            bits &= PL181_STATUS_RX_FIFO;
        } else {
            bits &= PL181_STATUS_TX_FIFO;
        }
        s->status |= bits;
    }
}
コード例 #3
0
ファイル: s5pc1xx_mmc.c プロジェクト: vonnyfly/qemu-s5pc110
/* Transfer data between the card and the FIFO.  This is complicated by
   the FIFO holding 32-bit words and the card taking data in single byte
   chunks.  FIFO bytes are transferred in little-endian order.  */
static void mmc_fifo_run(S5pc1xxMMCState *s)
{
    uint32_t value;
    int n;
    uint32_t pos;
    int is_read;
    uint32_t datacnt, boundary_chk, boundary_count;
    uint8_t dma_buf_boundary, dma_mask_flag;

    is_read = (s->trnmod & S5C_HSMMC_TRNS_READ) != 0;

    if (s->blkcnt != 0 && (!is_read || sd_data_ready(s->card))) {
        n = 0;
        value = 0;

        if (s->blkcnt > 1) {
            /* multi block */
            if (s->norintstsen & 0x8)
                dma_mask_flag = 1;  /* DMA enable */
            else
                dma_mask_flag = 0;  /* DMA disable */

            dma_buf_boundary = (s->blksize & 0xf000) >> 12;
            boundary_chk = 1 << (dma_buf_boundary+12);
            boundary_count = boundary_chk - (s->sysad % boundary_chk);
            while (s->blkcnt) {
                datacnt = s->blksize & 0x0fff;
                pos = 0;
                while (datacnt) {
                    if (is_read) {
                        value |= (uint32_t)sd_read_data(s->card) << (n * 8);
                        n++;
                        if (n == 4) {
                            mmc_fifo_push(s, pos, value);
                            value = 0;
                            n = 0;
                            pos += 4;
                        }
                    } else {
                        if (n == 0) {
                            value = mmc_fifo_pop(s, pos);
                            n = 4;
                            pos += 4;
                        }
                        sd_write_data(s->card, value & 0xff);
                        value >>= 8;
                        n--;
                    }
                    datacnt--;
                }
                s->sysad += s->blksize & 0x0fff;
                boundary_count -= s->blksize & 0x0fff;
                s->blkcnt--;

                if ((boundary_count == 0) && dma_mask_flag)
                    break;
            }
            if (s->blkcnt == 0)
                s->norintsts |= S5C_HSMMC_NIS_TRSCMP;
            else
                s->norintsts |= S5C_HSMMC_NIS_DMA;
        } else {