1/* 2 * This file contains low level CPU setup functions. 3 * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org) 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 8 * 2 of the License, or (at your option) any later version. 9 * 10 */ 11 12#include <asm/processor.h> 13#include <asm/page.h> 14#include <asm/cputable.h> 15#include <asm/ppc_asm.h> 16#include <asm/asm-offsets.h> 17#include <asm/cache.h> 18 19/* Entry: r3 = crap, r4 = ptr to cputable entry 20 * 21 * Note that we can be called twice for pseudo-PVRs 22 */ 23_GLOBAL(__setup_cpu_power7) 24 mflr r11 25 bl __init_hvmode_206 26 mtlr r11 27 beqlr 28 li r0,0 29 mtspr SPRN_LPID,r0 30 mfspr r3,SPRN_LPCR 31 bl __init_LPCR 32 bl __init_tlb_power7 33 mtlr r11 34 blr 35 36_GLOBAL(__restore_cpu_power7) 37 mflr r11 38 mfmsr r3 39 rldicl. r0,r3,4,63 40 beqlr 41 li r0,0 42 mtspr SPRN_LPID,r0 43 mfspr r3,SPRN_LPCR 44 bl __init_LPCR 45 bl __init_tlb_power7 46 mtlr r11 47 blr 48 49_GLOBAL(__setup_cpu_power8) 50 mflr r11 51 bl __init_FSCR 52 bl __init_PMU 53 bl __init_hvmode_206 54 mtlr r11 55 beqlr 56 li r0,0 57 mtspr SPRN_LPID,r0 58 mfspr r3,SPRN_LPCR 59 ori r3, r3, LPCR_PECEDH 60 bl __init_LPCR 61 bl __init_HFSCR 62 bl __init_tlb_power8 63 bl __init_PMU_HV 64 mtlr r11 65 blr 66 67_GLOBAL(__restore_cpu_power8) 68 mflr r11 69 bl __init_FSCR 70 bl __init_PMU 71 mfmsr r3 72 rldicl. r0,r3,4,63 73 mtlr r11 74 beqlr 75 li r0,0 76 mtspr SPRN_LPID,r0 77 mfspr r3,SPRN_LPCR 78 ori r3, r3, LPCR_PECEDH 79 bl __init_LPCR 80 bl __init_HFSCR 81 bl __init_tlb_power8 82 bl __init_PMU_HV 83 mtlr r11 84 blr 85 86__init_hvmode_206: 87 /* Disable CPU_FTR_HVMODE and exit if MSR:HV is not set */ 88 mfmsr r3 89 rldicl. r0,r3,4,63 90 bnelr 91 ld r5,CPU_SPEC_FEATURES(r4) 92 LOAD_REG_IMMEDIATE(r6,CPU_FTR_HVMODE) 93 xor r5,r5,r6 94 std r5,CPU_SPEC_FEATURES(r4) 95 blr 96 97__init_LPCR: 98 /* Setup a sane LPCR: 99 * Called with initial LPCR in R3 100 * 101 * LPES = 0b01 (HSRR0/1 used for 0x500) 102 * PECE = 0b111 103 * DPFD = 4 104 * HDICE = 0 105 * VC = 0b100 (VPM0=1, VPM1=0, ISL=0) 106 * VRMASD = 0b10000 (L=1, LP=00) 107 * 108 * Other bits untouched for now 109 */ 110 li r5,1 111 rldimi r3,r5, LPCR_LPES_SH, 64-LPCR_LPES_SH-2 112 ori r3,r3,(LPCR_PECE0|LPCR_PECE1|LPCR_PECE2) 113 li r5,4 114 rldimi r3,r5, LPCR_DPFD_SH, 64-LPCR_DPFD_SH-3 115 clrrdi r3,r3,1 /* clear HDICE */ 116 li r5,4 117 rldimi r3,r5, LPCR_VC_SH, 0 118 li r5,0x10 119 rldimi r3,r5, LPCR_VRMASD_SH, 64-LPCR_VRMASD_SH-5 120 mtspr SPRN_LPCR,r3 121 isync 122 blr 123 124__init_FSCR: 125 mfspr r3,SPRN_FSCR 126 ori r3,r3,FSCR_TAR|FSCR_DSCR|FSCR_EBB 127 mtspr SPRN_FSCR,r3 128 blr 129 130__init_HFSCR: 131 mfspr r3,SPRN_HFSCR 132 ori r3,r3,HFSCR_TAR|HFSCR_TM|HFSCR_BHRB|HFSCR_PM|\ 133 HFSCR_DSCR|HFSCR_VECVSX|HFSCR_FP|HFSCR_EBB 134 mtspr SPRN_HFSCR,r3 135 blr 136 137/* 138 * Clear the TLB using the specified IS form of tlbiel instruction 139 * (invalidate by congruence class). P7 has 128 CCs., P8 has 512. 140 */ 141__init_tlb_power7: 142 li r6,128 143 mtctr r6 144 li r7,0xc00 /* IS field = 0b11 */ 145 ptesync 1462: tlbiel r7 147 addi r7,r7,0x1000 148 bdnz 2b 149 ptesync 1501: blr 151 152__init_tlb_power8: 153 li r6,512 154 mtctr r6 155 li r7,0xc00 /* IS field = 0b11 */ 156 ptesync 1572: tlbiel r7 158 addi r7,r7,0x1000 159 bdnz 2b 160 ptesync 1611: blr 162 163__init_PMU_HV: 164 li r5,0 165 mtspr SPRN_MMCRC,r5 166 mtspr SPRN_MMCRH,r5 167 blr 168 169__init_PMU: 170 li r5,0 171 mtspr SPRN_MMCRS,r5 172 mtspr SPRN_MMCRA,r5 173 mtspr SPRN_MMCR0,r5 174 mtspr SPRN_MMCR1,r5 175 mtspr SPRN_MMCR2,r5 176 blr 177