?? pxa2xx.c
字號:
(s->status[0] & (1 << 6)); /* EOC */ intr |= (s->control[0] & (1 << 2)) && /* TUS */ (s->status[0] & (1 << 1)); /* TUR */ intr |= s->status[0] & 0x25; /* FRE, RAB, EIF */ pxa2xx_dma_request(s->dma, PXA2XX_RX_RQ_ICP, (s->status[0] >> 4) & 1); pxa2xx_dma_request(s->dma, PXA2XX_TX_RQ_ICP, (s->status[0] >> 3) & 1); qemu_set_irq(s->irq, intr && s->enable);}#define ICCR0 0x00 /* FICP Control register 0 */#define ICCR1 0x04 /* FICP Control register 1 */#define ICCR2 0x08 /* FICP Control register 2 */#define ICDR 0x0c /* FICP Data register */#define ICSR0 0x14 /* FICP Status register 0 */#define ICSR1 0x18 /* FICP Status register 1 */#define ICFOR 0x1c /* FICP FIFO Occupancy Status register */static uint32_t pxa2xx_fir_read(void *opaque, target_phys_addr_t addr){ struct pxa2xx_fir_s *s = (struct pxa2xx_fir_s *) opaque; uint8_t ret; addr -= s->base; switch (addr) { case ICCR0: return s->control[0]; case ICCR1: return s->control[1]; case ICCR2: return s->control[2]; case ICDR: s->status[0] &= ~0x01; s->status[1] &= ~0x72; if (s->rx_len) { s->rx_len --; ret = s->rx_fifo[s->rx_start ++]; s->rx_start &= 63; pxa2xx_fir_update(s); return ret; } printf("%s: Rx FIFO underrun.\n", __FUNCTION__); break; case ICSR0: return s->status[0]; case ICSR1: return s->status[1] | (1 << 3); /* TNF */ case ICFOR: return s->rx_len; default: printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr); break; } return 0;}static void pxa2xx_fir_write(void *opaque, target_phys_addr_t addr, uint32_t value){ struct pxa2xx_fir_s *s = (struct pxa2xx_fir_s *) opaque; uint8_t ch; addr -= s->base; switch (addr) { case ICCR0: s->control[0] = value; if (!(value & (1 << 4))) /* RXE */ s->rx_len = s->rx_start = 0; if (!(value & (1 << 3))) /* TXE */ /* Nop */; s->enable = value & 1; /* ITR */ if (!s->enable) s->status[0] = 0; pxa2xx_fir_update(s); break; case ICCR1: s->control[1] = value; break; case ICCR2: s->control[2] = value & 0x3f; pxa2xx_fir_update(s); break; case ICDR: if (s->control[2] & (1 << 2)) /* TXP */ ch = value; else ch = ~value; if (s->chr && s->enable && (s->control[0] & (1 << 3))) /* TXE */ qemu_chr_write(s->chr, &ch, 1); break; case ICSR0: s->status[0] &= ~(value & 0x66); pxa2xx_fir_update(s); break; case ICFOR: break; default: printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr); }}static CPUReadMemoryFunc *pxa2xx_fir_readfn[] = { pxa2xx_fir_read, pxa2xx_fir_read, pxa2xx_fir_read,};static CPUWriteMemoryFunc *pxa2xx_fir_writefn[] = { pxa2xx_fir_write, pxa2xx_fir_write, pxa2xx_fir_write,};static int pxa2xx_fir_is_empty(void *opaque){ struct pxa2xx_fir_s *s = (struct pxa2xx_fir_s *) opaque; return (s->rx_len < 64);}static void pxa2xx_fir_rx(void *opaque, const uint8_t *buf, int size){ struct pxa2xx_fir_s *s = (struct pxa2xx_fir_s *) opaque; if (!(s->control[0] & (1 << 4))) /* RXE */ return; while (size --) { s->status[1] |= 1 << 4; /* EOF */ if (s->rx_len >= 64) { s->status[1] |= 1 << 6; /* ROR */ break; } if (s->control[2] & (1 << 3)) /* RXP */ s->rx_fifo[(s->rx_start + s->rx_len ++) & 63] = *(buf ++); else s->rx_fifo[(s->rx_start + s->rx_len ++) & 63] = ~*(buf ++); } pxa2xx_fir_update(s);}static void pxa2xx_fir_event(void *opaque, int event){}static void pxa2xx_fir_save(QEMUFile *f, void *opaque){ struct pxa2xx_fir_s *s = (struct pxa2xx_fir_s *) opaque; int i; qemu_put_be32(f, s->enable); qemu_put_8s(f, &s->control[0]); qemu_put_8s(f, &s->control[1]); qemu_put_8s(f, &s->control[2]); qemu_put_8s(f, &s->status[0]); qemu_put_8s(f, &s->status[1]); qemu_put_byte(f, s->rx_len); for (i = 0; i < s->rx_len; i ++) qemu_put_byte(f, s->rx_fifo[(s->rx_start + i) & 63]);}static int pxa2xx_fir_load(QEMUFile *f, void *opaque, int version_id){ struct pxa2xx_fir_s *s = (struct pxa2xx_fir_s *) opaque; int i; s->enable = qemu_get_be32(f); qemu_get_8s(f, &s->control[0]); qemu_get_8s(f, &s->control[1]); qemu_get_8s(f, &s->control[2]); qemu_get_8s(f, &s->status[0]); qemu_get_8s(f, &s->status[1]); s->rx_len = qemu_get_byte(f); s->rx_start = 0; for (i = 0; i < s->rx_len; i ++) s->rx_fifo[i] = qemu_get_byte(f); return 0;}static struct pxa2xx_fir_s *pxa2xx_fir_init(target_phys_addr_t base, qemu_irq irq, struct pxa2xx_dma_state_s *dma, CharDriverState *chr){ int iomemtype; struct pxa2xx_fir_s *s = (struct pxa2xx_fir_s *) qemu_mallocz(sizeof(struct pxa2xx_fir_s)); s->base = base; s->irq = irq; s->dma = dma; s->chr = chr; pxa2xx_fir_reset(s); iomemtype = cpu_register_io_memory(0, pxa2xx_fir_readfn, pxa2xx_fir_writefn, s); cpu_register_physical_memory(s->base, 0x1000, iomemtype); if (chr) qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty, pxa2xx_fir_rx, pxa2xx_fir_event, s); register_savevm("pxa2xx_fir", 0, 0, pxa2xx_fir_save, pxa2xx_fir_load, s); return s;}static void pxa2xx_reset(void *opaque, int line, int level){ struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; if (level && (s->pm_regs[PCFR >> 2] & 0x10)) { /* GPR_EN */ cpu_reset(s->env); /* TODO: reset peripherals */ }}/* Initialise a PXA270 integrated chip (ARM based core). */struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, DisplayState *ds, const char *revision){ struct pxa2xx_state_s *s; struct pxa2xx_ssp_s *ssp; int iomemtype, i; int index; s = (struct pxa2xx_state_s *) qemu_mallocz(sizeof(struct pxa2xx_state_s)); if (revision && strncmp(revision, "pxa27", 5)) { fprintf(stderr, "Machine requires a PXA27x processor.\n"); exit(1); } if (!revision) revision = "pxa270"; s->env = cpu_init(revision); if (!s->env) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } register_savevm("cpu", 0, ARM_CPU_SAVE_VERSION, cpu_save, cpu_load, s->env); s->reset = qemu_allocate_irqs(pxa2xx_reset, s, 1)[0]; /* SDRAM & Internal Memory Storage */ cpu_register_physical_memory(PXA2XX_SDRAM_BASE, sdram_size, qemu_ram_alloc(sdram_size) | IO_MEM_RAM); cpu_register_physical_memory(PXA2XX_INTERNAL_BASE, 0x40000, qemu_ram_alloc(0x40000) | IO_MEM_RAM); s->pic = pxa2xx_pic_init(0x40d00000, s->env); s->dma = pxa27x_dma_init(0x40000000, s->pic[PXA2XX_PIC_DMA]); pxa27x_timer_init(0x40a00000, &s->pic[PXA2XX_PIC_OST_0], s->pic[PXA27X_PIC_OST_4_11]); s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 121); index = drive_get_index(IF_SD, 0, 0); if (index == -1) { fprintf(stderr, "qemu: missing SecureDigital device\n"); exit(1); } s->mmc = pxa2xx_mmci_init(0x41100000, drives_table[index].bdrv, s->pic[PXA2XX_PIC_MMC], s->dma); for (i = 0; pxa270_serial[i].io_base; i ++) if (serial_hds[i]) serial_mm_init(pxa270_serial[i].io_base, 2, s->pic[pxa270_serial[i].irqn], serial_hds[i], 1); else break; if (serial_hds[i]) s->fir = pxa2xx_fir_init(0x40800000, s->pic[PXA2XX_PIC_ICP], s->dma, serial_hds[i]); if (ds) s->lcd = pxa2xx_lcdc_init(0x44000000, s->pic[PXA2XX_PIC_LCD], ds); s->cm_base = 0x41300000; s->cm_regs[CCCR >> 2] = 0x02000210; /* 416.0 MHz */ s->clkcfg = 0x00000009; /* Turbo mode active */ iomemtype = cpu_register_io_memory(0, pxa2xx_cm_readfn, pxa2xx_cm_writefn, s); cpu_register_physical_memory(s->cm_base, 0x1000, iomemtype); register_savevm("pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s); cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s); s->mm_base = 0x48000000; s->mm_regs[MDMRS >> 2] = 0x00020002; s->mm_regs[MDREFR >> 2] = 0x03ca4000; s->mm_regs[MECR >> 2] = 0x00000001; /* Two PC Card sockets */ iomemtype = cpu_register_io_memory(0, pxa2xx_mm_readfn, pxa2xx_mm_writefn, s); cpu_register_physical_memory(s->mm_base, 0x1000, iomemtype); register_savevm("pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s); s->pm_base = 0x40f00000; iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn, pxa2xx_pm_writefn, s); cpu_register_physical_memory(s->pm_base, 0x100, iomemtype); register_savevm("pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s); for (i = 0; pxa27x_ssp[i].io_base; i ++); s->ssp = (struct pxa2xx_ssp_s **) qemu_mallocz(sizeof(struct pxa2xx_ssp_s *) * i); ssp = (struct pxa2xx_ssp_s *) qemu_mallocz(sizeof(struct pxa2xx_ssp_s) * i); for (i = 0; pxa27x_ssp[i].io_base; i ++) { s->ssp[i] = &ssp[i]; ssp[i].irq = s->pic[pxa27x_ssp[i].irqn]; iomemtype = cpu_register_io_memory(0, pxa2xx_ssp_readfn, pxa2xx_ssp_writefn, &ssp[i]); cpu_register_physical_memory(ssp[i].base, 0x1000, iomemtype); register_savevm("pxa2xx_ssp", i, 0, pxa2xx_ssp_save, pxa2xx_ssp_load, s); } if (usb_enabled) { usb_ohci_init_pxa(0x4c000000, 3, -1, s->pic[PXA2XX_PIC_USBH1]); } s->pcmcia[0] = pxa2xx_pcmcia_init(0x20000000); s->pcmcia[1] = pxa2xx_pcmcia_init(0x30000000); s->rtc_base = 0x40900000; iomemtype = cpu_register_io_memory(0, pxa2xx_rtc_readfn, pxa2xx_rtc_writefn, s); cpu_register_physical_memory(s->rtc_base, 0x1000, iomemtype); pxa2xx_rtc_init(s); register_savevm("pxa2xx_rtc", 0, 0, pxa2xx_rtc_save, pxa2xx_rtc_load, s); s->i2c[0] = pxa2xx_i2c_init(0x40301600, s->pic[PXA2XX_PIC_I2C], 0xffff); s->i2c[1] = pxa2xx_i2c_init(0x40f00100, s->pic[PXA2XX_PIC_PWRI2C], 0xff); s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma); s->kp = pxa27x_keypad_init(0x41500000, s->pic[PXA2XX_PIC_KEYPAD]); /* GPIO1 resets the processor */ /* The handler can be overridden by board-specific code */ pxa2xx_gpio_out_set(s->gpio, 1, s->reset);}/* Initialise a PXA255 integrated chip (ARM based core). */struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, DisplayState *ds){ struct pxa2xx_state_s *s; struct pxa2xx_ssp_s *ssp; int iomemtype, i; int index; s = (struct pxa2xx_state_s *) qemu_mallocz(sizeof(struct pxa2xx_state_s)); s->env = cpu_init("pxa255"); if (!s->env) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } register_savevm("cpu", 0, ARM_CPU_SAVE_VERSION, cpu_save, cpu_load, s->env); s->reset = qemu_allocate_irqs(pxa2xx_reset, s, 1)[0]; /* SDRAM & Internal Memory Storage */ cpu_register_physical_memory(PXA2XX_SDRAM_BASE, sdram_size, qemu_ram_alloc(sdram_size) | IO_MEM_RAM); cpu_register_physical_memory(PXA2XX_INTERNAL_BASE, PXA2XX_INTERNAL_SIZE, qemu_ram_alloc(PXA2XX_INTERNAL_SIZE) | IO_MEM_RAM); s->pic = pxa2xx_pic_init(0x40d00000, s->env); s->dma = pxa255_dma_init(0x40000000, s->pic[PXA2XX_PIC_DMA]); pxa25x_timer_init(0x40a00000, &s->pic[PXA2XX_PIC_OST_0]); s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 85); index = drive_get_index(IF_SD, 0, 0); if (index == -1) { fprintf(stderr, "qemu: missing SecureDigital device\n"); exit(1); } s->mmc = pxa2xx_mmci_init(0x41100000, drives_table[index].bdrv, s->pic[PXA2XX_PIC_MMC], s->dma); for (i = 0; pxa255_serial[i].io_base; i ++) if (serial_hds[i]) serial_mm_init(pxa255_serial[i].io_base, 2, s->pic[pxa255_serial[i].irqn], serial_hds[i], 1); else break; if (serial_hds[i]) s->fir = pxa2xx_fir_init(0x40800000, s->pic[PXA2XX_PIC_ICP], s->dma, serial_hds[i]); if (ds) s->lcd = pxa2xx_lcdc_init(0x44000000, s->pic[PXA2XX_PIC_LCD], ds); s->cm_base = 0x41300000; s->cm_regs[CCCR >> 2] = 0x02000210; /* 416.0 MHz */ s->clkcfg = 0x00000009; /* Turbo mode active */ iomemtype = cpu_register_io_memory(0, pxa2xx_cm_readfn, pxa2xx_cm_writefn, s); cpu_register_physical_memory(s->cm_base, 0x1000, iomemtype); register_savevm("pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s); cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s); s->mm_base = 0x48000000; s->mm_regs[MDMRS >> 2] = 0x00020002; s->mm_regs[MDREFR >> 2] = 0x03ca4000; s->mm_regs[MECR >> 2] = 0x00000001; /* Two PC Card sockets */ iomemtype = cpu_register_io_memory(0, pxa2xx_mm_readfn, pxa2xx_mm_writefn, s); cpu_register_physical_memory(s->mm_base, 0x1000, iomemtype); register_savevm("pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s); s->pm_base = 0x40f00000; iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn, pxa2xx_pm_writefn, s); cpu_register_physical_memory(s->pm_base, 0x100, iomemtype); register_savevm("pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s); for (i = 0; pxa255_ssp[i].io_base; i ++); s->ssp = (struct pxa2xx_ssp_s **) qemu_mallocz(sizeof(struct pxa2xx_ssp_s *) * i); ssp = (struct pxa2xx_ssp_s *) qemu_mallocz(sizeof(struct pxa2xx_ssp_s) * i); for (i = 0; pxa255_ssp[i].io_base; i ++) { s->ssp[i] = &ssp[i]; ssp[i].base = pxa255_ssp[i].io_base; ssp[i].irq = s->pic[pxa255_ssp[i].irqn]; iomemtype = cpu_register_io_memory(0, pxa2xx_ssp_readfn,
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -