Пример #1
0
static int pca954x_event(I2CSlave *i2c, enum i2c_event event)
{
    PCA954XState *s = PCA954X(i2c);
    int i;

    s->event = event;
    for (i = 0; i < s->lanes; ++i) {
        if (s->active_lanes & (1 << i)) {
            switch (event) {
            /* defer START conditions until we have an address */
            case I2C_START_SEND:
            case I2C_START_RECV:
                break;
            /* Forward others to sub busses */
            case I2C_FINISH:
                if (!s->control_decoded) {
                    DB_PRINT("stopping active bus %d\n", i);
                    i2c_end_transfer(s->busses[i]);
                }
                break;
            case I2C_NACK:
                if (!s->control_decoded) {
                    DB_PRINT("nacking active bus %d\n", i);
                    i2c_nack(s->busses[i]);
                }
                break;
            }
        }
    }

    return 0;
}
Пример #2
0
/*
 * init the epg db
 * buffer: IN, db node table.
 */
INT32 init_epg_db(OSAL_ID flag, UINT8 *buffer, UINT32 buf_len)
{
	if (buffer == NULL || buf_len == 0)
	{
		DB_PRINT("%s: buffer is NULL!\n",__FUNCTION__);
		return ERR_FAILED;
	}

	MEMSET(buffer, 0, buf_len);
	db_block.node = (struct DB_NODE*)buffer;
	db_block.max_count = buf_len / sizeof(struct DB_NODE);
	db_block.index = 0;
	db_block.count = 0;
	DB_PRINT("epg db buffer: 0x%X, len: %d, sizeof DB_NODE: %d, max count: %d\n",
				buffer, buf_len, sizeof(struct DB_NODE), db_block.max_count);

	if (flag == OSAL_INVALID_ID)
	{
		DB_PRINT("%s: flag ivalid!\n",__FUNCTION__);
		return ERR_FAILED;
	}
	db_block.flag = flag;
#ifdef EPG_MULTI_TP
	g_update_all_events = FALSE;
	
	MEMSET(&epg_update_view, 0, sizeof(epg_update_view));
	
	reset_multi_tp();
#endif
	osal_flag_set(db_block.flag, EPGDB_FLAG_MUTEX);

	return SUCCESS;
}
Пример #3
0
static void spi_flush_txfifo(XilinxSPI *s)
{
    uint32_t tx;
    uint32_t rx;

    while (!fifo8_is_empty(&s->tx_fifo)) {
        tx = (uint32_t)fifo8_pop(&s->tx_fifo);
        DB_PRINT("data tx:%x\n", tx);
        rx = ssi_transfer(s->spi, tx);
        DB_PRINT("data rx:%x\n", rx);
        if (fifo8_is_full(&s->rx_fifo)) {
            s->regs[R_IPISR] |= IRQ_DRR_OVERRUN;
        } else {
            fifo8_push(&s->rx_fifo, (uint8_t)rx);
            if (fifo8_is_full(&s->rx_fifo)) {
                s->regs[R_SPISR] |= SR_RX_FULL;
                s->regs[R_IPISR] |= IRQ_DRR_FULL;
            }
        }

        s->regs[R_SPISR] &= ~SR_RX_EMPTY;
        s->regs[R_SPISR] &= ~SR_TX_FULL;
        s->regs[R_SPISR] |= SR_TX_EMPTY;

        s->regs[R_IPISR] |= IRQ_DTR_EMPTY;
        s->regs[R_IPISR] |= IRQ_DRR_NOT_EMPTY;
    }

}
Пример #4
0
static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
{
    for (;;) {
        int i;
        uint8_t rx;
        uint8_t tx = 0;

        for (i = 0; i < num_effective_busses(s); ++i) {
            if (!i || s->snoop_state == SNOOP_STRIPING) {
                if (fifo8_is_empty(&s->tx_fifo)) {
                    s->regs[R_INTR_STATUS] |= IXR_TX_FIFO_UNDERFLOW;
                    xilinx_spips_update_ixr(s);
                    return;
                } else {
                    tx = fifo8_pop(&s->tx_fifo);
                }
            }
            rx = ssi_transfer(s->spi[i], (uint32_t)tx);
            DB_PRINT("tx = %02x rx = %02x\n", tx, rx);
            if (!i || s->snoop_state == SNOOP_STRIPING) {
                if (fifo8_is_full(&s->rx_fifo)) {
                    s->regs[R_INTR_STATUS] |= IXR_RX_FIFO_OVERFLOW;
                    DB_PRINT("rx FIFO overflow");
                } else {
                    fifo8_push(&s->rx_fifo, (uint8_t)rx);
                }
            }
        }

        switch (s->snoop_state) {
        case (SNOOP_CHECKING):
            switch (tx) { /* new instruction code */
            case READ: /* 3 address bytes, no dummy bytes/cycles */
            case PP:
            case DPP:
            case QPP:
                s->snoop_state = 3;
                break;
            case FAST_READ: /* 3 address bytes, 1 dummy byte */
            case DOR:
            case QOR:
            case DIOR: /* FIXME: these vary between vendor - set to spansion */
                s->snoop_state = 4;
                break;
            case QIOR: /* 3 address bytes, 2 dummy bytes */
                s->snoop_state = 6;
                break;
            default:
                s->snoop_state = SNOOP_NONE;
            }
            break;
        case (SNOOP_STRIPING):
        case (SNOOP_NONE):
            break;
        default:
            s->snoop_state--;
        }
    }
}
Пример #5
0
void fdt_init_yield(FDTMachineInfo *fdti)
{
    static int yield_index;
    int this_yield = yield_index++;

    DB_PRINT(1, "Yield #%d\n", this_yield);
    qemu_co_queue_wait(fdti->cq, NULL);
    DB_PRINT(1, "Unyield #%d\n", this_yield);
}
Пример #6
0
static int xilinx_spi_init(SysBusDevice *sbd)
{
    DeviceState *dev = DEVICE(sbd);
    XilinxSPI *s = XILINX_SPI(dev);
    int i;

    DB_PRINT("\n");

    s->spi = ssi_create_bus(dev, "spi");

    sysbus_init_irq(sbd, &s->irq);
    s->cs_lines = g_new0(qemu_irq, s->num_cs);
    ssi_auto_connect_slaves(dev, s->cs_lines, s->spi);
    for (i = 0; i < s->num_cs; ++i) {
        sysbus_init_irq(sbd, &s->cs_lines[i]);
    }

    memory_region_init_io(&s->mmio, OBJECT(s), &spi_ops, s,
                          "xilinx-spi", R_MAX * 4);
    sysbus_init_mmio(sbd, &s->mmio);

    s->irqline = -1;

    fifo8_create(&s->tx_fifo, FIFO_CAPACITY);
    fifo8_create(&s->rx_fifo, FIFO_CAPACITY);

    return 0;
}
Пример #7
0
static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
{
    int i, j;
    bool found = false;
    int field = s->regs[R_CONFIG] >> CS_SHIFT;

    for (i = 0; i < s->num_cs; i++) {
        for (j = 0; j < num_effective_busses(s); j++) {
            int upage = !!(s->regs[R_LQSPI_STS] & LQSPI_CFG_U_PAGE);
            int cs_to_set = (j * s->num_cs + i + upage) %
                                (s->num_cs * s->num_busses);

            if (~field & (1 << i) && !found) {
                DB_PRINT("selecting slave %d\n", i);
                qemu_set_irq(s->cs_lines[cs_to_set], 0);
            } else {
                qemu_set_irq(s->cs_lines[cs_to_set], 1);
            }
        }
        if (~field & (1 << i)) {
            found = true;
        }
    }
    if (!found) {
        s->snoop_state = SNOOP_CHECKING;
    }
}
Пример #8
0
static uint64_t stm32f2xx_syscfg_read(void *opaque, hwaddr addr,
                                     unsigned int size)
{
    STM32F2XXSyscfgState *s = opaque;

    DB_PRINT("0x%"HWADDR_PRIx"\n", addr);

    switch (addr) {
    case SYSCFG_MEMRMP:
        return s->syscfg_memrmp;
    case SYSCFG_PMC:
        return s->syscfg_pmc;
    case SYSCFG_EXTICR1:
        return s->syscfg_exticr1;
    case SYSCFG_EXTICR2:
        return s->syscfg_exticr2;
    case SYSCFG_EXTICR3:
        return s->syscfg_exticr3;
    case SYSCFG_EXTICR4:
        return s->syscfg_exticr4;
    case SYSCFG_CMPCR:
        return s->syscfg_cmpcr;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
        return 0;
    }

    return 0;
}
Пример #9
0
static int pca954x_decode_address(I2CSlave *i2c, uint8_t address)
{
    PCA954XState *s = PCA954X(i2c);
    int i;
    uint8_t channel_status = 0;

    s->control_decoded = address ==
                    (PCA954X_CONTROL_ADDR | (s->chip_enable & 0x7));

    if (s->control_decoded) {
        return 0;
    }

    for (i = 0; i < s->lanes; ++i) {
        if (s->active_lanes & (1 << i)) {
            DB_PRINT("starting active bus %d addr:%02x rnw:%d\n", i, address,
                    s->event == I2C_START_RECV);
            channel_status |= (i2c_start_transfer(s->busses[i], address,
                               s->event == I2C_START_RECV)) << i;
        }
    }

    if (s->active_lanes == channel_status) {
        return 1;
    }

    return 0;
}
Пример #10
0
int simple_bus_fdt_init(char *bus_node_path, FDTMachineInfo *fdti, void *unused)
{
    int i;
    int num_children = qemu_devtree_get_num_children(fdti->fdt, bus_node_path,
                                                        1);
    char **children = qemu_devtree_get_children(fdti->fdt, bus_node_path, 1);
    int initialRoutinesPending = fdti->routinesPending;

    DB_PRINT("num child devices: %d\n", num_children);

    for (i = 0; i < num_children; i++) {
        struct FDTInitNodeArgs *init_args = g_malloc0(sizeof(*init_args));
        init_args->node_path = children[i];
        init_args->fdti = fdti;
        fdti->routinesPending++;
        qemu_coroutine_enter(qemu_coroutine_create(fdt_init_node), init_args);
    }

    if (fdti->routinesPending != initialRoutinesPending) {
        bdrv_drain_all();
    }

    g_free(children);
    return 0;
}
Пример #11
0
static int xilinx_spi_init(SysBusDevice *dev)
{
    int i;
    XilinxSPI *s = FROM_SYSBUS(typeof(*s), dev);

    DB_PRINT("\n");

    s->spi = ssi_create_bus(&dev->qdev, "spi");

    sysbus_init_irq(dev, &s->irq);
    s->cs_lines = g_new(qemu_irq, s->num_cs);
    ssi_auto_connect_slaves(DEVICE(s), s->cs_lines, s->spi);
    for (i = 0; i < s->num_cs; ++i) {
        sysbus_init_irq(dev, &s->cs_lines[i]);
    }

    memory_region_init_io(&s->mmio, OBJECT(s), &spi_ops, s,
                          "xilinx-spi", R_MAX * 4);
    sysbus_init_mmio(dev, &s->mmio);

    s->irqline = -1;

    fifo8_create(&s->tx_fifo, FIFO_CAPACITY);
    fifo8_create(&s->rx_fifo, FIFO_CAPACITY);

    return 0;
}
Пример #12
0
FDTMachineInfo *fdt_generic_create_machine(void *fdt, qemu_irq *cpu_irq)
{
    char node_path[DT_PATH_LENGTH];

    FDTMachineInfo *fdti = fdt_init_new_fdti(fdt);

    fdti->irq_base = cpu_irq;

    /* parse the device tree */
    if (!qemu_devtree_get_root_node(fdt, node_path)) {
        memory_region_transaction_begin();
        fdt_init_set_opaque(fdti, node_path, NULL);
        simple_bus_fdt_init(node_path, fdti);
        while (qemu_co_enter_next(fdti->cq));
        fdt_init_all_irqs(fdti);
        memory_region_transaction_commit();
    } else {
        fprintf(stderr, "FDT: ERROR: cannot get root node from device tree %s\n"
            , node_path);
    }

    DB_PRINT(0, "FDT: Device tree scan complete\n");
    FDTMachineInfo *ret = g_malloc0(sizeof(*ret));
    return fdti;
}
Пример #13
0
static void xlnx_zynqmp_ipi_update_irq(XlnxZynqMPIPI *s)
{
    bool pending = s->regs[R_IPI_ISR] & ~s->regs[R_IPI_IMR];

    DB_PRINT("irq=%d isr=%x mask=%x\n",
             pending, s->regs[R_IPI_ISR], s->regs[R_IPI_IMR]);
    qemu_set_irq(s->irq, pending);
}
Пример #14
0
static void ipi_update_irq(IPI *s)
{
    bool pending = s->regs[R_IPI_ISR] & ~s->regs[R_IPI_IMR];
    DB_PRINT("%s: irq=%d isr=%x mask=%x\n",
             object_get_canonical_path(OBJECT(s)),
             pending, s->regs[R_IPI_ISR], s->regs[R_IPI_IMR]);
    qemu_set_irq(s->irq, pending);
}
Пример #15
0
static uint64_t zynq_slcr_read(void *opaque, hwaddr offset,
    unsigned size)
{
    uint32_t ret = zynq_slcr_read_imp(opaque, offset);

    DB_PRINT("addr: %08x data: %08x\n", offset, ret);
    return ret;
}
Пример #16
0
static void xlnx_zynqmp_obs_handler(void *opaque, int n, int level)
{
    XlnxZynqMPIPI *s = XLNX_ZYNQMP_IPI(opaque);

    DB_PRINT("OBS input irq[%d]=%d\n", n, level);

    s->regs[R_IPI_OBS] &= ~(1ULL << n);
    s->regs[R_IPI_OBS] |= (level << n);
}
Пример #17
0
static void xlnx_zynqmp_ipi_handler(void *opaque, int n, int level)
{
    XlnxZynqMPIPI *s = XLNX_ZYNQMP_IPI(opaque);
    uint32_t val = (!!level) << n;

    DB_PRINT("IPI input irq[%d]=%d\n", n, level);

    s->regs[R_IPI_ISR] |= val;
    xlnx_zynqmp_ipi_set_obs(s, s->regs[R_IPI_ISR]);
    xlnx_zynqmp_ipi_update_irq(s);
}
Пример #18
0
static int pca954x_recv(I2CSlave *i2c)
{
    PCA954XState *s = PCA954X(i2c);
    int i;
    int ret = 0;

    if (s->control_decoded) {
        ret |= s->control_reg;
        DB_PRINT("returning control register: %x\n", ret);
    } else {
        for (i = 0; i < s->lanes; ++i) {
            if (s->active_lanes & (1 << i)) {
                ret |= i2c_recv(s->busses[i]);
                DB_PRINT("recieving from active bus %d:%x\n", i, ret);
            }
        }
    }

    return ret;
}
Пример #19
0
static uint64_t stm32f2xx_timer_read(void *opaque, hwaddr offset,
                           unsigned size)
{
    STM32F2XXTimerState *s = opaque;

    DB_PRINT("Read 0x%"HWADDR_PRIx"\n", offset);

    switch (offset) {
    case TIM_CR1:
        return s->tim_cr1;
    case TIM_CR2:
        return s->tim_cr2;
    case TIM_SMCR:
        return s->tim_smcr;
    case TIM_DIER:
        return s->tim_dier;
    case TIM_SR:
        return s->tim_sr;
    case TIM_EGR:
        return s->tim_egr;
    case TIM_CCMR1:
        return s->tim_ccmr1;
    case TIM_CCMR2:
        return s->tim_ccmr2;
    case TIM_CCER:
        return s->tim_ccer;
    case TIM_CNT:
        return stm32f2xx_ns_to_ticks(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) -
               s->tick_offset;
    case TIM_PSC:
        return s->tim_psc;
    case TIM_ARR:
        return s->tim_arr;
    case TIM_CCR1:
        return s->tim_ccr1;
    case TIM_CCR2:
        return s->tim_ccr2;
    case TIM_CCR3:
        return s->tim_ccr3;
    case TIM_CCR4:
        return s->tim_ccr4;
    case TIM_DCR:
        return s->tim_dcr;
    case TIM_DMAR:
        return s->tim_dmar;
    case TIM_OR:
        return s->tim_or;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, offset);
    }

    return 0;
}
Пример #20
0
static void stm32f2xx_timer_interrupt(void *opaque)
{
    STM32F2XXTimerState *s = opaque;

    DB_PRINT("Interrupt\n");

    if (s->tim_dier & TIM_DIER_UIE && s->tim_cr1 & TIM_CR1_CEN) {
        s->tim_sr |= 1;
        qemu_irq_pulse(s->irq);
        stm32f2xx_timer_set_alarm(s, s->hit_time);
    }
}
Пример #21
0
static void xlnx_zynqmp_ipi_set_obs(XlnxZynqMPIPI *s, uint32_t val)
{
    int i, ipi_index, ipi_mask;

    for (i = 0; i < NUM_IPIS; i++) {
        ipi_index = index_array[i];
        ipi_mask = (1 << ipi_index);
        DB_PRINT("Setting %s=%d\n", index_array_names[i],
                 !!(val & ipi_mask));
        qemu_set_irq(s->irq_obs_out[i], !!(val & ipi_mask));
    }
}
Пример #22
0
static void stm32f2xx_timer_interrupt(void *opaque)
{
    STM32F2XXTimerState *s = opaque;

    DB_PRINT("Interrupt\n");

    if (s->tim_dier & TIM_DIER_UIE && s->tim_cr1 & TIM_CR1_CEN) {
        s->tim_sr |= 1;
        qemu_irq_pulse(s->irq);
        stm32f2xx_timer_set_alarm(s, s->hit_time);
    }

    if (s->tim_ccmr1 & (TIM_CCMR1_OC2M2 | TIM_CCMR1_OC2M1) &&
        !(s->tim_ccmr1 & TIM_CCMR1_OC2M0) &&
        s->tim_ccmr1 & TIM_CCMR1_OC2PE &&
        s->tim_ccer & TIM_CCER_CC2E) {
        /* PWM 2 - Mode 1 */
        DB_PRINT("PWM2 Duty Cycle: %d%%\n",
                s->tim_ccr2 / (100 * (s->tim_psc + 1)));
    }
}
Пример #23
0
static inline void razwi_unimp_rw(void *opaque, hwaddr addr, uint64_t val64,
                           unsigned int size, bool rnw) {
    char str[1024];

    snprintf(str, sizeof(str), "%s: RAZ/WI device %s: addr: %#llx data: %#llx"
             " size: %d\n",
             opaque ? (const char *)opaque : "(none)", rnw ? "read" : "write",
             (unsigned long long)addr, (unsigned long long)val64, size);

    DB_PRINT(0, "%s", str);
    qemu_log_mask(LOG_UNIMP, "%s", str);
}
Пример #24
0
static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
                                                        unsigned size)
{
    XilinxSPIPS *s = opaque;
    uint32_t mask = ~0;
    uint32_t ret;

    addr >>= 2;
    switch (addr) {
    case R_CONFIG:
        mask = 0x0002FFFF;
        break;
    case R_INTR_STATUS:
    case R_INTR_MASK:
        mask = IXR_ALL;
        break;
    case  R_EN:
        mask = 0x1;
        break;
    case R_SLAVE_IDLE_COUNT:
        mask = 0xFF;
        break;
    case R_MOD_ID:
        mask = 0x01FFFFFF;
        break;
    case R_INTR_EN:
    case R_INTR_DIS:
    case R_TX_DATA:
        mask = 0;
        break;
    case R_RX_DATA:
        rx_data_bytes(s, &ret, s->num_txrx_bytes);
        DB_PRINT("addr=" TARGET_FMT_plx " = %x\n", addr * 4, ret);
        xilinx_spips_update_ixr(s);
        return ret;
    }
    DB_PRINT("addr=" TARGET_FMT_plx " = %x\n", addr * 4, s->regs[addr] & mask);
    return s->regs[addr] & mask;

}
Пример #25
0
static void stm32f2xx_timer_set_alarm(STM32F2XXTimerState *s, int64_t now)
{
    uint64_t ticks;
    int64_t now_ticks;

    if (s->tim_arr == 0) {
        return;
    }

    DB_PRINT("Alarm set at: 0x%x\n", s->tim_cr1);

    now_ticks = stm32f2xx_ns_to_ticks(s, now);
    ticks = s->tim_arr - (now_ticks - s->tick_offset);

    DB_PRINT("Alarm set in %d ticks\n", (int) ticks);

    s->hit_time = muldiv64((ticks + (uint64_t) now_ticks) * (s->tim_psc + 1),
                               1000000000ULL, s->freq_hz);

    timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->hit_time);
    DB_PRINT("Wait Time: %" PRId64 " ticks\n", s->hit_time);
}
Пример #26
0
static int pca954x_send(I2CSlave *i2c, uint8_t data)
{
    PCA954XState *s = PCA954X(i2c);
    int i;
    int ret = -1;

    if (s->control_decoded) {
        DB_PRINT("setting control register: %x\n", data);
        s->control_reg = data;
        pca954x_decode_lane(s);
        ret = 0;
    } else {
        for (i = 0; i < s->lanes; ++i) {
            if (s->active_lanes & (1 << i)) {
                DB_PRINT("sending to active bus %d:%x\n", i, data);
                ret &= i2c_send(s->busses[i], data);
            }
        }
    }

    return ret;
}
Пример #27
0
static void ipi_handler(void *opaque, int n, int level)
{
    IPI *s = XILINX_IPI(opaque);
    DepRegisterInfo *r_isr = &s->regs_info[A_IPI_ISR / 4];
    uint32_t val = (!!level) << n;
    uint64_t old_value = s->regs[R_IPI_ISR];

    DB_PRINT("%s: %s: irq[%d]=%d\n", __func__,
             object_get_canonical_path(OBJECT(s)), n, level);

    s->regs[R_IPI_ISR] |= val;
    ipi_update_irq(s);
    dep_register_refresh_gpios(r_isr, old_value);
}
Пример #28
0
static void fdt_init_all_irqs(FDTMachineInfo *fdti)
{
    while (fdti->irqs) {
        FDTIRQConnection *first = fdti->irqs;
        qemu_irq sink = first->irq;
        bool (*merge_fn)(bool *, int) = first->merge_fn;
        int num_sources = 0;
        FDTIRQConnection *irq;

        for (irq = first; irq; irq = irq->next) {
            if (irq->irq == sink) { /* Same sink */
                num_sources++;
            }
        }
        if (num_sources > 1) {
            QEMUIRQSharedState *s = g_malloc0(sizeof *s);
            s->sink = sink;
            s->merge_fn = merge_fn;
            qemu_irq *sources = qemu_allocate_irqs(qemu_irq_shared_handler, s,
                                                   num_sources);
            for (irq = first; irq; irq = irq->next) {
                if (irq->irq == sink) {
                    char *shared_irq_name = g_strdup_printf("shared-irq-%p",
                                                            *sources);

                    if (irq->merge_fn != merge_fn) {
                        fprintf(stderr, "ERROR: inconsistent IRQ merge fns\n");
                        exit(1);
                    }

                    object_property_add_child(OBJECT(irq->dev), shared_irq_name,
                                              OBJECT(*sources), &error_abort);
                    g_free(shared_irq_name);
                    irq->irq = *(sources++);
                    s->num++;
                }
            }
        }
        DB_PRINT(0, "%s: connected to %s irq line %d (%s)\n",
                 first->sink_info ? first->sink_info : "",
                 object_get_canonical_path(OBJECT(first->dev)),
                 first->i, first->name ? first->name : "");

        qdev_connect_gpio_out_named(DEVICE(first->dev), first->name, first->i,
                                    first->irq);
        fdti->irqs = first->next;
        g_free(first);
    }
}
Пример #29
0
static uint64_t
timer_read(void *opaque, hwaddr offset, unsigned int size)
{
    MSSTimerState *t = opaque;
    hwaddr addr;
    struct Msf2Timer *st;
    uint32_t ret = 0;
    int timer = 0;
    int isr;
    int ier;

    addr = offset >> 2;
    /*
     * Two independent timers has same base address.
     * Based on address passed figure out which timer is being used.
     */
    if ((addr >= R_TIM1_MAX) && (addr < NUM_TIMERS * R_TIM1_MAX)) {
        timer = 1;
        addr -= R_TIM1_MAX;
    }

    st = &t->timers[timer];

    switch (addr) {
    case R_TIM_VAL:
        ret = ptimer_get_count(st->ptimer);
        break;

    case R_TIM_MIS:
        isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
        ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
        ret = ier & isr;
        break;

    default:
        if (addr < R_TIM1_MAX) {
            ret = st->regs[addr];
        } else {
            qemu_log_mask(LOG_GUEST_ERROR,
                        TYPE_MSS_TIMER": 64-bit mode not supported\n");
            return ret;
        }
        break;
    }

    DB_PRINT("timer=%d 0x%" HWADDR_PRIx "=0x%" PRIx32, timer, offset,
            ret);
    return ret;
}
Пример #30
0
static uint64_t
spi_read(void *opaque, hwaddr addr, unsigned int size)
{
    XilinxSPI *s = opaque;
    uint32_t r = 0;

    addr >>= 2;
    switch (addr) {
    case R_SPIDRR:
        if (fifo8_is_empty(&s->rx_fifo)) {
            DB_PRINT("Read from empty FIFO!\n");
            return 0xdeadbeef;
        }

        s->regs[R_SPISR] &= ~SR_RX_FULL;
        r = fifo8_pop(&s->rx_fifo);
        if (fifo8_is_empty(&s->rx_fifo)) {
            s->regs[R_SPISR] |= SR_RX_EMPTY;
        }
        break;

    case R_SPISR:
        r = s->regs[addr];
        break;

    default:
        if (addr < ARRAY_SIZE(s->regs)) {
            r = s->regs[addr];
        }
        break;

    }
    DB_PRINT("addr=" TARGET_FMT_plx " = %x\n", addr * 4, r);
    xlx_spi_update_irq(s);
    return r;
}