예제 #1
0
파일: timer.c 프로젝트: M1cha/lk
void platform_init_timer(void)
{
    TRACE_ENTRY;

    /* read the base frequency from the control block */
    timer_freq = *REG32(REFCLK_CNTControl + CNTFID0);
    printf("timer running at %d Hz\n", timer_freq);

    /* calculate the ratio of microseconds and milliseconds */
    usec_ratio = timer_freq / 1000000U;
    msec_ratio = timer_freq / 1000U;

    /* start the physical timer */
    *REG32(REFCLK_CNTControl + CNTCR) = 1;

    mask_interrupt(INT_PPI_NSPHYS_TIMER);
    register_int_handler(INT_PPI_NSPHYS_TIMER, &platform_tick, NULL);
}
예제 #2
0
void platform_mask_irqs(void)
{
	int i;
	for (i=0; i<INT_VECTORS; i++)
		mask_interrupt(i);
}
예제 #3
0
파일: virtio.c 프로젝트: srodrig1/lk
int virtio_mmio_detect(void *ptr, uint count, const uint irqs[])
{
    LTRACEF("ptr %p, count %u\n", ptr, count);

    DEBUG_ASSERT(ptr);
    DEBUG_ASSERT(irqs);
    DEBUG_ASSERT(!devices);

    /* allocate an array big enough to hold a list of devices */
    devices = calloc(count, sizeof(struct virtio_device));
    if (!devices)
        return ERR_NO_MEMORY;

    int found = 0;
    for (uint i = 0; i < count; i++) {
        volatile struct virtio_mmio_config *mmio = (struct virtio_mmio_config *)((uint8_t *)ptr + i * 0x200);
        struct virtio_device *dev = &devices[i];

        dev->index = i;
        dev->irq = irqs[i];

        mask_interrupt(irqs[i]);
        register_int_handler(irqs[i], &virtio_mmio_irq, (void *)dev);

        LTRACEF("looking at magic 0x%x version 0x%x did 0x%x vid 0x%x\n",
                mmio->magic, mmio->version, mmio->device_id, mmio->vendor_id);

        if (mmio->magic != VIRTIO_MMIO_MAGIC) {
            continue;
        }

#if LOCAL_TRACE
        if (mmio->device_id != 0) {
            dump_mmio_config(mmio);
        }
#endif

#if WITH_DEV_VIRTIO_BLOCK
        if (mmio->device_id == 2) { // block device
            LTRACEF("found block device\n");

            dev->mmio_config = mmio;
            dev->config_ptr = (void *)mmio->config;

            status_t err = virtio_block_init(dev, mmio->host_features);
            if (err >= 0) {
                // good device
                dev->valid = true;

                if (dev->irq_driver_callback)
                    unmask_interrupt(dev->irq);

                // XXX quick test code, remove
#if 0
                uint8_t buf[512];
                memset(buf, 0x99, sizeof(buf));
                virtio_block_read_write(dev, buf, 0, sizeof(buf), false);
                hexdump8_ex(buf, sizeof(buf), 0);

                buf[0]++;
                virtio_block_read_write(dev, buf, 0, sizeof(buf), true);

                virtio_block_read_write(dev, buf, 0, sizeof(buf), false);
                hexdump8_ex(buf, sizeof(buf), 0);
#endif
            }

        }
#endif // WITH_DEV_VIRTIO_BLOCK
#if WITH_DEV_VIRTIO_NET
        if (mmio->device_id == 1) { // network device
            LTRACEF("found net device\n");

            dev->mmio_config = mmio;
            dev->config_ptr = (void *)mmio->config;

            status_t err = virtio_net_init(dev, mmio->host_features);
            if (err >= 0) {
                // good device
                dev->valid = true;

                if (dev->irq_driver_callback)
                    unmask_interrupt(dev->irq);
            }
        }
#endif // WITH_DEV_VIRTIO_NET
#if WITH_DEV_VIRTIO_GPU
        if (mmio->device_id == 0x10) { // virtio-gpu
            LTRACEF("found gpu device\n");

            dev->mmio_config = mmio;
            dev->config_ptr = (void *)mmio->config;

            status_t err = virtio_gpu_init(dev, mmio->host_features);
            if (err >= 0) {
                // good device
                dev->valid = true;

                if (dev->irq_driver_callback)
                    unmask_interrupt(dev->irq);

                virtio_gpu_start(dev);
            }
        }
#endif // WITH_DEV_VIRTIO_GPU

        if (dev->valid)
            found++;
    }

    return found;
}
예제 #4
0
int msm_i2c_xfer(struct i2c_msg msgs[], int num)
{
	int ret, ret_wait;

	clk_enable(dev.pdata->clk_nr);
	unmask_interrupt(dev.pdata->irq_nr);

	ret = msm_i2c_poll_notbusy(1);

	if (ret) {
		ret = msm_i2c_recover_bus_busy();
		if (ret)
			goto err;
	}

	enter_critical_section();
	if (dev.flush_cnt) {
		I2C_DBG(DEBUGLEVEL, "%d unrequested bytes read\n", dev.flush_cnt);
	}
	dev.msg = msgs;
	dev.rem = num;
	dev.pos = -1;
	dev.ret = num;
	dev.need_flush = false;
	dev.flush_cnt = 0;
	dev.cnt = msgs->len;
	msm_i2c_interrupt_locked();
	exit_critical_section();

	/*
	 * Now that we've setup the xfer, the ISR will transfer the data
	 * and wake us up with dev.err set if there was an error
	 */
	ret_wait = msm_i2c_poll_notbusy(0); /* Read may not have stopped in time */
	
	enter_critical_section();
	if (dev.flush_cnt) {
		I2C_DBG(DEBUGLEVEL, "%d unrequested bytes read\n", dev.flush_cnt);
	}
	ret = dev.ret;
	dev.msg = NULL;
	dev.rem = 0;
	dev.pos = 0;
	dev.ret = 0;
	dev.flush_cnt = 0;
	dev.cnt = 0;
	exit_critical_section();

	if (ret_wait) {
		I2C_DBG(DEBUGLEVEL, "Still busy after xfer completion\n");
		ret_wait = msm_i2c_recover_bus_busy();
		if (ret_wait)
			goto err;
	}
	if (timeout == ERR_TIMED_OUT) {
		I2C_DBG(DEBUGLEVEL, "Transaction timed out\n");
		ret = ERR_TIMED_OUT;
	}
	if (ret < 0) {
		I2C_ERR("Error during data xfer (%d)\n", ret);
		msm_i2c_recover_bus_busy();
	}
	/* if (timeout == ERR_TIMED_OUT) {
		I2C_DBG(DEBUGLEVEL, "Transaction timed out\n");
		ret = 2;
		msm_i2c_recover_bus_busy();
	}
	if (timeout == ERR_TIMED_OUT) {
		I2C_DBG(DEBUGLEVEL, "Transaction timed out\n");
		ret = ERR_TIMED_OUT;
	}
	if (ret < 0) {
		I2C_ERR("Error during data xfer (%d)\n", ret);
		msm_i2c_recover_bus_busy();
	} */
err:
	mask_interrupt(dev.pdata->irq_nr);
	clk_disable(dev.pdata->clk_nr);
	
	return ret;
}