?? ppc405_uc.c
字號(hào):
break; case MAL0_RXCTP0R: ret = mal->rxctpr[0]; break; case MAL0_RXCTP1R: ret = mal->rxctpr[1]; break; case MAL0_RCBS0: ret = mal->rcbs[0]; break; case MAL0_RCBS1: ret = mal->rcbs[1]; break; default: ret = 0; break; } return ret;}static void dcr_write_mal (void *opaque, int dcrn, target_ulong val){ ppc40x_mal_t *mal; int idx; mal = opaque; switch (dcrn) { case MAL0_CFG: if (val & 0x80000000) ppc40x_mal_reset(mal); mal->cfg = val & 0x00FFC087; break; case MAL0_ESR: /* Read/clear */ mal->esr &= ~val; break; case MAL0_IER: mal->ier = val & 0x0000001F; break; case MAL0_TXCASR: mal->txcasr = val & 0xF0000000; break; case MAL0_TXCARR: mal->txcarr = val & 0xF0000000; break; case MAL0_TXEOBISR: /* Read/clear */ mal->txeobisr &= ~val; break; case MAL0_TXDEIR: /* Read/clear */ mal->txdeir &= ~val; break; case MAL0_RXCASR: mal->rxcasr = val & 0xC0000000; break; case MAL0_RXCARR: mal->rxcarr = val & 0xC0000000; break; case MAL0_RXEOBISR: /* Read/clear */ mal->rxeobisr &= ~val; break; case MAL0_RXDEIR: /* Read/clear */ mal->rxdeir &= ~val; break; case MAL0_TXCTP0R: idx = 0; goto update_tx_ptr; case MAL0_TXCTP1R: idx = 1; goto update_tx_ptr; case MAL0_TXCTP2R: idx = 2; goto update_tx_ptr; case MAL0_TXCTP3R: idx = 3; update_tx_ptr: mal->txctpr[idx] = val; break; case MAL0_RXCTP0R: idx = 0; goto update_rx_ptr; case MAL0_RXCTP1R: idx = 1; update_rx_ptr: mal->rxctpr[idx] = val; break; case MAL0_RCBS0: idx = 0; goto update_rx_size; case MAL0_RCBS1: idx = 1; update_rx_size: mal->rcbs[idx] = val & 0x000000FF; break; }}static void ppc40x_mal_reset (void *opaque){ ppc40x_mal_t *mal; mal = opaque; mal->cfg = 0x0007C000; mal->esr = 0x00000000; mal->ier = 0x00000000; mal->rxcasr = 0x00000000; mal->rxdeir = 0x00000000; mal->rxeobisr = 0x00000000; mal->txcasr = 0x00000000; mal->txdeir = 0x00000000; mal->txeobisr = 0x00000000;}void ppc405_mal_init (CPUState *env, qemu_irq irqs[4]){ ppc40x_mal_t *mal; int i; mal = qemu_mallocz(sizeof(ppc40x_mal_t)); if (mal != NULL) { for (i = 0; i < 4; i++) mal->irqs[i] = irqs[i]; ppc40x_mal_reset(mal); qemu_register_reset(&ppc40x_mal_reset, mal); ppc_dcr_register(env, MAL0_CFG, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_ESR, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_IER, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_TXCASR, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_TXCARR, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_TXEOBISR, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_TXDEIR, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_RXCASR, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_RXCARR, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_RXEOBISR, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_RXDEIR, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_TXCTP0R, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_TXCTP1R, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_TXCTP2R, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_TXCTP3R, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_RXCTP0R, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_RXCTP1R, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_RCBS0, mal, &dcr_read_mal, &dcr_write_mal); ppc_dcr_register(env, MAL0_RCBS1, mal, &dcr_read_mal, &dcr_write_mal); }}/*****************************************************************************//* SPR */void ppc40x_core_reset (CPUState *env){ target_ulong dbsr; printf("Reset PowerPC core\n"); env->interrupt_request |= CPU_INTERRUPT_EXITTB; /* XXX: TOFIX */#if 0 cpu_ppc_reset(env);#else qemu_system_reset_request();#endif dbsr = env->spr[SPR_40x_DBSR]; dbsr &= ~0x00000300; dbsr |= 0x00000100; env->spr[SPR_40x_DBSR] = dbsr;}void ppc40x_chip_reset (CPUState *env){ target_ulong dbsr; printf("Reset PowerPC chip\n"); env->interrupt_request |= CPU_INTERRUPT_EXITTB; /* XXX: TOFIX */#if 0 cpu_ppc_reset(env);#else qemu_system_reset_request();#endif /* XXX: TODO reset all internal peripherals */ dbsr = env->spr[SPR_40x_DBSR]; dbsr &= ~0x00000300; dbsr |= 0x00000200; env->spr[SPR_40x_DBSR] = dbsr;}void ppc40x_system_reset (CPUState *env){ printf("Reset PowerPC system\n"); qemu_system_reset_request();}void store_40x_dbcr0 (CPUState *env, uint32_t val){ switch ((val >> 28) & 0x3) { case 0x0: /* No action */ break; case 0x1: /* Core reset */ ppc40x_core_reset(env); break; case 0x2: /* Chip reset */ ppc40x_chip_reset(env); break; case 0x3: /* System reset */ ppc40x_system_reset(env); break; }}/*****************************************************************************//* PowerPC 405CR */enum { PPC405CR_CPC0_PLLMR = 0x0B0, PPC405CR_CPC0_CR0 = 0x0B1, PPC405CR_CPC0_CR1 = 0x0B2, PPC405CR_CPC0_PSR = 0x0B4, PPC405CR_CPC0_JTAGID = 0x0B5, PPC405CR_CPC0_ER = 0x0B9, PPC405CR_CPC0_FR = 0x0BA, PPC405CR_CPC0_SR = 0x0BB,};enum { PPC405CR_CPU_CLK = 0, PPC405CR_TMR_CLK = 1, PPC405CR_PLB_CLK = 2, PPC405CR_SDRAM_CLK = 3, PPC405CR_OPB_CLK = 4, PPC405CR_EXT_CLK = 5, PPC405CR_UART_CLK = 6, PPC405CR_CLK_NB = 7,};typedef struct ppc405cr_cpc_t ppc405cr_cpc_t;struct ppc405cr_cpc_t { clk_setup_t clk_setup[PPC405CR_CLK_NB]; uint32_t sysclk; uint32_t psr; uint32_t cr0; uint32_t cr1; uint32_t jtagid; uint32_t pllmr; uint32_t er; uint32_t fr;};static void ppc405cr_clk_setup (ppc405cr_cpc_t *cpc){ uint64_t VCO_out, PLL_out; uint32_t CPU_clk, TMR_clk, SDRAM_clk, PLB_clk, OPB_clk, EXT_clk, UART_clk; int M, D0, D1, D2; D0 = ((cpc->pllmr >> 26) & 0x3) + 1; /* CBDV */ if (cpc->pllmr & 0x80000000) { D1 = (((cpc->pllmr >> 20) - 1) & 0xF) + 1; /* FBDV */ D2 = 8 - ((cpc->pllmr >> 16) & 0x7); /* FWDVA */ M = D0 * D1 * D2; VCO_out = cpc->sysclk * M; if (VCO_out < 400000000 || VCO_out > 800000000) { /* PLL cannot lock */ cpc->pllmr &= ~0x80000000; goto bypass_pll; } PLL_out = VCO_out / D2; } else { /* Bypass PLL */ bypass_pll: M = D0; PLL_out = cpc->sysclk * M; } CPU_clk = PLL_out; if (cpc->cr1 & 0x00800000) TMR_clk = cpc->sysclk; /* Should have a separate clock */ else TMR_clk = CPU_clk; PLB_clk = CPU_clk / D0; SDRAM_clk = PLB_clk; D0 = ((cpc->pllmr >> 10) & 0x3) + 1; OPB_clk = PLB_clk / D0; D0 = ((cpc->pllmr >> 24) & 0x3) + 2; EXT_clk = PLB_clk / D0; D0 = ((cpc->cr0 >> 1) & 0x1F) + 1; UART_clk = CPU_clk / D0; /* Setup CPU clocks */ clk_setup(&cpc->clk_setup[PPC405CR_CPU_CLK], CPU_clk); /* Setup time-base clock */ clk_setup(&cpc->clk_setup[PPC405CR_TMR_CLK], TMR_clk); /* Setup PLB clock */ clk_setup(&cpc->clk_setup[PPC405CR_PLB_CLK], PLB_clk); /* Setup SDRAM clock */ clk_setup(&cpc->clk_setup[PPC405CR_SDRAM_CLK], SDRAM_clk); /* Setup OPB clock */ clk_setup(&cpc->clk_setup[PPC405CR_OPB_CLK], OPB_clk); /* Setup external clock */ clk_setup(&cpc->clk_setup[PPC405CR_EXT_CLK], EXT_clk); /* Setup UART clock */ clk_setup(&cpc->clk_setup[PPC405CR_UART_CLK], UART_clk);}static target_ulong dcr_read_crcpc (void *opaque, int dcrn){ ppc405cr_cpc_t *cpc; target_ulong ret; cpc = opaque; switch (dcrn) { case PPC405CR_CPC0_PLLMR: ret = cpc->pllmr; break; case PPC405CR_CPC0_CR0: ret = cpc->cr0; break; case PPC405CR_CPC0_CR1: ret = cpc->cr1; break; case PPC405CR_CPC0_PSR: ret = cpc->psr; break; case PPC405CR_CPC0_JTAGID: ret = cpc->jtagid; break; case PPC405CR_CPC0_ER: ret = cpc->er; break; case PPC405CR_CPC0_FR: ret = cpc->fr; break; case PPC405CR_CPC0_SR: ret = ~(cpc->er | cpc->fr) & 0xFFFF0000; break; default: /* Avoid gcc warning */ ret = 0; break; } return ret;}static void dcr_write_crcpc (void *opaque, int dcrn, target_ulong val){ ppc405cr_cpc_t *cpc; cpc = opaque; switch (dcrn) { case PPC405CR_CPC0_PLLMR: cpc->pllmr = val & 0xFFF77C3F; break; case PPC405CR_CPC0_CR0: cpc->cr0 = val & 0x0FFFFFFE; break; case PPC405CR_CPC0_CR1: cpc->cr1 = val & 0x00800000; break; case PPC405CR_CPC0_PSR: /* Read-only */ break; case PPC405CR_CPC0_JTAGID: /* Read-only */ break; case PPC405CR_CPC0_ER: cpc->er = val & 0xBFFC0000; break; case PPC405CR_CPC0_FR: cpc->fr = val & 0xBFFC0000; break; case PPC405CR_CPC0_SR: /* Read-only */ break; }}static void ppc405cr_cpc_reset (void *opaque){ ppc405cr_cpc_t *cpc; int D; cpc = opaque; /* Compute PLLMR value from PSR settings */ cpc->pllmr = 0x80000000; /* PFWD */ switch ((cpc->psr >> 30) & 3) { case 0: /* Bypass */ cpc->pllmr &= ~0x80000000; break; case 1: /* Divide by 3 */ cpc->pllmr |= 5 << 16; break; case 2: /* Divide by 4 */ cpc->pllmr |= 4 << 16; break; case 3: /* Divide by 6 */ cpc->pllmr |= 2 << 16; break; } /* PFBD */ D = (cpc->psr >> 28) & 3; cpc->pllmr |= (D + 1) << 20; /* PT */ D = (cpc->psr >> 25) & 7; switch (D) { case 0x2: cpc->pllmr |= 0x13; break; case 0x4: cpc->pllmr |= 0x15; break; case 0x5: cpc->pllmr |= 0x16; break; default: break; } /* PDC */ D = (cpc->psr >> 23) & 3; cpc->pllmr |= D << 26; /* ODP */ D = (cpc->psr >> 21) & 3; cpc->pllmr |= D << 10; /* EBPD */ D = (cpc->psr >> 17) & 3; cpc->pllmr |= D << 24; cpc->cr0 = 0x0000003C; cpc->cr1 = 0x2B0D8800; cpc->er = 0x00000000; cpc->fr = 0x00000000; ppc405cr_clk_setup(cpc);}static void ppc405cr_clk_init (ppc405cr_cpc_t *cpc){ int D; /* XXX: this should be read from IO pins */ cpc->psr = 0x00000000; /* 8 bits ROM */ /* PFWD */ D = 0x2; /* Divide by 4 */ cpc->psr |= D << 30; /* PFBD */ D = 0x1; /* Divide by 2 */ cpc->psr |= D << 28; /* PDC */ D = 0x1; /* Divide by 2 */ cpc->psr |= D << 23; /* PT */ D = 0x5; /* M = 16 */ cpc->psr |= D << 25; /* ODP */ D = 0x1; /* Divide by 2 */ cpc->psr |= D << 21; /* EBDP */ D = 0x2; /* Divide by 4 */ cpc->psr |= D << 17;}static void ppc405cr_cpc_init (CPUState *env, clk_setup_t clk_setup[7], uint32_t sysclk){ ppc405cr_cpc_t *cpc; cpc = qemu_mallocz(sizeof(ppc405cr_cpc_t)); if (cpc != NULL) { memcpy(cpc->clk_setup, clk_setup, PPC405CR_CLK_NB * sizeof(clk_setup_t)); cpc->sysclk = sysclk; cpc->jtagid = 0x42051049; ppc_dcr_register(env, PPC405CR_CPC0_PSR, cpc, &dcr_read_crcpc, &dcr_write_crcpc); ppc_dcr_register(env, PPC405CR_CPC0_CR0, cpc, &dcr_read_crcpc, &dcr_write_crcpc); ppc_dcr_register(env, PPC405CR_CPC0_CR1, cpc, &dcr_read_crcpc, &dcr_write_crcpc); ppc_dcr_register(env, PPC405CR_CPC0_JTAGID, cpc, &dcr_read_crcpc, &dcr_write_crcpc); ppc_dcr_register(env, PPC405CR_CPC0_PLLMR, cpc,
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -