omap2.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 2,270 行 · 第 1/5 页
C
2,270 行
static void omap_gp_timer_writeh(void *opaque, target_phys_addr_t addr, uint32_t value){ struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque; if (addr & 2) return omap_gp_timer_write(opaque, addr, (value << 16) | s->writeh); else s->writeh = (uint16_t) value;}static CPUWriteMemoryFunc *omap_gp_timer_writefn[] = { omap_badwidth_write32, omap_gp_timer_writeh, omap_gp_timer_write,};struct omap_gp_timer_s *omap_gp_timer_init(struct omap_target_agent_s *ta, qemu_irq irq, omap_clk fclk, omap_clk iclk){ int iomemtype; struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) qemu_mallocz(sizeof(struct omap_gp_timer_s)); s->ta = ta; s->irq = irq; s->clk = fclk; s->timer = qemu_new_timer(vm_clock, omap_gp_timer_tick, s); s->match = qemu_new_timer(vm_clock, omap_gp_timer_match, s); s->in = qemu_allocate_irqs(omap_gp_timer_input, s, 1)[0]; omap_gp_timer_reset(s); omap_gp_timer_clk_setup(s); iomemtype = cpu_register_io_memory(0, omap_gp_timer_readfn, omap_gp_timer_writefn, s); s->base = omap_l4_attach(ta, 0, iomemtype); return s;}/* 32-kHz Sync Timer of the OMAP2 */static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) { return muldiv64(qemu_get_clock(vm_clock), 0x8000, ticks_per_sec);}static void omap_synctimer_reset(struct omap_synctimer_s *s){ s->val = omap_synctimer_read(s);}static uint32_t omap_synctimer_readw(void *opaque, target_phys_addr_t addr){ struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque; int offset = addr - s->base; switch (offset) { case 0x00: /* 32KSYNCNT_REV */ return 0x21; case 0x10: /* CR */ return omap_synctimer_read(s) - s->val; } OMAP_BAD_REG(addr); return 0;}static uint32_t omap_synctimer_readh(void *opaque, target_phys_addr_t addr){ struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque; uint32_t ret; if (addr & 2) return s->readh; else { ret = omap_synctimer_readw(opaque, addr); s->readh = ret >> 16; return ret & 0xffff; }}static CPUReadMemoryFunc *omap_synctimer_readfn[] = { omap_badwidth_read32, omap_synctimer_readh, omap_synctimer_readw,};static void omap_synctimer_write(void *opaque, target_phys_addr_t addr, uint32_t value){ OMAP_BAD_REG(addr);}static CPUWriteMemoryFunc *omap_synctimer_writefn[] = { omap_badwidth_write32, omap_synctimer_write, omap_synctimer_write,};void omap_synctimer_init(struct omap_target_agent_s *ta, struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk){ struct omap_synctimer_s *s = &mpu->synctimer; omap_synctimer_reset(s); s->base = omap_l4_attach(ta, 0, cpu_register_io_memory(0, omap_synctimer_readfn, omap_synctimer_writefn, s));}/* General-Purpose Interface of OMAP2 */struct omap2_gpio_s { target_phys_addr_t base; qemu_irq irq[2]; qemu_irq wkup; qemu_irq *in; qemu_irq handler[32]; uint8_t config[2]; uint32_t inputs; uint32_t outputs; uint32_t dir; uint32_t level[2]; uint32_t edge[2]; uint32_t mask[2]; uint32_t wumask; uint32_t ints[2]; uint32_t debounce; uint8_t delay;};static inline void omap_gpio_module_int_update(struct omap2_gpio_s *s, int line){ qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]);}static void omap_gpio_module_wake(struct omap2_gpio_s *s, int line){ if (!(s->config[0] & (1 << 2))) /* ENAWAKEUP */ return; if (!(s->config[0] & (3 << 3))) /* Force Idle */ return; if (!(s->wumask & (1 << line))) return; qemu_irq_raise(s->wkup);}static inline void omap_gpio_module_out_update(struct omap2_gpio_s *s, uint32_t diff){ int ln; s->outputs ^= diff; diff &= ~s->dir; while ((ln = ffs(diff))) { ln --; qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1); diff &= ~(1 << ln); }}static void omap_gpio_module_level_update(struct omap2_gpio_s *s, int line){ s->ints[line] |= s->dir & ((s->inputs & s->level[1]) | (~s->inputs & s->level[0])); omap_gpio_module_int_update(s, line);}static inline void omap_gpio_module_int(struct omap2_gpio_s *s, int line){ s->ints[0] |= 1 << line; omap_gpio_module_int_update(s, 0); s->ints[1] |= 1 << line; omap_gpio_module_int_update(s, 1); omap_gpio_module_wake(s, line);}static void omap_gpio_module_set(void *opaque, int line, int level){ struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque; if (level) { if (s->dir & (1 << line) & ((~s->inputs & s->edge[0]) | s->level[1])) omap_gpio_module_int(s, line); s->inputs |= 1 << line; } else { if (s->dir & (1 << line) & ((s->inputs & s->edge[1]) | s->level[0])) omap_gpio_module_int(s, line); s->inputs &= ~(1 << line); }}static void omap_gpio_module_reset(struct omap2_gpio_s *s){ s->config[0] = 0; s->config[1] = 2; s->ints[0] = 0; s->ints[1] = 0; s->mask[0] = 0; s->mask[1] = 0; s->wumask = 0; s->dir = ~0; s->level[0] = 0; s->level[1] = 0; s->edge[0] = 0; s->edge[1] = 0; s->debounce = 0; s->delay = 0;}static uint32_t omap_gpio_module_read(void *opaque, target_phys_addr_t addr){ struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque; int offset = addr - s->base; switch (offset) { case 0x00: /* GPIO_REVISION */ return 0x18; case 0x10: /* GPIO_SYSCONFIG */ return s->config[0]; case 0x14: /* GPIO_SYSSTATUS */ return 0x01; case 0x18: /* GPIO_IRQSTATUS1 */ return s->ints[0]; case 0x1c: /* GPIO_IRQENABLE1 */ case 0x60: /* GPIO_CLEARIRQENABLE1 */ case 0x64: /* GPIO_SETIRQENABLE1 */ return s->mask[0]; case 0x20: /* GPIO_WAKEUPENABLE */ case 0x80: /* GPIO_CLEARWKUENA */ case 0x84: /* GPIO_SETWKUENA */ return s->wumask; case 0x28: /* GPIO_IRQSTATUS2 */ return s->ints[1]; case 0x2c: /* GPIO_IRQENABLE2 */ case 0x70: /* GPIO_CLEARIRQENABLE2 */ case 0x74: /* GPIO_SETIREQNEABLE2 */ return s->mask[1]; case 0x30: /* GPIO_CTRL */ return s->config[1]; case 0x34: /* GPIO_OE */ return s->dir; case 0x38: /* GPIO_DATAIN */ return s->inputs; case 0x3c: /* GPIO_DATAOUT */ case 0x90: /* GPIO_CLEARDATAOUT */ case 0x94: /* GPIO_SETDATAOUT */ return s->outputs; case 0x40: /* GPIO_LEVELDETECT0 */ return s->level[0]; case 0x44: /* GPIO_LEVELDETECT1 */ return s->level[1]; case 0x48: /* GPIO_RISINGDETECT */ return s->edge[0]; case 0x4c: /* GPIO_FALLINGDETECT */ return s->edge[1]; case 0x50: /* GPIO_DEBOUNCENABLE */ return s->debounce; case 0x54: /* GPIO_DEBOUNCINGTIME */ return s->delay; } OMAP_BAD_REG(addr); return 0;}static void omap_gpio_module_write(void *opaque, target_phys_addr_t addr, uint32_t value){ struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque; int offset = addr - s->base; uint32_t diff; int ln; switch (offset) { case 0x00: /* GPIO_REVISION */ case 0x14: /* GPIO_SYSSTATUS */ case 0x38: /* GPIO_DATAIN */ OMAP_RO_REG(addr); break; case 0x10: /* GPIO_SYSCONFIG */ if (((value >> 3) & 3) == 3) fprintf(stderr, "%s: bad IDLEMODE value\n", __FUNCTION__); if (value & 2) omap_gpio_module_reset(s); s->config[0] = value & 0x1d; break; case 0x18: /* GPIO_IRQSTATUS1 */ if (s->ints[0] & value) { s->ints[0] &= ~value; omap_gpio_module_level_update(s, 0); } break; case 0x1c: /* GPIO_IRQENABLE1 */ s->mask[0] = value; omap_gpio_module_int_update(s, 0); break; case 0x20: /* GPIO_WAKEUPENABLE */ s->wumask = value; break; case 0x28: /* GPIO_IRQSTATUS2 */ if (s->ints[1] & value) { s->ints[1] &= ~value; omap_gpio_module_level_update(s, 1); } break; case 0x2c: /* GPIO_IRQENABLE2 */ s->mask[1] = value; omap_gpio_module_int_update(s, 1); break; case 0x30: /* GPIO_CTRL */ s->config[1] = value & 7; break; case 0x34: /* GPIO_OE */ diff = s->outputs & (s->dir ^ value); s->dir = value; value = s->outputs & ~s->dir; while ((ln = ffs(diff))) { diff &= ~(1 <<-- ln); qemu_set_irq(s->handler[ln], (value >> ln) & 1); } omap_gpio_module_level_update(s, 0); omap_gpio_module_level_update(s, 1); break; case 0x3c: /* GPIO_DATAOUT */ omap_gpio_module_out_update(s, s->outputs ^ value); break; case 0x40: /* GPIO_LEVELDETECT0 */ s->level[0] = value; omap_gpio_module_level_update(s, 0); omap_gpio_module_level_update(s, 1); break; case 0x44: /* GPIO_LEVELDETECT1 */ s->level[1] = value; omap_gpio_module_level_update(s, 0); omap_gpio_module_level_update(s, 1); break; case 0x48: /* GPIO_RISINGDETECT */ s->edge[0] = value; break; case 0x4c: /* GPIO_FALLINGDETECT */ s->edge[1] = value; break; case 0x50: /* GPIO_DEBOUNCENABLE */ s->debounce = value; break; case 0x54: /* GPIO_DEBOUNCINGTIME */ s->delay = value; break; case 0x60: /* GPIO_CLEARIRQENABLE1 */ s->mask[0] &= ~value; omap_gpio_module_int_update(s, 0); break; case 0x64: /* GPIO_SETIRQENABLE1 */ s->mask[0] |= value; omap_gpio_module_int_update(s, 0); break; case 0x70: /* GPIO_CLEARIRQENABLE2 */ s->mask[1] &= ~value; omap_gpio_module_int_update(s, 1); break; case 0x74: /* GPIO_SETIREQNEABLE2 */ s->mask[1] |= value; omap_gpio_module_int_update(s, 1); break; case 0x80: /* GPIO_CLEARWKUENA */ s->wumask &= ~value; break; case 0x84: /* GPIO_SETWKUENA */ s->wumask |= value; break; case 0x90: /* GPIO_CLEARDATAOUT */ omap_gpio_module_out_update(s, s->outputs & value); break; case 0x94: /* GPIO_SETDATAOUT */ omap_gpio_module_out_update(s, ~s->outputs & value); break; default: OMAP_BAD_REG(addr); return; }}static uint32_t omap_gpio_module_readp(void *opaque, target_phys_addr_t addr){ return omap_gpio_module_readp(opaque, addr) >> ((addr & 3) << 3);}static void omap_gpio_module_writep(void *opaque, target_phys_addr_t addr, uint32_t value){ struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque; int offset = addr - s->base; uint32_t cur = 0; uint32_t mask = 0xffff; switch (offset & ~3) { case 0x00: /* GPIO_REVISION */ case 0x14: /* GPIO_SYSSTATUS */ case 0x38: /* GPIO_DATAIN */ OMAP_RO_REG(addr); break; case 0x10: /* GPIO_SYSCONFIG */ case 0x1c: /* GPIO_IRQENABLE1 */ case 0x20: /* GPIO_WAKEUPENABLE */ case 0x2c: /* GPIO_IRQENABLE2 */ case 0x30: /* GPIO_CTRL */ case 0x34: /* GPIO_OE */ case 0x3c: /* GPIO_DATAOUT */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?