?? ppc405_uc.c
字號:
i2c->sts &= ~(value & 0x0A); break; case 0x09: i2c->extsts &= ~(value & 0x8F); break; case 0x0A: i2c->lsadr = value; break; case 0x0B: i2c->hsadr = value; break; case 0x0C: i2c->clkdiv = value; break; case 0x0D: i2c->intrmsk = value; break; case 0x0E: i2c->xfrcnt = value & 0x77; break; case 0x0F: i2c->xtcntlss = value; break; case 0x10: i2c->directcntl = value & 0x7; break; }}static uint32_t ppc4xx_i2c_readw (void *opaque, target_phys_addr_t addr){ uint32_t ret;#ifdef DEBUG_I2C printf("%s: addr " PADDRX "\n", __func__, addr);#endif ret = ppc4xx_i2c_readb(opaque, addr) << 8; ret |= ppc4xx_i2c_readb(opaque, addr + 1); return ret;}static void ppc4xx_i2c_writew (void *opaque, target_phys_addr_t addr, uint32_t value){#ifdef DEBUG_I2C printf("%s: addr " PADDRX " val %08" PRIx32 "\n", __func__, addr, value);#endif ppc4xx_i2c_writeb(opaque, addr, value >> 8); ppc4xx_i2c_writeb(opaque, addr + 1, value);}static uint32_t ppc4xx_i2c_readl (void *opaque, target_phys_addr_t addr){ uint32_t ret;#ifdef DEBUG_I2C printf("%s: addr " PADDRX "\n", __func__, addr);#endif ret = ppc4xx_i2c_readb(opaque, addr) << 24; ret |= ppc4xx_i2c_readb(opaque, addr + 1) << 16; ret |= ppc4xx_i2c_readb(opaque, addr + 2) << 8; ret |= ppc4xx_i2c_readb(opaque, addr + 3); return ret;}static void ppc4xx_i2c_writel (void *opaque, target_phys_addr_t addr, uint32_t value){#ifdef DEBUG_I2C printf("%s: addr " PADDRX " val %08" PRIx32 "\n", __func__, addr, value);#endif ppc4xx_i2c_writeb(opaque, addr, value >> 24); ppc4xx_i2c_writeb(opaque, addr + 1, value >> 16); ppc4xx_i2c_writeb(opaque, addr + 2, value >> 8); ppc4xx_i2c_writeb(opaque, addr + 3, value);}static CPUReadMemoryFunc *i2c_read[] = { &ppc4xx_i2c_readb, &ppc4xx_i2c_readw, &ppc4xx_i2c_readl,};static CPUWriteMemoryFunc *i2c_write[] = { &ppc4xx_i2c_writeb, &ppc4xx_i2c_writew, &ppc4xx_i2c_writel,};static void ppc4xx_i2c_reset (void *opaque){ ppc4xx_i2c_t *i2c; i2c = opaque; i2c->mdata = 0x00; i2c->sdata = 0x00; i2c->cntl = 0x00; i2c->mdcntl = 0x00; i2c->sts = 0x00; i2c->extsts = 0x00; i2c->clkdiv = 0x00; i2c->xfrcnt = 0x00; i2c->directcntl = 0x0F;}void ppc405_i2c_init (CPUState *env, ppc4xx_mmio_t *mmio, target_phys_addr_t offset, qemu_irq irq){ ppc4xx_i2c_t *i2c; i2c = qemu_mallocz(sizeof(ppc4xx_i2c_t)); if (i2c != NULL) { i2c->base = offset; i2c->irq = irq; ppc4xx_i2c_reset(i2c);#ifdef DEBUG_I2C printf("%s: offset " PADDRX "\n", __func__, offset);#endif ppc4xx_mmio_register(env, mmio, offset, 0x011, i2c_read, i2c_write, i2c); qemu_register_reset(ppc4xx_i2c_reset, i2c); }}/*****************************************************************************//* General purpose timers */typedef struct ppc4xx_gpt_t ppc4xx_gpt_t;struct ppc4xx_gpt_t { target_phys_addr_t base; int64_t tb_offset; uint32_t tb_freq; struct QEMUTimer *timer; qemu_irq irqs[5]; uint32_t oe; uint32_t ol; uint32_t im; uint32_t is; uint32_t ie; uint32_t comp[5]; uint32_t mask[5];};static uint32_t ppc4xx_gpt_readb (void *opaque, target_phys_addr_t addr){#ifdef DEBUG_GPT printf("%s: addr " PADDRX "\n", __func__, addr);#endif /* XXX: generate a bus fault */ return -1;}static void ppc4xx_gpt_writeb (void *opaque, target_phys_addr_t addr, uint32_t value){#ifdef DEBUG_I2C printf("%s: addr " PADDRX " val %08" PRIx32 "\n", __func__, addr, value);#endif /* XXX: generate a bus fault */}static uint32_t ppc4xx_gpt_readw (void *opaque, target_phys_addr_t addr){#ifdef DEBUG_GPT printf("%s: addr " PADDRX "\n", __func__, addr);#endif /* XXX: generate a bus fault */ return -1;}static void ppc4xx_gpt_writew (void *opaque, target_phys_addr_t addr, uint32_t value){#ifdef DEBUG_I2C printf("%s: addr " PADDRX " val %08" PRIx32 "\n", __func__, addr, value);#endif /* XXX: generate a bus fault */}static int ppc4xx_gpt_compare (ppc4xx_gpt_t *gpt, int n){ /* XXX: TODO */ return 0;}static void ppc4xx_gpt_set_output (ppc4xx_gpt_t *gpt, int n, int level){ /* XXX: TODO */}static void ppc4xx_gpt_set_outputs (ppc4xx_gpt_t *gpt){ uint32_t mask; int i; mask = 0x80000000; for (i = 0; i < 5; i++) { if (gpt->oe & mask) { /* Output is enabled */ if (ppc4xx_gpt_compare(gpt, i)) { /* Comparison is OK */ ppc4xx_gpt_set_output(gpt, i, gpt->ol & mask); } else { /* Comparison is KO */ ppc4xx_gpt_set_output(gpt, i, gpt->ol & mask ? 0 : 1); } } mask = mask >> 1; }}static void ppc4xx_gpt_set_irqs (ppc4xx_gpt_t *gpt){ uint32_t mask; int i; mask = 0x00008000; for (i = 0; i < 5; i++) { if (gpt->is & gpt->im & mask) qemu_irq_raise(gpt->irqs[i]); else qemu_irq_lower(gpt->irqs[i]); mask = mask >> 1; }}static void ppc4xx_gpt_compute_timer (ppc4xx_gpt_t *gpt){ /* XXX: TODO */}static uint32_t ppc4xx_gpt_readl (void *opaque, target_phys_addr_t addr){ ppc4xx_gpt_t *gpt; uint32_t ret; int idx;#ifdef DEBUG_GPT printf("%s: addr " PADDRX "\n", __func__, addr);#endif gpt = opaque; switch (addr - gpt->base) { case 0x00: /* Time base counter */ ret = muldiv64(qemu_get_clock(vm_clock) + gpt->tb_offset, gpt->tb_freq, ticks_per_sec); break; case 0x10: /* Output enable */ ret = gpt->oe; break; case 0x14: /* Output level */ ret = gpt->ol; break; case 0x18: /* Interrupt mask */ ret = gpt->im; break; case 0x1C: case 0x20: /* Interrupt status */ ret = gpt->is; break; case 0x24: /* Interrupt enable */ ret = gpt->ie; break; case 0x80 ... 0x90: /* Compare timer */ idx = ((addr - gpt->base) - 0x80) >> 2; ret = gpt->comp[idx]; break; case 0xC0 ... 0xD0: /* Compare mask */ idx = ((addr - gpt->base) - 0xC0) >> 2; ret = gpt->mask[idx]; break; default: ret = -1; break; } return ret;}static void ppc4xx_gpt_writel (void *opaque, target_phys_addr_t addr, uint32_t value){ ppc4xx_gpt_t *gpt; int idx;#ifdef DEBUG_I2C printf("%s: addr " PADDRX " val %08" PRIx32 "\n", __func__, addr, value);#endif gpt = opaque; switch (addr - gpt->base) { case 0x00: /* Time base counter */ gpt->tb_offset = muldiv64(value, ticks_per_sec, gpt->tb_freq) - qemu_get_clock(vm_clock); ppc4xx_gpt_compute_timer(gpt); break; case 0x10: /* Output enable */ gpt->oe = value & 0xF8000000; ppc4xx_gpt_set_outputs(gpt); break; case 0x14: /* Output level */ gpt->ol = value & 0xF8000000; ppc4xx_gpt_set_outputs(gpt); break; case 0x18: /* Interrupt mask */ gpt->im = value & 0x0000F800; break; case 0x1C: /* Interrupt status set */ gpt->is |= value & 0x0000F800; ppc4xx_gpt_set_irqs(gpt); break; case 0x20: /* Interrupt status clear */ gpt->is &= ~(value & 0x0000F800); ppc4xx_gpt_set_irqs(gpt); break; case 0x24: /* Interrupt enable */ gpt->ie = value & 0x0000F800; ppc4xx_gpt_set_irqs(gpt); break; case 0x80 ... 0x90: /* Compare timer */ idx = ((addr - gpt->base) - 0x80) >> 2; gpt->comp[idx] = value & 0xF8000000; ppc4xx_gpt_compute_timer(gpt); break; case 0xC0 ... 0xD0: /* Compare mask */ idx = ((addr - gpt->base) - 0xC0) >> 2; gpt->mask[idx] = value & 0xF8000000; ppc4xx_gpt_compute_timer(gpt); break; }}static CPUReadMemoryFunc *gpt_read[] = { &ppc4xx_gpt_readb, &ppc4xx_gpt_readw, &ppc4xx_gpt_readl,};static CPUWriteMemoryFunc *gpt_write[] = { &ppc4xx_gpt_writeb, &ppc4xx_gpt_writew, &ppc4xx_gpt_writel,};static void ppc4xx_gpt_cb (void *opaque){ ppc4xx_gpt_t *gpt; gpt = opaque; ppc4xx_gpt_set_irqs(gpt); ppc4xx_gpt_set_outputs(gpt); ppc4xx_gpt_compute_timer(gpt);}static void ppc4xx_gpt_reset (void *opaque){ ppc4xx_gpt_t *gpt; int i; gpt = opaque; qemu_del_timer(gpt->timer); gpt->oe = 0x00000000; gpt->ol = 0x00000000; gpt->im = 0x00000000; gpt->is = 0x00000000; gpt->ie = 0x00000000; for (i = 0; i < 5; i++) { gpt->comp[i] = 0x00000000; gpt->mask[i] = 0x00000000; }}void ppc4xx_gpt_init (CPUState *env, ppc4xx_mmio_t *mmio, target_phys_addr_t offset, qemu_irq irqs[5]){ ppc4xx_gpt_t *gpt; int i; gpt = qemu_mallocz(sizeof(ppc4xx_gpt_t)); if (gpt != NULL) { gpt->base = offset; for (i = 0; i < 5; i++) gpt->irqs[i] = irqs[i]; gpt->timer = qemu_new_timer(vm_clock, &ppc4xx_gpt_cb, gpt); ppc4xx_gpt_reset(gpt);#ifdef DEBUG_GPT printf("%s: offset " PADDRX "\n", __func__, offset);#endif ppc4xx_mmio_register(env, mmio, offset, 0x0D4, gpt_read, gpt_write, gpt); qemu_register_reset(ppc4xx_gpt_reset, gpt); }}/*****************************************************************************//* MAL */enum { MAL0_CFG = 0x180, MAL0_ESR = 0x181, MAL0_IER = 0x182, MAL0_TXCASR = 0x184, MAL0_TXCARR = 0x185, MAL0_TXEOBISR = 0x186, MAL0_TXDEIR = 0x187, MAL0_RXCASR = 0x190, MAL0_RXCARR = 0x191, MAL0_RXEOBISR = 0x192, MAL0_RXDEIR = 0x193, MAL0_TXCTP0R = 0x1A0, MAL0_TXCTP1R = 0x1A1, MAL0_TXCTP2R = 0x1A2, MAL0_TXCTP3R = 0x1A3, MAL0_RXCTP0R = 0x1C0, MAL0_RXCTP1R = 0x1C1, MAL0_RCBS0 = 0x1E0, MAL0_RCBS1 = 0x1E1,};typedef struct ppc40x_mal_t ppc40x_mal_t;struct ppc40x_mal_t { qemu_irq irqs[4]; uint32_t cfg; uint32_t esr; uint32_t ier; uint32_t txcasr; uint32_t txcarr; uint32_t txeobisr; uint32_t txdeir; uint32_t rxcasr; uint32_t rxcarr; uint32_t rxeobisr; uint32_t rxdeir; uint32_t txctpr[4]; uint32_t rxctpr[2]; uint32_t rcbs[2];};static void ppc40x_mal_reset (void *opaque);static target_ulong dcr_read_mal (void *opaque, int dcrn){ ppc40x_mal_t *mal; target_ulong ret; mal = opaque; switch (dcrn) { case MAL0_CFG: ret = mal->cfg; break; case MAL0_ESR: ret = mal->esr; break; case MAL0_IER: ret = mal->ier; break; case MAL0_TXCASR: ret = mal->txcasr; break; case MAL0_TXCARR: ret = mal->txcarr; break; case MAL0_TXEOBISR: ret = mal->txeobisr; break; case MAL0_TXDEIR: ret = mal->txdeir; break; case MAL0_RXCASR: ret = mal->rxcasr; break; case MAL0_RXCARR: ret = mal->rxcarr; break; case MAL0_RXEOBISR: ret = mal->rxeobisr; break; case MAL0_RXDEIR: ret = mal->rxdeir; break; case MAL0_TXCTP0R: ret = mal->txctpr[0]; break; case MAL0_TXCTP1R: ret = mal->txctpr[1]; break; case MAL0_TXCTP2R: ret = mal->txctpr[2]; break; case MAL0_TXCTP3R: ret = mal->txctpr[3];
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -