int spr_post_test (int flags) { int ret = 0; int ic = icache_status (); int i; unsigned long code[] = { 0x7c6002a6, /* mfspr r3,SPR */ 0x4e800020 /* blr */ }; unsigned long (*get_spr) (void) = (void *) code; if (ic) icache_disable (); for (i = 0; i < spr_test_list_size; i++) { int num = spr_test_list[i].number; /* mfspr r3,num */ code[0] = 0x7c6002a6 | ((num & 0x1F) << 16) | ((num & 0x3E0) << 6); if ((get_spr () & spr_test_list[i].mask) != (spr_test_list[i].value & spr_test_list[i].mask)) { post_log ("The value of %s special register " "is incorrect: 0x%08X\n", spr_test_list[i].name, get_spr ()); ret = -1; } } if (ic) icache_enable (); return ret; }
static uint32_t get_l1csr0(void) { uint32_t ret; sync(); ret = get_spr(1010); sync(); return ret; }
static void rdecl save_perfregs_7450(PPC_PERFREGS *pcr) { pcr->mpc7450.mmc[0] = get_spr( PPC7450_SPR_MMCR0 ); /* Disable counting so that a PMI isn't generated in the kernel code. */ set_spr( PPC7450_SPR_MMCR0, 0x80000000); pcr->mpc7450.mmc[1] = get_spr( PPC7450_SPR_MMCR1 ); pcr->mpc7450.mmc[2] = get_spr( PPC7450_SPR_MMCR2 ); pcr->mpc7450.pmc[0] = get_spr( PPC7450_SPR_PMC1 ); pcr->mpc7450.pmc[1] = get_spr( PPC7450_SPR_PMC2 ); pcr->mpc7450.pmc[2] = get_spr( PPC7450_SPR_PMC3 ); pcr->mpc7450.pmc[3] = get_spr( PPC7450_SPR_PMC4 ); pcr->mpc7450.pmc[4] = get_spr( PPC7450_SPR_PMC5 ); pcr->mpc7450.pmc[5] = get_spr( PPC7450_SPR_PMC6 ); pcr->mpc7450.sia = get_spr( PPC7450_SPR_SIA ); }
static void extra_74xx_save(struct cpu_extra_state *state) { state->u.ppc600.pir = get_spr(PPC700_SPR_PIR); state->u.ppc600.ldstcr = get_spr(PPC700_SPR_LDSTCR); state->u.ppc600.ictrl = get_spr(PPC700_SPR_ICTRL); state->u.ppc600.l2cr = get_spr(PPC700_SPR_L2CR); state->u.ppc600.l3cr = get_spr(PPC700_SPR_L3CR); state->u.ppc600.msscr0 = get_spr(PPC700_SPR_MSSCR0); state->u.ppc600.msssr0 = get_spr(PPC700_SPR_MSSSR0); }
int spr_post_test (int flags) { int ret = 0; int i; unsigned long code[] = { 0x7c6002a6, /* mfspr r3,SPR */ 0x4e800020 /* blr */ }; unsigned long (*get_spr) (void) = (void *) code; #ifdef CONFIG_4xx_DCACHE /* disable cache */ change_tlb(gd->bd->bi_memstart, gd->bd->bi_memsize, TLB_WORD2_I_ENABLE); #endif for (i = 0; i < spr_test_list_size; i++) { int num = spr_test_list[i].number; /* mfspr r3,num */ code[0] = 0x7c6002a6 | ((num & 0x1F) << 16) | ((num & 0x3E0) << 6); asm volatile ("isync"); if ((get_spr () & spr_test_list[i].mask) != (spr_test_list[i].value & spr_test_list[i].mask)) { post_log ("The value of %s special register " "is incorrect: 0x%08X\n", spr_test_list[i].name, get_spr ()); ret = -1; } } #ifdef CONFIG_4xx_DCACHE /* enable cache */ change_tlb(gd->bd->bi_memstart, gd->bd->bi_memsize, 0); #endif return ret; }
static uint32 Mcu_CheckCpu( void ) { uint32 pvr; // uint32 pir; const cpu_info_t *cpuType; const core_info_t *coreType; // We have to registers to read here, PIR and PVR // pir = get_spr(SPR_PIR); pvr = get_spr(SPR_PVR); cpuType = Mcu_IdentifyCpu(pvr); coreType = Mcu_IdentifyCore(pvr); if( (cpuType == NULL) || (coreType == NULL) ) { // Just hang while(1) ; } //DEBUG(DEBUG_HIGH,"/drivers/mcu: Cpu: %s( 0x%08x )\n",cpuType->name,pvr); //DEBUG(DEBUG_HIGH,"/drivers/mcu: Core: %s( 0x%08x )\n",coreType->name,pvr); return 0; }
void config_cpu(unsigned pvr, const struct exc_copy_block **entry, const struct exc_copy_block **exitlocal) { set_spr( PPCBKE_SPR_DBCR0, 0 ); #ifdef VARIANT_booke SYSPAGE_CPU_ENTRY(ppc,kerinfo)->init_msr |= PPC_MSR_DE; #endif switch(PPC_GET_FAM_MEMBER(pvr)) { case PPC_440GP: ppcbke_tlb_select = PPCBKE_TLB_SELECT_IBM; trap_install_set(traps_440gp, NUM_ELTS(traps_440gp)); fix_pgsizes(); break; case PPC_440GX: ppcbke_tlb_select = PPCBKE_TLB_SELECT_IBM; trap_install_set(traps_440gx, NUM_ELTS(traps_440gx)); fix_pgsizes(); break; case PPC_E500V2: ppcbke_tlb_select = PPCBKE_TLB_SELECT_E500v2; trap_install_set(traps_e500, NUM_ELTS(traps_e500)); alt_souls.size = sizeof(PPC_SPE_REGISTERS); *entry++ = &ctx_save_e500_extra; *exitlocal++ = &ctx_restore_e500_extra; break; case PPC_E500: ppcbke_tlb_select = PPCBKE_TLB_SELECT_E500; trap_install_set(traps_e500, NUM_ELTS(traps_e500)); alt_souls.size = sizeof(PPC_SPE_REGISTERS); *entry++ = &ctx_save_e500_extra; *exitlocal++ = &ctx_restore_e500_extra; break; default: kprintf("Unsupported PVR value: %x\n", pvr); crash(); break; } trap_install_set(traps_booke, NUM_ELTS(traps_booke)); if(__cpu_flags & CPU_FLAG_FPU) { if(fpuemul) { // Emulation trap_install(PPCBKE_SPR_IVOR7, __exc_fpu_emulation, &__common_exc_entry); } else { // Real floating point trap_install(PPCBKE_SPR_IVOR7, __exc_fpu_unavail, &__exc_ffpu); } } // Make data & instruction TLB misses go to the // data and instruction storage exceptions. This will // be changed if/when copy_vm_code() gets called and // we know we're running in virtual mode. set_spr(PPCBKE_SPR_IVOR13, get_spr(PPCBKE_SPR_IVOR2)); set_spr(PPCBKE_SPR_IVOR14, get_spr(PPCBKE_SPR_IVOR3)); *entry++ = &ctx_save_usprg0; *exitlocal++ = &ctx_restore_usprg0; *entry = NULL; *exitlocal = NULL; ppc_ienable_bits |= PPC_MSR_CE | PPC_MSR_ME; }
static void extra_e500v2_save(struct cpu_extra_state *state) { extra_e500_save(state); state->u.ppcbkem.spr.mas[7] = get_spr(PPCBKEM_SPR_MAS7); }
static void extra_e500_save(struct cpu_extra_state *state) { //NYI: Should look at MMUCFG to decide how many pid registers //and if we need to save MAS5 state->u.ppcbkem.spr.mas[0] = get_spr(PPCBKEM_SPR_MAS0); state->u.ppcbkem.spr.mas[1] = get_spr(PPCBKEM_SPR_MAS1); state->u.ppcbkem.spr.mas[2] = get_spr(PPCBKEM_SPR_MAS2); state->u.ppcbkem.spr.mas[3] = get_spr(PPCBKEM_SPR_MAS3); state->u.ppcbkem.spr.mas[4] = get_spr(PPCBKEM_SPR_MAS4); // state->u.ppcbkem.spr.mas[5] = get_spr(PPCBKEM_SPR_MAS5); state->u.ppcbkem.spr.mas[6] = get_spr(PPCBKEM_SPR_MAS6); state->u.ppcbkem.spr.pid1 = get_spr(PPCBKEM_SPR_PID1); state->u.ppcbkem.spr.pid2 = get_spr(PPCBKEM_SPR_PID2); state->u.ppce500.spr.ivor32 = get_spr(PPCE500_SPR_IVOR32); state->u.ppce500.spr.ivor33 = get_spr(PPCE500_SPR_IVOR33); state->u.ppce500.spr.ivor34 = get_spr(PPCE500_SPR_IVOR34); state->u.ppce500.spr.ivor35 = get_spr(PPCE500_SPR_IVOR35); state->u.ppce500.spr.hid0 = get_spr(PPCE500_SPR_HID0); state->u.ppce500.spr.hid1 = get_spr(PPCE500_SPR_HID1); state->u.ppce500.spr.bucsr = get_spr(PPCE500_SPR_BUCSR); }
static void extra_440_save(struct cpu_extra_state *state) { state->u.ppc440.spr.ccr0 = get_spr(PPC440_SPR_CCR0); state->u.ppc440.spr.mmucr = get_spr(PPC440_SPR_MMUCR); state->u.ppc440.spr.rstcfg = get_spr(PPC440_SPR_RSTCFG); }
void cpu_save_extra(struct cpu_extra_state *state) { unsigned i; unsigned j; unsigned num_entries; switch(SYSPAGE_CPU_ENTRY(ppc, kerinfo)->ppc_family) { case PPC_FAMILY_400: state->u.ppc400.spr.dear = get_spr(PPC400_SPR_DEAR); state->u.ppc400.spr.esr = get_spr(PPC400_SPR_ESR); if(SYSPAGE_ENTRY(cpuinfo)->flags & CPU_FLAG_MMU) { state->u.ppc400.spr.pid = get_spr(PPC400_SPR_PID); state->u.ppc400.spr.zpr = get_spr(PPC400_SPR_ZPR); for(i = 0; i < state->u.ppc400.tlb.num_entries; ++i) { extern void get_tlb400(); get_tlb400(i, &state->u.ppc400.tlb.entry[i]); } } break; case PPC_FAMILY_600: state->u.ppc600.hid0 = get_spr(PPC603_SPR_HID0); state->u.ppc600.hid1 = get_spr(PPC603_SPR_HID1); state->u.ppc600.dbat[0].lo = get_spr(PPC_SPR_DBAT0L); state->u.ppc600.dbat[0].up = get_spr(PPC_SPR_DBAT0U); state->u.ppc600.dbat[1].lo = get_spr(PPC_SPR_DBAT1L); state->u.ppc600.dbat[1].up = get_spr(PPC_SPR_DBAT1U); state->u.ppc600.dbat[2].lo = get_spr(PPC_SPR_DBAT2L); state->u.ppc600.dbat[2].up = get_spr(PPC_SPR_DBAT2U); state->u.ppc600.dbat[3].lo = get_spr(PPC_SPR_DBAT3L); state->u.ppc600.dbat[3].up = get_spr(PPC_SPR_DBAT3U); state->u.ppc600.ibat[0].lo = get_spr(PPC_SPR_IBAT0L); state->u.ppc600.ibat[0].up = get_spr(PPC_SPR_IBAT0U); state->u.ppc600.ibat[1].lo = get_spr(PPC_SPR_IBAT1L); state->u.ppc600.ibat[1].up = get_spr(PPC_SPR_IBAT1U); state->u.ppc600.ibat[2].lo = get_spr(PPC_SPR_IBAT2L); state->u.ppc600.ibat[2].up = get_spr(PPC_SPR_IBAT2U); state->u.ppc600.ibat[3].lo = get_spr(PPC_SPR_IBAT3L); state->u.ppc600.ibat[3].up = get_spr(PPC_SPR_IBAT3U); if(SYSPAGE_ENTRY(cpuinfo)->flags & PPC_CPU_EXTRA_BAT) { state->u.ppc600.dbat[4].lo = get_spr(PPC_SPR_DBAT4L); state->u.ppc600.dbat[4].up = get_spr(PPC_SPR_DBAT4U); state->u.ppc600.dbat[5].lo = get_spr(PPC_SPR_DBAT5L); state->u.ppc600.dbat[5].up = get_spr(PPC_SPR_DBAT5U); state->u.ppc600.dbat[6].lo = get_spr(PPC_SPR_DBAT6L); state->u.ppc600.dbat[6].up = get_spr(PPC_SPR_DBAT6U); state->u.ppc600.dbat[7].lo = get_spr(PPC_SPR_DBAT7L); state->u.ppc600.dbat[7].up = get_spr(PPC_SPR_DBAT7U); state->u.ppc600.ibat[4].lo = get_spr(PPC_SPR_IBAT4L); state->u.ppc600.ibat[4].up = get_spr(PPC_SPR_IBAT4U); state->u.ppc600.ibat[5].lo = get_spr(PPC_SPR_IBAT5L); state->u.ppc600.ibat[5].up = get_spr(PPC_SPR_IBAT5U); state->u.ppc600.ibat[6].lo = get_spr(PPC_SPR_IBAT6L); state->u.ppc600.ibat[6].up = get_spr(PPC_SPR_IBAT6U); state->u.ppc600.ibat[7].lo = get_spr(PPC_SPR_IBAT7L); state->u.ppc600.ibat[7].up = get_spr(PPC_SPR_IBAT7U); } state->u.ppc600.srr0 = get_spr(PPC_SPR_SRR0); state->u.ppc600.srr1 = get_spr(PPC_SPR_SRR1); for (i = 0; i < 16; i++) { state->u.ppc600.sr[i] = get_sreg(i << 28); } state->u.ppc600.sprg0 = get_spr(PPC_SPR_SPRG0); state->u.ppc600.sprg1 = get_spr(PPC_SPR_SPRG1); state->u.ppc600.sprg2 = get_spr(PPC_SPR_SPRG2); state->u.ppc600.sprg3 = get_spr(PPC_SPR_SPRG3); break; case PPC_FAMILY_900: state->u.ppc900.hid[0] = get_spr64(PPC603_SPR_HID0); state->u.ppc900.hid[1] = get_spr64(PPC603_SPR_HID1); state->u.ppc900.dsisr = get_spr64(PPC_SPR_DSISR); state->u.ppc900.dar = get_spr64(PPC_SPR_DAR); state->u.ppc900.sdr1 = get_spr64(PPC_SPR_SDR1); //PA6T doesn't seem to have ACCR, but AMR uses same SPR number? // state->u.ppc900.accr = get_spr64(PPC_SPR_ACCR); //PA6T hangs up on read of CTRL register // state->u.ppc900.ctrl = get_spr64(PPC_SPR_CTRL); state->u.ppc900.asr = get_spr64(PPC_SPR_ASR); state->u.ppc900.pir = get_spr64(PPC700_SPR_PIR); for(i = 0; i < 16; ++i) { ppc_slbmfev(state->u.ppc900.slb[i].v, i); ppc_slbmfee(state->u.ppc900.slb[i].e, i); } break; case PPC_FAMILY_800: // nothing to do (for now) break; case PPC_FAMILY_booke: state->u.ppcbke.spr.dbcr0 = get_spr(PPCBKE_SPR_DBCR0); state->u.ppcbke.spr.dbcr1 = get_spr(PPCBKE_SPR_DBCR1); state->u.ppcbke.spr.dbcr2 = get_spr(PPCBKE_SPR_DBCR2); state->u.ppcbke.spr.dbsr = get_spr(PPCBKE_SPR_DBSR); state->u.ppcbke.spr.dear = get_spr(PPCBKE_SPR_DEAR); state->u.ppcbke.spr.esr = get_spr(PPCBKE_SPR_ESR); state->u.ppcbke.spr.ivpr = get_spr(PPCBKE_SPR_IVPR); state->u.ppcbke.spr.ivor[0] = get_spr(PPCBKE_SPR_IVOR0); state->u.ppcbke.spr.ivor[1] = get_spr(PPCBKE_SPR_IVOR1); state->u.ppcbke.spr.ivor[2] = get_spr(PPCBKE_SPR_IVOR2); state->u.ppcbke.spr.ivor[3] = get_spr(PPCBKE_SPR_IVOR3); state->u.ppcbke.spr.ivor[4] = get_spr(PPCBKE_SPR_IVOR4); state->u.ppcbke.spr.ivor[5] = get_spr(PPCBKE_SPR_IVOR5); state->u.ppcbke.spr.ivor[6] = get_spr(PPCBKE_SPR_IVOR6); state->u.ppcbke.spr.ivor[7] = get_spr(PPCBKE_SPR_IVOR7); state->u.ppcbke.spr.ivor[8] = get_spr(PPCBKE_SPR_IVOR8); state->u.ppcbke.spr.ivor[9] = get_spr(PPCBKE_SPR_IVOR9); state->u.ppcbke.spr.ivor[10] = get_spr(PPCBKE_SPR_IVOR10); state->u.ppcbke.spr.ivor[11] = get_spr(PPCBKE_SPR_IVOR11); state->u.ppcbke.spr.ivor[12] = get_spr(PPCBKE_SPR_IVOR12); state->u.ppcbke.spr.ivor[13] = get_spr(PPCBKE_SPR_IVOR13); state->u.ppcbke.spr.ivor[14] = get_spr(PPCBKE_SPR_IVOR14); state->u.ppcbke.spr.ivor[15] = get_spr(PPCBKE_SPR_IVOR15); state->u.ppcbke.spr.pid = get_spr(PPCBKE_SPR_PID); state->u.ppcbke.spr.pir = get_spr(PPCBKE_SPR_PIR); state->u.ppcbke.spr.sprg4 = get_spr(PPCBKE_SPR_SPRG4RO); state->u.ppcbke.spr.sprg5 = get_spr(PPCBKE_SPR_SPRG5RO); state->u.ppcbke.spr.sprg6 = get_spr(PPCBKE_SPR_SPRG6RO); state->u.ppcbke.spr.sprg7 = get_spr(PPCBKE_SPR_SPRG7RO); state->u.ppcbke.spr.tcr = get_spr(PPCBKE_SPR_TCR); state->u.ppcbke.spr.tsr = get_spr(PPCBKE_SPR_TSR); i = 0; for(;;) { num_entries = state->u.ppcbke.tlb[i].num_entries; if(num_entries == 0) break; for(j = 0; j < num_entries; ++j) { bke_tlb_read(i, j, &state->u.ppcbke.tlb[i].entry[j]); } ++i; } break; } extra_chip_save(state); }
static uint32 fls_GetPc(void) { return get_spr(SPR_LR); }