omap2.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 2,270 行 · 第 1/5 页
C
2,270 行
case 0x40: /* GPIO_LEVELDETECT0 */ case 0x44: /* GPIO_LEVELDETECT1 */ case 0x48: /* GPIO_RISINGDETECT */ case 0x4c: /* GPIO_FALLINGDETECT */ case 0x50: /* GPIO_DEBOUNCENABLE */ case 0x54: /* GPIO_DEBOUNCINGTIME */ cur = omap_gpio_module_read(opaque, addr & ~3) & ~(mask << ((addr & 3) << 3)); /* Fall through. */ case 0x18: /* GPIO_IRQSTATUS1 */ case 0x28: /* GPIO_IRQSTATUS2 */ case 0x60: /* GPIO_CLEARIRQENABLE1 */ case 0x64: /* GPIO_SETIRQENABLE1 */ case 0x70: /* GPIO_CLEARIRQENABLE2 */ case 0x74: /* GPIO_SETIREQNEABLE2 */ case 0x80: /* GPIO_CLEARWKUENA */ case 0x84: /* GPIO_SETWKUENA */ case 0x90: /* GPIO_CLEARDATAOUT */ case 0x94: /* GPIO_SETDATAOUT */ value <<= (addr & 3) << 3; omap_gpio_module_write(opaque, addr, cur | value); break; default: OMAP_BAD_REG(addr); return; }}static CPUReadMemoryFunc *omap_gpio_module_readfn[] = { omap_gpio_module_readp, omap_gpio_module_readp, omap_gpio_module_read,};static CPUWriteMemoryFunc *omap_gpio_module_writefn[] = { omap_gpio_module_writep, omap_gpio_module_writep, omap_gpio_module_write,};static void omap_gpio_module_init(struct omap2_gpio_s *s, struct omap_target_agent_s *ta, int region, qemu_irq mpu, qemu_irq dsp, qemu_irq wkup, omap_clk fclk, omap_clk iclk){ int iomemtype; s->irq[0] = mpu; s->irq[1] = dsp; s->wkup = wkup; s->in = qemu_allocate_irqs(omap_gpio_module_set, s, 32); iomemtype = cpu_register_io_memory(0, omap_gpio_module_readfn, omap_gpio_module_writefn, s); s->base = omap_l4_attach(ta, region, iomemtype);}struct omap_gpif_s { struct omap2_gpio_s module[5]; int modules; target_phys_addr_t topbase; int autoidle; int gpo;};static void omap_gpif_reset(struct omap_gpif_s *s){ int i; for (i = 0; i < s->modules; i ++) omap_gpio_module_reset(s->module + i); s->autoidle = 0; s->gpo = 0;}static uint32_t omap_gpif_top_read(void *opaque, target_phys_addr_t addr){ struct omap_gpif_s *s = (struct omap_gpif_s *) opaque; int offset = addr - s->topbase; switch (offset) { case 0x00: /* IPGENERICOCPSPL_REVISION */ return 0x18; case 0x10: /* IPGENERICOCPSPL_SYSCONFIG */ return s->autoidle; case 0x14: /* IPGENERICOCPSPL_SYSSTATUS */ return 0x01; case 0x18: /* IPGENERICOCPSPL_IRQSTATUS */ return 0x00; case 0x40: /* IPGENERICOCPSPL_GPO */ return s->gpo; case 0x50: /* IPGENERICOCPSPL_GPI */ return 0x00; } OMAP_BAD_REG(addr); return 0;}static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr, uint32_t value){ struct omap_gpif_s *s = (struct omap_gpif_s *) opaque; int offset = addr - s->topbase; switch (offset) { case 0x00: /* IPGENERICOCPSPL_REVISION */ case 0x14: /* IPGENERICOCPSPL_SYSSTATUS */ case 0x18: /* IPGENERICOCPSPL_IRQSTATUS */ case 0x50: /* IPGENERICOCPSPL_GPI */ OMAP_RO_REG(addr); break; case 0x10: /* IPGENERICOCPSPL_SYSCONFIG */ if (value & (1 << 1)) /* SOFTRESET */ omap_gpif_reset(s); s->autoidle = value & 1; break; case 0x40: /* IPGENERICOCPSPL_GPO */ s->gpo = value & 1; break; default: OMAP_BAD_REG(addr); return; }}static CPUReadMemoryFunc *omap_gpif_top_readfn[] = { omap_gpif_top_read, omap_gpif_top_read, omap_gpif_top_read,};static CPUWriteMemoryFunc *omap_gpif_top_writefn[] = { omap_gpif_top_write, omap_gpif_top_write, omap_gpif_top_write,};struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta, qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules){ int iomemtype, i; struct omap_gpif_s *s = (struct omap_gpif_s *) qemu_mallocz(sizeof(struct omap_gpif_s)); int region[4] = { 0, 2, 4, 5 }; s->modules = modules; for (i = 0; i < modules; i ++) omap_gpio_module_init(s->module + i, ta, region[i], irq[i], 0, 0, fclk[i], iclk); omap_gpif_reset(s); iomemtype = cpu_register_io_memory(0, omap_gpif_top_readfn, omap_gpif_top_writefn, s); s->topbase = omap_l4_attach(ta, 1, iomemtype); return s;}qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start){ if (start >= s->modules * 32 || start < 0) cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, start); return s->module[start >> 5].in + (start & 31);}void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler){ if (line >= s->modules * 32 || line < 0) cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line); s->module[line >> 5].handler[line & 31] = handler;}/* Multichannel SPI */struct omap_mcspi_s { target_phys_addr_t base; qemu_irq irq; int chnum; uint32_t sysconfig; uint32_t systest; uint32_t irqst; uint32_t irqen; uint32_t wken; uint32_t control; struct omap_mcspi_ch_s { qemu_irq txdrq; qemu_irq rxdrq; uint32_t (*txrx)(void *opaque, uint32_t, int); void *opaque; uint32_t tx; uint32_t rx; uint32_t config; uint32_t status; uint32_t control; } ch[4];};static inline void omap_mcspi_interrupt_update(struct omap_mcspi_s *s){ qemu_set_irq(s->irq, s->irqst & s->irqen);}static inline void omap_mcspi_dmarequest_update(struct omap_mcspi_ch_s *ch){ qemu_set_irq(ch->txdrq, (ch->control & 1) && /* EN */ (ch->config & (1 << 14)) && /* DMAW */ (ch->status & (1 << 1)) && /* TXS */ ((ch->config >> 12) & 3) != 1); /* TRM */ qemu_set_irq(ch->rxdrq, (ch->control & 1) && /* EN */ (ch->config & (1 << 15)) && /* DMAW */ (ch->status & (1 << 0)) && /* RXS */ ((ch->config >> 12) & 3) != 2); /* TRM */}static void omap_mcspi_transfer_run(struct omap_mcspi_s *s, int chnum){ struct omap_mcspi_ch_s *ch = s->ch + chnum; if (!(ch->control & 1)) /* EN */ return; if ((ch->status & (1 << 0)) && /* RXS */ ((ch->config >> 12) & 3) != 2 && /* TRM */ !(ch->config & (1 << 19))) /* TURBO */ goto intr_update; if ((ch->status & (1 << 1)) && /* TXS */ ((ch->config >> 12) & 3) != 1) /* TRM */ goto intr_update; if (!(s->control & 1) || /* SINGLE */ (ch->config & (1 << 20))) { /* FORCE */ if (ch->txrx) ch->rx = ch->txrx(ch->opaque, ch->tx, /* WL */ 1 + (0x1f & (ch->config >> 7))); } ch->tx = 0; ch->status |= 1 << 2; /* EOT */ ch->status |= 1 << 1; /* TXS */ if (((ch->config >> 12) & 3) != 2) /* TRM */ ch->status |= 1 << 0; /* RXS */intr_update: if ((ch->status & (1 << 0)) && /* RXS */ ((ch->config >> 12) & 3) != 2 && /* TRM */ !(ch->config & (1 << 19))) /* TURBO */ s->irqst |= 1 << (2 + 4 * chnum); /* RX_FULL */ if ((ch->status & (1 << 1)) && /* TXS */ ((ch->config >> 12) & 3) != 1) /* TRM */ s->irqst |= 1 << (0 + 4 * chnum); /* TX_EMPTY */ omap_mcspi_interrupt_update(s); omap_mcspi_dmarequest_update(ch);}static void omap_mcspi_reset(struct omap_mcspi_s *s){ int ch; s->sysconfig = 0; s->systest = 0; s->irqst = 0; s->irqen = 0; s->wken = 0; s->control = 4; for (ch = 0; ch < 4; ch ++) { s->ch[ch].config = 0x060000; s->ch[ch].status = 2; /* TXS */ s->ch[ch].control = 0; omap_mcspi_dmarequest_update(s->ch + ch); } omap_mcspi_interrupt_update(s);}static uint32_t omap_mcspi_read(void *opaque, target_phys_addr_t addr){ struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque; int offset = addr - s->base; int ch = 0; uint32_t ret; switch (offset) { case 0x00: /* MCSPI_REVISION */ return 0x91; case 0x10: /* MCSPI_SYSCONFIG */ return s->sysconfig; case 0x14: /* MCSPI_SYSSTATUS */ return 1; /* RESETDONE */ case 0x18: /* MCSPI_IRQSTATUS */ return s->irqst; case 0x1c: /* MCSPI_IRQENABLE */ return s->irqen; case 0x20: /* MCSPI_WAKEUPENABLE */ return s->wken; case 0x24: /* MCSPI_SYST */ return s->systest; case 0x28: /* MCSPI_MODULCTRL */ return s->control; case 0x68: ch ++; case 0x54: ch ++; case 0x40: ch ++; case 0x2c: /* MCSPI_CHCONF */ return s->ch[ch].config; case 0x6c: ch ++; case 0x58: ch ++; case 0x44: ch ++; case 0x30: /* MCSPI_CHSTAT */ return s->ch[ch].status; case 0x70: ch ++; case 0x5c: ch ++; case 0x48: ch ++; case 0x34: /* MCSPI_CHCTRL */ return s->ch[ch].control; case 0x74: ch ++; case 0x60: ch ++; case 0x4c: ch ++; case 0x38: /* MCSPI_TX */ return s->ch[ch].tx; case 0x78: ch ++; case 0x64: ch ++; case 0x50: ch ++; case 0x3c: /* MCSPI_RX */ s->ch[ch].status &= ~(1 << 0); /* RXS */ ret = s->ch[ch].rx; omap_mcspi_transfer_run(s, ch); return ret; } OMAP_BAD_REG(addr); return 0;}static void omap_mcspi_write(void *opaque, target_phys_addr_t addr, uint32_t value){ struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque; int offset = addr - s->base; int ch = 0; switch (offset) { case 0x00: /* MCSPI_REVISION */ case 0x14: /* MCSPI_SYSSTATUS */ case 0x30: /* MCSPI_CHSTAT0 */ case 0x3c: /* MCSPI_RX0 */ case 0x44: /* MCSPI_CHSTAT1 */ case 0x50: /* MCSPI_RX1 */ case 0x58: /* MCSPI_CHSTAT2 */ case 0x64: /* MCSPI_RX2 */ case 0x6c: /* MCSPI_CHSTAT3 */ case 0x78: /* MCSPI_RX3 */ OMAP_RO_REG(addr); return; case 0x10: /* MCSPI_SYSCONFIG */ if (value & (1 << 1)) /* SOFTRESET */ omap_mcspi_reset(s); s->sysconfig = value & 0x31d; break; case 0x18: /* MCSPI_IRQSTATUS */ if (!((s->control & (1 << 3)) && (s->systest & (1 << 11)))) { s->irqst &= ~value; omap_mcspi_interrupt_update(s); } break; case 0x1c: /* MCSPI_IRQENABLE */ s->irqen = value & 0x1777f; omap_mcspi_interrupt_update(s); break; case 0x20: /* MCSPI_WAKEUPENABLE */ s->wken = value & 1; break; case 0x24: /* MCSPI_SYST */ if (s->control & (1 << 3)) /* SYSTEM_TEST */ if (value & (1 << 11)) { /* SSB */ s->irqst |= 0x1777f; omap_mcspi_interrupt_update(s); } s->systest = value & 0xfff; break; case 0x28: /* MCSPI_MODULCTRL */ if (value & (1 << 3)) /* SYSTEM_TEST */ if (s->systest & (1 << 11)) { /* SSB */ s->irqst |= 0x1777f; omap_mcspi_interrupt_update(s); } s->control = value & 0xf; break; case 0x68: ch ++; case 0x54: ch ++; case 0x40: ch ++; case 0x2c: /* MCSPI_CHCONF */ if ((value ^ s->ch[ch].config) & (3 << 14)) /* DMAR | DMAW */ omap_mcspi_dmarequest_update(s->ch + ch); if (((value >> 12) & 3) == 3) /* TRM */ fprintf(stderr, "%s: invalid TRM value (3)\n", __FUNCTION__); if (((value >> 7) & 0x1f) < 3) /* WL */ fprintf(stderr, "%s: invalid WL value (%i)\n", __FUNCTION__, (value >> 7) & 0x1f); s->ch[ch].config = value & 0x7fffff; break; case 0x70: ch ++; case 0x5c: ch ++; case 0x48: ch ++; case 0x34: /* MCSPI_CHCTRL */ if (value & ~s->ch[ch].control & 1) { /* EN */ s->ch[ch].control |= 1; omap_mcspi_transfer_run(s, ch); } else s->ch[ch].control = value & 1; break; case 0x74: ch ++; case 0x60: ch ++; case 0x4c: ch ++;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?