diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2015-01-21 02:57:54 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2015-01-21 02:57:54 +0000 |
commit | 301885260edcb68943c33844bd5d522ef7caaf2f (patch) | |
tree | f4ed4c8d193c1aa8884acca96bb1f8488bb30979 /sys | |
parent | b4fa4f6baa40f0815a0bad3475903e47fee4b076 (diff) | |
download | FreeBSD-src-301885260edcb68943c33844bd5d522ef7caaf2f.zip FreeBSD-src-301885260edcb68943c33844bd5d522ef7caaf2f.tar.gz |
On 64-bit PowerPC, use more native forms of the PPC 970 HID restore
sequences, like are used to read the HIDs. This is both easier to read
and avoids a miscompilation by GCC in certain circumstances. Also avoid
double restoration of HID4 and HID5.
MFC after: 2 weeks
Diffstat (limited to 'sys')
-rw-r--r-- | sys/powerpc/aim/mp_cpudep.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/sys/powerpc/aim/mp_cpudep.c b/sys/powerpc/aim/mp_cpudep.c index 3bc21a4..59a24e2 100644 --- a/sys/powerpc/aim/mp_cpudep.c +++ b/sys/powerpc/aim/mp_cpudep.c @@ -58,7 +58,9 @@ SYSINIT(cpu_save_config, SI_SUB_CPU, SI_ORDER_ANY, cpudep_save_config, NULL); void cpudep_ap_early_bootstrap(void) { +#ifndef __powerpc64__ register_t reg; +#endif __asm __volatile("mtsprg 0, %0" :: "r"(ap_pcpu)); powerpc_sync(); @@ -69,12 +71,17 @@ cpudep_ap_early_bootstrap(void) case IBM970MP: /* Restore HID4 and HID5, which are necessary for the MMU */ +#ifdef __powerpc64__ + mtspr(SPR_HID4, bsp_state[2]); powerpc_sync(); isync(); + mtspr(SPR_HID5, bsp_state[3]); powerpc_sync(); isync(); +#else __asm __volatile("ld %0, 16(%2); sync; isync; \ mtspr %1, %0; sync; isync;" : "=r"(reg) : "K"(SPR_HID4), "r"(bsp_state)); __asm __volatile("ld %0, 24(%2); sync; isync; \ mtspr %1, %0; sync; isync;" : "=r"(reg) : "K"(SPR_HID5), "r"(bsp_state)); +#endif powerpc_sync(); break; } @@ -292,9 +299,24 @@ cpudep_ap_setup() /* * The 970 has strange rules about how to update HID registers. * See Table 2-3, 970MP manual + * + * Note: HID4 and HID5 restored already in + * cpudep_ap_early_bootstrap() */ __asm __volatile("mtasr %0; sync" :: "r"(0)); + #ifdef __powerpc64__ + __asm __volatile(" \ + sync; isync; \ + mtspr %1, %0; \ + mfspr %0, %1; mfspr %0, %1; mfspr %0, %1; \ + mfspr %0, %1; mfspr %0, %1; mfspr %0, %1; \ + sync; isync" + :: "r"(bsp_state[0]), "K"(SPR_HID0)); + __asm __volatile("sync; isync; \ + mtspr %1, %0; mtspr %1, %0; sync; isync" + :: "r"(bsp_state[1]), "K"(SPR_HID1)); + #else __asm __volatile(" \ ld %0,0(%2); \ sync; isync; \ @@ -306,12 +328,7 @@ cpudep_ap_setup() __asm __volatile("ld %0, 8(%2); sync; isync; \ mtspr %1, %0; mtspr %1, %0; sync; isync" : "=r"(reg) : "K"(SPR_HID1), "r"(bsp_state)); - __asm __volatile("ld %0, 16(%2); sync; isync; \ - mtspr %1, %0; sync; isync;" - : "=r"(reg) : "K"(SPR_HID4), "r"(bsp_state)); - __asm __volatile("ld %0, 24(%2); sync; isync; \ - mtspr %1, %0; sync; isync;" - : "=r"(reg) : "K"(SPR_HID5), "r"(bsp_state)); + #endif powerpc_sync(); break; |