1 /* SPDX-License-Identifier: GPL-2.0 */ 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* head.S: Initial boot code for the Sparc64 p 2 /* head.S: Initial boot code for the Sparc64 port of Linux. 3 * 3 * 4 * Copyright (C) 1996, 1997, 2007 David S. Mil 4 * Copyright (C) 1996, 1997, 2007 David S. Miller (davem@davemloft.net) 5 * Copyright (C) 1996 David Sitsky (David.Sits 5 * Copyright (C) 1996 David Sitsky (David.Sitsky@anu.edu.au) 6 * Copyright (C) 1997, 1998 Jakub Jelinek (jj@ 6 * Copyright (C) 1997, 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 7 * Copyright (C) 1997 Miguel de Icaza (miguel@ 7 * Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx) 8 */ 8 */ 9 9 10 #include <linux/version.h> 10 #include <linux/version.h> 11 #include <linux/errno.h> 11 #include <linux/errno.h> 12 #include <linux/export.h> 12 #include <linux/export.h> 13 #include <linux/threads.h> 13 #include <linux/threads.h> 14 #include <linux/init.h> 14 #include <linux/init.h> 15 #include <linux/linkage.h> 15 #include <linux/linkage.h> 16 #include <linux/pgtable.h> 16 #include <linux/pgtable.h> 17 #include <asm/thread_info.h> 17 #include <asm/thread_info.h> 18 #include <asm/asi.h> 18 #include <asm/asi.h> 19 #include <asm/pstate.h> 19 #include <asm/pstate.h> 20 #include <asm/ptrace.h> 20 #include <asm/ptrace.h> 21 #include <asm/spitfire.h> 21 #include <asm/spitfire.h> 22 #include <asm/page.h> 22 #include <asm/page.h> 23 #include <asm/errno.h> 23 #include <asm/errno.h> 24 #include <asm/signal.h> 24 #include <asm/signal.h> 25 #include <asm/processor.h> 25 #include <asm/processor.h> 26 #include <asm/lsu.h> 26 #include <asm/lsu.h> 27 #include <asm/dcr.h> 27 #include <asm/dcr.h> 28 #include <asm/dcu.h> 28 #include <asm/dcu.h> 29 #include <asm/head.h> 29 #include <asm/head.h> 30 #include <asm/ttable.h> 30 #include <asm/ttable.h> 31 #include <asm/mmu.h> 31 #include <asm/mmu.h> 32 #include <asm/cpudata.h> 32 #include <asm/cpudata.h> 33 #include <asm/pil.h> 33 #include <asm/pil.h> 34 #include <asm/estate.h> 34 #include <asm/estate.h> 35 #include <asm/sfafsr.h> 35 #include <asm/sfafsr.h> 36 #include <asm/unistd.h> 36 #include <asm/unistd.h> 37 37 38 /* This section from from _start to sparc64_bo 38 /* This section from from _start to sparc64_boot_end should fit into 39 * 0x0000000000404000 to 0x0000000000408000. 39 * 0x0000000000404000 to 0x0000000000408000. 40 */ 40 */ 41 .text 41 .text 42 .globl start, _start, stext, _stext 42 .globl start, _start, stext, _stext 43 _start: 43 _start: 44 start: 44 start: 45 _stext: 45 _stext: 46 stext: 46 stext: 47 ! 0x0000000000404000 47 ! 0x0000000000404000 48 b sparc64_boot 48 b sparc64_boot 49 flushw 49 flushw /* Flush register file. */ 50 50 51 /* This stuff has to be in sync with SILO and 51 /* This stuff has to be in sync with SILO and other potential boot loaders 52 * Fields should be kept upward compatible and 52 * Fields should be kept upward compatible and whenever any change is made, 53 * HdrS version should be incremented. 53 * HdrS version should be incremented. 54 */ 54 */ 55 .global root_flags, ram_flags, root_de 55 .global root_flags, ram_flags, root_dev 56 .global sparc_ramdisk_image, sparc_ram 56 .global sparc_ramdisk_image, sparc_ramdisk_size 57 .global sparc_ramdisk_image64 57 .global sparc_ramdisk_image64 58 58 59 .ascii "HdrS" 59 .ascii "HdrS" 60 .word LINUX_VERSION_CODE 60 .word LINUX_VERSION_CODE 61 61 62 /* History: 62 /* History: 63 * 63 * 64 * 0x0300 : Supports being located at 64 * 0x0300 : Supports being located at other than 0x4000 65 * 0x0202 : Supports kernel params str 65 * 0x0202 : Supports kernel params string 66 * 0x0201 : Supports reboot_command 66 * 0x0201 : Supports reboot_command 67 */ 67 */ 68 .half 0x0301 /* HdrS versio 68 .half 0x0301 /* HdrS version */ 69 69 70 root_flags: 70 root_flags: 71 .half 1 71 .half 1 72 root_dev: 72 root_dev: 73 .half 0 73 .half 0 74 ram_flags: 74 ram_flags: 75 .half 0 75 .half 0 76 sparc_ramdisk_image: 76 sparc_ramdisk_image: 77 .word 0 77 .word 0 78 sparc_ramdisk_size: 78 sparc_ramdisk_size: 79 .word 0 79 .word 0 80 .xword reboot_command 80 .xword reboot_command 81 .xword bootstr_info 81 .xword bootstr_info 82 sparc_ramdisk_image64: 82 sparc_ramdisk_image64: 83 .xword 0 83 .xword 0 84 .word _end 84 .word _end 85 85 86 /* PROM cif handler code address is in 86 /* PROM cif handler code address is in %o4. */ 87 sparc64_boot: 87 sparc64_boot: 88 mov %o4, %l7 88 mov %o4, %l7 89 89 90 /* We need to remap the kernel. Use p 90 /* We need to remap the kernel. Use position independent 91 * code to remap us to KERNBASE. 91 * code to remap us to KERNBASE. 92 * 92 * 93 * SILO can invoke us with 32-bit addr 93 * SILO can invoke us with 32-bit address masking enabled, 94 * so make sure that's clear. 94 * so make sure that's clear. 95 */ 95 */ 96 rdpr %pstate, %g1 96 rdpr %pstate, %g1 97 andn %g1, PSTATE_AM, %g1 97 andn %g1, PSTATE_AM, %g1 98 wrpr %g1, 0x0, %pstate 98 wrpr %g1, 0x0, %pstate 99 ba,a,pt %xcc, 1f 99 ba,a,pt %xcc, 1f 100 nop 100 nop 101 101 102 .globl prom_finddev_name, prom_chosen 102 .globl prom_finddev_name, prom_chosen_path, prom_root_node 103 .globl prom_getprop_name, prom_mmu_na 103 .globl prom_getprop_name, prom_mmu_name, prom_peer_name 104 .globl prom_callmethod_name, prom_tra 104 .globl prom_callmethod_name, prom_translate_name, prom_root_compatible 105 .globl prom_map_name, prom_unmap_name 105 .globl prom_map_name, prom_unmap_name, prom_mmu_ihandle_cache 106 .globl prom_boot_mapped_pc, prom_boot 106 .globl prom_boot_mapped_pc, prom_boot_mapping_mode 107 .globl prom_boot_mapping_phys_high, p 107 .globl prom_boot_mapping_phys_high, prom_boot_mapping_phys_low 108 .globl prom_compatible_name, prom_cpu 108 .globl prom_compatible_name, prom_cpu_path, prom_cpu_compatible 109 .globl is_sun4v, sun4v_chip_type, pro 109 .globl is_sun4v, sun4v_chip_type, prom_set_trap_table_name 110 prom_peer_name: 110 prom_peer_name: 111 .asciz "peer" 111 .asciz "peer" 112 prom_compatible_name: 112 prom_compatible_name: 113 .asciz "compatible" 113 .asciz "compatible" 114 prom_finddev_name: 114 prom_finddev_name: 115 .asciz "finddevice" 115 .asciz "finddevice" 116 prom_chosen_path: 116 prom_chosen_path: 117 .asciz "/chosen" 117 .asciz "/chosen" 118 prom_cpu_path: 118 prom_cpu_path: 119 .asciz "/cpu" 119 .asciz "/cpu" 120 prom_getprop_name: 120 prom_getprop_name: 121 .asciz "getprop" 121 .asciz "getprop" 122 prom_mmu_name: 122 prom_mmu_name: 123 .asciz "mmu" 123 .asciz "mmu" 124 prom_callmethod_name: 124 prom_callmethod_name: 125 .asciz "call-method" 125 .asciz "call-method" 126 prom_translate_name: 126 prom_translate_name: 127 .asciz "translate" 127 .asciz "translate" 128 prom_map_name: 128 prom_map_name: 129 .asciz "map" 129 .asciz "map" 130 prom_unmap_name: 130 prom_unmap_name: 131 .asciz "unmap" 131 .asciz "unmap" 132 prom_set_trap_table_name: 132 prom_set_trap_table_name: 133 .asciz "SUNW,set-trap-table" 133 .asciz "SUNW,set-trap-table" 134 prom_sun4v_name: 134 prom_sun4v_name: 135 .asciz "sun4v" 135 .asciz "sun4v" 136 prom_niagara_prefix: 136 prom_niagara_prefix: 137 .asciz "SUNW,UltraSPARC-T" 137 .asciz "SUNW,UltraSPARC-T" 138 prom_sparc_prefix: 138 prom_sparc_prefix: 139 .asciz "SPARC-" 139 .asciz "SPARC-" 140 prom_sparc64x_prefix: 140 prom_sparc64x_prefix: 141 .asciz "SPARC64-X" 141 .asciz "SPARC64-X" 142 .align 4 142 .align 4 143 prom_root_compatible: 143 prom_root_compatible: 144 .skip 64 144 .skip 64 145 prom_cpu_compatible: 145 prom_cpu_compatible: 146 .skip 64 146 .skip 64 147 prom_root_node: 147 prom_root_node: 148 .word 0 148 .word 0 149 EXPORT_SYMBOL(prom_root_node) 149 EXPORT_SYMBOL(prom_root_node) 150 prom_mmu_ihandle_cache: 150 prom_mmu_ihandle_cache: 151 .word 0 151 .word 0 152 prom_boot_mapped_pc: 152 prom_boot_mapped_pc: 153 .word 0 153 .word 0 154 prom_boot_mapping_mode: 154 prom_boot_mapping_mode: 155 .word 0 155 .word 0 156 .align 8 156 .align 8 157 prom_boot_mapping_phys_high: 157 prom_boot_mapping_phys_high: 158 .xword 0 158 .xword 0 159 prom_boot_mapping_phys_low: 159 prom_boot_mapping_phys_low: 160 .xword 0 160 .xword 0 161 is_sun4v: 161 is_sun4v: 162 .word 0 162 .word 0 163 sun4v_chip_type: 163 sun4v_chip_type: 164 .word SUN4V_CHIP_INVALID 164 .word SUN4V_CHIP_INVALID 165 EXPORT_SYMBOL(sun4v_chip_type) 165 EXPORT_SYMBOL(sun4v_chip_type) 166 1: 166 1: 167 rd %pc, %l0 167 rd %pc, %l0 168 168 169 mov (1b - prom_peer_name), %l1 169 mov (1b - prom_peer_name), %l1 170 sub %l0, %l1, %l1 170 sub %l0, %l1, %l1 171 mov 0, %l2 171 mov 0, %l2 172 172 173 /* prom_root_node = prom_peer(0) */ 173 /* prom_root_node = prom_peer(0) */ 174 stx %l1, [%sp + 2047 + 128 + 0x00] 174 stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "peer" 175 mov 1, %l3 175 mov 1, %l3 176 stx %l3, [%sp + 2047 + 128 + 0x08] 176 stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 1 177 stx %l3, [%sp + 2047 + 128 + 0x10] 177 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 178 stx %l2, [%sp + 2047 + 128 + 0x18] 178 stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1, 0 179 stx %g0, [%sp + 2047 + 128 + 0x20] 179 stx %g0, [%sp + 2047 + 128 + 0x20] ! ret1 180 call %l7 180 call %l7 181 add %sp, (2047 + 128), %o0 181 add %sp, (2047 + 128), %o0 ! argument array 182 182 183 ldx [%sp + 2047 + 128 + 0x20], %l4 183 ldx [%sp + 2047 + 128 + 0x20], %l4 ! prom root node 184 mov (1b - prom_root_node), %l1 184 mov (1b - prom_root_node), %l1 185 sub %l0, %l1, %l1 185 sub %l0, %l1, %l1 186 stw %l4, [%l1] 186 stw %l4, [%l1] 187 187 188 mov (1b - prom_getprop_name), %l1 188 mov (1b - prom_getprop_name), %l1 189 mov (1b - prom_compatible_name), % 189 mov (1b - prom_compatible_name), %l2 190 mov (1b - prom_root_compatible), % 190 mov (1b - prom_root_compatible), %l5 191 sub %l0, %l1, %l1 191 sub %l0, %l1, %l1 192 sub %l0, %l2, %l2 192 sub %l0, %l2, %l2 193 sub %l0, %l5, %l5 193 sub %l0, %l5, %l5 194 194 195 /* prom_getproperty(prom_root_node, "c 195 /* prom_getproperty(prom_root_node, "compatible", 196 * &prom_root_compati 196 * &prom_root_compatible, 64) 197 */ 197 */ 198 stx %l1, [%sp + 2047 + 128 + 0x00] 198 stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "getprop" 199 mov 4, %l3 199 mov 4, %l3 200 stx %l3, [%sp + 2047 + 128 + 0x08] 200 stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 4 201 mov 1, %l3 201 mov 1, %l3 202 stx %l3, [%sp + 2047 + 128 + 0x10] 202 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 203 stx %l4, [%sp + 2047 + 128 + 0x18] 203 stx %l4, [%sp + 2047 + 128 + 0x18] ! arg1, prom_root_node 204 stx %l2, [%sp + 2047 + 128 + 0x20] 204 stx %l2, [%sp + 2047 + 128 + 0x20] ! arg2, "compatible" 205 stx %l5, [%sp + 2047 + 128 + 0x28] 205 stx %l5, [%sp + 2047 + 128 + 0x28] ! arg3, &prom_root_compatible 206 mov 64, %l3 206 mov 64, %l3 207 stx %l3, [%sp + 2047 + 128 + 0x30] 207 stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4, size 208 stx %g0, [%sp + 2047 + 128 + 0x38] 208 stx %g0, [%sp + 2047 + 128 + 0x38] ! ret1 209 call %l7 209 call %l7 210 add %sp, (2047 + 128), %o0 210 add %sp, (2047 + 128), %o0 ! argument array 211 211 212 mov (1b - prom_finddev_name), %l1 212 mov (1b - prom_finddev_name), %l1 213 mov (1b - prom_chosen_path), %l2 213 mov (1b - prom_chosen_path), %l2 214 mov (1b - prom_boot_mapped_pc), %l 214 mov (1b - prom_boot_mapped_pc), %l3 215 sub %l0, %l1, %l1 215 sub %l0, %l1, %l1 216 sub %l0, %l2, %l2 216 sub %l0, %l2, %l2 217 sub %l0, %l3, %l3 217 sub %l0, %l3, %l3 218 stw %l0, [%l3] 218 stw %l0, [%l3] 219 sub %sp, (192 + 128), %sp 219 sub %sp, (192 + 128), %sp 220 220 221 /* chosen_node = prom_finddevice("/cho 221 /* chosen_node = prom_finddevice("/chosen") */ 222 stx %l1, [%sp + 2047 + 128 + 0x00] 222 stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "finddevice" 223 mov 1, %l3 223 mov 1, %l3 224 stx %l3, [%sp + 2047 + 128 + 0x08] 224 stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 1 225 stx %l3, [%sp + 2047 + 128 + 0x10] 225 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 226 stx %l2, [%sp + 2047 + 128 + 0x18] 226 stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1, "/chosen" 227 stx %g0, [%sp + 2047 + 128 + 0x20] 227 stx %g0, [%sp + 2047 + 128 + 0x20] ! ret1 228 call %l7 228 call %l7 229 add %sp, (2047 + 128), %o0 229 add %sp, (2047 + 128), %o0 ! argument array 230 230 231 ldx [%sp + 2047 + 128 + 0x20], %l4 231 ldx [%sp + 2047 + 128 + 0x20], %l4 ! chosen device node 232 232 233 mov (1b - prom_getprop_name), %l1 233 mov (1b - prom_getprop_name), %l1 234 mov (1b - prom_mmu_name), %l2 234 mov (1b - prom_mmu_name), %l2 235 mov (1b - prom_mmu_ihandle_cache), 235 mov (1b - prom_mmu_ihandle_cache), %l5 236 sub %l0, %l1, %l1 236 sub %l0, %l1, %l1 237 sub %l0, %l2, %l2 237 sub %l0, %l2, %l2 238 sub %l0, %l5, %l5 238 sub %l0, %l5, %l5 239 239 240 /* prom_mmu_ihandle_cache = prom_getin 240 /* prom_mmu_ihandle_cache = prom_getint(chosen_node, "mmu") */ 241 stx %l1, [%sp + 2047 + 128 + 0x00] 241 stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "getprop" 242 mov 4, %l3 242 mov 4, %l3 243 stx %l3, [%sp + 2047 + 128 + 0x08] 243 stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 4 244 mov 1, %l3 244 mov 1, %l3 245 stx %l3, [%sp + 2047 + 128 + 0x10] 245 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 246 stx %l4, [%sp + 2047 + 128 + 0x18] 246 stx %l4, [%sp + 2047 + 128 + 0x18] ! arg1, chosen_node 247 stx %l2, [%sp + 2047 + 128 + 0x20] 247 stx %l2, [%sp + 2047 + 128 + 0x20] ! arg2, "mmu" 248 stx %l5, [%sp + 2047 + 128 + 0x28] 248 stx %l5, [%sp + 2047 + 128 + 0x28] ! arg3, &prom_mmu_ihandle_cache 249 mov 4, %l3 249 mov 4, %l3 250 stx %l3, [%sp + 2047 + 128 + 0x30] 250 stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4, sizeof(arg3) 251 stx %g0, [%sp + 2047 + 128 + 0x38] 251 stx %g0, [%sp + 2047 + 128 + 0x38] ! ret1 252 call %l7 252 call %l7 253 add %sp, (2047 + 128), %o0 253 add %sp, (2047 + 128), %o0 ! argument array 254 254 255 mov (1b - prom_callmethod_name), % 255 mov (1b - prom_callmethod_name), %l1 256 mov (1b - prom_translate_name), %l 256 mov (1b - prom_translate_name), %l2 257 sub %l0, %l1, %l1 257 sub %l0, %l1, %l1 258 sub %l0, %l2, %l2 258 sub %l0, %l2, %l2 259 lduw [%l5], %l5 259 lduw [%l5], %l5 ! prom_mmu_ihandle_cache 260 260 261 stx %l1, [%sp + 2047 + 128 + 0x00] 261 stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "call-method" 262 mov 3, %l3 262 mov 3, %l3 263 stx %l3, [%sp + 2047 + 128 + 0x08] 263 stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 3 264 mov 5, %l3 264 mov 5, %l3 265 stx %l3, [%sp + 2047 + 128 + 0x10] 265 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 5 266 stx %l2, [%sp + 2047 + 128 + 0x18] 266 stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1: "translate" 267 stx %l5, [%sp + 2047 + 128 + 0x20] 267 stx %l5, [%sp + 2047 + 128 + 0x20] ! arg2: prom_mmu_ihandle_cache 268 /* PAGE align */ 268 /* PAGE align */ 269 srlx %l0, 13, %l3 269 srlx %l0, 13, %l3 270 sllx %l3, 13, %l3 270 sllx %l3, 13, %l3 271 stx %l3, [%sp + 2047 + 128 + 0x28] 271 stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: vaddr, our PC 272 stx %g0, [%sp + 2047 + 128 + 0x30] 272 stx %g0, [%sp + 2047 + 128 + 0x30] ! res1 273 stx %g0, [%sp + 2047 + 128 + 0x38] 273 stx %g0, [%sp + 2047 + 128 + 0x38] ! res2 274 stx %g0, [%sp + 2047 + 128 + 0x40] 274 stx %g0, [%sp + 2047 + 128 + 0x40] ! res3 275 stx %g0, [%sp + 2047 + 128 + 0x48] 275 stx %g0, [%sp + 2047 + 128 + 0x48] ! res4 276 stx %g0, [%sp + 2047 + 128 + 0x50] 276 stx %g0, [%sp + 2047 + 128 + 0x50] ! res5 277 call %l7 277 call %l7 278 add %sp, (2047 + 128), %o0 278 add %sp, (2047 + 128), %o0 ! argument array 279 279 280 ldx [%sp + 2047 + 128 + 0x40], %l1 280 ldx [%sp + 2047 + 128 + 0x40], %l1 ! translation mode 281 mov (1b - prom_boot_mapping_mode), 281 mov (1b - prom_boot_mapping_mode), %l4 282 sub %l0, %l4, %l4 282 sub %l0, %l4, %l4 283 stw %l1, [%l4] 283 stw %l1, [%l4] 284 mov (1b - prom_boot_mapping_phys_h 284 mov (1b - prom_boot_mapping_phys_high), %l4 285 sub %l0, %l4, %l4 285 sub %l0, %l4, %l4 286 ldx [%sp + 2047 + 128 + 0x48], %l2 286 ldx [%sp + 2047 + 128 + 0x48], %l2 ! physaddr high 287 stx %l2, [%l4 + 0x0] 287 stx %l2, [%l4 + 0x0] 288 ldx [%sp + 2047 + 128 + 0x50], %l3 288 ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low 289 /* 4MB align */ 289 /* 4MB align */ 290 srlx %l3, ILOG2_4MB, %l3 290 srlx %l3, ILOG2_4MB, %l3 291 sllx %l3, ILOG2_4MB, %l3 291 sllx %l3, ILOG2_4MB, %l3 292 stx %l3, [%l4 + 0x8] 292 stx %l3, [%l4 + 0x8] 293 293 294 /* Leave service as-is, "call-method" 294 /* Leave service as-is, "call-method" */ 295 mov 7, %l3 295 mov 7, %l3 296 stx %l3, [%sp + 2047 + 128 + 0x08] 296 stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 7 297 mov 1, %l3 297 mov 1, %l3 298 stx %l3, [%sp + 2047 + 128 + 0x10] 298 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 299 mov (1b - prom_map_name), %l3 299 mov (1b - prom_map_name), %l3 300 sub %l0, %l3, %l3 300 sub %l0, %l3, %l3 301 stx %l3, [%sp + 2047 + 128 + 0x18] 301 stx %l3, [%sp + 2047 + 128 + 0x18] ! arg1: "map" 302 /* Leave arg2 as-is, prom_mmu_ihandle_ 302 /* Leave arg2 as-is, prom_mmu_ihandle_cache */ 303 mov -1, %l3 303 mov -1, %l3 304 stx %l3, [%sp + 2047 + 128 + 0x28] 304 stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: mode (-1 default) 305 /* 4MB align the kernel image size. */ 305 /* 4MB align the kernel image size. */ 306 set (_end - KERNBASE), %l3 306 set (_end - KERNBASE), %l3 307 set ((4 * 1024 * 1024) - 1), %l4 307 set ((4 * 1024 * 1024) - 1), %l4 308 add %l3, %l4, %l3 308 add %l3, %l4, %l3 309 andn %l3, %l4, %l3 309 andn %l3, %l4, %l3 310 stx %l3, [%sp + 2047 + 128 + 0x30] 310 stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4: roundup(ksize, 4MB) 311 sethi %hi(KERNBASE), %l3 311 sethi %hi(KERNBASE), %l3 312 stx %l3, [%sp + 2047 + 128 + 0x38] 312 stx %l3, [%sp + 2047 + 128 + 0x38] ! arg5: vaddr (KERNBASE) 313 stx %g0, [%sp + 2047 + 128 + 0x40] 313 stx %g0, [%sp + 2047 + 128 + 0x40] ! arg6: empty 314 mov (1b - prom_boot_mapping_phys_l 314 mov (1b - prom_boot_mapping_phys_low), %l3 315 sub %l0, %l3, %l3 315 sub %l0, %l3, %l3 316 ldx [%l3], %l3 316 ldx [%l3], %l3 317 stx %l3, [%sp + 2047 + 128 + 0x48] 317 stx %l3, [%sp + 2047 + 128 + 0x48] ! arg7: phys addr 318 call %l7 318 call %l7 319 add %sp, (2047 + 128), %o0 319 add %sp, (2047 + 128), %o0 ! argument array 320 320 321 add %sp, (192 + 128), %sp 321 add %sp, (192 + 128), %sp 322 322 323 sethi %hi(prom_root_compatible), %g1 323 sethi %hi(prom_root_compatible), %g1 324 or %g1, %lo(prom_root_compatible) 324 or %g1, %lo(prom_root_compatible), %g1 325 sethi %hi(prom_sun4v_name), %g7 325 sethi %hi(prom_sun4v_name), %g7 326 or %g7, %lo(prom_sun4v_name), %g7 326 or %g7, %lo(prom_sun4v_name), %g7 327 mov 5, %g3 327 mov 5, %g3 328 90: ldub [%g7], %g2 328 90: ldub [%g7], %g2 329 ldub [%g1], %g4 329 ldub [%g1], %g4 330 cmp %g2, %g4 330 cmp %g2, %g4 331 bne,pn %icc, 80f 331 bne,pn %icc, 80f 332 add %g7, 1, %g7 332 add %g7, 1, %g7 333 subcc %g3, 1, %g3 333 subcc %g3, 1, %g3 334 bne,pt %xcc, 90b 334 bne,pt %xcc, 90b 335 add %g1, 1, %g1 335 add %g1, 1, %g1 336 336 337 sethi %hi(is_sun4v), %g1 337 sethi %hi(is_sun4v), %g1 338 or %g1, %lo(is_sun4v), %g1 338 or %g1, %lo(is_sun4v), %g1 339 mov 1, %g7 339 mov 1, %g7 340 stw %g7, [%g1] 340 stw %g7, [%g1] 341 341 342 /* cpu_node = prom_finddevice("/cpu") 342 /* cpu_node = prom_finddevice("/cpu") */ 343 mov (1b - prom_finddev_name), %l1 343 mov (1b - prom_finddev_name), %l1 344 mov (1b - prom_cpu_path), %l2 344 mov (1b - prom_cpu_path), %l2 345 sub %l0, %l1, %l1 345 sub %l0, %l1, %l1 346 sub %l0, %l2, %l2 346 sub %l0, %l2, %l2 347 sub %sp, (192 + 128), %sp 347 sub %sp, (192 + 128), %sp 348 348 349 stx %l1, [%sp + 2047 + 128 + 0x00] 349 stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "finddevice" 350 mov 1, %l3 350 mov 1, %l3 351 stx %l3, [%sp + 2047 + 128 + 0x08] 351 stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 1 352 stx %l3, [%sp + 2047 + 128 + 0x10] 352 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 353 stx %l2, [%sp + 2047 + 128 + 0x18] 353 stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1, "/cpu" 354 stx %g0, [%sp + 2047 + 128 + 0x20] 354 stx %g0, [%sp + 2047 + 128 + 0x20] ! ret1 355 call %l7 355 call %l7 356 add %sp, (2047 + 128), %o0 356 add %sp, (2047 + 128), %o0 ! argument array 357 357 358 ldx [%sp + 2047 + 128 + 0x20], %l4 358 ldx [%sp + 2047 + 128 + 0x20], %l4 ! cpu device node 359 359 360 mov (1b - prom_getprop_name), %l1 360 mov (1b - prom_getprop_name), %l1 361 mov (1b - prom_compatible_name), % 361 mov (1b - prom_compatible_name), %l2 362 mov (1b - prom_cpu_compatible), %l 362 mov (1b - prom_cpu_compatible), %l5 363 sub %l0, %l1, %l1 363 sub %l0, %l1, %l1 364 sub %l0, %l2, %l2 364 sub %l0, %l2, %l2 365 sub %l0, %l5, %l5 365 sub %l0, %l5, %l5 366 366 367 /* prom_getproperty(cpu_node, "compati 367 /* prom_getproperty(cpu_node, "compatible", 368 * &prom_cpu_compatib 368 * &prom_cpu_compatible, 64) 369 */ 369 */ 370 stx %l1, [%sp + 2047 + 128 + 0x00] 370 stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "getprop" 371 mov 4, %l3 371 mov 4, %l3 372 stx %l3, [%sp + 2047 + 128 + 0x08] 372 stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 4 373 mov 1, %l3 373 mov 1, %l3 374 stx %l3, [%sp + 2047 + 128 + 0x10] 374 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 375 stx %l4, [%sp + 2047 + 128 + 0x18] 375 stx %l4, [%sp + 2047 + 128 + 0x18] ! arg1, cpu_node 376 stx %l2, [%sp + 2047 + 128 + 0x20] 376 stx %l2, [%sp + 2047 + 128 + 0x20] ! arg2, "compatible" 377 stx %l5, [%sp + 2047 + 128 + 0x28] 377 stx %l5, [%sp + 2047 + 128 + 0x28] ! arg3, &prom_cpu_compatible 378 mov 64, %l3 378 mov 64, %l3 379 stx %l3, [%sp + 2047 + 128 + 0x30] 379 stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4, size 380 stx %g0, [%sp + 2047 + 128 + 0x38] 380 stx %g0, [%sp + 2047 + 128 + 0x38] ! ret1 381 call %l7 381 call %l7 382 add %sp, (2047 + 128), %o0 382 add %sp, (2047 + 128), %o0 ! argument array 383 383 384 add %sp, (192 + 128), %sp 384 add %sp, (192 + 128), %sp 385 385 386 sethi %hi(prom_cpu_compatible), %g1 386 sethi %hi(prom_cpu_compatible), %g1 387 or %g1, %lo(prom_cpu_compatible), 387 or %g1, %lo(prom_cpu_compatible), %g1 388 sethi %hi(prom_niagara_prefix), %g7 388 sethi %hi(prom_niagara_prefix), %g7 389 or %g7, %lo(prom_niagara_prefix), 389 or %g7, %lo(prom_niagara_prefix), %g7 390 mov 17, %g3 390 mov 17, %g3 391 90: ldub [%g7], %g2 391 90: ldub [%g7], %g2 392 ldub [%g1], %g4 392 ldub [%g1], %g4 393 cmp %g2, %g4 393 cmp %g2, %g4 394 bne,pn %icc, 89f 394 bne,pn %icc, 89f 395 add %g7, 1, %g7 395 add %g7, 1, %g7 396 subcc %g3, 1, %g3 396 subcc %g3, 1, %g3 397 bne,pt %xcc, 90b 397 bne,pt %xcc, 90b 398 add %g1, 1, %g1 398 add %g1, 1, %g1 399 ba,pt %xcc, 91f 399 ba,pt %xcc, 91f 400 nop 400 nop 401 401 402 89: sethi %hi(prom_cpu_compatible), %g1 402 89: sethi %hi(prom_cpu_compatible), %g1 403 or %g1, %lo(prom_cpu_compatible), 403 or %g1, %lo(prom_cpu_compatible), %g1 404 sethi %hi(prom_sparc_prefix), %g7 404 sethi %hi(prom_sparc_prefix), %g7 405 or %g7, %lo(prom_sparc_prefix), % 405 or %g7, %lo(prom_sparc_prefix), %g7 406 mov 6, %g3 406 mov 6, %g3 407 90: ldub [%g7], %g2 407 90: ldub [%g7], %g2 408 ldub [%g1], %g4 408 ldub [%g1], %g4 409 cmp %g2, %g4 409 cmp %g2, %g4 410 bne,pn %icc, 4f 410 bne,pn %icc, 4f 411 add %g7, 1, %g7 411 add %g7, 1, %g7 412 subcc %g3, 1, %g3 412 subcc %g3, 1, %g3 413 bne,pt %xcc, 90b 413 bne,pt %xcc, 90b 414 add %g1, 1, %g1 414 add %g1, 1, %g1 415 415 416 sethi %hi(prom_cpu_compatible), %g1 416 sethi %hi(prom_cpu_compatible), %g1 417 or %g1, %lo(prom_cpu_compatible), 417 or %g1, %lo(prom_cpu_compatible), %g1 418 ldub [%g1 + 6], %g2 418 ldub [%g1 + 6], %g2 419 cmp %g2, 'T' 419 cmp %g2, 'T' 420 be,pt %xcc, 70f 420 be,pt %xcc, 70f 421 cmp %g2, 'M' 421 cmp %g2, 'M' 422 be,pt %xcc, 70f 422 be,pt %xcc, 70f 423 cmp %g2, 'S' 423 cmp %g2, 'S' 424 bne,pn %xcc, 49f 424 bne,pn %xcc, 49f 425 nop 425 nop 426 426 427 70: ldub [%g1 + 7], %g2 427 70: ldub [%g1 + 7], %g2 428 cmp %g2, CPU_ID_NIAGARA3 428 cmp %g2, CPU_ID_NIAGARA3 429 be,pt %xcc, 5f 429 be,pt %xcc, 5f 430 mov SUN4V_CHIP_NIAGARA3, %g4 430 mov SUN4V_CHIP_NIAGARA3, %g4 431 cmp %g2, CPU_ID_NIAGARA4 431 cmp %g2, CPU_ID_NIAGARA4 432 be,pt %xcc, 5f 432 be,pt %xcc, 5f 433 mov SUN4V_CHIP_NIAGARA4, %g4 433 mov SUN4V_CHIP_NIAGARA4, %g4 434 cmp %g2, CPU_ID_NIAGARA5 434 cmp %g2, CPU_ID_NIAGARA5 435 be,pt %xcc, 5f 435 be,pt %xcc, 5f 436 mov SUN4V_CHIP_NIAGARA5, %g4 436 mov SUN4V_CHIP_NIAGARA5, %g4 437 cmp %g2, CPU_ID_M6 437 cmp %g2, CPU_ID_M6 438 be,pt %xcc, 5f 438 be,pt %xcc, 5f 439 mov SUN4V_CHIP_SPARC_M6, %g4 439 mov SUN4V_CHIP_SPARC_M6, %g4 440 cmp %g2, CPU_ID_M7 440 cmp %g2, CPU_ID_M7 441 be,pt %xcc, 5f 441 be,pt %xcc, 5f 442 mov SUN4V_CHIP_SPARC_M7, %g4 442 mov SUN4V_CHIP_SPARC_M7, %g4 443 cmp %g2, CPU_ID_M8 443 cmp %g2, CPU_ID_M8 444 be,pt %xcc, 5f 444 be,pt %xcc, 5f 445 mov SUN4V_CHIP_SPARC_M8, %g4 445 mov SUN4V_CHIP_SPARC_M8, %g4 446 cmp %g2, CPU_ID_SONOMA1 446 cmp %g2, CPU_ID_SONOMA1 447 be,pt %xcc, 5f 447 be,pt %xcc, 5f 448 mov SUN4V_CHIP_SPARC_SN, %g4 448 mov SUN4V_CHIP_SPARC_SN, %g4 449 ba,pt %xcc, 49f 449 ba,pt %xcc, 49f 450 nop 450 nop 451 451 452 91: sethi %hi(prom_cpu_compatible), %g1 452 91: sethi %hi(prom_cpu_compatible), %g1 453 or %g1, %lo(prom_cpu_compatible), 453 or %g1, %lo(prom_cpu_compatible), %g1 454 ldub [%g1 + 17], %g2 454 ldub [%g1 + 17], %g2 455 cmp %g2, CPU_ID_NIAGARA1 455 cmp %g2, CPU_ID_NIAGARA1 456 be,pt %xcc, 5f 456 be,pt %xcc, 5f 457 mov SUN4V_CHIP_NIAGARA1, %g4 457 mov SUN4V_CHIP_NIAGARA1, %g4 458 cmp %g2, CPU_ID_NIAGARA2 458 cmp %g2, CPU_ID_NIAGARA2 459 be,pt %xcc, 5f 459 be,pt %xcc, 5f 460 mov SUN4V_CHIP_NIAGARA2, %g4 460 mov SUN4V_CHIP_NIAGARA2, %g4 461 461 462 4: 462 4: 463 /* Athena */ 463 /* Athena */ 464 sethi %hi(prom_cpu_compatible), %g1 464 sethi %hi(prom_cpu_compatible), %g1 465 or %g1, %lo(prom_cpu_compatible), 465 or %g1, %lo(prom_cpu_compatible), %g1 466 sethi %hi(prom_sparc64x_prefix), %g7 466 sethi %hi(prom_sparc64x_prefix), %g7 467 or %g7, %lo(prom_sparc64x_prefix) 467 or %g7, %lo(prom_sparc64x_prefix), %g7 468 mov 9, %g3 468 mov 9, %g3 469 41: ldub [%g7], %g2 469 41: ldub [%g7], %g2 470 ldub [%g1], %g4 470 ldub [%g1], %g4 471 cmp %g2, %g4 471 cmp %g2, %g4 472 bne,pn %icc, 49f 472 bne,pn %icc, 49f 473 add %g7, 1, %g7 473 add %g7, 1, %g7 474 subcc %g3, 1, %g3 474 subcc %g3, 1, %g3 475 bne,pt %xcc, 41b 475 bne,pt %xcc, 41b 476 add %g1, 1, %g1 476 add %g1, 1, %g1 477 ba,pt %xcc, 5f 477 ba,pt %xcc, 5f 478 mov SUN4V_CHIP_SPARC64X, %g4 478 mov SUN4V_CHIP_SPARC64X, %g4 479 479 480 49: 480 49: 481 mov SUN4V_CHIP_UNKNOWN, %g4 481 mov SUN4V_CHIP_UNKNOWN, %g4 482 5: sethi %hi(sun4v_chip_type), %g2 482 5: sethi %hi(sun4v_chip_type), %g2 483 or %g2, %lo(sun4v_chip_type), %g2 483 or %g2, %lo(sun4v_chip_type), %g2 484 stw %g4, [%g2] 484 stw %g4, [%g2] 485 485 486 80: 486 80: 487 BRANCH_IF_SUN4V(g1, jump_to_sun4u_init 487 BRANCH_IF_SUN4V(g1, jump_to_sun4u_init) 488 BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_b 488 BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot) 489 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1, 489 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot) 490 ba,pt %xcc, spitfire_boot 490 ba,pt %xcc, spitfire_boot 491 nop 491 nop 492 492 493 cheetah_plus_boot: 493 cheetah_plus_boot: 494 /* Preserve OBP chosen DCU and DCR reg 494 /* Preserve OBP chosen DCU and DCR register settings. */ 495 ba,pt %xcc, cheetah_generic_boot 495 ba,pt %xcc, cheetah_generic_boot 496 nop 496 nop 497 497 498 cheetah_boot: 498 cheetah_boot: 499 mov DCR_BPE | DCR_RPE | DCR_SI | D 499 mov DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1 500 wr %g1, %asr18 500 wr %g1, %asr18 501 501 502 sethi %uhi(DCU_ME|DCU_RE|DCU_HPE|DCU 502 sethi %uhi(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g7 503 or %g7, %ulo(DCU_ME|DCU_RE|DCU_HP 503 or %g7, %ulo(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g7 504 sllx %g7, 32, %g7 504 sllx %g7, 32, %g7 505 or %g7, DCU_DM | DCU_IM | DCU_DC 505 or %g7, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g7 506 stxa %g7, [%g0] ASI_DCU_CONTROL_REG 506 stxa %g7, [%g0] ASI_DCU_CONTROL_REG 507 membar #Sync 507 membar #Sync 508 508 509 cheetah_generic_boot: 509 cheetah_generic_boot: 510 mov TSB_EXTENSION_P, %g3 510 mov TSB_EXTENSION_P, %g3 511 stxa %g0, [%g3] ASI_DMMU 511 stxa %g0, [%g3] ASI_DMMU 512 stxa %g0, [%g3] ASI_IMMU 512 stxa %g0, [%g3] ASI_IMMU 513 membar #Sync 513 membar #Sync 514 514 515 mov TSB_EXTENSION_S, %g3 515 mov TSB_EXTENSION_S, %g3 516 stxa %g0, [%g3] ASI_DMMU 516 stxa %g0, [%g3] ASI_DMMU 517 membar #Sync 517 membar #Sync 518 518 519 mov TSB_EXTENSION_N, %g3 519 mov TSB_EXTENSION_N, %g3 520 stxa %g0, [%g3] ASI_DMMU 520 stxa %g0, [%g3] ASI_DMMU 521 stxa %g0, [%g3] ASI_IMMU 521 stxa %g0, [%g3] ASI_IMMU 522 membar #Sync 522 membar #Sync 523 523 524 ba,a,pt %xcc, jump_to_sun4u_init 524 ba,a,pt %xcc, jump_to_sun4u_init 525 525 526 spitfire_boot: 526 spitfire_boot: 527 /* Typically PROM has already enabled 527 /* Typically PROM has already enabled both MMU's and both on-chip 528 * caches, but we do it here anyway ju 528 * caches, but we do it here anyway just to be paranoid. 529 */ 529 */ 530 mov (LSU_CONTROL_IC|LSU_CONTROL_DC 530 mov (LSU_CONTROL_IC|LSU_CONTROL_DC|LSU_CONTROL_IM|LSU_CONTROL_DM), %g1 531 stxa %g1, [%g0] ASI_LSU_CONTROL 531 stxa %g1, [%g0] ASI_LSU_CONTROL 532 membar #Sync 532 membar #Sync 533 533 534 jump_to_sun4u_init: 534 jump_to_sun4u_init: 535 /* 535 /* 536 * Make sure we are in privileged mode 536 * Make sure we are in privileged mode, have address masking, 537 * using the ordinary globals and have 537 * using the ordinary globals and have enabled floating 538 * point. 538 * point. 539 * 539 * 540 * Again, typically PROM has left %pil 540 * Again, typically PROM has left %pil at 13 or similar, and 541 * (PSTATE_PRIV | PSTATE_PEF | PSTATE_ 541 * (PSTATE_PRIV | PSTATE_PEF | PSTATE_IE) in %pstate. 542 */ 542 */ 543 wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|P 543 wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate 544 wr %g0, 0, %fprs 544 wr %g0, 0, %fprs 545 545 546 set sun4u_init, %g2 546 set sun4u_init, %g2 547 jmpl %g2 + %g0, %g0 547 jmpl %g2 + %g0, %g0 548 nop 548 nop 549 549 550 __REF 550 __REF 551 sun4u_init: 551 sun4u_init: 552 BRANCH_IF_SUN4V(g1, sun4v_init) 552 BRANCH_IF_SUN4V(g1, sun4v_init) 553 553 554 /* Set ctx 0 */ 554 /* Set ctx 0 */ 555 mov PRIMARY_CONTEXT, %g7 555 mov PRIMARY_CONTEXT, %g7 556 stxa %g0, [%g7] ASI_DMMU 556 stxa %g0, [%g7] ASI_DMMU 557 membar #Sync 557 membar #Sync 558 558 559 mov SECONDARY_CONTEXT, %g7 559 mov SECONDARY_CONTEXT, %g7 560 stxa %g0, [%g7] ASI_DMMU 560 stxa %g0, [%g7] ASI_DMMU 561 membar #Sync 561 membar #Sync 562 562 563 ba,a,pt %xcc, sun4u_continue 563 ba,a,pt %xcc, sun4u_continue 564 564 565 sun4v_init: 565 sun4v_init: 566 /* Set ctx 0 */ 566 /* Set ctx 0 */ 567 mov PRIMARY_CONTEXT, %g7 567 mov PRIMARY_CONTEXT, %g7 568 stxa %g0, [%g7] ASI_MMU 568 stxa %g0, [%g7] ASI_MMU 569 membar #Sync 569 membar #Sync 570 570 571 mov SECONDARY_CONTEXT, %g7 571 mov SECONDARY_CONTEXT, %g7 572 stxa %g0, [%g7] ASI_MMU 572 stxa %g0, [%g7] ASI_MMU 573 membar #Sync 573 membar #Sync 574 ba,a,pt %xcc, niagara_tlb_fixu 574 ba,a,pt %xcc, niagara_tlb_fixup 575 575 576 sun4u_continue: 576 sun4u_continue: 577 BRANCH_IF_ANY_CHEETAH(g1, g7, cheetah_ 577 BRANCH_IF_ANY_CHEETAH(g1, g7, cheetah_tlb_fixup) 578 578 579 ba,a,pt %xcc, spitfire_tlb_fixup 579 ba,a,pt %xcc, spitfire_tlb_fixup 580 580 581 niagara_tlb_fixup: 581 niagara_tlb_fixup: 582 mov 3, %g2 /* Set TLB typ 582 mov 3, %g2 /* Set TLB type to hypervisor. */ 583 sethi %hi(tlb_type), %g1 583 sethi %hi(tlb_type), %g1 584 stw %g2, [%g1 + %lo(tlb_type)] 584 stw %g2, [%g1 + %lo(tlb_type)] 585 585 586 /* Patch copy/clear ops. */ 586 /* Patch copy/clear ops. */ 587 sethi %hi(sun4v_chip_type), %g1 587 sethi %hi(sun4v_chip_type), %g1 588 lduw [%g1 + %lo(sun4v_chip_type)], 588 lduw [%g1 + %lo(sun4v_chip_type)], %g1 589 cmp %g1, SUN4V_CHIP_NIAGARA1 589 cmp %g1, SUN4V_CHIP_NIAGARA1 590 be,pt %xcc, niagara_patch 590 be,pt %xcc, niagara_patch 591 cmp %g1, SUN4V_CHIP_NIAGARA2 591 cmp %g1, SUN4V_CHIP_NIAGARA2 592 be,pt %xcc, niagara2_patch 592 be,pt %xcc, niagara2_patch 593 nop 593 nop 594 cmp %g1, SUN4V_CHIP_NIAGARA3 594 cmp %g1, SUN4V_CHIP_NIAGARA3 595 be,pt %xcc, niagara2_patch 595 be,pt %xcc, niagara2_patch 596 nop 596 nop 597 cmp %g1, SUN4V_CHIP_NIAGARA4 597 cmp %g1, SUN4V_CHIP_NIAGARA4 598 be,pt %xcc, niagara4_patch 598 be,pt %xcc, niagara4_patch 599 nop 599 nop 600 cmp %g1, SUN4V_CHIP_NIAGARA5 600 cmp %g1, SUN4V_CHIP_NIAGARA5 601 be,pt %xcc, niagara4_patch 601 be,pt %xcc, niagara4_patch 602 nop 602 nop 603 cmp %g1, SUN4V_CHIP_SPARC_M6 603 cmp %g1, SUN4V_CHIP_SPARC_M6 604 be,pt %xcc, niagara4_patch 604 be,pt %xcc, niagara4_patch 605 nop 605 nop 606 cmp %g1, SUN4V_CHIP_SPARC_M7 606 cmp %g1, SUN4V_CHIP_SPARC_M7 607 be,pt %xcc, sparc_m7_patch 607 be,pt %xcc, sparc_m7_patch 608 nop 608 nop 609 cmp %g1, SUN4V_CHIP_SPARC_M8 609 cmp %g1, SUN4V_CHIP_SPARC_M8 610 be,pt %xcc, sparc_m7_patch 610 be,pt %xcc, sparc_m7_patch 611 nop 611 nop 612 cmp %g1, SUN4V_CHIP_SPARC_SN 612 cmp %g1, SUN4V_CHIP_SPARC_SN 613 be,pt %xcc, niagara4_patch 613 be,pt %xcc, niagara4_patch 614 nop 614 nop 615 615 616 call generic_patch_copyops 616 call generic_patch_copyops 617 nop 617 nop 618 call generic_patch_bzero 618 call generic_patch_bzero 619 nop 619 nop 620 call generic_patch_pageops 620 call generic_patch_pageops 621 nop 621 nop 622 622 623 ba,a,pt %xcc, 80f 623 ba,a,pt %xcc, 80f 624 nop 624 nop 625 625 626 sparc_m7_patch: 626 sparc_m7_patch: 627 call m7_patch_copyops 627 call m7_patch_copyops 628 nop 628 nop 629 call m7_patch_bzero 629 call m7_patch_bzero 630 nop 630 nop 631 call m7_patch_pageops 631 call m7_patch_pageops 632 nop 632 nop 633 633 634 ba,a,pt %xcc, 80f 634 ba,a,pt %xcc, 80f 635 nop 635 nop 636 636 637 niagara4_patch: 637 niagara4_patch: 638 call niagara4_patch_copyops 638 call niagara4_patch_copyops 639 nop 639 nop 640 call niagara4_patch_bzero 640 call niagara4_patch_bzero 641 nop 641 nop 642 call niagara4_patch_pageops 642 call niagara4_patch_pageops 643 nop 643 nop 644 call niagara4_patch_fls 644 call niagara4_patch_fls 645 nop 645 nop 646 646 647 ba,a,pt %xcc, 80f 647 ba,a,pt %xcc, 80f 648 nop 648 nop 649 649 650 niagara2_patch: 650 niagara2_patch: 651 call niagara2_patch_copyops 651 call niagara2_patch_copyops 652 nop 652 nop 653 call niagara_patch_bzero 653 call niagara_patch_bzero 654 nop 654 nop 655 call niagara_patch_pageops 655 call niagara_patch_pageops 656 nop 656 nop 657 657 658 ba,a,pt %xcc, 80f 658 ba,a,pt %xcc, 80f 659 nop 659 nop 660 660 661 niagara_patch: 661 niagara_patch: 662 call niagara_patch_copyops 662 call niagara_patch_copyops 663 nop 663 nop 664 call niagara_patch_bzero 664 call niagara_patch_bzero 665 nop 665 nop 666 call niagara_patch_pageops 666 call niagara_patch_pageops 667 nop 667 nop 668 668 669 80: 669 80: 670 /* Patch TLB/cache ops. */ 670 /* Patch TLB/cache ops. */ 671 call hypervisor_patch_cachetlbops 671 call hypervisor_patch_cachetlbops 672 nop 672 nop 673 673 674 ba,a,pt %xcc, tlb_fixup_done 674 ba,a,pt %xcc, tlb_fixup_done 675 675 676 cheetah_tlb_fixup: 676 cheetah_tlb_fixup: 677 mov 2, %g2 /* Set TLB typ 677 mov 2, %g2 /* Set TLB type to cheetah+. */ 678 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1, 678 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f) 679 679 680 mov 1, %g2 /* Set TLB typ 680 mov 1, %g2 /* Set TLB type to cheetah. */ 681 681 682 1: sethi %hi(tlb_type), %g1 682 1: sethi %hi(tlb_type), %g1 683 stw %g2, [%g1 + %lo(tlb_type)] 683 stw %g2, [%g1 + %lo(tlb_type)] 684 684 685 /* Patch copy/page operations to cheet 685 /* Patch copy/page operations to cheetah optimized versions. */ 686 call cheetah_patch_copyops 686 call cheetah_patch_copyops 687 nop 687 nop 688 call cheetah_patch_copy_page 688 call cheetah_patch_copy_page 689 nop 689 nop 690 call cheetah_patch_cachetlbops 690 call cheetah_patch_cachetlbops 691 nop 691 nop 692 692 693 ba,a,pt %xcc, tlb_fixup_done 693 ba,a,pt %xcc, tlb_fixup_done 694 694 695 spitfire_tlb_fixup: 695 spitfire_tlb_fixup: 696 /* Set TLB type to spitfire. */ 696 /* Set TLB type to spitfire. */ 697 mov 0, %g2 697 mov 0, %g2 698 sethi %hi(tlb_type), %g1 698 sethi %hi(tlb_type), %g1 699 stw %g2, [%g1 + %lo(tlb_type)] 699 stw %g2, [%g1 + %lo(tlb_type)] 700 700 701 tlb_fixup_done: 701 tlb_fixup_done: 702 sethi %hi(init_thread_union), %g6 702 sethi %hi(init_thread_union), %g6 703 or %g6, %lo(init_thread_union), % 703 or %g6, %lo(init_thread_union), %g6 704 ldx [%g6 + TI_TASK], %g4 704 ldx [%g6 + TI_TASK], %g4 705 705 706 wr %g0, ASI_P, %asi 706 wr %g0, ASI_P, %asi 707 mov 1, %g1 707 mov 1, %g1 708 sllx %g1, THREAD_SHIFT, %g1 708 sllx %g1, THREAD_SHIFT, %g1 709 sub %g1, (STACKFRAME_SZ + STACK_BI 709 sub %g1, (STACKFRAME_SZ + STACK_BIAS + TRACEREG_SZ), %g1 710 add %g6, %g1, %sp 710 add %g6, %g1, %sp 711 711 712 /* Set per-cpu pointer initially to ze 712 /* Set per-cpu pointer initially to zero, this makes 713 * the boot-cpu use the in-kernel-imag 713 * the boot-cpu use the in-kernel-image per-cpu areas 714 * before setup_per_cpu_area() is invo 714 * before setup_per_cpu_area() is invoked. 715 */ 715 */ 716 clr %g5 716 clr %g5 717 717 718 wrpr %g0, 0, %wstate 718 wrpr %g0, 0, %wstate 719 wrpr %g0, 0x0, %tl 719 wrpr %g0, 0x0, %tl 720 720 721 /* Clear the bss */ 721 /* Clear the bss */ 722 sethi %hi(__bss_start), %o0 722 sethi %hi(__bss_start), %o0 723 or %o0, %lo(__bss_start), %o0 723 or %o0, %lo(__bss_start), %o0 724 sethi %hi(_end), %o1 724 sethi %hi(_end), %o1 725 or %o1, %lo(_end), %o1 725 or %o1, %lo(_end), %o1 726 call __bzero 726 call __bzero 727 sub %o1, %o0, %o1 727 sub %o1, %o0, %o1 728 728 729 call prom_init 729 call prom_init 730 mov %l7, %o0 730 mov %l7, %o0 ! OpenPROM cif handler 731 731 732 /* To create a one-register-window buf 732 /* To create a one-register-window buffer between the kernel's 733 * initial stack and the last stack fr 733 * initial stack and the last stack frame we use from the firmware, 734 * do the rest of the boot from a C he 734 * do the rest of the boot from a C helper function. 735 */ 735 */ 736 call start_early_boot 736 call start_early_boot 737 nop 737 nop 738 /* Not reached... */ 738 /* Not reached... */ 739 739 740 .previous 740 .previous 741 741 742 /* This is meant to allow the sharing 742 /* This is meant to allow the sharing of this code between 743 * boot processor invocation (via setu 743 * boot processor invocation (via setup_tba() below) and 744 * secondary processor startup (via tr 744 * secondary processor startup (via trampoline.S). The 745 * former does use this code, the latt 745 * former does use this code, the latter does not yet due 746 * to some complexities. That should 746 * to some complexities. That should be fixed up at some 747 * point. 747 * point. 748 * 748 * 749 * There used to be enormous complexit 749 * There used to be enormous complexity wrt. transferring 750 * over from the firmware's trap table 750 * over from the firmware's trap table to the Linux kernel's. 751 * For example, there was a chicken & 751 * For example, there was a chicken & egg problem wrt. building 752 * the OBP page tables, yet needing to 752 * the OBP page tables, yet needing to be on the Linux kernel 753 * trap table (to translate PAGE_OFFSE 753 * trap table (to translate PAGE_OFFSET addresses) in order to 754 * do that. 754 * do that. 755 * 755 * 756 * We now handle OBP tlb misses differ 756 * We now handle OBP tlb misses differently, via linear lookups 757 * into the prom_trans[] array. So th 757 * into the prom_trans[] array. So that specific problem no 758 * longer exists. Yet, unfortunately 758 * longer exists. Yet, unfortunately there are still some issues 759 * preventing trampoline.S from using 759 * preventing trampoline.S from using this code... ho hum. 760 */ 760 */ 761 .globl setup_trap_table 761 .globl setup_trap_table 762 setup_trap_table: 762 setup_trap_table: 763 save %sp, -192, %sp 763 save %sp, -192, %sp 764 764 765 /* Force interrupts to be disabled. */ 765 /* Force interrupts to be disabled. */ 766 rdpr %pstate, %l0 766 rdpr %pstate, %l0 767 andn %l0, PSTATE_IE, %o1 767 andn %l0, PSTATE_IE, %o1 768 wrpr %o1, 0x0, %pstate 768 wrpr %o1, 0x0, %pstate 769 rdpr %pil, %l1 769 rdpr %pil, %l1 770 wrpr %g0, PIL_NORMAL_MAX, %pil 770 wrpr %g0, PIL_NORMAL_MAX, %pil 771 771 772 /* Make the firmware call to jump over 772 /* Make the firmware call to jump over to the Linux trap table. */ 773 sethi %hi(is_sun4v), %o0 773 sethi %hi(is_sun4v), %o0 774 lduw [%o0 + %lo(is_sun4v)], %o0 774 lduw [%o0 + %lo(is_sun4v)], %o0 775 brz,pt %o0, 1f 775 brz,pt %o0, 1f 776 nop 776 nop 777 777 778 TRAP_LOAD_TRAP_BLOCK(%g2, %g3) 778 TRAP_LOAD_TRAP_BLOCK(%g2, %g3) 779 add %g2, TRAP_PER_CPU_FAULT_INFO, 779 add %g2, TRAP_PER_CPU_FAULT_INFO, %g2 780 stxa %g2, [%g0] ASI_SCRATCHPAD 780 stxa %g2, [%g0] ASI_SCRATCHPAD 781 781 782 /* Compute physical address: 782 /* Compute physical address: 783 * 783 * 784 * paddr = kern_base + (mmfsa_vaddr - 784 * paddr = kern_base + (mmfsa_vaddr - KERNBASE) 785 */ 785 */ 786 sethi %hi(KERNBASE), %g3 786 sethi %hi(KERNBASE), %g3 787 sub %g2, %g3, %g2 787 sub %g2, %g3, %g2 788 sethi %hi(kern_base), %g3 788 sethi %hi(kern_base), %g3 789 ldx [%g3 + %lo(kern_base)], %g3 789 ldx [%g3 + %lo(kern_base)], %g3 790 add %g2, %g3, %o1 790 add %g2, %g3, %o1 791 sethi %hi(sparc64_ttable_tl0), %o0 791 sethi %hi(sparc64_ttable_tl0), %o0 792 792 793 set prom_set_trap_table_name, %g2 793 set prom_set_trap_table_name, %g2 794 stx %g2, [%sp + 2047 + 128 + 0x00] 794 stx %g2, [%sp + 2047 + 128 + 0x00] 795 mov 2, %g2 795 mov 2, %g2 796 stx %g2, [%sp + 2047 + 128 + 0x08] 796 stx %g2, [%sp + 2047 + 128 + 0x08] 797 mov 0, %g2 797 mov 0, %g2 798 stx %g2, [%sp + 2047 + 128 + 0x10] 798 stx %g2, [%sp + 2047 + 128 + 0x10] 799 stx %o0, [%sp + 2047 + 128 + 0x18] 799 stx %o0, [%sp + 2047 + 128 + 0x18] 800 stx %o1, [%sp + 2047 + 128 + 0x20] 800 stx %o1, [%sp + 2047 + 128 + 0x20] 801 sethi %hi(p1275buf), %g2 801 sethi %hi(p1275buf), %g2 802 or %g2, %lo(p1275buf), %g2 802 or %g2, %lo(p1275buf), %g2 803 ldx [%g2 + 0x08], %o1 803 ldx [%g2 + 0x08], %o1 804 call %o1 804 call %o1 805 add %sp, (2047 + 128), %o0 805 add %sp, (2047 + 128), %o0 806 806 807 ba,a,pt %xcc, 2f 807 ba,a,pt %xcc, 2f 808 808 809 1: sethi %hi(sparc64_ttable_tl0), %o0 809 1: sethi %hi(sparc64_ttable_tl0), %o0 810 set prom_set_trap_table_name, %g2 810 set prom_set_trap_table_name, %g2 811 stx %g2, [%sp + 2047 + 128 + 0x00] 811 stx %g2, [%sp + 2047 + 128 + 0x00] 812 mov 1, %g2 812 mov 1, %g2 813 stx %g2, [%sp + 2047 + 128 + 0x08] 813 stx %g2, [%sp + 2047 + 128 + 0x08] 814 mov 0, %g2 814 mov 0, %g2 815 stx %g2, [%sp + 2047 + 128 + 0x10] 815 stx %g2, [%sp + 2047 + 128 + 0x10] 816 stx %o0, [%sp + 2047 + 128 + 0x18] 816 stx %o0, [%sp + 2047 + 128 + 0x18] 817 sethi %hi(p1275buf), %g2 817 sethi %hi(p1275buf), %g2 818 or %g2, %lo(p1275buf), %g2 818 or %g2, %lo(p1275buf), %g2 819 ldx [%g2 + 0x08], %o1 819 ldx [%g2 + 0x08], %o1 820 call %o1 820 call %o1 821 add %sp, (2047 + 128), %o0 821 add %sp, (2047 + 128), %o0 822 822 823 /* Start using proper page size encodi 823 /* Start using proper page size encodings in ctx register. */ 824 2: sethi %hi(sparc64_kern_pri_context), 824 2: sethi %hi(sparc64_kern_pri_context), %g3 825 ldx [%g3 + %lo(sparc64_kern_pri_co 825 ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2 826 826 827 mov PRIMARY_CONTEXT, %g1 827 mov PRIMARY_CONTEXT, %g1 828 828 829 661: stxa %g2, [%g1] ASI_DMMU 829 661: stxa %g2, [%g1] ASI_DMMU 830 .section .sun4v_1insn_patch, "a 830 .section .sun4v_1insn_patch, "ax" 831 .word 661b 831 .word 661b 832 stxa %g2, [%g1] ASI_MMU 832 stxa %g2, [%g1] ASI_MMU 833 .previous 833 .previous 834 834 835 membar #Sync 835 membar #Sync 836 836 837 BRANCH_IF_SUN4V(o2, 1f) 837 BRANCH_IF_SUN4V(o2, 1f) 838 838 839 /* Kill PROM timer */ 839 /* Kill PROM timer */ 840 sethi %hi(0x80000000), %o2 840 sethi %hi(0x80000000), %o2 841 sllx %o2, 32, %o2 841 sllx %o2, 32, %o2 842 wr %o2, 0, %tick_cmpr 842 wr %o2, 0, %tick_cmpr 843 843 844 BRANCH_IF_ANY_CHEETAH(o2, o3, 1f) 844 BRANCH_IF_ANY_CHEETAH(o2, o3, 1f) 845 845 846 ba,a,pt %xcc, 2f 846 ba,a,pt %xcc, 2f 847 847 848 /* Disable STICK_INT interrupts. */ 848 /* Disable STICK_INT interrupts. */ 849 1: 849 1: 850 sethi %hi(0x80000000), %o2 850 sethi %hi(0x80000000), %o2 851 sllx %o2, 32, %o2 851 sllx %o2, 32, %o2 852 wr %o2, %asr25 852 wr %o2, %asr25 853 853 854 2: 854 2: 855 wrpr %g0, %g0, %wstate 855 wrpr %g0, %g0, %wstate 856 856 857 call init_irqwork_curcpu 857 call init_irqwork_curcpu 858 nop 858 nop 859 859 860 /* Now we can restore interrupt state. 860 /* Now we can restore interrupt state. */ 861 wrpr %l0, 0, %pstate 861 wrpr %l0, 0, %pstate 862 wrpr %l1, 0x0, %pil 862 wrpr %l1, 0x0, %pil 863 863 864 ret 864 ret 865 restore 865 restore 866 866 867 .globl setup_tba 867 .globl setup_tba 868 setup_tba: 868 setup_tba: 869 save %sp, -192, %sp 869 save %sp, -192, %sp 870 870 871 /* The boot processor is the only cpu 871 /* The boot processor is the only cpu which invokes this 872 * routine, the other cpus set things 872 * routine, the other cpus set things up via trampoline.S. 873 * So save the OBP trap table address 873 * So save the OBP trap table address here. 874 */ 874 */ 875 rdpr %tba, %g7 875 rdpr %tba, %g7 876 sethi %hi(prom_tba), %o1 876 sethi %hi(prom_tba), %o1 877 or %o1, %lo(prom_tba), %o1 877 or %o1, %lo(prom_tba), %o1 878 stx %g7, [%o1] 878 stx %g7, [%o1] 879 879 880 call setup_trap_table 880 call setup_trap_table 881 nop 881 nop 882 882 883 ret 883 ret 884 restore 884 restore 885 sparc64_boot_end: 885 sparc64_boot_end: 886 886 887 #include "etrap_64.S" 887 #include "etrap_64.S" 888 #include "rtrap_64.S" 888 #include "rtrap_64.S" 889 #include "winfixup.S" 889 #include "winfixup.S" 890 #include "fpu_traps.S" 890 #include "fpu_traps.S" 891 #include "ivec.S" 891 #include "ivec.S" 892 #include "getsetcc.S" 892 #include "getsetcc.S" 893 #include "utrap.S" 893 #include "utrap.S" 894 #include "spiterrs.S" 894 #include "spiterrs.S" 895 #include "cherrs.S" 895 #include "cherrs.S" 896 #include "misctrap.S" 896 #include "misctrap.S" 897 #include "syscalls.S" 897 #include "syscalls.S" 898 #include "helpers.S" 898 #include "helpers.S" 899 #include "sun4v_tlb_miss.S" 899 #include "sun4v_tlb_miss.S" 900 #include "sun4v_mcd.S" 900 #include "sun4v_mcd.S" 901 #include "sun4v_ivec.S" 901 #include "sun4v_ivec.S" 902 #include "ktlb.S" 902 #include "ktlb.S" 903 #include "tsb.S" 903 #include "tsb.S" 904 904 905 /* 905 /* 906 * The following skip makes sure the trap tabl 906 * The following skip makes sure the trap table in ttable.S is aligned 907 * on a 32K boundary as required by the v9 spe 907 * on a 32K boundary as required by the v9 specs for TBA register. 908 * 908 * 909 * We align to a 32K boundary, then we have th 909 * We align to a 32K boundary, then we have the 32K kernel TSB, 910 * the 64K kernel 4MB TSB, and then the 32K al 910 * the 64K kernel 4MB TSB, and then the 32K aligned trap table. 911 */ 911 */ 912 1: 912 1: 913 .skip 0x4000 + _start - 1b 913 .skip 0x4000 + _start - 1b 914 914 915 ! 0x0000000000408000 915 ! 0x0000000000408000 916 916 917 .globl swapper_tsb 917 .globl swapper_tsb 918 swapper_tsb: 918 swapper_tsb: 919 .skip (32 * 1024) 919 .skip (32 * 1024) 920 920 921 .globl swapper_4m_tsb 921 .globl swapper_4m_tsb 922 swapper_4m_tsb: 922 swapper_4m_tsb: 923 .skip (64 * 1024) 923 .skip (64 * 1024) 924 924 925 ! 0x0000000000420000 925 ! 0x0000000000420000 926 926 927 /* Some care needs to be exercised if 927 /* Some care needs to be exercised if you try to move the 928 * location of the trap table relative 928 * location of the trap table relative to other things. For 929 * one thing there are br* instruction 929 * one thing there are br* instructions in some of the 930 * trap table entires which branch bac 930 * trap table entires which branch back to code in ktlb.S 931 * Those instructions can only handle 931 * Those instructions can only handle a signed 16-bit 932 * displacement. 932 * displacement. 933 * 933 * 934 * There is a binutils bug (bugzilla # 934 * There is a binutils bug (bugzilla #4558) which causes 935 * the relocation overflow checks for 935 * the relocation overflow checks for such instructions to 936 * not be done correctly. So bintuils 936 * not be done correctly. So bintuils will not notice the 937 * error and will instead write junk i 937 * error and will instead write junk into the relocation and 938 * you'll have an unbootable kernel. 938 * you'll have an unbootable kernel. 939 */ 939 */ 940 #include "ttable_64.S" 940 #include "ttable_64.S" 941 941 942 ! 0x0000000000428000 942 ! 0x0000000000428000 943 943 944 #include "hvcalls.S" 944 #include "hvcalls.S" 945 #include "systbls_64.S" 945 #include "systbls_64.S" 946 946 947 .data 947 .data 948 .align 8 948 .align 8 949 .globl prom_tba, tlb_type 949 .globl prom_tba, tlb_type 950 prom_tba: .xword 0 950 prom_tba: .xword 0 951 tlb_type: .word 0 /* Must NOT en 951 tlb_type: .word 0 /* Must NOT end up in BSS */ 952 EXPORT_SYMBOL(tlb_type) 952 EXPORT_SYMBOL(tlb_type) 953 .section ".fixup",#alloc,#execi 953 .section ".fixup",#alloc,#execinstr 954 954 955 ENTRY(__retl_efault) 955 ENTRY(__retl_efault) 956 retl 956 retl 957 mov -EFAULT, %o0 957 mov -EFAULT, %o0 958 ENDPROC(__retl_efault) 958 ENDPROC(__retl_efault) 959 959 960 ENTRY(__retl_o1) 960 ENTRY(__retl_o1) 961 retl 961 retl 962 mov %o1, %o0 962 mov %o1, %o0 963 ENDPROC(__retl_o1) 963 ENDPROC(__retl_o1) 964 964 965 ENTRY(__retl_o1_asi) 965 ENTRY(__retl_o1_asi) 966 wr %o5, 0x0, %asi 966 wr %o5, 0x0, %asi 967 retl 967 retl 968 mov %o1, %o0 968 mov %o1, %o0 969 ENDPROC(__retl_o1_asi) 969 ENDPROC(__retl_o1_asi)
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.