?? pxa2xx.c
字號:
case CPPMN3: return; } /* Fall through */ default: printf("%s: Bad register 0x%x\n", __FUNCTION__, reg); break; }}#define MDCNFG 0x00 /* SDRAM Configuration register */#define MDREFR 0x04 /* SDRAM Refresh Control register */#define MSC0 0x08 /* Static Memory Control register 0 */#define MSC1 0x0c /* Static Memory Control register 1 */#define MSC2 0x10 /* Static Memory Control register 2 */#define MECR 0x14 /* Expansion Memory Bus Config register */#define SXCNFG 0x1c /* Synchronous Static Memory Config register */#define MCMEM0 0x28 /* PC Card Memory Socket 0 Timing register */#define MCMEM1 0x2c /* PC Card Memory Socket 1 Timing register */#define MCATT0 0x30 /* PC Card Attribute Socket 0 register */#define MCATT1 0x34 /* PC Card Attribute Socket 1 register */#define MCIO0 0x38 /* PC Card I/O Socket 0 Timing register */#define MCIO1 0x3c /* PC Card I/O Socket 1 Timing register */#define MDMRS 0x40 /* SDRAM Mode Register Set Config register */#define BOOT_DEF 0x44 /* Boot-time Default Configuration register */#define ARB_CNTL 0x48 /* Arbiter Control register */#define BSCNTR0 0x4c /* Memory Buffer Strength Control register 0 */#define BSCNTR1 0x50 /* Memory Buffer Strength Control register 1 */#define LCDBSCNTR 0x54 /* LCD Buffer Strength Control register */#define MDMRSLP 0x58 /* Low Power SDRAM Mode Set Config register */#define BSCNTR2 0x5c /* Memory Buffer Strength Control register 2 */#define BSCNTR3 0x60 /* Memory Buffer Strength Control register 3 */#define SA1110 0x64 /* SA-1110 Memory Compatibility register */static uint32_t pxa2xx_mm_read(void *opaque, target_phys_addr_t addr){ struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; addr -= s->mm_base; switch (addr) { case MDCNFG ... SA1110: if ((addr & 3) == 0) return s->mm_regs[addr >> 2]; default: printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr); break; } return 0;}static void pxa2xx_mm_write(void *opaque, target_phys_addr_t addr, uint32_t value){ struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; addr -= s->mm_base; switch (addr) { case MDCNFG ... SA1110: if ((addr & 3) == 0) { s->mm_regs[addr >> 2] = value; break; } default: printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr); break; }}static CPUReadMemoryFunc *pxa2xx_mm_readfn[] = { pxa2xx_mm_read, pxa2xx_mm_read, pxa2xx_mm_read,};static CPUWriteMemoryFunc *pxa2xx_mm_writefn[] = { pxa2xx_mm_write, pxa2xx_mm_write, pxa2xx_mm_write,};static void pxa2xx_mm_save(QEMUFile *f, void *opaque){ struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; int i; for (i = 0; i < 0x1a; i ++) qemu_put_be32s(f, &s->mm_regs[i]);}static int pxa2xx_mm_load(QEMUFile *f, void *opaque, int version_id){ struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; int i; for (i = 0; i < 0x1a; i ++) qemu_get_be32s(f, &s->mm_regs[i]); return 0;}/* Synchronous Serial Ports */struct pxa2xx_ssp_s { target_phys_addr_t base; qemu_irq irq; int enable; uint32_t sscr[2]; uint32_t sspsp; uint32_t ssto; uint32_t ssitr; uint32_t sssr; uint8_t sstsa; uint8_t ssrsa; uint8_t ssacd; uint32_t rx_fifo[16]; int rx_level; int rx_start; uint32_t (*readfn)(void *opaque); void (*writefn)(void *opaque, uint32_t value); void *opaque;};#define SSCR0 0x00 /* SSP Control register 0 */#define SSCR1 0x04 /* SSP Control register 1 */#define SSSR 0x08 /* SSP Status register */#define SSITR 0x0c /* SSP Interrupt Test register */#define SSDR 0x10 /* SSP Data register */#define SSTO 0x28 /* SSP Time-Out register */#define SSPSP 0x2c /* SSP Programmable Serial Protocol register */#define SSTSA 0x30 /* SSP TX Time Slot Active register */#define SSRSA 0x34 /* SSP RX Time Slot Active register */#define SSTSS 0x38 /* SSP Time Slot Status register */#define SSACD 0x3c /* SSP Audio Clock Divider register *//* Bitfields for above registers */#define SSCR0_SPI(x) (((x) & 0x30) == 0x00)#define SSCR0_SSP(x) (((x) & 0x30) == 0x10)#define SSCR0_UWIRE(x) (((x) & 0x30) == 0x20)#define SSCR0_PSP(x) (((x) & 0x30) == 0x30)#define SSCR0_SSE (1 << 7)#define SSCR0_RIM (1 << 22)#define SSCR0_TIM (1 << 23)#define SSCR0_MOD (1 << 31)#define SSCR0_DSS(x) (((((x) >> 16) & 0x10) | ((x) & 0xf)) + 1)#define SSCR1_RIE (1 << 0)#define SSCR1_TIE (1 << 1)#define SSCR1_LBM (1 << 2)#define SSCR1_MWDS (1 << 5)#define SSCR1_TFT(x) ((((x) >> 6) & 0xf) + 1)#define SSCR1_RFT(x) ((((x) >> 10) & 0xf) + 1)#define SSCR1_EFWR (1 << 14)#define SSCR1_PINTE (1 << 18)#define SSCR1_TINTE (1 << 19)#define SSCR1_RSRE (1 << 20)#define SSCR1_TSRE (1 << 21)#define SSCR1_EBCEI (1 << 29)#define SSITR_INT (7 << 5)#define SSSR_TNF (1 << 2)#define SSSR_RNE (1 << 3)#define SSSR_TFS (1 << 5)#define SSSR_RFS (1 << 6)#define SSSR_ROR (1 << 7)#define SSSR_PINT (1 << 18)#define SSSR_TINT (1 << 19)#define SSSR_EOC (1 << 20)#define SSSR_TUR (1 << 21)#define SSSR_BCE (1 << 23)#define SSSR_RW 0x00bc0080static void pxa2xx_ssp_int_update(struct pxa2xx_ssp_s *s){ int level = 0; level |= s->ssitr & SSITR_INT; level |= (s->sssr & SSSR_BCE) && (s->sscr[1] & SSCR1_EBCEI); level |= (s->sssr & SSSR_TUR) && !(s->sscr[0] & SSCR0_TIM); level |= (s->sssr & SSSR_EOC) && (s->sssr & (SSSR_TINT | SSSR_PINT)); level |= (s->sssr & SSSR_TINT) && (s->sscr[1] & SSCR1_TINTE); level |= (s->sssr & SSSR_PINT) && (s->sscr[1] & SSCR1_PINTE); level |= (s->sssr & SSSR_ROR) && !(s->sscr[0] & SSCR0_RIM); level |= (s->sssr & SSSR_RFS) && (s->sscr[1] & SSCR1_RIE); level |= (s->sssr & SSSR_TFS) && (s->sscr[1] & SSCR1_TIE); qemu_set_irq(s->irq, !!level);}static void pxa2xx_ssp_fifo_update(struct pxa2xx_ssp_s *s){ s->sssr &= ~(0xf << 12); /* Clear RFL */ s->sssr &= ~(0xf << 8); /* Clear TFL */ s->sssr &= ~SSSR_TNF; if (s->enable) { s->sssr |= ((s->rx_level - 1) & 0xf) << 12; if (s->rx_level >= SSCR1_RFT(s->sscr[1])) s->sssr |= SSSR_RFS; else s->sssr &= ~SSSR_RFS; if (0 <= SSCR1_TFT(s->sscr[1])) s->sssr |= SSSR_TFS; else s->sssr &= ~SSSR_TFS; if (s->rx_level) s->sssr |= SSSR_RNE; else s->sssr &= ~SSSR_RNE; s->sssr |= SSSR_TNF; } pxa2xx_ssp_int_update(s);}static uint32_t pxa2xx_ssp_read(void *opaque, target_phys_addr_t addr){ struct pxa2xx_ssp_s *s = (struct pxa2xx_ssp_s *) opaque; uint32_t retval; addr -= s->base; switch (addr) { case SSCR0: return s->sscr[0]; case SSCR1: return s->sscr[1]; case SSPSP: return s->sspsp; case SSTO: return s->ssto; case SSITR: return s->ssitr; case SSSR: return s->sssr | s->ssitr; case SSDR: if (!s->enable) return 0xffffffff; if (s->rx_level < 1) { printf("%s: SSP Rx Underrun\n", __FUNCTION__); return 0xffffffff; } s->rx_level --; retval = s->rx_fifo[s->rx_start ++]; s->rx_start &= 0xf; pxa2xx_ssp_fifo_update(s); return retval; case SSTSA: return s->sstsa; case SSRSA: return s->ssrsa; case SSTSS: return 0; case SSACD: return s->ssacd; default: printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr); break; } return 0;}static void pxa2xx_ssp_write(void *opaque, target_phys_addr_t addr, uint32_t value){ struct pxa2xx_ssp_s *s = (struct pxa2xx_ssp_s *) opaque; addr -= s->base; switch (addr) { case SSCR0: s->sscr[0] = value & 0xc7ffffff; s->enable = value & SSCR0_SSE; if (value & SSCR0_MOD) printf("%s: Attempt to use network mode\n", __FUNCTION__); if (s->enable && SSCR0_DSS(value) < 4) printf("%s: Wrong data size: %i bits\n", __FUNCTION__, SSCR0_DSS(value)); if (!(value & SSCR0_SSE)) { s->sssr = 0; s->ssitr = 0; s->rx_level = 0; } pxa2xx_ssp_fifo_update(s); break; case SSCR1: s->sscr[1] = value; if (value & (SSCR1_LBM | SSCR1_EFWR)) printf("%s: Attempt to use SSP test mode\n", __FUNCTION__); pxa2xx_ssp_fifo_update(s); break; case SSPSP: s->sspsp = value; break; case SSTO: break; case SSITR: s->ssitr = value & SSITR_INT; pxa2xx_ssp_int_update(s); break; case SSSR: s->sssr &= ~(value & SSSR_RW); pxa2xx_ssp_int_update(s); break; case SSDR: if (SSCR0_UWIRE(s->sscr[0])) { if (s->sscr[1] & SSCR1_MWDS) value &= 0xffff; else value &= 0xff; } else /* Note how 32bits overflow does no harm here */ value &= (1 << SSCR0_DSS(s->sscr[0])) - 1; /* Data goes from here to the Tx FIFO and is shifted out from * there directly to the slave, no need to buffer it. */ if (s->enable) { if (s->writefn) s->writefn(s->opaque, value); if (s->rx_level < 0x10) { if (s->readfn) s->rx_fifo[(s->rx_start + s->rx_level ++) & 0xf] = s->readfn(s->opaque); else s->rx_fifo[(s->rx_start + s->rx_level ++) & 0xf] = 0x0; } else s->sssr |= SSSR_ROR; } pxa2xx_ssp_fifo_update(s); break; case SSTSA: s->sstsa = value; break; case SSRSA: s->ssrsa = value; break; case SSACD: s->ssacd = value; break; default: printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr); break; }}void pxa2xx_ssp_attach(struct pxa2xx_ssp_s *port, uint32_t (*readfn)(void *opaque), void (*writefn)(void *opaque, uint32_t value), void *opaque){ if (!port) { printf("%s: no such SSP\n", __FUNCTION__); exit(-1); } port->opaque = opaque; port->readfn = readfn; port->writefn = writefn;}static CPUReadMemoryFunc *pxa2xx_ssp_readfn[] = { pxa2xx_ssp_read, pxa2xx_ssp_read, pxa2xx_ssp_read,};static CPUWriteMemoryFunc *pxa2xx_ssp_writefn[] = { pxa2xx_ssp_write, pxa2xx_ssp_write, pxa2xx_ssp_write,};static void pxa2xx_ssp_save(QEMUFile *f, void *opaque){ struct pxa2xx_ssp_s *s = (struct pxa2xx_ssp_s *) opaque; int i; qemu_put_be32(f, s->enable); qemu_put_be32s(f, &s->sscr[0]); qemu_put_be32s(f, &s->sscr[1]); qemu_put_be32s(f, &s->sspsp); qemu_put_be32s(f, &s->ssto); qemu_put_be32s(f, &s->ssitr); qemu_put_be32s(f, &s->sssr); qemu_put_8s(f, &s->sstsa); qemu_put_8s(f, &s->ssrsa); qemu_put_8s(f, &s->ssacd); qemu_put_byte(f, s->rx_level); for (i = 0; i < s->rx_level; i ++) qemu_put_byte(f, s->rx_fifo[(s->rx_start + i) & 0xf]);}static int pxa2xx_ssp_load(QEMUFile *f, void *opaque, int version_id){ struct pxa2xx_ssp_s *s = (struct pxa2xx_ssp_s *) opaque; int i; s->enable = qemu_get_be32(f); qemu_get_be32s(f, &s->sscr[0]); qemu_get_be32s(f, &s->sscr[1]); qemu_get_be32s(f, &s->sspsp); qemu_get_be32s(f, &s->ssto); qemu_get_be32s(f, &s->ssitr); qemu_get_be32s(f, &s->sssr); qemu_get_8s(f, &s->sstsa); qemu_get_8s(f, &s->ssrsa); qemu_get_8s(f, &s->ssacd); s->rx_level = qemu_get_byte(f); s->rx_start = 0; for (i = 0; i < s->rx_level; i ++) s->rx_fifo[i] = qemu_get_byte(f); return 0;}/* Real-Time Clock */#define RCNR 0x00 /* RTC Counter register */#define RTAR 0x04 /* RTC Alarm register */#define RTSR 0x08 /* RTC Status register */#define RTTR 0x0c /* RTC Timer Trim register */#define RDCR 0x10 /* RTC Day Counter register */#define RYCR 0x14 /* RTC Year Counter register */#define RDAR1 0x18 /* RTC Wristwatch Day Alarm register 1 */#define RYAR1 0x1c /* RTC Wristwatch Year Alarm register 1 */#define RDAR2 0x20 /* RTC Wristwatch Day Alarm register 2 */#define RYAR2 0x24 /* RTC Wristwatch Year Alarm register 2 */#define SWCR 0x28 /* RTC Stopwatch Counter register */#define SWAR1 0x2c /* RTC Stopwatch Alarm register 1 */#define SWAR2 0x30 /* RTC Stopwatch Alarm register 2 */#define RTCPICR 0x34 /* RTC Periodic Interrupt Counter register */#define PIAR 0x38 /* RTC Periodic Interrupt Alarm register */static inline void pxa2xx_rtc_int_update(struct pxa2xx_state_s *s){ qemu_set_irq(s->pic[PXA2XX_PIC_RTCALARM], !!(s->rtsr & 0x2553));}static void pxa2xx_rtc_hzupdate(struct pxa2xx_state_s *s){
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -