tusb6010.c

来自「xen虚拟机源代码安装包」· C语言 代码 · 共 771 行 · 第 1/2 页

C
771
字号
    case TUSB_DMA_INT_SRC:    case TUSB_DMA_INT_SET:	/* TODO: What do these two return?  */    case TUSB_DMA_INT_CLEAR:        return s->dma_intr;    case TUSB_DMA_INT_MASK:        return s->dma_mask;    case TUSB_GPIO_INT_SRC:	/* TODO: What do these two return?  */    case TUSB_GPIO_INT_SET:    case TUSB_GPIO_INT_CLEAR:        return s->gpio_intr;    case TUSB_GPIO_INT_MASK:        return s->gpio_mask;    case TUSB_INT_SRC:    case TUSB_INT_SRC_SET:	/* TODO: What do these two return?  */    case TUSB_INT_SRC_CLEAR:        return s->intr;    case TUSB_INT_MASK:        return s->mask;    case TUSB_GPIO_REV:        return 0x30;    case TUSB_GPIO_CONF:        return s->gpio_config;    case TUSB_DMA_CTRL_REV:        return 0x30;    case TUSB_DMA_REQ_CONF:        return s->dma_config;    case TUSB_EP0_CONF:        return s->ep0_config;    case TUSB_EP_IN_SIZE ... (TUSB_EP_IN_SIZE + 0x3b):        epnum = (offset - TUSB_EP_IN_SIZE) >> 2;        return s->tx_config[epnum];    case TUSB_DMA_EP_MAP:        return s->dma_map;    case TUSB_EP_OUT_SIZE ... (TUSB_EP_OUT_SIZE + 0x3b):        epnum = (offset - TUSB_EP_OUT_SIZE) >> 2;        return s->rx_config[epnum];    case TUSB_EP_MAX_PACKET_SIZE_OFFSET ...            (TUSB_EP_MAX_PACKET_SIZE_OFFSET + 0x3b):        epnum = (offset - TUSB_EP_MAX_PACKET_SIZE_OFFSET) >> 2;        return 0x00000000;	/* TODO */    case TUSB_WAIT_COUNT:        return 0x00;		/* TODO */    case TUSB_SCRATCH_PAD:        return s->scratch;    case TUSB_PROD_TEST_RESET:        return s->test_reset;    /* DIE IDs */    case TUSB_DIDR1_LO:        return 0xa9453c59;    case TUSB_DIDR1_HI:        return 0x54059adf;    }    printf("%s: unknown register at %03x\n", __FUNCTION__, offset);    return 0;}static void tusb_async_writeb(void *opaque, target_phys_addr_t addr,                uint32_t value){    struct tusb_s *s = (struct tusb_s *) opaque;    switch (addr & 0xfff) {    case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):        musb_write[0](s->musb, addr & 0x1ff, value);        break;    case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):        musb_write[0](s->musb, 0x20 + ((addr >> 3) & 0x3c), value);        break;    default:        printf("%s: unknown register at %03x\n",                        __FUNCTION__, (int) (addr & 0xfff));        return;    }}static void tusb_async_writeh(void *opaque, target_phys_addr_t addr,                uint32_t value){    struct tusb_s *s = (struct tusb_s *) opaque;    switch (addr & 0xfff) {    case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):        musb_write[1](s->musb, addr & 0x1ff, value);        break;    case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):        musb_write[1](s->musb, 0x20 + ((addr >> 3) & 0x3c), value);        break;    default:        printf("%s: unknown register at %03x\n",                        __FUNCTION__, (int) (addr & 0xfff));        return;    }}static void tusb_async_writew(void *opaque, target_phys_addr_t addr,                uint32_t value){    struct tusb_s *s = (struct tusb_s *) opaque;    int offset = addr & 0xfff;    int epnum;    switch (offset) {    case TUSB_VLYNQ_CTRL:        break;    case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):        musb_write[2](s->musb, offset & 0x1ff, value);        break;    case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):        musb_write[2](s->musb, 0x20 + ((addr >> 3) & 0x3c), value);        break;    case TUSB_DEV_CONF:        s->dev_config = value;        s->host_mode = (value & TUSB_DEV_CONF_USB_HOST_MODE);        if (value & TUSB_DEV_CONF_PROD_TEST_MODE)            cpu_abort(cpu_single_env, "%s: Product Test mode not allowed\n",                            __FUNCTION__);        break;    case TUSB_PHY_OTG_CTRL_ENABLE:    case TUSB_PHY_OTG_CTRL:        return;		/* TODO */    case TUSB_DEV_OTG_TIMER:        s->otg_timer_val = value;        if (value & TUSB_DEV_OTG_TIMER_ENABLE)            qemu_mod_timer(s->otg_timer, qemu_get_clock(vm_clock) +                            muldiv64(TUSB_DEV_OTG_TIMER_VAL(value),                                    ticks_per_sec, TUSB_DEVCLOCK));        else            qemu_del_timer(s->otg_timer);        break;    case TUSB_PRCM_CONF:        s->prcm_config = value;        break;    case TUSB_PRCM_MNGMT:        s->prcm_mngmt = value;        break;    case TUSB_PRCM_WAKEUP_CLEAR:        break;    case TUSB_PRCM_WAKEUP_MASK:        s->wkup_mask = value;        break;    case TUSB_PULLUP_1_CTRL:        s->pullup[0] = value;        break;    case TUSB_PULLUP_2_CTRL:        s->pullup[1] = value;        break;    case TUSB_INT_CTRL_CONF:        s->control_config = value;        tusb_intr_update(s);        break;    case TUSB_USBIP_INT_SET:        s->usbip_intr |= value;        tusb_usbip_intr_update(s);        break;    case TUSB_USBIP_INT_CLEAR:        s->usbip_intr &= ~value;        tusb_usbip_intr_update(s);        musb_core_intr_clear(s->musb, ~value);        break;    case TUSB_USBIP_INT_MASK:        s->usbip_mask = value;        tusb_usbip_intr_update(s);        break;    case TUSB_DMA_INT_SET:        s->dma_intr |= value;        tusb_dma_intr_update(s);        break;    case TUSB_DMA_INT_CLEAR:        s->dma_intr &= ~value;        tusb_dma_intr_update(s);        break;    case TUSB_DMA_INT_MASK:        s->dma_mask = value;        tusb_dma_intr_update(s);        break;    case TUSB_GPIO_INT_SET:        s->gpio_intr |= value;        tusb_gpio_intr_update(s);        break;    case TUSB_GPIO_INT_CLEAR:        s->gpio_intr &= ~value;        tusb_gpio_intr_update(s);        break;    case TUSB_GPIO_INT_MASK:        s->gpio_mask = value;        tusb_gpio_intr_update(s);        break;    case TUSB_INT_SRC_SET:        s->intr |= value;        tusb_intr_update(s);        break;    case TUSB_INT_SRC_CLEAR:        s->intr &= ~value;        tusb_intr_update(s);        break;    case TUSB_INT_MASK:        s->mask = value;        tusb_intr_update(s);        break;    case TUSB_GPIO_CONF:        s->gpio_config = value;        break;    case TUSB_DMA_REQ_CONF:        s->dma_config = value;        break;    case TUSB_EP0_CONF:        s->ep0_config = value & 0x1ff;        musb_set_size(s->musb, 0, TUSB_EP0_CONFIG_XFR_SIZE(value),                        value & TUSB_EP0_CONFIG_DIR_TX);        break;    case TUSB_EP_IN_SIZE ... (TUSB_EP_IN_SIZE + 0x3b):        epnum = (offset - TUSB_EP_IN_SIZE) >> 2;        s->tx_config[epnum] = value;        musb_set_size(s->musb, epnum + 1, TUSB_EP_CONFIG_XFR_SIZE(value), 1);        break;    case TUSB_DMA_EP_MAP:        s->dma_map = value;        break;    case TUSB_EP_OUT_SIZE ... (TUSB_EP_OUT_SIZE + 0x3b):        epnum = (offset - TUSB_EP_OUT_SIZE) >> 2;        s->rx_config[epnum] = value;        musb_set_size(s->musb, epnum + 1, TUSB_EP_CONFIG_XFR_SIZE(value), 0);        break;    case TUSB_EP_MAX_PACKET_SIZE_OFFSET ...            (TUSB_EP_MAX_PACKET_SIZE_OFFSET + 0x3b):        epnum = (offset - TUSB_EP_MAX_PACKET_SIZE_OFFSET) >> 2;        return;		/* TODO */    case TUSB_WAIT_COUNT:        return;		/* TODO */    case TUSB_SCRATCH_PAD:        s->scratch = value;        break;    case TUSB_PROD_TEST_RESET:        s->test_reset = value;        break;    default:        printf("%s: unknown register at %03x\n", __FUNCTION__, offset);        return;    }}static CPUReadMemoryFunc *tusb_async_readfn[] = {    tusb_async_readb,    tusb_async_readh,    tusb_async_readw,};static CPUWriteMemoryFunc *tusb_async_writefn[] = {    tusb_async_writeb,    tusb_async_writeh,    tusb_async_writew,};static void tusb_otg_tick(void *opaque){    struct tusb_s *s = (struct tusb_s *) opaque;    s->otg_timer_val = 0;    s->intr |= TUSB_INT_SRC_OTG_TIMEOUT;    tusb_intr_update(s);}static void tusb_power_tick(void *opaque){    struct tusb_s *s = (struct tusb_s *) opaque;    if (s->power) {        s->intr_ok = ~0;        tusb_intr_update(s);    }}static void tusb_musb_core_intr(void *opaque, int source, int level){    struct tusb_s *s = (struct tusb_s *) opaque;    uint16_t otg_status = s->otg_status;    switch (source) {    case musb_set_vbus:        if (level)            otg_status |= TUSB_DEV_OTG_STAT_VBUS_VALID;        else            otg_status &= ~TUSB_DEV_OTG_STAT_VBUS_VALID;        /* XXX: only if TUSB_PHY_OTG_CTRL_OTG_VBUS_DET_EN set?  */        /* XXX: only if TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN set?  */        if (s->otg_status != otg_status) {            s->otg_status = otg_status;            s->intr |= TUSB_INT_SRC_VBUS_SENSE_CHNG;            tusb_intr_update(s);        }        break;    case musb_set_session:        /* XXX: only if TUSB_PHY_OTG_CTRL_OTG_SESS_END_EN set?  */        /* XXX: only if TUSB_PRCM_MNGMT_OTG_SESS_END_EN set?  */        if (level) {            s->otg_status |= TUSB_DEV_OTG_STAT_SESS_VALID;            s->otg_status &= ~TUSB_DEV_OTG_STAT_SESS_END;        } else {            s->otg_status &= ~TUSB_DEV_OTG_STAT_SESS_VALID;            s->otg_status |= TUSB_DEV_OTG_STAT_SESS_END;        }        /* XXX: some IRQ or anything?  */        break;    case musb_irq_tx:    case musb_irq_rx:        s->usbip_intr = musb_core_intr_get(s->musb);        /* Fall through.  */    default:        if (level)            s->intr |= 1 << source;        else            s->intr &= ~(1 << source);        tusb_intr_update(s);        break;    }}struct tusb_s *tusb6010_init(qemu_irq intr){    struct tusb_s *s = qemu_mallocz(sizeof(*s));    s->test_reset = TUSB_PROD_TEST_RESET_VAL;    s->host_mode = 0;    s->dev_config = 0;    s->otg_status = 0;	/* !TUSB_DEV_OTG_STAT_ID_STATUS means host mode */    s->power = 0;    s->mask = 0xffffffff;    s->intr = 0x00000000;    s->otg_timer_val = 0;    s->iomemtype[1] = cpu_register_io_memory(0, tusb_async_readfn,                    tusb_async_writefn, s);    s->irq = intr;    s->otg_timer = qemu_new_timer(vm_clock, tusb_otg_tick, s);    s->pwr_timer = qemu_new_timer(vm_clock, tusb_power_tick, s);    s->musb = musb_init(qemu_allocate_irqs(tusb_musb_core_intr, s,                            __musb_irq_max));    return s;}void tusb6010_power(struct tusb_s *s, int on){    if (!on)        s->power = 0;    else if (!s->power && on) {        s->power = 1;        /* Pull the interrupt down after TUSB6010 comes up.  */        s->intr_ok = 0;        tusb_intr_update(s);        qemu_mod_timer(s->pwr_timer,                        qemu_get_clock(vm_clock) + ticks_per_sec / 2);    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?