| 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */
|
| 2 | /*
|
| 3 | * This file contains low level CPU setup functions.
|
| 4 | * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org)
|
| 5 | */
|
| 6 |
|
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 |
|
| 14 | _GLOBAL(__cpu_preinit_ppc970)
|
| 15 | /* Do nothing if not running in HV mode */
|
| 16 | mfmsr r0
|
| 17 | rldicl. r0,r0,4,63
|
| 18 | beqlr
|
| 19 |
|
| 20 | /* Make sure HID4:rm_ci is off before MMU is turned off, that large
|
| 21 | * pages are enabled with HID4:61 and clear HID5:DCBZ_size and
|
| 22 | * HID5:DCBZ32_ill
|
| 23 | */
|
| 24 | li r0,0
|
| 25 | mfspr r3,SPRN_HID4
|
| 26 | rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */
|
| 27 | rldimi r3,r0,2,61 /* clear bit 61 (lg_pg_en) */
|
| 28 | sync
|
| 29 | mtspr SPRN_HID4,r3
|
| 30 | isync
|
| 31 | sync
|
| 32 | mfspr r3,SPRN_HID5
|
| 33 | rldimi r3,r0,6,56 /* clear bits 56 & 57 (DCBZ*) */
|
| 34 | sync
|
| 35 | mtspr SPRN_HID5,r3
|
| 36 | isync
|
| 37 | sync
|
| 38 |
|
| 39 | /* Setup some basic HID1 features */
|
| 40 | mfspr r0,SPRN_HID1
|
| 41 | li r3,0x1200 /* enable i-fetch cacheability */
|
| 42 | sldi r3,r3,44 /* and prefetch */
|
| 43 | or r0,r0,r3
|
| 44 | mtspr SPRN_HID1,r0
|
| 45 | mtspr SPRN_HID1,r0
|
| 46 | isync
|
| 47 |
|
| 48 | /* Clear HIOR */
|
| 49 | li r0,0
|
| 50 | sync
|
| 51 | mtspr SPRN_HIOR,0 /* Clear interrupt prefix */
|
| 52 | isync
|
| 53 | blr
|
| 54 |
|
| 55 | /* Definitions for the table use to save CPU states */
|
| 56 | |
| 57 | |
| 58 | |
| 59 | |
| 60 | |
| 61 |
|
| 62 | .data
|
| 63 | .balign L1_CACHE_BYTES,0
|
| 64 | cpu_state_storage:
|
| 65 | .space CS_SIZE
|
| 66 | .balign L1_CACHE_BYTES,0
|
| 67 | .text
|
| 68 |
|
| 69 |
|
| 70 | _GLOBAL(__setup_cpu_ppc970)
|
| 71 | /* Do nothing if not running in HV mode */
|
| 72 | mfmsr r0
|
| 73 | rldicl. r0,r0,4,63
|
| 74 | beq no_hv_mode
|
| 75 |
|
| 76 | mfspr r0,SPRN_HID0
|
| 77 | li r11,5 /* clear DOZE and SLEEP */
|
| 78 | rldimi r0,r11,52,8 /* set NAP and DPM */
|
| 79 | li r11,0
|
| 80 | rldimi r0,r11,32,31 /* clear EN_ATTN */
|
| 81 | b load_hids /* Jump to shared code */
|
| 82 |
|
| 83 |
|
| 84 | _GLOBAL(__setup_cpu_ppc970MP)
|
| 85 | /* Do nothing if not running in HV mode */
|
| 86 | mfmsr r0
|
| 87 | rldicl. r0,r0,4,63
|
| 88 | beq no_hv_mode
|
| 89 |
|
| 90 | mfspr r0,SPRN_HID0
|
| 91 | li r11,0x15 /* clear DOZE and SLEEP */
|
| 92 | rldimi r0,r11,52,6 /* set DEEPNAP, NAP and DPM */
|
| 93 | li r11,0
|
| 94 | rldimi r0,r11,32,31 /* clear EN_ATTN */
|
| 95 |
|
| 96 | load_hids:
|
| 97 | mtspr SPRN_HID0,r0
|
| 98 | mfspr r0,SPRN_HID0
|
| 99 | mfspr r0,SPRN_HID0
|
| 100 | mfspr r0,SPRN_HID0
|
| 101 | mfspr r0,SPRN_HID0
|
| 102 | mfspr r0,SPRN_HID0
|
| 103 | mfspr r0,SPRN_HID0
|
| 104 | sync
|
| 105 | isync
|
| 106 |
|
| 107 | /* Try to set LPES = 01 in HID4 */
|
| 108 | mfspr r0,SPRN_HID4
|
| 109 | clrldi r0,r0,1 /* clear LPES0 */
|
| 110 | ori r0,r0,HID4_LPES1 /* set LPES1 */
|
| 111 | sync
|
| 112 | mtspr SPRN_HID4,r0
|
| 113 | isync
|
| 114 |
|
| 115 | /* Save away cpu state */
|
| 116 | LOAD_REG_ADDR(r5,cpu_state_storage)
|
| 117 |
|
| 118 | /* Save HID0,1,4 and 5 */
|
| 119 | mfspr r3,SPRN_HID0
|
| 120 | std r3,CS_HID0(r5)
|
| 121 | mfspr r3,SPRN_HID1
|
| 122 | std r3,CS_HID1(r5)
|
| 123 | mfspr r4,SPRN_HID4
|
| 124 | std r4,CS_HID4(r5)
|
| 125 | mfspr r3,SPRN_HID5
|
| 126 | std r3,CS_HID5(r5)
|
| 127 |
|
| 128 | /* See if we successfully set LPES1 to 1; if not we are in Apple mode */
|
| 129 | andi. r4,r4,HID4_LPES1
|
| 130 | bnelr
|
| 131 |
|
| 132 | no_hv_mode:
|
| 133 | /* Disable CPU_FTR_HVMODE and exit, since we don't have HV mode */
|
| 134 | ld r5,CPU_SPEC_FEATURES(r4)
|
| 135 | LOAD_REG_IMMEDIATE(r6,CPU_FTR_HVMODE)
|
| 136 | andc r5,r5,r6
|
| 137 | std r5,CPU_SPEC_FEATURES(r4)
|
| 138 | blr
|
| 139 |
|
| 140 | /* Called with no MMU context (typically MSR:IR/DR off) to
|
| 141 | * restore CPU state as backed up by the previous
|
| 142 | * function. This does not include cache setting
|
| 143 | */
|
| 144 | _GLOBAL(__restore_cpu_ppc970)
|
| 145 | /* Do nothing if not running in HV mode */
|
| 146 | mfmsr r0
|
| 147 | rldicl. r0,r0,4,63
|
| 148 | beqlr
|
| 149 |
|
| 150 | LOAD_REG_ADDR(r5,cpu_state_storage)
|
| 151 | /* Before accessing memory, we make sure rm_ci is clear */
|
| 152 | li r0,0
|
| 153 | mfspr r3,SPRN_HID4
|
| 154 | rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */
|
| 155 | sync
|
| 156 | mtspr SPRN_HID4,r3
|
| 157 | isync
|
| 158 | sync
|
| 159 |
|
| 160 | /* Clear interrupt prefix */
|
| 161 | li r0,0
|
| 162 | sync
|
| 163 | mtspr SPRN_HIOR,0
|
| 164 | isync
|
| 165 |
|
| 166 | /* Restore HID0 */
|
| 167 | ld r3,CS_HID0(r5)
|
| 168 | sync
|
| 169 | isync
|
| 170 | mtspr SPRN_HID0,r3
|
| 171 | mfspr r3,SPRN_HID0
|
| 172 | mfspr r3,SPRN_HID0
|
| 173 | mfspr r3,SPRN_HID0
|
| 174 | mfspr r3,SPRN_HID0
|
| 175 | mfspr r3,SPRN_HID0
|
| 176 | mfspr r3,SPRN_HID0
|
| 177 | sync
|
| 178 | isync
|
| 179 |
|
| 180 | /* Restore HID1 */
|
| 181 | ld r3,CS_HID1(r5)
|
| 182 | sync
|
| 183 | isync
|
| 184 | mtspr SPRN_HID1,r3
|
| 185 | mtspr SPRN_HID1,r3
|
| 186 | sync
|
| 187 | isync
|
| 188 |
|
| 189 | /* Restore HID4 */
|
| 190 | ld r3,CS_HID4(r5)
|
| 191 | sync
|
| 192 | isync
|
| 193 | mtspr SPRN_HID4,r3
|
| 194 | sync
|
| 195 | isync
|
| 196 |
|
| 197 | /* Restore HID5 */
|
| 198 | ld r3,CS_HID5(r5)
|
| 199 | sync
|
| 200 | isync
|
| 201 | mtspr SPRN_HID5,r3
|
| 202 | sync
|
| 203 | isync
|
| 204 | blr
|
| 205 |
|