Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6

+914 -1198
+8
arch/sparc64/Kconfig.debug
··· 33 33 depends on DEBUG_KERNEL 34 34 bool "Debug BOOTMEM initialization" 35 35 36 + config DEBUG_PAGEALLOC 37 + bool "Page alloc debugging" 38 + depends on DEBUG_KERNEL && !SOFTWARE_SUSPEND 39 + help 40 + Unmap pages from the kernel linear mapping after free_pages(). 41 + This results in a large slowdown, but helps to find certain types 42 + of memory corruptions. 43 + 36 44 config MCOUNT 37 45 bool 38 46 depends on STACK_DEBUG
+22
arch/sparc64/kernel/devices.c
··· 135 135 cpu_data(0).clock_tick = prom_getintdefault(cpu_node, 136 136 "clock-frequency", 137 137 0); 138 + cpu_data(0).dcache_size = prom_getintdefault(cpu_node, 139 + "dcache-size", 140 + 16 * 1024); 141 + cpu_data(0).dcache_line_size = 142 + prom_getintdefault(cpu_node, "dcache-line-size", 32); 143 + cpu_data(0).icache_size = prom_getintdefault(cpu_node, 144 + "icache-size", 145 + 16 * 1024); 146 + cpu_data(0).icache_line_size = 147 + prom_getintdefault(cpu_node, "icache-line-size", 32); 148 + cpu_data(0).ecache_size = prom_getintdefault(cpu_node, 149 + "ecache-size", 150 + 4 * 1024 * 1024); 151 + cpu_data(0).ecache_line_size = 152 + prom_getintdefault(cpu_node, "ecache-line-size", 64); 153 + printk("CPU[0]: Caches " 154 + "D[sz(%d):line_sz(%d)] " 155 + "I[sz(%d):line_sz(%d)] " 156 + "E[sz(%d):line_sz(%d)]\n", 157 + cpu_data(0).dcache_size, cpu_data(0).dcache_line_size, 158 + cpu_data(0).icache_size, cpu_data(0).icache_line_size, 159 + cpu_data(0).ecache_size, cpu_data(0).ecache_line_size); 138 160 } 139 161 #endif 140 162
+1 -12
arch/sparc64/kernel/dtlb_backend.S
··· 9 9 #include <asm/pgtable.h> 10 10 #include <asm/mmu.h> 11 11 12 - #if PAGE_SHIFT == 13 13 - #define SZ_BITS _PAGE_SZ8K 14 - #elif PAGE_SHIFT == 16 15 - #define SZ_BITS _PAGE_SZ64K 16 - #elif PAGE_SHIFT == 19 17 - #define SZ_BITS _PAGE_SZ512K 18 - #elif PAGE_SHIFT == 22 19 - #define SZ_BITS _PAGE_SZ4MB 20 - #endif 21 - 22 - #define VALID_SZ_BITS (_PAGE_VALID | SZ_BITS) 12 + #define VALID_SZ_BITS (_PAGE_VALID | _PAGE_SZBITS) 23 13 24 14 #define VPTE_BITS (_PAGE_CP | _PAGE_CV | _PAGE_P ) 25 15 #define VPTE_SHIFT (PAGE_SHIFT - 3) ··· 153 163 stxa %g4, [%g1 + %g1] ASI_DMMU ! Restore previous TAG_ACCESS 154 164 retry ! Load PTE once again 155 165 156 - #undef SZ_BITS 157 166 #undef VALID_SZ_BITS 158 167 #undef VPTE_SHIFT 159 168 #undef VPTE_BITS
+4 -4
arch/sparc64/kernel/dtlb_base.S
··· 71 71 from_tl1_trap: 72 72 rdpr %tl, %g5 ! For TL==3 test 73 73 CREATE_VPTE_OFFSET1(%g4, %g6) ! Create VPTE offset 74 - be,pn %xcc, 3f ! Yep, special processing 74 + be,pn %xcc, kvmap ! Yep, special processing 75 75 CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset 76 76 cmp %g5, 4 ! Last trap level? 77 77 be,pn %xcc, longpath ! Yep, cannot risk VPTE miss ··· 83 83 nop ! Delay-slot 84 84 9: stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB 85 85 retry ! Trap return 86 - 3: brlz,pt %g4, 9b ! Kernel virtual map? 87 - xor %g2, %g4, %g5 ! Finish bit twiddles 88 - ba,a,pt %xcc, kvmap ! Yep, go check for obp/vmalloc 86 + nop 87 + nop 88 + nop 89 89 90 90 /* DTLB ** ICACHE line 3: winfixups+real_faults */ 91 91 longpath:
+18 -162
arch/sparc64/kernel/entry.S
··· 30 30 .text 31 31 .align 32 32 32 33 - .globl sparc64_vpte_patchme1 34 - .globl sparc64_vpte_patchme2 35 - /* 36 - * On a second level vpte miss, check whether the original fault is to the OBP 37 - * range (note that this is only possible for instruction miss, data misses to 38 - * obp range do not use vpte). If so, go back directly to the faulting address. 39 - * This is because we want to read the tpc, otherwise we have no way of knowing 40 - * the 8k aligned faulting address if we are using >8k kernel pagesize. This 41 - * also ensures no vpte range addresses are dropped into tlb while obp is 42 - * executing (see inherit_locked_prom_mappings() rant). 43 - */ 44 - sparc64_vpte_nucleus: 45 - /* Note that kvmap below has verified that the address is 46 - * in the range MODULES_VADDR --> VMALLOC_END already. So 47 - * here we need only check if it is an OBP address or not. 48 - */ 49 - sethi %hi(LOW_OBP_ADDRESS), %g5 50 - cmp %g4, %g5 51 - blu,pn %xcc, sparc64_vpte_patchme1 52 - mov 0x1, %g5 53 - sllx %g5, 32, %g5 54 - cmp %g4, %g5 55 - blu,pn %xcc, obp_iaddr_patch 56 - nop 57 - 58 - /* These two instructions are patched by paginig_init(). */ 59 - sparc64_vpte_patchme1: 60 - sethi %hi(0), %g5 61 - sparc64_vpte_patchme2: 62 - or %g5, %lo(0), %g5 63 - 64 - /* With kernel PGD in %g5, branch back into dtlb_backend. */ 65 - ba,pt %xcc, sparc64_kpte_continue 66 - andn %g1, 0x3, %g1 /* Finish PMD offset adjustment. */ 67 - 68 - vpte_noent: 69 - /* Restore previous TAG_ACCESS, %g5 is zero, and we will 70 - * skip over the trap instruction so that the top level 71 - * TLB miss handler will thing this %g5 value is just an 72 - * invalid PTE, thus branching to full fault processing. 73 - */ 74 - mov TLB_SFSR, %g1 75 - stxa %g4, [%g1 + %g1] ASI_DMMU 76 - done 77 - 78 - .globl obp_iaddr_patch 79 - obp_iaddr_patch: 80 - /* These two instructions patched by inherit_prom_mappings(). */ 81 - sethi %hi(0), %g5 82 - or %g5, %lo(0), %g5 83 - 84 - /* Behave as if we are at TL0. */ 85 - wrpr %g0, 1, %tl 86 - rdpr %tpc, %g4 /* Find original faulting iaddr */ 87 - srlx %g4, 13, %g4 /* Throw out context bits */ 88 - sllx %g4, 13, %g4 /* g4 has vpn + ctx0 now */ 89 - 90 - /* Restore previous TAG_ACCESS. */ 91 - mov TLB_SFSR, %g1 92 - stxa %g4, [%g1 + %g1] ASI_IMMU 93 - 94 - /* Get PMD offset. */ 95 - srlx %g4, 23, %g6 96 - and %g6, 0x7ff, %g6 97 - sllx %g6, 2, %g6 98 - 99 - /* Load PMD, is it valid? */ 100 - lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 101 - brz,pn %g5, longpath 102 - sllx %g5, 11, %g5 103 - 104 - /* Get PTE offset. */ 105 - srlx %g4, 13, %g6 106 - and %g6, 0x3ff, %g6 107 - sllx %g6, 3, %g6 108 - 109 - /* Load PTE. */ 110 - ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 111 - brgez,pn %g5, longpath 112 - nop 113 - 114 - /* TLB load and return from trap. */ 115 - stxa %g5, [%g0] ASI_ITLB_DATA_IN 116 - retry 117 - 118 - .globl obp_daddr_patch 119 - obp_daddr_patch: 120 - /* These two instructions patched by inherit_prom_mappings(). */ 121 - sethi %hi(0), %g5 122 - or %g5, %lo(0), %g5 123 - 124 - /* Get PMD offset. */ 125 - srlx %g4, 23, %g6 126 - and %g6, 0x7ff, %g6 127 - sllx %g6, 2, %g6 128 - 129 - /* Load PMD, is it valid? */ 130 - lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 131 - brz,pn %g5, longpath 132 - sllx %g5, 11, %g5 133 - 134 - /* Get PTE offset. */ 135 - srlx %g4, 13, %g6 136 - and %g6, 0x3ff, %g6 137 - sllx %g6, 3, %g6 138 - 139 - /* Load PTE. */ 140 - ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 141 - brgez,pn %g5, longpath 142 - nop 143 - 144 - /* TLB load and return from trap. */ 145 - stxa %g5, [%g0] ASI_DTLB_DATA_IN 146 - retry 147 - 148 - /* 149 - * On a first level data miss, check whether this is to the OBP range (note 150 - * that such accesses can be made by prom, as well as by kernel using 151 - * prom_getproperty on "address"), and if so, do not use vpte access ... 152 - * rather, use information saved during inherit_prom_mappings() using 8k 153 - * pagesize. 154 - */ 155 - .align 32 156 - kvmap: 157 - sethi %hi(MODULES_VADDR), %g5 158 - cmp %g4, %g5 159 - blu,pn %xcc, longpath 160 - mov (VMALLOC_END >> 24), %g5 161 - sllx %g5, 24, %g5 162 - cmp %g4, %g5 163 - bgeu,pn %xcc, longpath 164 - nop 165 - 166 - kvmap_check_obp: 167 - sethi %hi(LOW_OBP_ADDRESS), %g5 168 - cmp %g4, %g5 169 - blu,pn %xcc, kvmap_vmalloc_addr 170 - mov 0x1, %g5 171 - sllx %g5, 32, %g5 172 - cmp %g4, %g5 173 - blu,pn %xcc, obp_daddr_patch 174 - nop 175 - 176 - kvmap_vmalloc_addr: 177 - /* If we get here, a vmalloc addr was accessed, load kernel VPTE. */ 178 - ldxa [%g3 + %g6] ASI_N, %g5 179 - brgez,pn %g5, longpath 180 - nop 181 - 182 - /* PTE is valid, load into TLB and return from trap. */ 183 - stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB 184 - retry 185 - 186 33 /* This is trivial with the new code... */ 187 34 .globl do_fpdis 188 35 do_fpdis: ··· 372 525 * 373 526 * DATA 0: [low 32-bits] Address of function to call, jmp to this 374 527 * [high 32-bits] MMU Context Argument 0, place in %g5 375 - * DATA 1: Address Argument 1, place in %g6 528 + * DATA 1: Address Argument 1, place in %g1 376 529 * DATA 2: Address Argument 2, place in %g7 377 530 * 378 531 * With this method we can do most of the cross-call tlb/cache 379 532 * flushing very quickly. 380 533 * 381 - * Current CPU's IRQ worklist table is locked into %g1, 382 - * don't touch. 534 + * Current CPU's IRQ worklist table is locked into %g6, don't touch. 383 535 */ 384 536 .text 385 537 .align 32 ··· 852 1006 nop 853 1007 854 1008 do_cheetah_plus_data_parity: 855 - ba,pt %xcc, etrap 1009 + rdpr %pil, %g2 1010 + wrpr %g0, 15, %pil 1011 + ba,pt %xcc, etrap_irq 856 1012 rd %pc, %g7 857 1013 mov 0x0, %o0 858 1014 call cheetah_plus_parity_error 859 1015 add %sp, PTREGS_OFF, %o1 860 - ba,pt %xcc, rtrap 861 - clr %l6 1016 + ba,a,pt %xcc, rtrap_irq 862 1017 863 1018 cheetah_plus_dcpe_trap_vector_tl1: 864 1019 membar #Sync ··· 883 1036 nop 884 1037 885 1038 do_cheetah_plus_insn_parity: 886 - ba,pt %xcc, etrap 1039 + rdpr %pil, %g2 1040 + wrpr %g0, 15, %pil 1041 + ba,pt %xcc, etrap_irq 887 1042 rd %pc, %g7 888 1043 mov 0x1, %o0 889 1044 call cheetah_plus_parity_error 890 1045 add %sp, PTREGS_OFF, %o1 891 - ba,pt %xcc, rtrap 892 - clr %l6 1046 + ba,a,pt %xcc, rtrap_irq 893 1047 894 1048 cheetah_plus_icpe_trap_vector_tl1: 895 1049 membar #Sync ··· 923 1075 nop 924 1076 wrpr %g1, %tl ! Restore original trap level 925 1077 do_dcpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */ 1078 + sethi %hi(dcache_parity_tl1_occurred), %g2 1079 + lduw [%g2 + %lo(dcache_parity_tl1_occurred)], %g1 1080 + add %g1, 1, %g1 1081 + stw %g1, [%g2 + %lo(dcache_parity_tl1_occurred)] 926 1082 /* Reset D-cache parity */ 927 1083 sethi %hi(1 << 16), %g1 ! D-cache size 928 1084 mov (1 << 5), %g2 ! D-cache line size ··· 973 1121 nop 974 1122 wrpr %g1, %tl ! Restore original trap level 975 1123 do_icpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */ 1124 + sethi %hi(icache_parity_tl1_occurred), %g2 1125 + lduw [%g2 + %lo(icache_parity_tl1_occurred)], %g1 1126 + add %g1, 1, %g1 1127 + stw %g1, [%g2 + %lo(icache_parity_tl1_occurred)] 976 1128 /* Flush I-cache */ 977 1129 sethi %hi(1 << 15), %g1 ! I-cache size 978 1130 mov (1 << 5), %g2 ! I-cache line size
+161 -397
arch/sparc64/kernel/head.S
··· 80 80 .xword 0 81 81 .word _end 82 82 83 - /* We must be careful, 32-bit OpenBOOT will get confused if it 84 - * tries to save away a register window to a 64-bit kernel 85 - * stack address. Flush all windows, disable interrupts, 86 - * remap if necessary, jump onto kernel trap table, then kernel 87 - * stack, or else we die. 88 - * 89 - * PROM entry point is on %o4 90 - */ 83 + /* PROM cif handler code address is in %o4. */ 91 84 sparc64_boot: 85 + 1: rd %pc, %g7 86 + set 1b, %g1 87 + cmp %g1, %g7 88 + be,pn %xcc, sparc64_boot_after_remap 89 + mov %o4, %l7 90 + 91 + /* We need to remap the kernel. Use position independant 92 + * code to remap us to KERNBASE. 93 + * 94 + * SILO can invoke us with 32-bit address masking enabled, 95 + * so make sure that's clear. 96 + */ 97 + rdpr %pstate, %g1 98 + andn %g1, PSTATE_AM, %g1 99 + wrpr %g1, 0x0, %pstate 100 + ba,a,pt %xcc, 1f 101 + 102 + .globl prom_finddev_name, prom_chosen_path 103 + .globl prom_getprop_name, prom_mmu_name 104 + .globl prom_callmethod_name, prom_translate_name 105 + .globl prom_map_name, prom_unmap_name, prom_mmu_ihandle_cache 106 + .globl prom_boot_mapped_pc, prom_boot_mapping_mode 107 + .globl prom_boot_mapping_phys_high, prom_boot_mapping_phys_low 108 + prom_finddev_name: 109 + .asciz "finddevice" 110 + prom_chosen_path: 111 + .asciz "/chosen" 112 + prom_getprop_name: 113 + .asciz "getprop" 114 + prom_mmu_name: 115 + .asciz "mmu" 116 + prom_callmethod_name: 117 + .asciz "call-method" 118 + prom_translate_name: 119 + .asciz "translate" 120 + prom_map_name: 121 + .asciz "map" 122 + prom_unmap_name: 123 + .asciz "unmap" 124 + .align 4 125 + prom_mmu_ihandle_cache: 126 + .word 0 127 + prom_boot_mapped_pc: 128 + .word 0 129 + prom_boot_mapping_mode: 130 + .word 0 131 + .align 8 132 + prom_boot_mapping_phys_high: 133 + .xword 0 134 + prom_boot_mapping_phys_low: 135 + .xword 0 136 + 1: 137 + rd %pc, %l0 138 + mov (1b - prom_finddev_name), %l1 139 + mov (1b - prom_chosen_path), %l2 140 + mov (1b - prom_boot_mapped_pc), %l3 141 + sub %l0, %l1, %l1 142 + sub %l0, %l2, %l2 143 + sub %l0, %l3, %l3 144 + stw %l0, [%l3] 145 + sub %sp, (192 + 128), %sp 146 + 147 + /* chosen_node = prom_finddevice("/chosen") */ 148 + stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "finddevice" 149 + mov 1, %l3 150 + stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 1 151 + stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 152 + stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1, "/chosen" 153 + stx %g0, [%sp + 2047 + 128 + 0x20] ! ret1 154 + call %l7 155 + add %sp, (2047 + 128), %o0 ! argument array 156 + 157 + ldx [%sp + 2047 + 128 + 0x20], %l4 ! chosen device node 158 + 159 + mov (1b - prom_getprop_name), %l1 160 + mov (1b - prom_mmu_name), %l2 161 + mov (1b - prom_mmu_ihandle_cache), %l5 162 + sub %l0, %l1, %l1 163 + sub %l0, %l2, %l2 164 + sub %l0, %l5, %l5 165 + 166 + /* prom_mmu_ihandle_cache = prom_getint(chosen_node, "mmu") */ 167 + stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "getprop" 168 + mov 4, %l3 169 + stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 4 170 + mov 1, %l3 171 + stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 172 + stx %l4, [%sp + 2047 + 128 + 0x18] ! arg1, chosen_node 173 + stx %l2, [%sp + 2047 + 128 + 0x20] ! arg2, "mmu" 174 + stx %l5, [%sp + 2047 + 128 + 0x28] ! arg3, &prom_mmu_ihandle_cache 175 + mov 4, %l3 176 + stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4, sizeof(arg3) 177 + stx %g0, [%sp + 2047 + 128 + 0x38] ! ret1 178 + call %l7 179 + add %sp, (2047 + 128), %o0 ! argument array 180 + 181 + mov (1b - prom_callmethod_name), %l1 182 + mov (1b - prom_translate_name), %l2 183 + sub %l0, %l1, %l1 184 + sub %l0, %l2, %l2 185 + lduw [%l5], %l5 ! prom_mmu_ihandle_cache 186 + 187 + stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "call-method" 188 + mov 3, %l3 189 + stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 3 190 + mov 5, %l3 191 + stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 5 192 + stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1: "translate" 193 + stx %l5, [%sp + 2047 + 128 + 0x20] ! arg2: prom_mmu_ihandle_cache 194 + srlx %l0, 22, %l3 195 + sllx %l3, 22, %l3 196 + stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: vaddr, our PC 197 + stx %g0, [%sp + 2047 + 128 + 0x30] ! res1 198 + stx %g0, [%sp + 2047 + 128 + 0x38] ! res2 199 + stx %g0, [%sp + 2047 + 128 + 0x40] ! res3 200 + stx %g0, [%sp + 2047 + 128 + 0x48] ! res4 201 + stx %g0, [%sp + 2047 + 128 + 0x50] ! res5 202 + call %l7 203 + add %sp, (2047 + 128), %o0 ! argument array 204 + 205 + ldx [%sp + 2047 + 128 + 0x40], %l1 ! translation mode 206 + mov (1b - prom_boot_mapping_mode), %l4 207 + sub %l0, %l4, %l4 208 + stw %l1, [%l4] 209 + mov (1b - prom_boot_mapping_phys_high), %l4 210 + sub %l0, %l4, %l4 211 + ldx [%sp + 2047 + 128 + 0x48], %l2 ! physaddr high 212 + stx %l2, [%l4 + 0x0] 213 + ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low 214 + stx %l3, [%l4 + 0x8] 215 + 216 + /* Leave service as-is, "call-method" */ 217 + mov 7, %l3 218 + stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 7 219 + mov 1, %l3 220 + stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 221 + mov (1b - prom_map_name), %l3 222 + sub %l0, %l3, %l3 223 + stx %l3, [%sp + 2047 + 128 + 0x18] ! arg1: "map" 224 + /* Leave arg2 as-is, prom_mmu_ihandle_cache */ 225 + mov -1, %l3 226 + stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: mode (-1 default) 227 + sethi %hi(8 * 1024 * 1024), %l3 228 + stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4: size (8MB) 229 + sethi %hi(KERNBASE), %l3 230 + stx %l3, [%sp + 2047 + 128 + 0x38] ! arg5: vaddr (KERNBASE) 231 + stx %g0, [%sp + 2047 + 128 + 0x40] ! arg6: empty 232 + mov (1b - prom_boot_mapping_phys_low), %l3 233 + sub %l0, %l3, %l3 234 + ldx [%l3], %l3 235 + stx %l3, [%sp + 2047 + 128 + 0x48] ! arg7: phys addr 236 + call %l7 237 + add %sp, (2047 + 128), %o0 ! argument array 238 + 239 + add %sp, (192 + 128), %sp 240 + 241 + sparc64_boot_after_remap: 92 242 BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot) 93 243 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot) 94 244 ba,pt %xcc, spitfire_boot ··· 275 125 stxa %g0, [%g3] ASI_IMMU 276 126 membar #Sync 277 127 278 - wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate 279 - wr %g0, 0, %fprs 280 - 281 - /* Just like for Spitfire, we probe itlb-2 for a mapping which 282 - * matches our current %pc. We take the physical address in 283 - * that mapping and use it to make our own. 284 - */ 285 - 286 - /* %g5 holds the tlb data */ 287 - sethi %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5 288 - sllx %g5, 32, %g5 289 - or %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W | _PAGE_G), %g5 290 - 291 - /* Put PADDR tlb data mask into %g3. */ 292 - sethi %uhi(_PAGE_PADDR), %g3 293 - or %g3, %ulo(_PAGE_PADDR), %g3 294 - sllx %g3, 32, %g3 295 - sethi %hi(_PAGE_PADDR), %g7 296 - or %g7, %lo(_PAGE_PADDR), %g7 297 - or %g3, %g7, %g3 298 - 299 - set 2 << 16, %l0 /* TLB entry walker. */ 300 - set 0x1fff, %l2 /* Page mask. */ 301 - rd %pc, %l3 302 - andn %l3, %l2, %g2 /* vaddr comparator */ 303 - 304 - 1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1 305 - membar #Sync 306 - andn %g1, %l2, %g1 307 - cmp %g1, %g2 308 - be,pn %xcc, cheetah_got_tlbentry 309 - nop 310 - and %l0, (127 << 3), %g1 311 - cmp %g1, (127 << 3) 312 - blu,pt %xcc, 1b 313 - add %l0, (1 << 3), %l0 314 - 315 - /* Search the small TLB. OBP never maps us like that but 316 - * newer SILO can. 317 - */ 318 - clr %l0 319 - 320 - 1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1 321 - membar #Sync 322 - andn %g1, %l2, %g1 323 - cmp %g1, %g2 324 - be,pn %xcc, cheetah_got_tlbentry 325 - nop 326 - cmp %l0, (15 << 3) 327 - blu,pt %xcc, 1b 328 - add %l0, (1 << 3), %l0 329 - 330 - /* BUG() if we get here... */ 331 - ta 0x5 332 - 333 - cheetah_got_tlbentry: 334 - ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g0 335 - ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1 336 - membar #Sync 337 - and %g1, %g3, %g1 338 - set 0x5fff, %l0 339 - andn %g1, %l0, %g1 340 - or %g5, %g1, %g5 341 - 342 - /* Clear out any KERNBASE area entries. */ 343 - set 2 << 16, %l0 344 - sethi %hi(KERNBASE), %g3 345 - sethi %hi(KERNBASE<<1), %g7 346 - mov TLB_TAG_ACCESS, %l7 347 - 348 - /* First, check ITLB */ 349 - 1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1 350 - membar #Sync 351 - andn %g1, %l2, %g1 352 - cmp %g1, %g3 353 - blu,pn %xcc, 2f 354 - cmp %g1, %g7 355 - bgeu,pn %xcc, 2f 356 - nop 357 - stxa %g0, [%l7] ASI_IMMU 358 - membar #Sync 359 - stxa %g0, [%l0] ASI_ITLB_DATA_ACCESS 360 - membar #Sync 361 - 362 - 2: and %l0, (127 << 3), %g1 363 - cmp %g1, (127 << 3) 364 - blu,pt %xcc, 1b 365 - add %l0, (1 << 3), %l0 366 - 367 - /* Next, check DTLB */ 368 - set 2 << 16, %l0 369 - 1: ldxa [%l0] ASI_DTLB_TAG_READ, %g1 370 - membar #Sync 371 - andn %g1, %l2, %g1 372 - cmp %g1, %g3 373 - blu,pn %xcc, 2f 374 - cmp %g1, %g7 375 - bgeu,pn %xcc, 2f 376 - nop 377 - stxa %g0, [%l7] ASI_DMMU 378 - membar #Sync 379 - stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS 380 - membar #Sync 381 - 382 - 2: and %l0, (511 << 3), %g1 383 - cmp %g1, (511 << 3) 384 - blu,pt %xcc, 1b 385 - add %l0, (1 << 3), %l0 386 - 387 - /* On Cheetah+, have to check second DTLB. */ 388 - BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,l0,2f) 389 - ba,pt %xcc, 9f 390 - nop 391 - 392 - 2: set 3 << 16, %l0 393 - 1: ldxa [%l0] ASI_DTLB_TAG_READ, %g1 394 - membar #Sync 395 - andn %g1, %l2, %g1 396 - cmp %g1, %g3 397 - blu,pn %xcc, 2f 398 - cmp %g1, %g7 399 - bgeu,pn %xcc, 2f 400 - nop 401 - stxa %g0, [%l7] ASI_DMMU 402 - membar #Sync 403 - stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS 404 - membar #Sync 405 - 406 - 2: and %l0, (511 << 3), %g1 407 - cmp %g1, (511 << 3) 408 - blu,pt %xcc, 1b 409 - add %l0, (1 << 3), %l0 410 - 411 - 9: 412 - 413 - /* Now lock the TTE we created into ITLB-0 and DTLB-0, 414 - * entry 15 (and maybe 14 too). 415 - */ 416 - sethi %hi(KERNBASE), %g3 417 - set (0 << 16) | (15 << 3), %g7 418 - stxa %g3, [%l7] ASI_DMMU 419 - membar #Sync 420 - stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS 421 - membar #Sync 422 - stxa %g3, [%l7] ASI_IMMU 423 - membar #Sync 424 - stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS 425 - membar #Sync 426 - flush %g3 427 - membar #Sync 428 - sethi %hi(_end), %g3 /* Check for bigkernel case */ 429 - or %g3, %lo(_end), %g3 430 - srl %g3, 23, %g3 /* Check if _end > 8M */ 431 - brz,pt %g3, 1f 432 - sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */ 433 - sethi %hi(0x400000), %g3 434 - or %g3, %lo(0x400000), %g3 435 - add %g5, %g3, %g5 /* New tte data */ 436 - andn %g5, (_PAGE_G), %g5 437 - sethi %hi(KERNBASE+0x400000), %g3 438 - or %g3, %lo(KERNBASE+0x400000), %g3 439 - set (0 << 16) | (14 << 3), %g7 440 - stxa %g3, [%l7] ASI_DMMU 441 - membar #Sync 442 - stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS 443 - membar #Sync 444 - stxa %g3, [%l7] ASI_IMMU 445 - membar #Sync 446 - stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS 447 - membar #Sync 448 - flush %g3 449 - membar #Sync 450 - sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */ 451 - ba,pt %xcc, 1f 452 - nop 453 - 454 - 1: set sun4u_init, %g2 455 - jmpl %g2 + %g0, %g0 456 - nop 128 + ba,a,pt %xcc, jump_to_sun4u_init 457 129 458 130 spitfire_boot: 459 131 /* Typically PROM has already enabled both MMU's and both on-chip ··· 285 313 stxa %g1, [%g0] ASI_LSU_CONTROL 286 314 membar #Sync 287 315 316 + jump_to_sun4u_init: 288 317 /* 289 318 * Make sure we are in privileged mode, have address masking, 290 319 * using the ordinary globals and have enabled floating ··· 297 324 wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate 298 325 wr %g0, 0, %fprs 299 326 300 - spitfire_create_mappings: 301 - /* %g5 holds the tlb data */ 302 - sethi %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5 303 - sllx %g5, 32, %g5 304 - or %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W | _PAGE_G), %g5 305 - 306 - /* Base of physical memory cannot reliably be assumed to be 307 - * at 0x0! Figure out where it happens to be. -DaveM 308 - */ 309 - 310 - /* Put PADDR tlb data mask into %g3. */ 311 - sethi %uhi(_PAGE_PADDR_SF), %g3 312 - or %g3, %ulo(_PAGE_PADDR_SF), %g3 313 - sllx %g3, 32, %g3 314 - sethi %hi(_PAGE_PADDR_SF), %g7 315 - or %g7, %lo(_PAGE_PADDR_SF), %g7 316 - or %g3, %g7, %g3 317 - 318 - /* Walk through entire ITLB, looking for entry which maps 319 - * our %pc currently, stick PADDR from there into %g5 tlb data. 320 - */ 321 - clr %l0 /* TLB entry walker. */ 322 - set 0x1fff, %l2 /* Page mask. */ 323 - rd %pc, %l3 324 - andn %l3, %l2, %g2 /* vaddr comparator */ 325 - 1: 326 - /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */ 327 - ldxa [%l0] ASI_ITLB_TAG_READ, %g1 328 - nop 329 - nop 330 - nop 331 - andn %g1, %l2, %g1 /* Get vaddr */ 332 - cmp %g1, %g2 333 - be,a,pn %xcc, spitfire_got_tlbentry 334 - ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1 335 - cmp %l0, (63 << 3) 336 - blu,pt %xcc, 1b 337 - add %l0, (1 << 3), %l0 338 - 339 - /* BUG() if we get here... */ 340 - ta 0x5 341 - 342 - spitfire_got_tlbentry: 343 - /* Nops here again, perhaps Cheetah/Blackbird are better behaved... */ 344 - nop 345 - nop 346 - nop 347 - and %g1, %g3, %g1 /* Mask to just get paddr bits. */ 348 - set 0x5fff, %l3 /* Mask offset to get phys base. */ 349 - andn %g1, %l3, %g1 350 - 351 - /* NOTE: We hold on to %g1 paddr base as we need it below to lock 352 - * NOTE: the PROM cif code into the TLB. 353 - */ 354 - 355 - or %g5, %g1, %g5 /* Or it into TAG being built. */ 356 - 357 - clr %l0 /* TLB entry walker. */ 358 - sethi %hi(KERNBASE), %g3 /* 4M lower limit */ 359 - sethi %hi(KERNBASE<<1), %g7 /* 8M upper limit */ 360 - mov TLB_TAG_ACCESS, %l7 361 - 1: 362 - /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */ 363 - ldxa [%l0] ASI_ITLB_TAG_READ, %g1 364 - nop 365 - nop 366 - nop 367 - andn %g1, %l2, %g1 /* Get vaddr */ 368 - cmp %g1, %g3 369 - blu,pn %xcc, 2f 370 - cmp %g1, %g7 371 - bgeu,pn %xcc, 2f 372 - nop 373 - stxa %g0, [%l7] ASI_IMMU 374 - stxa %g0, [%l0] ASI_ITLB_DATA_ACCESS 375 - membar #Sync 376 - 2: 377 - cmp %l0, (63 << 3) 378 - blu,pt %xcc, 1b 379 - add %l0, (1 << 3), %l0 380 - 381 - nop; nop; nop 382 - 383 - clr %l0 /* TLB entry walker. */ 384 - 1: 385 - /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */ 386 - ldxa [%l0] ASI_DTLB_TAG_READ, %g1 387 - nop 388 - nop 389 - nop 390 - andn %g1, %l2, %g1 /* Get vaddr */ 391 - cmp %g1, %g3 392 - blu,pn %xcc, 2f 393 - cmp %g1, %g7 394 - bgeu,pn %xcc, 2f 395 - nop 396 - stxa %g0, [%l7] ASI_DMMU 397 - stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS 398 - membar #Sync 399 - 2: 400 - cmp %l0, (63 << 3) 401 - blu,pt %xcc, 1b 402 - add %l0, (1 << 3), %l0 403 - 404 - nop; nop; nop 405 - 406 - 407 - /* PROM never puts any TLB entries into the MMU with the lock bit 408 - * set. So we gladly use tlb entry 63 for KERNBASE. And maybe 62 too. 409 - */ 410 - 411 - sethi %hi(KERNBASE), %g3 412 - mov (63 << 3), %g7 413 - stxa %g3, [%l7] ASI_DMMU /* KERNBASE into TLB TAG */ 414 - stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS /* TTE into TLB DATA */ 415 - membar #Sync 416 - stxa %g3, [%l7] ASI_IMMU /* KERNBASE into TLB TAG */ 417 - stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS /* TTE into TLB DATA */ 418 - membar #Sync 419 - flush %g3 420 - membar #Sync 421 - sethi %hi(_end), %g3 /* Check for bigkernel case */ 422 - or %g3, %lo(_end), %g3 423 - srl %g3, 23, %g3 /* Check if _end > 8M */ 424 - brz,pt %g3, 2f 425 - sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */ 426 - sethi %hi(0x400000), %g3 427 - or %g3, %lo(0x400000), %g3 428 - add %g5, %g3, %g5 /* New tte data */ 429 - andn %g5, (_PAGE_G), %g5 430 - sethi %hi(KERNBASE+0x400000), %g3 431 - or %g3, %lo(KERNBASE+0x400000), %g3 432 - mov (62 << 3), %g7 433 - stxa %g3, [%l7] ASI_DMMU 434 - stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS 435 - membar #Sync 436 - stxa %g3, [%l7] ASI_IMMU 437 - stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS 438 - membar #Sync 439 - flush %g3 440 - membar #Sync 441 - sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */ 442 - 2: ba,pt %xcc, 1f 443 - nop 444 - 1: 445 327 set sun4u_init, %g2 446 328 jmpl %g2 + %g0, %g0 447 329 nop ··· 311 483 stxa %g0, [%g7] ASI_DMMU 312 484 membar #Sync 313 485 314 - /* We are now safely (we hope) in Nucleus context (0), rewrite 315 - * the KERNBASE TTE's so they no longer have the global bit set. 316 - * Don't forget to setup TAG_ACCESS first 8-) 317 - */ 318 - mov TLB_TAG_ACCESS, %g2 319 - stxa %g3, [%g2] ASI_IMMU 320 - stxa %g3, [%g2] ASI_DMMU 321 - membar #Sync 322 - 323 486 BRANCH_IF_ANY_CHEETAH(g1,g7,cheetah_tlb_fixup) 324 487 325 488 ba,pt %xcc, spitfire_tlb_fixup 326 489 nop 327 490 328 491 cheetah_tlb_fixup: 329 - set (0 << 16) | (15 << 3), %g7 330 - ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g0 331 - ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1 332 - andn %g1, (_PAGE_G), %g1 333 - stxa %g1, [%g7] ASI_ITLB_DATA_ACCESS 334 - membar #Sync 335 - 336 - ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g0 337 - ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g1 338 - andn %g1, (_PAGE_G), %g1 339 - stxa %g1, [%g7] ASI_DTLB_DATA_ACCESS 340 - membar #Sync 341 - 342 - /* Kill instruction prefetch queues. */ 343 - flush %g3 344 - membar #Sync 345 - 346 492 mov 2, %g2 /* Set TLB type to cheetah+. */ 347 493 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f) 348 494 ··· 353 551 nop 354 552 355 553 spitfire_tlb_fixup: 356 - mov (63 << 3), %g7 357 - ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1 358 - andn %g1, (_PAGE_G), %g1 359 - stxa %g1, [%g7] ASI_ITLB_DATA_ACCESS 360 - membar #Sync 361 - 362 - ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g1 363 - andn %g1, (_PAGE_G), %g1 364 - stxa %g1, [%g7] ASI_DTLB_DATA_ACCESS 365 - membar #Sync 366 - 367 - /* Kill instruction prefetch queues. */ 368 - flush %g3 369 - membar #Sync 370 - 371 554 /* Set TLB type to spitfire. */ 372 555 mov 0, %g2 373 556 sethi %hi(tlb_type), %g1 ··· 364 577 ldx [%g6 + TI_TASK], %g4 365 578 mov %sp, %l6 366 579 mov %o4, %l7 367 - 368 - #if 0 /* We don't do it like this anymore, but for historical hack value 369 - * I leave this snippet here to show how crazy we can be sometimes. 8-) 370 - */ 371 - 372 - /* Setup "Linux Current Register", thanks Sun 8-) */ 373 - wr %g0, 0x1, %pcr 374 - 375 - /* Blackbird errata workaround. See commentary in 376 - * smp.c:smp_percpu_timer_interrupt() for more 377 - * information. 378 - */ 379 - ba,pt %xcc, 99f 380 - nop 381 - .align 64 382 - 99: wr %g6, %g0, %pic 383 - rd %pic, %g0 384 - #endif 385 580 386 581 wr %g0, ASI_P, %asi 387 582 mov 1, %g1 ··· 525 756 526 757 #include "ttable.S" 527 758 #include "systbls.S" 528 - 529 - .align 1024 530 - .globl swapper_pg_dir 531 - swapper_pg_dir: 532 - .word 0 533 - 759 + #include "ktlb.S" 534 760 #include "etrap.S" 535 761 #include "rtrap.S" 536 762 #include "winfixup.S"
+198
arch/sparc64/kernel/ktlb.S
··· 1 + /* arch/sparc64/kernel/ktlb.S: Kernel mapping TLB miss handling. 2 + * 3 + * Copyright (C) 1995, 1997, 2005 David S. Miller <davem@davemloft.net> 4 + * Copyright (C) 1996 Eddie C. Dost (ecd@brainaid.de) 5 + * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) 6 + * Copyright (C) 1996,98,99 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 7 + */ 8 + 9 + #include <linux/config.h> 10 + #include <asm/head.h> 11 + #include <asm/asi.h> 12 + #include <asm/page.h> 13 + #include <asm/pgtable.h> 14 + 15 + .text 16 + .align 32 17 + 18 + /* 19 + * On a second level vpte miss, check whether the original fault is to the OBP 20 + * range (note that this is only possible for instruction miss, data misses to 21 + * obp range do not use vpte). If so, go back directly to the faulting address. 22 + * This is because we want to read the tpc, otherwise we have no way of knowing 23 + * the 8k aligned faulting address if we are using >8k kernel pagesize. This 24 + * also ensures no vpte range addresses are dropped into tlb while obp is 25 + * executing (see inherit_locked_prom_mappings() rant). 26 + */ 27 + sparc64_vpte_nucleus: 28 + /* Note that kvmap below has verified that the address is 29 + * in the range MODULES_VADDR --> VMALLOC_END already. So 30 + * here we need only check if it is an OBP address or not. 31 + */ 32 + sethi %hi(LOW_OBP_ADDRESS), %g5 33 + cmp %g4, %g5 34 + blu,pn %xcc, kern_vpte 35 + mov 0x1, %g5 36 + sllx %g5, 32, %g5 37 + cmp %g4, %g5 38 + blu,pn %xcc, vpte_insn_obp 39 + nop 40 + 41 + /* These two instructions are patched by paginig_init(). */ 42 + kern_vpte: 43 + sethi %hi(swapper_pgd_zero), %g5 44 + lduw [%g5 + %lo(swapper_pgd_zero)], %g5 45 + 46 + /* With kernel PGD in %g5, branch back into dtlb_backend. */ 47 + ba,pt %xcc, sparc64_kpte_continue 48 + andn %g1, 0x3, %g1 /* Finish PMD offset adjustment. */ 49 + 50 + vpte_noent: 51 + /* Restore previous TAG_ACCESS, %g5 is zero, and we will 52 + * skip over the trap instruction so that the top level 53 + * TLB miss handler will thing this %g5 value is just an 54 + * invalid PTE, thus branching to full fault processing. 55 + */ 56 + mov TLB_SFSR, %g1 57 + stxa %g4, [%g1 + %g1] ASI_DMMU 58 + done 59 + 60 + vpte_insn_obp: 61 + sethi %hi(prom_pmd_phys), %g5 62 + ldx [%g5 + %lo(prom_pmd_phys)], %g5 63 + 64 + /* Behave as if we are at TL0. */ 65 + wrpr %g0, 1, %tl 66 + rdpr %tpc, %g4 /* Find original faulting iaddr */ 67 + srlx %g4, 13, %g4 /* Throw out context bits */ 68 + sllx %g4, 13, %g4 /* g4 has vpn + ctx0 now */ 69 + 70 + /* Restore previous TAG_ACCESS. */ 71 + mov TLB_SFSR, %g1 72 + stxa %g4, [%g1 + %g1] ASI_IMMU 73 + 74 + /* Get PMD offset. */ 75 + srlx %g4, 23, %g6 76 + and %g6, 0x7ff, %g6 77 + sllx %g6, 2, %g6 78 + 79 + /* Load PMD, is it valid? */ 80 + lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 81 + brz,pn %g5, longpath 82 + sllx %g5, 11, %g5 83 + 84 + /* Get PTE offset. */ 85 + srlx %g4, 13, %g6 86 + and %g6, 0x3ff, %g6 87 + sllx %g6, 3, %g6 88 + 89 + /* Load PTE. */ 90 + ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 91 + brgez,pn %g5, longpath 92 + nop 93 + 94 + /* TLB load and return from trap. */ 95 + stxa %g5, [%g0] ASI_ITLB_DATA_IN 96 + retry 97 + 98 + kvmap_do_obp: 99 + sethi %hi(prom_pmd_phys), %g5 100 + ldx [%g5 + %lo(prom_pmd_phys)], %g5 101 + 102 + /* Get PMD offset. */ 103 + srlx %g4, 23, %g6 104 + and %g6, 0x7ff, %g6 105 + sllx %g6, 2, %g6 106 + 107 + /* Load PMD, is it valid? */ 108 + lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 109 + brz,pn %g5, longpath 110 + sllx %g5, 11, %g5 111 + 112 + /* Get PTE offset. */ 113 + srlx %g4, 13, %g6 114 + and %g6, 0x3ff, %g6 115 + sllx %g6, 3, %g6 116 + 117 + /* Load PTE. */ 118 + ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 119 + brgez,pn %g5, longpath 120 + nop 121 + 122 + /* TLB load and return from trap. */ 123 + stxa %g5, [%g0] ASI_DTLB_DATA_IN 124 + retry 125 + 126 + /* 127 + * On a first level data miss, check whether this is to the OBP range (note 128 + * that such accesses can be made by prom, as well as by kernel using 129 + * prom_getproperty on "address"), and if so, do not use vpte access ... 130 + * rather, use information saved during inherit_prom_mappings() using 8k 131 + * pagesize. 132 + */ 133 + .align 32 134 + kvmap: 135 + brgez,pn %g4, kvmap_nonlinear 136 + nop 137 + 138 + #ifdef CONFIG_DEBUG_PAGEALLOC 139 + .globl kvmap_linear_patch 140 + kvmap_linear_patch: 141 + #endif 142 + ba,pt %xcc, kvmap_load 143 + xor %g2, %g4, %g5 144 + 145 + #ifdef CONFIG_DEBUG_PAGEALLOC 146 + sethi %hi(swapper_pg_dir), %g5 147 + or %g5, %lo(swapper_pg_dir), %g5 148 + sllx %g4, 64 - (PGDIR_SHIFT + PGDIR_BITS), %g6 149 + srlx %g6, 64 - PAGE_SHIFT, %g6 150 + andn %g6, 0x3, %g6 151 + lduw [%g5 + %g6], %g5 152 + brz,pn %g5, longpath 153 + sllx %g4, 64 - (PMD_SHIFT + PMD_BITS), %g6 154 + srlx %g6, 64 - PAGE_SHIFT, %g6 155 + sllx %g5, 11, %g5 156 + andn %g6, 0x3, %g6 157 + lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 158 + brz,pn %g5, longpath 159 + sllx %g4, 64 - PMD_SHIFT, %g6 160 + srlx %g6, 64 - PAGE_SHIFT, %g6 161 + sllx %g5, 11, %g5 162 + andn %g6, 0x7, %g6 163 + ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 164 + brz,pn %g5, longpath 165 + nop 166 + ba,a,pt %xcc, kvmap_load 167 + #endif 168 + 169 + kvmap_nonlinear: 170 + sethi %hi(MODULES_VADDR), %g5 171 + cmp %g4, %g5 172 + blu,pn %xcc, longpath 173 + mov (VMALLOC_END >> 24), %g5 174 + sllx %g5, 24, %g5 175 + cmp %g4, %g5 176 + bgeu,pn %xcc, longpath 177 + nop 178 + 179 + kvmap_check_obp: 180 + sethi %hi(LOW_OBP_ADDRESS), %g5 181 + cmp %g4, %g5 182 + blu,pn %xcc, kvmap_vmalloc_addr 183 + mov 0x1, %g5 184 + sllx %g5, 32, %g5 185 + cmp %g4, %g5 186 + blu,pn %xcc, kvmap_do_obp 187 + nop 188 + 189 + kvmap_vmalloc_addr: 190 + /* If we get here, a vmalloc addr was accessed, load kernel VPTE. */ 191 + ldxa [%g3 + %g6] ASI_N, %g5 192 + brgez,pn %g5, longpath 193 + nop 194 + 195 + kvmap_load: 196 + /* PTE is valid, load into TLB and return from trap. */ 197 + stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB 198 + retry
+1 -1
arch/sparc64/kernel/pci_schizo.c
··· 330 330 static void tomatillo_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2) 331 331 { 332 332 unsigned long sync_reg = (unsigned long) _arg2; 333 - u64 mask = 1 << (__irq_ino(__irq(bucket)) & IMAP_INO); 333 + u64 mask = 1UL << (__irq_ino(__irq(bucket)) & IMAP_INO); 334 334 u64 val; 335 335 int limit; 336 336
+9 -22
arch/sparc64/kernel/setup.c
··· 496 496 497 497 void __init setup_arch(char **cmdline_p) 498 498 { 499 - unsigned long highest_paddr; 500 499 int i; 501 500 502 501 /* Initialize PROM console and command line. */ ··· 518 519 idprom_init(); 519 520 (void) prom_probe_memory(); 520 521 521 - /* In paging_init() we tip off this value to see if we need 522 - * to change init_mm.pgd to point to the real alias mapping. 523 - */ 524 522 phys_base = 0xffffffffffffffffUL; 525 - highest_paddr = 0UL; 526 523 for (i = 0; sp_banks[i].num_bytes != 0; i++) { 527 524 unsigned long top; 528 525 ··· 526 531 phys_base = sp_banks[i].base_addr; 527 532 top = sp_banks[i].base_addr + 528 533 sp_banks[i].num_bytes; 529 - if (highest_paddr < top) 530 - highest_paddr = top; 531 534 } 532 535 pfn_base = phys_base >> PAGE_SHIFT; 533 536 534 - switch (tlb_type) { 535 - default: 536 - case spitfire: 537 - kern_base = spitfire_get_itlb_data(sparc64_highest_locked_tlbent()); 538 - kern_base &= _PAGE_PADDR_SF; 539 - break; 540 - 541 - case cheetah: 542 - case cheetah_plus: 543 - kern_base = cheetah_get_litlb_data(sparc64_highest_locked_tlbent()); 544 - kern_base &= _PAGE_PADDR; 545 - break; 546 - }; 547 - 537 + kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL; 548 538 kern_size = (unsigned long)&_end - (unsigned long)KERNBASE; 549 539 550 540 if (!root_flags) ··· 605 625 extern void smp_bogo(struct seq_file *); 606 626 extern void mmu_info(struct seq_file *); 607 627 628 + unsigned int dcache_parity_tl1_occurred; 629 + unsigned int icache_parity_tl1_occurred; 630 + 608 631 static int show_cpuinfo(struct seq_file *m, void *__unused) 609 632 { 610 633 seq_printf(m, ··· 618 635 "type\t\t: sun4u\n" 619 636 "ncpus probed\t: %ld\n" 620 637 "ncpus active\t: %ld\n" 638 + "D$ parity tl1\t: %u\n" 639 + "I$ parity tl1\t: %u\n" 621 640 #ifndef CONFIG_SMP 622 641 "Cpu0Bogo\t: %lu.%02lu\n" 623 642 "Cpu0ClkTck\t: %016lx\n" ··· 632 647 (prom_prev >> 8) & 0xff, 633 648 prom_prev & 0xff, 634 649 (long)num_possible_cpus(), 635 - (long)num_online_cpus() 650 + (long)num_online_cpus(), 651 + dcache_parity_tl1_occurred, 652 + icache_parity_tl1_occurred 636 653 #ifndef CONFIG_SMP 637 654 , cpu_data(0).udelay_val/(500000/HZ), 638 655 (cpu_data(0).udelay_val/(5000/HZ)) % 100,
+21
arch/sparc64/kernel/smp.c
··· 93 93 cpu_data(id).pte_cache[1] = NULL; 94 94 cpu_data(id).pgd_cache = NULL; 95 95 cpu_data(id).idle_volume = 1; 96 + 97 + cpu_data(id).dcache_size = prom_getintdefault(cpu_node, "dcache-size", 98 + 16 * 1024); 99 + cpu_data(id).dcache_line_size = 100 + prom_getintdefault(cpu_node, "dcache-line-size", 32); 101 + cpu_data(id).icache_size = prom_getintdefault(cpu_node, "icache-size", 102 + 16 * 1024); 103 + cpu_data(id).icache_line_size = 104 + prom_getintdefault(cpu_node, "icache-line-size", 32); 105 + cpu_data(id).ecache_size = prom_getintdefault(cpu_node, "ecache-size", 106 + 4 * 1024 * 1024); 107 + cpu_data(id).ecache_line_size = 108 + prom_getintdefault(cpu_node, "ecache-line-size", 64); 109 + printk("CPU[%d]: Caches " 110 + "D[sz(%d):line_sz(%d)] " 111 + "I[sz(%d):line_sz(%d)] " 112 + "E[sz(%d):line_sz(%d)]\n", 113 + id, 114 + cpu_data(id).dcache_size, cpu_data(id).dcache_line_size, 115 + cpu_data(id).icache_size, cpu_data(id).icache_line_size, 116 + cpu_data(id).ecache_size, cpu_data(id).ecache_line_size); 96 117 } 97 118 98 119 static void smp_setup_percpu_timer(void);
+8 -8
arch/sparc64/kernel/trampoline.S
··· 119 119 sethi %hi(itlb_load), %g2 120 120 or %g2, %lo(itlb_load), %g2 121 121 stx %g2, [%sp + 2047 + 128 + 0x18] 122 - sethi %hi(mmu_ihandle_cache), %g2 123 - lduw [%g2 + %lo(mmu_ihandle_cache)], %g2 122 + sethi %hi(prom_mmu_ihandle_cache), %g2 123 + lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2 124 124 stx %g2, [%sp + 2047 + 128 + 0x20] 125 125 sethi %hi(KERNBASE), %g2 126 126 stx %g2, [%sp + 2047 + 128 + 0x28] ··· 156 156 sethi %hi(itlb_load), %g2 157 157 or %g2, %lo(itlb_load), %g2 158 158 stx %g2, [%sp + 2047 + 128 + 0x18] 159 - sethi %hi(mmu_ihandle_cache), %g2 160 - lduw [%g2 + %lo(mmu_ihandle_cache)], %g2 159 + sethi %hi(prom_mmu_ihandle_cache), %g2 160 + lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2 161 161 stx %g2, [%sp + 2047 + 128 + 0x20] 162 162 sethi %hi(KERNBASE + 0x400000), %g2 163 163 stx %g2, [%sp + 2047 + 128 + 0x28] ··· 190 190 sethi %hi(dtlb_load), %g2 191 191 or %g2, %lo(dtlb_load), %g2 192 192 stx %g2, [%sp + 2047 + 128 + 0x18] 193 - sethi %hi(mmu_ihandle_cache), %g2 194 - lduw [%g2 + %lo(mmu_ihandle_cache)], %g2 193 + sethi %hi(prom_mmu_ihandle_cache), %g2 194 + lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2 195 195 stx %g2, [%sp + 2047 + 128 + 0x20] 196 196 sethi %hi(KERNBASE), %g2 197 197 stx %g2, [%sp + 2047 + 128 + 0x28] ··· 228 228 sethi %hi(dtlb_load), %g2 229 229 or %g2, %lo(dtlb_load), %g2 230 230 stx %g2, [%sp + 2047 + 128 + 0x18] 231 - sethi %hi(mmu_ihandle_cache), %g2 232 - lduw [%g2 + %lo(mmu_ihandle_cache)], %g2 231 + sethi %hi(prom_mmu_ihandle_cache), %g2 232 + lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2 233 233 stx %g2, [%sp + 2047 + 128 + 0x20] 234 234 sethi %hi(KERNBASE + 0x400000), %g2 235 235 stx %g2, [%sp + 2047 + 128 + 0x28]
+27 -13
arch/sparc64/kernel/traps.c
··· 869 869 */ 870 870 static void __cheetah_flush_icache(void) 871 871 { 872 - unsigned long i; 872 + unsigned int icache_size, icache_line_size; 873 + unsigned long addr; 874 + 875 + icache_size = local_cpu_data().icache_size; 876 + icache_line_size = local_cpu_data().icache_line_size; 873 877 874 878 /* Clear the valid bits in all the tags. */ 875 - for (i = 0; i < (1 << 15); i += (1 << 5)) { 879 + for (addr = 0; addr < icache_size; addr += icache_line_size) { 876 880 __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" 877 881 "membar #Sync" 878 882 : /* no outputs */ 879 - : "r" (i | (2 << 3)), "i" (ASI_IC_TAG)); 883 + : "r" (addr | (2 << 3)), 884 + "i" (ASI_IC_TAG)); 880 885 } 881 886 } 882 887 ··· 909 904 910 905 static void cheetah_flush_dcache(void) 911 906 { 912 - unsigned long i; 907 + unsigned int dcache_size, dcache_line_size; 908 + unsigned long addr; 913 909 914 - for (i = 0; i < (1 << 16); i += (1 << 5)) { 910 + dcache_size = local_cpu_data().dcache_size; 911 + dcache_line_size = local_cpu_data().dcache_line_size; 912 + 913 + for (addr = 0; addr < dcache_size; addr += dcache_line_size) { 915 914 __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" 916 915 "membar #Sync" 917 916 : /* no outputs */ 918 - : "r" (i), "i" (ASI_DCACHE_TAG)); 917 + : "r" (addr), "i" (ASI_DCACHE_TAG)); 919 918 } 920 919 } 921 920 ··· 930 921 */ 931 922 static void cheetah_plus_zap_dcache_parity(void) 932 923 { 933 - unsigned long i; 924 + unsigned int dcache_size, dcache_line_size; 925 + unsigned long addr; 934 926 935 - for (i = 0; i < (1 << 16); i += (1 << 5)) { 936 - unsigned long tag = (i >> 14); 937 - unsigned long j; 927 + dcache_size = local_cpu_data().dcache_size; 928 + dcache_line_size = local_cpu_data().dcache_line_size; 929 + 930 + for (addr = 0; addr < dcache_size; addr += dcache_line_size) { 931 + unsigned long tag = (addr >> 14); 932 + unsigned long line; 938 933 939 934 __asm__ __volatile__("membar #Sync\n\t" 940 935 "stxa %0, [%1] %2\n\t" 941 936 "membar #Sync" 942 937 : /* no outputs */ 943 - : "r" (tag), "r" (i), 938 + : "r" (tag), "r" (addr), 944 939 "i" (ASI_DCACHE_UTAG)); 945 - for (j = i; j < i + (1 << 5); j += (1 << 3)) 940 + for (line = addr; line < addr + dcache_line_size; line += 8) 946 941 __asm__ __volatile__("membar #Sync\n\t" 947 942 "stxa %%g0, [%0] %1\n\t" 948 943 "membar #Sync" 949 944 : /* no outputs */ 950 - : "r" (j), "i" (ASI_DCACHE_DATA)); 945 + : "r" (line), 946 + "i" (ASI_DCACHE_DATA)); 951 947 } 952 948 } 953 949
+1 -2
arch/sparc64/kernel/vmlinux.lds.S
··· 9 9 jiffies = jiffies_64; 10 10 SECTIONS 11 11 { 12 - swapper_pmd_dir = 0x0000000000402000; 13 - empty_pg_dir = 0x0000000000403000; 12 + swapper_low_pmd_dir = 0x0000000000402000; 14 13 . = 0x4000; 15 14 .text 0x0000000000404000 : 16 15 {
+313 -361
arch/sparc64/mm/init.c
··· 20 20 #include <linux/fs.h> 21 21 #include <linux/seq_file.h> 22 22 #include <linux/kprobes.h> 23 + #include <linux/cache.h> 23 24 24 25 #include <asm/head.h> 25 26 #include <asm/system.h> ··· 43 42 44 43 struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS]; 45 44 46 - unsigned long *sparc64_valid_addr_bitmap; 45 + unsigned long *sparc64_valid_addr_bitmap __read_mostly; 47 46 48 47 /* Ugly, but necessary... -DaveM */ 49 - unsigned long phys_base; 50 - unsigned long kern_base; 51 - unsigned long kern_size; 52 - unsigned long pfn_base; 53 - 54 - /* This is even uglier. We have a problem where the kernel may not be 55 - * located at phys_base. However, initial __alloc_bootmem() calls need to 56 - * be adjusted to be within the 4-8Megs that the kernel is mapped to, else 57 - * those page mappings wont work. Things are ok after inherit_prom_mappings 58 - * is called though. Dave says he'll clean this up some other time. 59 - * -- BenC 60 - */ 61 - static unsigned long bootmap_base; 48 + unsigned long phys_base __read_mostly; 49 + unsigned long kern_base __read_mostly; 50 + unsigned long kern_size __read_mostly; 51 + unsigned long pfn_base __read_mostly; 62 52 63 53 /* get_new_mmu_context() uses "cache + 1". */ 64 54 DEFINE_SPINLOCK(ctx_alloc_lock); ··· 65 73 extern unsigned int sparc_ramdisk_image; 66 74 extern unsigned int sparc_ramdisk_size; 67 75 68 - struct page *mem_map_zero; 76 + struct page *mem_map_zero __read_mostly; 69 77 70 78 int bigkernel = 0; 71 79 ··· 171 179 : "g1", "g7"); 172 180 } 173 181 174 - extern void __update_mmu_cache(unsigned long mmu_context_hw, unsigned long address, pte_t pte, int code); 175 - 176 182 void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) 177 183 { 178 184 struct page *page; ··· 197 207 198 208 put_cpu(); 199 209 } 200 - 201 - if (get_thread_fault_code()) 202 - __update_mmu_cache(CTX_NRBITS(vma->vm_mm->context), 203 - address, pte, get_thread_fault_code()); 204 210 } 205 211 206 212 void flush_dcache_page(struct page *page) ··· 295 309 unsigned long size; 296 310 unsigned long data; 297 311 }; 312 + static struct linux_prom_translation prom_trans[512] __initdata; 298 313 299 314 extern unsigned long prom_boot_page; 300 315 extern void prom_remap(unsigned long physpage, unsigned long virtpage, int mmu_ihandle); ··· 305 318 /* Exported for SMP bootup purposes. */ 306 319 unsigned long kern_locked_tte_data; 307 320 308 - void __init early_pgtable_allocfail(char *type) 321 + /* Exported for kernel TLB miss handling in ktlb.S */ 322 + unsigned long prom_pmd_phys __read_mostly; 323 + unsigned int swapper_pgd_zero __read_mostly; 324 + 325 + /* Allocate power-of-2 aligned chunks from the end of the 326 + * kernel image. Return physical address. 327 + */ 328 + static inline unsigned long early_alloc_phys(unsigned long size) 309 329 { 310 - prom_printf("inherit_prom_mappings: Cannot alloc kernel %s.\n", type); 311 - prom_halt(); 330 + unsigned long base; 331 + 332 + BUILD_BUG_ON(size & (size - 1)); 333 + 334 + kern_size = (kern_size + (size - 1)) & ~(size - 1); 335 + base = kern_base + kern_size; 336 + kern_size += size; 337 + 338 + return base; 339 + } 340 + 341 + static inline unsigned long load_phys32(unsigned long pa) 342 + { 343 + unsigned long val; 344 + 345 + __asm__ __volatile__("lduwa [%1] %2, %0" 346 + : "=&r" (val) 347 + : "r" (pa), "i" (ASI_PHYS_USE_EC)); 348 + 349 + return val; 350 + } 351 + 352 + static inline unsigned long load_phys64(unsigned long pa) 353 + { 354 + unsigned long val; 355 + 356 + __asm__ __volatile__("ldxa [%1] %2, %0" 357 + : "=&r" (val) 358 + : "r" (pa), "i" (ASI_PHYS_USE_EC)); 359 + 360 + return val; 361 + } 362 + 363 + static inline void store_phys32(unsigned long pa, unsigned long val) 364 + { 365 + __asm__ __volatile__("stwa %0, [%1] %2" 366 + : /* no outputs */ 367 + : "r" (val), "r" (pa), "i" (ASI_PHYS_USE_EC)); 368 + } 369 + 370 + static inline void store_phys64(unsigned long pa, unsigned long val) 371 + { 372 + __asm__ __volatile__("stxa %0, [%1] %2" 373 + : /* no outputs */ 374 + : "r" (val), "r" (pa), "i" (ASI_PHYS_USE_EC)); 312 375 } 313 376 314 377 #define BASE_PAGE_SIZE 8192 315 - static pmd_t *prompmd; 316 378 317 379 /* 318 380 * Translate PROM's mapping we capture at boot time into physical address. ··· 369 333 */ 370 334 unsigned long prom_virt_to_phys(unsigned long promva, int *error) 371 335 { 372 - pmd_t *pmdp = prompmd + ((promva >> 23) & 0x7ff); 373 - pte_t *ptep; 336 + unsigned long pmd_phys = (prom_pmd_phys + 337 + ((promva >> 23) & 0x7ff) * sizeof(pmd_t)); 338 + unsigned long pte_phys; 339 + pmd_t pmd_ent; 340 + pte_t pte_ent; 374 341 unsigned long base; 375 342 376 - if (pmd_none(*pmdp)) { 343 + pmd_val(pmd_ent) = load_phys32(pmd_phys); 344 + if (pmd_none(pmd_ent)) { 377 345 if (error) 378 346 *error = 1; 379 - return(0); 347 + return 0; 380 348 } 381 - ptep = (pte_t *)__pmd_page(*pmdp) + ((promva >> 13) & 0x3ff); 382 - if (!pte_present(*ptep)) { 349 + 350 + pte_phys = (unsigned long)pmd_val(pmd_ent) << 11UL; 351 + pte_phys += ((promva >> 13) & 0x3ff) * sizeof(pte_t); 352 + pte_val(pte_ent) = load_phys64(pte_phys); 353 + if (!pte_present(pte_ent)) { 383 354 if (error) 384 355 *error = 1; 385 - return(0); 356 + return 0; 386 357 } 387 358 if (error) { 388 359 *error = 0; 389 - return(pte_val(*ptep)); 360 + return pte_val(pte_ent); 390 361 } 391 - base = pte_val(*ptep) & _PAGE_PADDR; 392 - return(base + (promva & (BASE_PAGE_SIZE - 1))); 362 + base = pte_val(pte_ent) & _PAGE_PADDR; 363 + return (base + (promva & (BASE_PAGE_SIZE - 1))); 393 364 } 394 365 395 - static void inherit_prom_mappings(void) 366 + /* The obp translations are saved based on 8k pagesize, since obp can 367 + * use a mixture of pagesizes. Misses to the LOW_OBP_ADDRESS -> 368 + * HI_OBP_ADDRESS range are handled in entry.S and do not use the vpte 369 + * scheme (also, see rant in inherit_locked_prom_mappings()). 370 + */ 371 + static void __init build_obp_range(unsigned long start, unsigned long end, unsigned long data) 396 372 { 397 - struct linux_prom_translation *trans; 398 - unsigned long phys_page, tte_vaddr, tte_data; 399 - void (*remap_func)(unsigned long, unsigned long, int); 400 - pmd_t *pmdp; 401 - pte_t *ptep; 402 - int node, n, i, tsz; 403 - extern unsigned int obp_iaddr_patch[2], obp_daddr_patch[2]; 373 + unsigned long vaddr; 374 + 375 + for (vaddr = start; vaddr < end; vaddr += BASE_PAGE_SIZE) { 376 + unsigned long val, pte_phys, pmd_phys; 377 + pmd_t pmd_ent; 378 + int i; 379 + 380 + pmd_phys = (prom_pmd_phys + 381 + (((vaddr >> 23) & 0x7ff) * sizeof(pmd_t))); 382 + pmd_val(pmd_ent) = load_phys32(pmd_phys); 383 + if (pmd_none(pmd_ent)) { 384 + pte_phys = early_alloc_phys(BASE_PAGE_SIZE); 385 + 386 + for (i = 0; i < BASE_PAGE_SIZE / sizeof(pte_t); i++) 387 + store_phys64(pte_phys+i*sizeof(pte_t),0); 388 + 389 + pmd_val(pmd_ent) = pte_phys >> 11UL; 390 + store_phys32(pmd_phys, pmd_val(pmd_ent)); 391 + } 392 + 393 + pte_phys = (unsigned long)pmd_val(pmd_ent) << 11UL; 394 + pte_phys += (((vaddr >> 13) & 0x3ff) * sizeof(pte_t)); 395 + 396 + val = data; 397 + 398 + /* Clear diag TTE bits. */ 399 + if (tlb_type == spitfire) 400 + val &= ~0x0003fe0000000000UL; 401 + 402 + store_phys64(pte_phys, val | _PAGE_MODIFIED); 403 + 404 + data += BASE_PAGE_SIZE; 405 + } 406 + } 407 + 408 + static inline int in_obp_range(unsigned long vaddr) 409 + { 410 + return (vaddr >= LOW_OBP_ADDRESS && 411 + vaddr < HI_OBP_ADDRESS); 412 + } 413 + 414 + #define OBP_PMD_SIZE 2048 415 + static void __init build_obp_pgtable(int prom_trans_ents) 416 + { 417 + unsigned long i; 418 + 419 + prom_pmd_phys = early_alloc_phys(OBP_PMD_SIZE); 420 + for (i = 0; i < OBP_PMD_SIZE; i += 4) 421 + store_phys32(prom_pmd_phys + i, 0); 422 + 423 + for (i = 0; i < prom_trans_ents; i++) { 424 + unsigned long start, end; 425 + 426 + if (!in_obp_range(prom_trans[i].virt)) 427 + continue; 428 + 429 + start = prom_trans[i].virt; 430 + end = start + prom_trans[i].size; 431 + if (end > HI_OBP_ADDRESS) 432 + end = HI_OBP_ADDRESS; 433 + 434 + build_obp_range(start, end, prom_trans[i].data); 435 + } 436 + } 437 + 438 + /* Read OBP translations property into 'prom_trans[]'. 439 + * Return the number of entries. 440 + */ 441 + static int __init read_obp_translations(void) 442 + { 443 + int n, node; 404 444 405 445 node = prom_finddevice("/virtual-memory"); 406 446 n = prom_getproplen(node, "translations"); 407 - if (n == 0 || n == -1) { 408 - prom_printf("Couldn't get translation property\n"); 447 + if (unlikely(n == 0 || n == -1)) { 448 + prom_printf("prom_mappings: Couldn't get size.\n"); 409 449 prom_halt(); 410 450 } 411 - n += 5 * sizeof(struct linux_prom_translation); 412 - for (tsz = 1; tsz < n; tsz <<= 1) 413 - /* empty */; 414 - trans = __alloc_bootmem(tsz, SMP_CACHE_BYTES, bootmap_base); 415 - if (trans == NULL) { 416 - prom_printf("inherit_prom_mappings: Cannot alloc translations.\n"); 451 + if (unlikely(n > sizeof(prom_trans))) { 452 + prom_printf("prom_mappings: Size %Zd is too big.\n", n); 417 453 prom_halt(); 418 454 } 419 - memset(trans, 0, tsz); 420 455 421 - if ((n = prom_getproperty(node, "translations", (char *)trans, tsz)) == -1) { 422 - prom_printf("Couldn't get translation property\n"); 456 + if ((n = prom_getproperty(node, "translations", 457 + (char *)&prom_trans[0], 458 + sizeof(prom_trans))) == -1) { 459 + prom_printf("prom_mappings: Couldn't get property.\n"); 423 460 prom_halt(); 424 461 } 425 - n = n / sizeof(*trans); 462 + n = n / sizeof(struct linux_prom_translation); 463 + return n; 464 + } 426 465 427 - /* 428 - * The obp translations are saved based on 8k pagesize, since obp can 429 - * use a mixture of pagesizes. Misses to the 0xf0000000 - 0x100000000, 430 - * ie obp range, are handled in entry.S and do not use the vpte scheme 431 - * (see rant in inherit_locked_prom_mappings()). 432 - */ 433 - #define OBP_PMD_SIZE 2048 434 - prompmd = __alloc_bootmem(OBP_PMD_SIZE, OBP_PMD_SIZE, bootmap_base); 435 - if (prompmd == NULL) 436 - early_pgtable_allocfail("pmd"); 437 - memset(prompmd, 0, OBP_PMD_SIZE); 438 - for (i = 0; i < n; i++) { 439 - unsigned long vaddr; 440 - 441 - if (trans[i].virt >= LOW_OBP_ADDRESS && trans[i].virt < HI_OBP_ADDRESS) { 442 - for (vaddr = trans[i].virt; 443 - ((vaddr < trans[i].virt + trans[i].size) && 444 - (vaddr < HI_OBP_ADDRESS)); 445 - vaddr += BASE_PAGE_SIZE) { 446 - unsigned long val; 447 - 448 - pmdp = prompmd + ((vaddr >> 23) & 0x7ff); 449 - if (pmd_none(*pmdp)) { 450 - ptep = __alloc_bootmem(BASE_PAGE_SIZE, 451 - BASE_PAGE_SIZE, 452 - bootmap_base); 453 - if (ptep == NULL) 454 - early_pgtable_allocfail("pte"); 455 - memset(ptep, 0, BASE_PAGE_SIZE); 456 - pmd_set(pmdp, ptep); 457 - } 458 - ptep = (pte_t *)__pmd_page(*pmdp) + 459 - ((vaddr >> 13) & 0x3ff); 460 - 461 - val = trans[i].data; 462 - 463 - /* Clear diag TTE bits. */ 464 - if (tlb_type == spitfire) 465 - val &= ~0x0003fe0000000000UL; 466 - 467 - set_pte_at(&init_mm, vaddr, 468 - ptep, __pte(val | _PAGE_MODIFIED)); 469 - trans[i].data += BASE_PAGE_SIZE; 470 - } 471 - } 472 - } 473 - phys_page = __pa(prompmd); 474 - obp_iaddr_patch[0] |= (phys_page >> 10); 475 - obp_iaddr_patch[1] |= (phys_page & 0x3ff); 476 - flushi((long)&obp_iaddr_patch[0]); 477 - obp_daddr_patch[0] |= (phys_page >> 10); 478 - obp_daddr_patch[1] |= (phys_page & 0x3ff); 479 - flushi((long)&obp_daddr_patch[0]); 480 - 481 - /* Now fixup OBP's idea about where we really are mapped. */ 482 - prom_printf("Remapping the kernel... "); 483 - 484 - /* Spitfire Errata #32 workaround */ 485 - /* NOTE: Using plain zero for the context value is 486 - * correct here, we are not using the Linux trap 487 - * tables yet so we should not use the special 488 - * UltraSPARC-III+ page size encodings yet. 489 - */ 490 - __asm__ __volatile__("stxa %0, [%1] %2\n\t" 491 - "flush %%g6" 492 - : /* No outputs */ 493 - : "r" (0), "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); 494 - 495 - switch (tlb_type) { 496 - default: 497 - case spitfire: 498 - phys_page = spitfire_get_dtlb_data(sparc64_highest_locked_tlbent()); 499 - break; 500 - 501 - case cheetah: 502 - case cheetah_plus: 503 - phys_page = cheetah_get_litlb_data(sparc64_highest_locked_tlbent()); 504 - break; 505 - }; 506 - 507 - phys_page &= _PAGE_PADDR; 508 - phys_page += ((unsigned long)&prom_boot_page - 509 - (unsigned long)KERNBASE); 510 - 511 - if (tlb_type == spitfire) { 512 - /* Lock this into i/d tlb entry 59 */ 513 - __asm__ __volatile__( 514 - "stxa %%g0, [%2] %3\n\t" 515 - "stxa %0, [%1] %4\n\t" 516 - "membar #Sync\n\t" 517 - "flush %%g6\n\t" 518 - "stxa %%g0, [%2] %5\n\t" 519 - "stxa %0, [%1] %6\n\t" 520 - "membar #Sync\n\t" 521 - "flush %%g6" 522 - : : "r" (phys_page | _PAGE_VALID | _PAGE_SZ8K | _PAGE_CP | 523 - _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W), 524 - "r" (59 << 3), "r" (TLB_TAG_ACCESS), 525 - "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), 526 - "i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS) 527 - : "memory"); 528 - } else if (tlb_type == cheetah || tlb_type == cheetah_plus) { 529 - /* Lock this into i/d tlb-0 entry 11 */ 530 - __asm__ __volatile__( 531 - "stxa %%g0, [%2] %3\n\t" 532 - "stxa %0, [%1] %4\n\t" 533 - "membar #Sync\n\t" 534 - "flush %%g6\n\t" 535 - "stxa %%g0, [%2] %5\n\t" 536 - "stxa %0, [%1] %6\n\t" 537 - "membar #Sync\n\t" 538 - "flush %%g6" 539 - : : "r" (phys_page | _PAGE_VALID | _PAGE_SZ8K | _PAGE_CP | 540 - _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W), 541 - "r" ((0 << 16) | (11 << 3)), "r" (TLB_TAG_ACCESS), 542 - "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), 543 - "i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS) 544 - : "memory"); 545 - } else { 546 - /* Implement me :-) */ 547 - BUG(); 548 - } 466 + static void __init remap_kernel(void) 467 + { 468 + unsigned long phys_page, tte_vaddr, tte_data; 469 + int tlb_ent = sparc64_highest_locked_tlbent(); 549 470 550 471 tte_vaddr = (unsigned long) KERNBASE; 551 - 552 - /* Spitfire Errata #32 workaround */ 553 - /* NOTE: Using plain zero for the context value is 554 - * correct here, we are not using the Linux trap 555 - * tables yet so we should not use the special 556 - * UltraSPARC-III+ page size encodings yet. 557 - */ 558 - __asm__ __volatile__("stxa %0, [%1] %2\n\t" 559 - "flush %%g6" 560 - : /* No outputs */ 561 - : "r" (0), 562 - "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); 563 - 564 - if (tlb_type == spitfire) 565 - tte_data = spitfire_get_dtlb_data(sparc64_highest_locked_tlbent()); 566 - else 567 - tte_data = cheetah_get_ldtlb_data(sparc64_highest_locked_tlbent()); 472 + phys_page = (prom_boot_mapping_phys_low >> 22UL) << 22UL; 473 + tte_data = (phys_page | (_PAGE_VALID | _PAGE_SZ4MB | 474 + _PAGE_CP | _PAGE_CV | _PAGE_P | 475 + _PAGE_L | _PAGE_W)); 568 476 569 477 kern_locked_tte_data = tte_data; 570 478 571 - remap_func = (void *) ((unsigned long) &prom_remap - 572 - (unsigned long) &prom_boot_page); 573 - 574 - 575 - /* Spitfire Errata #32 workaround */ 576 - /* NOTE: Using plain zero for the context value is 577 - * correct here, we are not using the Linux trap 578 - * tables yet so we should not use the special 579 - * UltraSPARC-III+ page size encodings yet. 580 - */ 581 - __asm__ __volatile__("stxa %0, [%1] %2\n\t" 582 - "flush %%g6" 583 - : /* No outputs */ 584 - : "r" (0), 585 - "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); 586 - 587 - remap_func((tlb_type == spitfire ? 588 - (spitfire_get_dtlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR) : 589 - (cheetah_get_litlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR)), 590 - (unsigned long) KERNBASE, 591 - prom_get_mmu_ihandle()); 592 - 593 - if (bigkernel) 594 - remap_func(((tte_data + 0x400000) & _PAGE_PADDR), 595 - (unsigned long) KERNBASE + 0x400000, prom_get_mmu_ihandle()); 596 - 597 - /* Flush out that temporary mapping. */ 598 - spitfire_flush_dtlb_nucleus_page(0x0); 599 - spitfire_flush_itlb_nucleus_page(0x0); 600 - 601 - /* Now lock us back into the TLBs via OBP. */ 602 - prom_dtlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr); 603 - prom_itlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr); 479 + /* Now lock us into the TLBs via OBP. */ 480 + prom_dtlb_load(tlb_ent, tte_data, tte_vaddr); 481 + prom_itlb_load(tlb_ent, tte_data, tte_vaddr); 604 482 if (bigkernel) { 605 - prom_dtlb_load(sparc64_highest_locked_tlbent()-1, tte_data + 0x400000, 606 - tte_vaddr + 0x400000); 607 - prom_itlb_load(sparc64_highest_locked_tlbent()-1, tte_data + 0x400000, 608 - tte_vaddr + 0x400000); 483 + prom_dtlb_load(tlb_ent - 1, 484 + tte_data + 0x400000, 485 + tte_vaddr + 0x400000); 486 + prom_itlb_load(tlb_ent - 1, 487 + tte_data + 0x400000, 488 + tte_vaddr + 0x400000); 609 489 } 490 + } 610 491 611 - /* Re-read translations property. */ 612 - if ((n = prom_getproperty(node, "translations", (char *)trans, tsz)) == -1) { 613 - prom_printf("Couldn't get translation property\n"); 614 - prom_halt(); 615 - } 616 - n = n / sizeof(*trans); 492 + static void __init inherit_prom_mappings(void) 493 + { 494 + int n; 617 495 618 - for (i = 0; i < n; i++) { 619 - unsigned long vaddr = trans[i].virt; 620 - unsigned long size = trans[i].size; 496 + n = read_obp_translations(); 497 + build_obp_pgtable(n); 621 498 622 - if (vaddr < 0xf0000000UL) { 623 - unsigned long avoid_start = (unsigned long) KERNBASE; 624 - unsigned long avoid_end = avoid_start + (4 * 1024 * 1024); 625 - 626 - if (bigkernel) 627 - avoid_end += (4 * 1024 * 1024); 628 - if (vaddr < avoid_start) { 629 - unsigned long top = vaddr + size; 630 - 631 - if (top > avoid_start) 632 - top = avoid_start; 633 - prom_unmap(top - vaddr, vaddr); 634 - } 635 - if ((vaddr + size) > avoid_end) { 636 - unsigned long bottom = vaddr; 637 - 638 - if (bottom < avoid_end) 639 - bottom = avoid_end; 640 - prom_unmap((vaddr + size) - bottom, bottom); 641 - } 642 - } 643 - } 499 + /* Now fixup OBP's idea about where we really are mapped. */ 500 + prom_printf("Remapping the kernel... "); 501 + remap_kernel(); 644 502 645 503 prom_printf("done.\n"); 646 504 ··· 1277 1347 #endif 1278 1348 bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, pfn_base, end_pfn); 1279 1349 1280 - bootmap_base = bootmap_pfn << PAGE_SHIFT; 1281 - 1282 1350 /* Now register the available physical memory with the 1283 1351 * allocator. 1284 1352 */ ··· 1326 1398 return end_pfn; 1327 1399 } 1328 1400 1401 + #ifdef CONFIG_DEBUG_PAGEALLOC 1402 + static unsigned long kernel_map_range(unsigned long pstart, unsigned long pend, pgprot_t prot) 1403 + { 1404 + unsigned long vstart = PAGE_OFFSET + pstart; 1405 + unsigned long vend = PAGE_OFFSET + pend; 1406 + unsigned long alloc_bytes = 0UL; 1407 + 1408 + if ((vstart & ~PAGE_MASK) || (vend & ~PAGE_MASK)) { 1409 + prom_printf("kernel_map: Unaligned sp_banks[%lx:%lx]\n", 1410 + vstart, vend); 1411 + prom_halt(); 1412 + } 1413 + 1414 + while (vstart < vend) { 1415 + unsigned long this_end, paddr = __pa(vstart); 1416 + pgd_t *pgd = pgd_offset_k(vstart); 1417 + pud_t *pud; 1418 + pmd_t *pmd; 1419 + pte_t *pte; 1420 + 1421 + pud = pud_offset(pgd, vstart); 1422 + if (pud_none(*pud)) { 1423 + pmd_t *new; 1424 + 1425 + new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE); 1426 + alloc_bytes += PAGE_SIZE; 1427 + pud_populate(&init_mm, pud, new); 1428 + } 1429 + 1430 + pmd = pmd_offset(pud, vstart); 1431 + if (!pmd_present(*pmd)) { 1432 + pte_t *new; 1433 + 1434 + new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE); 1435 + alloc_bytes += PAGE_SIZE; 1436 + pmd_populate_kernel(&init_mm, pmd, new); 1437 + } 1438 + 1439 + pte = pte_offset_kernel(pmd, vstart); 1440 + this_end = (vstart + PMD_SIZE) & PMD_MASK; 1441 + if (this_end > vend) 1442 + this_end = vend; 1443 + 1444 + while (vstart < this_end) { 1445 + pte_val(*pte) = (paddr | pgprot_val(prot)); 1446 + 1447 + vstart += PAGE_SIZE; 1448 + paddr += PAGE_SIZE; 1449 + pte++; 1450 + } 1451 + } 1452 + 1453 + return alloc_bytes; 1454 + } 1455 + 1456 + extern struct linux_mlist_p1275 *prom_ptot_ptr; 1457 + extern unsigned int kvmap_linear_patch[1]; 1458 + 1459 + static void __init kernel_physical_mapping_init(void) 1460 + { 1461 + struct linux_mlist_p1275 *p = prom_ptot_ptr; 1462 + unsigned long mem_alloced = 0UL; 1463 + 1464 + while (p) { 1465 + unsigned long phys_start, phys_end; 1466 + 1467 + phys_start = p->start_adr; 1468 + phys_end = phys_start + p->num_bytes; 1469 + mem_alloced += kernel_map_range(phys_start, phys_end, 1470 + PAGE_KERNEL); 1471 + 1472 + p = p->theres_more; 1473 + } 1474 + 1475 + printk("Allocated %ld bytes for kernel page tables.\n", 1476 + mem_alloced); 1477 + 1478 + kvmap_linear_patch[0] = 0x01000000; /* nop */ 1479 + flushi(&kvmap_linear_patch[0]); 1480 + 1481 + __flush_tlb_all(); 1482 + } 1483 + 1484 + void kernel_map_pages(struct page *page, int numpages, int enable) 1485 + { 1486 + unsigned long phys_start = page_to_pfn(page) << PAGE_SHIFT; 1487 + unsigned long phys_end = phys_start + (numpages * PAGE_SIZE); 1488 + 1489 + kernel_map_range(phys_start, phys_end, 1490 + (enable ? PAGE_KERNEL : __pgprot(0))); 1491 + 1492 + /* we should perform an IPI and flush all tlbs, 1493 + * but that can deadlock->flush only current cpu. 1494 + */ 1495 + __flush_tlb_kernel_range(PAGE_OFFSET + phys_start, 1496 + PAGE_OFFSET + phys_end); 1497 + } 1498 + #endif 1499 + 1329 1500 /* paging_init() sets up the page tables */ 1330 1501 1331 1502 extern void cheetah_ecache_flush_init(void); 1332 1503 1333 1504 static unsigned long last_valid_pfn; 1505 + pgd_t swapper_pg_dir[2048]; 1334 1506 1335 1507 void __init paging_init(void) 1336 1508 { 1337 - extern pmd_t swapper_pmd_dir[1024]; 1338 - extern unsigned int sparc64_vpte_patchme1[1]; 1339 - extern unsigned int sparc64_vpte_patchme2[1]; 1340 - unsigned long alias_base = kern_base + PAGE_OFFSET; 1341 - unsigned long second_alias_page = 0; 1342 - unsigned long pt, flags, end_pfn, pages_avail; 1343 - unsigned long shift = alias_base - ((unsigned long)KERNBASE); 1509 + unsigned long end_pfn, pages_avail, shift; 1344 1510 unsigned long real_end; 1345 1511 1346 1512 set_bit(0, mmu_context_bmap); 1347 1513 1514 + shift = kern_base + PAGE_OFFSET - ((unsigned long)KERNBASE); 1515 + 1348 1516 real_end = (unsigned long)_end; 1349 1517 if ((real_end > ((unsigned long)KERNBASE + 0x400000))) 1350 1518 bigkernel = 1; 1351 - #ifdef CONFIG_BLK_DEV_INITRD 1352 - if (sparc_ramdisk_image || sparc_ramdisk_image64) 1353 - real_end = (PAGE_ALIGN(real_end) + PAGE_ALIGN(sparc_ramdisk_size)); 1354 - #endif 1355 - 1356 - /* We assume physical memory starts at some 4mb multiple, 1357 - * if this were not true we wouldn't boot up to this point 1358 - * anyways. 1359 - */ 1360 - pt = kern_base | _PAGE_VALID | _PAGE_SZ4MB; 1361 - pt |= _PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W; 1362 - local_irq_save(flags); 1363 - if (tlb_type == spitfire) { 1364 - __asm__ __volatile__( 1365 - " stxa %1, [%0] %3\n" 1366 - " stxa %2, [%5] %4\n" 1367 - " membar #Sync\n" 1368 - " flush %%g6\n" 1369 - " nop\n" 1370 - " nop\n" 1371 - " nop\n" 1372 - : /* No outputs */ 1373 - : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt), 1374 - "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (61 << 3) 1375 - : "memory"); 1376 - if (real_end >= KERNBASE + 0x340000) { 1377 - second_alias_page = alias_base + 0x400000; 1378 - __asm__ __volatile__( 1379 - " stxa %1, [%0] %3\n" 1380 - " stxa %2, [%5] %4\n" 1381 - " membar #Sync\n" 1382 - " flush %%g6\n" 1383 - " nop\n" 1384 - " nop\n" 1385 - " nop\n" 1386 - : /* No outputs */ 1387 - : "r" (TLB_TAG_ACCESS), "r" (second_alias_page), "r" (pt + 0x400000), 1388 - "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (60 << 3) 1389 - : "memory"); 1390 - } 1391 - } else if (tlb_type == cheetah || tlb_type == cheetah_plus) { 1392 - __asm__ __volatile__( 1393 - " stxa %1, [%0] %3\n" 1394 - " stxa %2, [%5] %4\n" 1395 - " membar #Sync\n" 1396 - " flush %%g6\n" 1397 - " nop\n" 1398 - " nop\n" 1399 - " nop\n" 1400 - : /* No outputs */ 1401 - : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt), 1402 - "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" ((0<<16) | (13<<3)) 1403 - : "memory"); 1404 - if (real_end >= KERNBASE + 0x340000) { 1405 - second_alias_page = alias_base + 0x400000; 1406 - __asm__ __volatile__( 1407 - " stxa %1, [%0] %3\n" 1408 - " stxa %2, [%5] %4\n" 1409 - " membar #Sync\n" 1410 - " flush %%g6\n" 1411 - " nop\n" 1412 - " nop\n" 1413 - " nop\n" 1414 - : /* No outputs */ 1415 - : "r" (TLB_TAG_ACCESS), "r" (second_alias_page), "r" (pt + 0x400000), 1416 - "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" ((0<<16) | (12<<3)) 1417 - : "memory"); 1418 - } 1519 + if ((real_end > ((unsigned long)KERNBASE + 0x800000))) { 1520 + prom_printf("paging_init: Kernel > 8MB, too large.\n"); 1521 + prom_halt(); 1419 1522 } 1420 - local_irq_restore(flags); 1421 - 1422 - /* Now set kernel pgd to upper alias so physical page computations 1523 + 1524 + /* Set kernel pgd to upper alias so physical page computations 1423 1525 * work. 1424 1526 */ 1425 1527 init_mm.pgd += ((shift) / (sizeof(pgd_t))); 1426 1528 1427 - memset(swapper_pmd_dir, 0, sizeof(swapper_pmd_dir)); 1529 + memset(swapper_low_pmd_dir, 0, sizeof(swapper_low_pmd_dir)); 1428 1530 1429 1531 /* Now can init the kernel/bad page tables. */ 1430 1532 pud_set(pud_offset(&swapper_pg_dir[0], 0), 1431 - swapper_pmd_dir + (shift / sizeof(pgd_t))); 1533 + swapper_low_pmd_dir + (shift / sizeof(pgd_t))); 1432 1534 1433 - sparc64_vpte_patchme1[0] |= 1434 - (((unsigned long)pgd_val(init_mm.pgd[0])) >> 10); 1435 - sparc64_vpte_patchme2[0] |= 1436 - (((unsigned long)pgd_val(init_mm.pgd[0])) & 0x3ff); 1437 - flushi((long)&sparc64_vpte_patchme1[0]); 1535 + swapper_pgd_zero = pgd_val(swapper_pg_dir[0]); 1438 1536 1439 - /* Setup bootmem... */ 1440 - pages_avail = 0; 1441 - last_valid_pfn = end_pfn = bootmem_init(&pages_avail); 1442 - 1443 1537 /* Inherit non-locked OBP mappings. */ 1444 1538 inherit_prom_mappings(); 1445 1539 ··· 1477 1527 1478 1528 inherit_locked_prom_mappings(1); 1479 1529 1480 - /* We only created DTLB mapping of this stuff. */ 1481 - spitfire_flush_dtlb_nucleus_page(alias_base); 1482 - if (second_alias_page) 1483 - spitfire_flush_dtlb_nucleus_page(second_alias_page); 1484 - 1485 1530 __flush_tlb_all(); 1531 + 1532 + /* Setup bootmem... */ 1533 + pages_avail = 0; 1534 + last_valid_pfn = end_pfn = bootmem_init(&pages_avail); 1535 + 1536 + #ifdef CONFIG_DEBUG_PAGEALLOC 1537 + kernel_physical_mapping_init(); 1538 + #endif 1486 1539 1487 1540 { 1488 1541 unsigned long zones_size[MAX_NR_ZONES]; ··· 1648 1695 1649 1696 i = last_valid_pfn >> ((22 - PAGE_SHIFT) + 6); 1650 1697 i += 1; 1651 - sparc64_valid_addr_bitmap = (unsigned long *) 1652 - __alloc_bootmem(i << 3, SMP_CACHE_BYTES, bootmap_base); 1698 + sparc64_valid_addr_bitmap = (unsigned long *) alloc_bootmem(i << 3); 1653 1699 if (sparc64_valid_addr_bitmap == NULL) { 1654 1700 prom_printf("mem_init: Cannot alloc valid_addr_bitmap.\n"); 1655 1701 prom_halt(); ··· 1701 1749 cheetah_ecache_flush_init(); 1702 1750 } 1703 1751 1704 - void free_initmem (void) 1752 + void free_initmem(void) 1705 1753 { 1706 1754 unsigned long addr, initend; 1707 1755
+22 -74
arch/sparc64/mm/ultra.S
··· 144 144 145 145 #define DTAG_MASK 0x3 146 146 147 + /* This routine is Spitfire specific so the hardcoded 148 + * D-cache size and line-size are OK. 149 + */ 147 150 .align 64 148 151 .globl __flush_dcache_page 149 152 __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */ 150 153 sethi %uhi(PAGE_OFFSET), %g1 151 154 sllx %g1, 32, %g1 152 - sub %o0, %g1, %o0 153 - clr %o4 154 - srlx %o0, 11, %o0 155 - sethi %hi(1 << 14), %o2 156 - 1: ldxa [%o4] ASI_DCACHE_TAG, %o3 ! LSU Group 157 - add %o4, (1 << 5), %o4 ! IEU0 158 - ldxa [%o4] ASI_DCACHE_TAG, %g1 ! LSU Group 159 - add %o4, (1 << 5), %o4 ! IEU0 160 - ldxa [%o4] ASI_DCACHE_TAG, %g2 ! LSU Group o3 available 161 - add %o4, (1 << 5), %o4 ! IEU0 162 - andn %o3, DTAG_MASK, %o3 ! IEU1 163 - ldxa [%o4] ASI_DCACHE_TAG, %g3 ! LSU Group 164 - add %o4, (1 << 5), %o4 ! IEU0 165 - andn %g1, DTAG_MASK, %g1 ! IEU1 166 - cmp %o0, %o3 ! IEU1 Group 167 - be,a,pn %xcc, dflush1 ! CTI 168 - sub %o4, (4 << 5), %o4 ! IEU0 (Group) 169 - cmp %o0, %g1 ! IEU1 Group 170 - andn %g2, DTAG_MASK, %g2 ! IEU0 171 - be,a,pn %xcc, dflush2 ! CTI 172 - sub %o4, (3 << 5), %o4 ! IEU0 (Group) 173 - cmp %o0, %g2 ! IEU1 Group 174 - andn %g3, DTAG_MASK, %g3 ! IEU0 175 - be,a,pn %xcc, dflush3 ! CTI 176 - sub %o4, (2 << 5), %o4 ! IEU0 (Group) 177 - cmp %o0, %g3 ! IEU1 Group 178 - be,a,pn %xcc, dflush4 ! CTI 179 - sub %o4, (1 << 5), %o4 ! IEU0 180 - 2: cmp %o4, %o2 ! IEU1 Group 181 - bne,pt %xcc, 1b ! CTI 182 - nop ! IEU0 155 + sub %o0, %g1, %o0 ! physical address 156 + srlx %o0, 11, %o0 ! make D-cache TAG 157 + sethi %hi(1 << 14), %o2 ! D-cache size 158 + sub %o2, (1 << 5), %o2 ! D-cache line size 159 + 1: ldxa [%o2] ASI_DCACHE_TAG, %o3 ! load D-cache TAG 160 + andcc %o3, DTAG_MASK, %g0 ! Valid? 161 + be,pn %xcc, 2f ! Nope, branch 162 + andn %o3, DTAG_MASK, %o3 ! Clear valid bits 163 + cmp %o3, %o0 ! TAG match? 164 + bne,pt %xcc, 2f ! Nope, branch 165 + nop 166 + stxa %g0, [%o2] ASI_DCACHE_TAG ! Invalidate TAG 167 + membar #Sync 168 + 2: brnz,pt %o2, 1b 169 + sub %o2, (1 << 5), %o2 ! D-cache line size 183 170 184 171 /* The I-cache does not snoop local stores so we 185 172 * better flush that too when necessary. ··· 176 189 retl 177 190 nop 178 191 179 - dflush1:stxa %g0, [%o4] ASI_DCACHE_TAG 180 - add %o4, (1 << 5), %o4 181 - dflush2:stxa %g0, [%o4] ASI_DCACHE_TAG 182 - add %o4, (1 << 5), %o4 183 - dflush3:stxa %g0, [%o4] ASI_DCACHE_TAG 184 - add %o4, (1 << 5), %o4 185 - dflush4:stxa %g0, [%o4] ASI_DCACHE_TAG 186 - add %o4, (1 << 5), %o4 187 - membar #Sync 188 - ba,pt %xcc, 2b 189 - nop 190 192 #endif /* DCACHE_ALIASING_POSSIBLE */ 191 193 192 - .previous .text 193 - .align 32 194 - __prefill_dtlb: 195 - rdpr %pstate, %g7 196 - wrpr %g7, PSTATE_IE, %pstate 197 - mov TLB_TAG_ACCESS, %g1 198 - stxa %o5, [%g1] ASI_DMMU 199 - stxa %o2, [%g0] ASI_DTLB_DATA_IN 200 - flush %g6 201 - retl 202 - wrpr %g7, %pstate 203 - __prefill_itlb: 204 - rdpr %pstate, %g7 205 - wrpr %g7, PSTATE_IE, %pstate 206 - mov TLB_TAG_ACCESS, %g1 207 - stxa %o5, [%g1] ASI_IMMU 208 - stxa %o2, [%g0] ASI_ITLB_DATA_IN 209 - flush %g6 210 - retl 211 - wrpr %g7, %pstate 212 - 213 - .globl __update_mmu_cache 214 - __update_mmu_cache: /* %o0=hw_context, %o1=address, %o2=pte, %o3=fault_code */ 215 - srlx %o1, PAGE_SHIFT, %o1 216 - andcc %o3, FAULT_CODE_DTLB, %g0 217 - sllx %o1, PAGE_SHIFT, %o5 218 - bne,pt %xcc, __prefill_dtlb 219 - or %o5, %o0, %o5 220 - ba,a,pt %xcc, __prefill_itlb 194 + .previous 221 195 222 196 /* Cheetah specific versions, patched at boot time. */ 223 197 __cheetah_flush_tlb_mm: /* 18 insns */ ··· 231 283 wrpr %g7, 0x0, %pstate 232 284 233 285 #ifdef DCACHE_ALIASING_POSSIBLE 234 - flush_dcpage_cheetah: /* 11 insns */ 286 + __cheetah_flush_dcache_page: /* 11 insns */ 235 287 sethi %uhi(PAGE_OFFSET), %g1 236 288 sllx %g1, 32, %g1 237 289 sub %o0, %g1, %o0 ··· 277 329 #ifdef DCACHE_ALIASING_POSSIBLE 278 330 sethi %hi(__flush_dcache_page), %o0 279 331 or %o0, %lo(__flush_dcache_page), %o0 280 - sethi %hi(flush_dcpage_cheetah), %o1 281 - or %o1, %lo(flush_dcpage_cheetah), %o1 332 + sethi %hi(__cheetah_flush_dcache_page), %o1 333 + or %o1, %lo(__cheetah_flush_dcache_page), %o1 282 334 call cheetah_patch_one 283 335 mov 11, %o2 284 336 #endif /* DCACHE_ALIASING_POSSIBLE */
+1 -1
arch/sparc64/prom/Makefile
··· 7 7 EXTRA_CFLAGS := -Werror 8 8 9 9 lib-y := bootstr.o devops.o init.o memory.o misc.o \ 10 - tree.o console.o printf.o p1275.o map.o cif.o 10 + tree.o console.o printf.o p1275.o cif.o
+1 -1
arch/sparc64/prom/console.c
··· 67 67 } 68 68 69 69 void 70 - prom_puts(char *s, int len) 70 + prom_puts(const char *s, int len) 71 71 { 72 72 p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)| 73 73 P1275_INOUT(3,1),
+1 -1
arch/sparc64/prom/devops.c
··· 16 16 * Returns 0 on failure. 17 17 */ 18 18 int 19 - prom_devopen(char *dstr) 19 + prom_devopen(const char *dstr) 20 20 { 21 21 return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)| 22 22 P1275_INOUT(1,1),
+1 -1
arch/sparc64/prom/init.c
··· 46 46 if((prom_root_node == 0) || (prom_root_node == -1)) 47 47 prom_halt(); 48 48 49 - prom_chosen_node = prom_finddevice("/chosen"); 49 + prom_chosen_node = prom_finddevice(prom_chosen_path); 50 50 if (!prom_chosen_node || prom_chosen_node == -1) 51 51 prom_halt(); 52 52
-72
arch/sparc64/prom/map.S
··· 1 - /* $Id: map.S,v 1.2 1999/11/19 05:53:02 davem Exp $ 2 - * map.S: Tricky coding required to fixup the kernel OBP maps 3 - * properly. 4 - * 5 - * Copyright (C) 1999 David S. Miller (davem@redhat.com) 6 - */ 7 - 8 - .text 9 - .align 8192 10 - .globl prom_boot_page 11 - prom_boot_page: 12 - call_method: 13 - .asciz "call-method" 14 - .align 8 15 - map: 16 - .asciz "map" 17 - .align 8 18 - 19 - /* When we are invoked, our caller has remapped us to 20 - * page zero, therefore we must use PC relative addressing 21 - * for everything after we begin performing the unmap/map 22 - * calls. 23 - */ 24 - .globl prom_remap 25 - prom_remap: /* %o0 = physpage, %o1 = virtpage, %o2 = mmu_ihandle */ 26 - rd %pc, %g1 27 - srl %o2, 0, %o2 ! kill sign extension 28 - sethi %hi(p1275buf), %g2 29 - or %g2, %lo(p1275buf), %g2 30 - ldx [%g2 + 0x10], %g3 ! prom_cif_stack 31 - save %g3, -(192 + 128), %sp 32 - ldx [%g2 + 0x08], %l0 ! prom_cif_handler 33 - mov %g6, %i3 34 - mov %g4, %i4 35 - mov %g5, %i5 36 - flushw 37 - 38 - sethi %hi(prom_remap - call_method), %g7 39 - or %g7, %lo(prom_remap - call_method), %g7 40 - sub %g1, %g7, %l2 ! call-method string 41 - sethi %hi(prom_remap - map), %g7 42 - or %g7, %lo(prom_remap - map), %g7 43 - sub %g1, %g7, %l4 ! map string 44 - 45 - /* OK, map the 4MB region we really live at. */ 46 - stx %l2, [%sp + 2047 + 128 + 0x00] ! call-method 47 - mov 7, %l5 48 - stx %l5, [%sp + 2047 + 128 + 0x08] ! num_args 49 - mov 1, %l5 50 - stx %l5, [%sp + 2047 + 128 + 0x10] ! num_rets 51 - stx %l4, [%sp + 2047 + 128 + 0x18] ! map 52 - stx %i2, [%sp + 2047 + 128 + 0x20] ! mmu_ihandle 53 - mov -1, %l5 54 - stx %l5, [%sp + 2047 + 128 + 0x28] ! mode == default 55 - sethi %hi(4 * 1024 * 1024), %l5 56 - stx %l5, [%sp + 2047 + 128 + 0x30] ! size 57 - stx %i1, [%sp + 2047 + 128 + 0x38] ! vaddr 58 - stx %g0, [%sp + 2047 + 128 + 0x40] ! filler 59 - stx %i0, [%sp + 2047 + 128 + 0x48] ! paddr 60 - call %l0 61 - add %sp, (2047 + 128), %o0 ! argument array 62 - 63 - /* Restore hard-coded globals. */ 64 - mov %i3, %g6 65 - mov %i4, %g4 66 - mov %i5, %g5 67 - 68 - /* Wheee.... we are done. */ 69 - ret 70 - restore 71 - 72 - .align 8192
+16 -18
arch/sparc64/prom/misc.c
··· 17 17 #include <asm/system.h> 18 18 19 19 /* Reset and reboot the machine with the command 'bcommand'. */ 20 - void prom_reboot(char *bcommand) 20 + void prom_reboot(const char *bcommand) 21 21 { 22 22 p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) | 23 23 P1275_INOUT(1, 0), bcommand); 24 24 } 25 25 26 26 /* Forth evaluate the expression contained in 'fstring'. */ 27 - void prom_feval(char *fstring) 27 + void prom_feval(const char *fstring) 28 28 { 29 29 if (!fstring || fstring[0] == 0) 30 30 return; ··· 148 148 p1275_cmd("SUNW,set-trap-table", P1275_INOUT(1, 0), tba); 149 149 } 150 150 151 - int mmu_ihandle_cache = 0; 152 - 153 151 int prom_get_mmu_ihandle(void) 154 152 { 155 153 int node, ret; 156 154 157 - if (mmu_ihandle_cache != 0) 158 - return mmu_ihandle_cache; 155 + if (prom_mmu_ihandle_cache != 0) 156 + return prom_mmu_ihandle_cache; 159 157 160 - node = prom_finddevice("/chosen"); 161 - ret = prom_getint(node, "mmu"); 158 + node = prom_finddevice(prom_chosen_path); 159 + ret = prom_getint(node, prom_mmu_name); 162 160 if (ret == -1 || ret == 0) 163 - mmu_ihandle_cache = -1; 161 + prom_mmu_ihandle_cache = -1; 164 162 else 165 - mmu_ihandle_cache = ret; 163 + prom_mmu_ihandle_cache = ret; 166 164 167 165 return ret; 168 166 } ··· 188 190 unsigned long tte_data, 189 191 unsigned long vaddr) 190 192 { 191 - return p1275_cmd("call-method", 193 + return p1275_cmd(prom_callmethod_name, 192 194 (P1275_ARG(0, P1275_ARG_IN_STRING) | 193 195 P1275_ARG(2, P1275_ARG_IN_64B) | 194 196 P1275_ARG(3, P1275_ARG_IN_64B) | ··· 205 207 unsigned long tte_data, 206 208 unsigned long vaddr) 207 209 { 208 - return p1275_cmd("call-method", 210 + return p1275_cmd(prom_callmethod_name, 209 211 (P1275_ARG(0, P1275_ARG_IN_STRING) | 210 212 P1275_ARG(2, P1275_ARG_IN_64B) | 211 213 P1275_ARG(3, P1275_ARG_IN_64B) | ··· 221 223 int prom_map(int mode, unsigned long size, 222 224 unsigned long vaddr, unsigned long paddr) 223 225 { 224 - int ret = p1275_cmd("call-method", 226 + int ret = p1275_cmd(prom_callmethod_name, 225 227 (P1275_ARG(0, P1275_ARG_IN_STRING) | 226 228 P1275_ARG(3, P1275_ARG_IN_64B) | 227 229 P1275_ARG(4, P1275_ARG_IN_64B) | 228 230 P1275_ARG(6, P1275_ARG_IN_64B) | 229 231 P1275_INOUT(7, 1)), 230 - "map", 232 + prom_map_name, 231 233 prom_get_mmu_ihandle(), 232 234 mode, 233 235 size, ··· 242 244 243 245 void prom_unmap(unsigned long size, unsigned long vaddr) 244 246 { 245 - p1275_cmd("call-method", 247 + p1275_cmd(prom_callmethod_name, 246 248 (P1275_ARG(0, P1275_ARG_IN_STRING) | 247 249 P1275_ARG(2, P1275_ARG_IN_64B) | 248 250 P1275_ARG(3, P1275_ARG_IN_64B) | 249 251 P1275_INOUT(4, 0)), 250 - "unmap", 252 + prom_unmap_name, 251 253 prom_get_mmu_ihandle(), 252 254 size, 253 255 vaddr); ··· 256 258 /* Set aside physical memory which is not touched or modified 257 259 * across soft resets. 258 260 */ 259 - unsigned long prom_retain(char *name, 261 + unsigned long prom_retain(const char *name, 260 262 unsigned long pa_low, unsigned long pa_high, 261 263 long size, long align) 262 264 { ··· 288 290 unsigned long phys_addr, 289 291 char *buf, int buflen) 290 292 { 291 - return p1275_cmd("call-method", 293 + return p1275_cmd(prom_callmethod_name, 292 294 (P1275_ARG(0, P1275_ARG_IN_STRING) | 293 295 P1275_ARG(3, P1275_ARG_OUT_BUF) | 294 296 P1275_ARG(6, P1275_ARG_IN_64B) |
+1 -1
arch/sparc64/prom/p1275.c
··· 46 46 */ 47 47 DEFINE_SPINLOCK(prom_entry_lock); 48 48 49 - long p1275_cmd (char *service, long fmt, ...) 49 + long p1275_cmd(const char *service, long fmt, ...) 50 50 { 51 51 char *p, *q; 52 52 unsigned long flags;
+1 -1
arch/sparc64/prom/printf.c
··· 34 34 } 35 35 36 36 void 37 - prom_printf(char *fmt, ...) 37 + prom_printf(const char *fmt, ...) 38 38 { 39 39 va_list args; 40 40 int i;
+26 -24
arch/sparc64/prom/tree.c
··· 69 69 * Return -1 on error. 70 70 */ 71 71 __inline__ int 72 - prom_getproplen(int node, char *prop) 72 + prom_getproplen(int node, const char *prop) 73 73 { 74 74 if((!node) || (!prop)) return -1; 75 75 return p1275_cmd ("getproplen", ··· 83 83 * was successful the length will be returned, else -1 is returned. 84 84 */ 85 85 __inline__ int 86 - prom_getproperty(int node, char *prop, char *buffer, int bufsize) 86 + prom_getproperty(int node, const char *prop, char *buffer, int bufsize) 87 87 { 88 88 int plen; 89 89 90 90 plen = prom_getproplen(node, prop); 91 - if((plen > bufsize) || (plen == 0) || (plen == -1)) 91 + if ((plen > bufsize) || (plen == 0) || (plen == -1)) { 92 92 return -1; 93 - else { 93 + } else { 94 94 /* Ok, things seem all right. */ 95 - return p1275_cmd ("getprop", 96 - P1275_ARG(1,P1275_ARG_IN_STRING)| 97 - P1275_ARG(2,P1275_ARG_OUT_BUF)| 98 - P1275_INOUT(4, 1), 99 - node, prop, buffer, P1275_SIZE(plen)); 95 + return p1275_cmd(prom_getprop_name, 96 + P1275_ARG(1,P1275_ARG_IN_STRING)| 97 + P1275_ARG(2,P1275_ARG_OUT_BUF)| 98 + P1275_INOUT(4, 1), 99 + node, prop, buffer, P1275_SIZE(plen)); 100 100 } 101 101 } 102 102 ··· 104 104 * on failure. 105 105 */ 106 106 __inline__ int 107 - prom_getint(int node, char *prop) 107 + prom_getint(int node, const char *prop) 108 108 { 109 109 int intprop; 110 110 ··· 119 119 */ 120 120 121 121 int 122 - prom_getintdefault(int node, char *property, int deflt) 122 + prom_getintdefault(int node, const char *property, int deflt) 123 123 { 124 124 int retval; 125 125 ··· 131 131 132 132 /* Acquire a boolean property, 1=TRUE 0=FALSE. */ 133 133 int 134 - prom_getbool(int node, char *prop) 134 + prom_getbool(int node, const char *prop) 135 135 { 136 136 int retval; 137 137 ··· 145 145 * buffer. 146 146 */ 147 147 void 148 - prom_getstring(int node, char *prop, char *user_buf, int ubuf_size) 148 + prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size) 149 149 { 150 150 int len; 151 151 ··· 160 160 * YES = 1 NO = 0 161 161 */ 162 162 int 163 - prom_nodematch(int node, char *name) 163 + prom_nodematch(int node, const char *name) 164 164 { 165 165 char namebuf[128]; 166 166 prom_getproperty(node, "name", namebuf, sizeof(namebuf)); ··· 172 172 * 'nodename'. Return node if successful, zero if not. 173 173 */ 174 174 int 175 - prom_searchsiblings(int node_start, char *nodename) 175 + prom_searchsiblings(int node_start, const char *nodename) 176 176 { 177 177 178 178 int thisnode, error; ··· 294 294 * property types for this node. 295 295 */ 296 296 __inline__ char * 297 - prom_nextprop(int node, char *oprop, char *buffer) 297 + prom_nextprop(int node, const char *oprop, char *buffer) 298 298 { 299 299 char buf[32]; 300 300 ··· 314 314 } 315 315 316 316 int 317 - prom_finddevice(char *name) 317 + prom_finddevice(const char *name) 318 318 { 319 - if(!name) return 0; 320 - return p1275_cmd ("finddevice", P1275_ARG(0,P1275_ARG_IN_STRING)| 321 - P1275_INOUT(1, 1), 322 - name); 319 + if (!name) 320 + return 0; 321 + return p1275_cmd(prom_finddev_name, 322 + P1275_ARG(0,P1275_ARG_IN_STRING)| 323 + P1275_INOUT(1, 1), 324 + name); 323 325 } 324 326 325 - int prom_node_has_property(int node, char *prop) 327 + int prom_node_has_property(int node, const char *prop) 326 328 { 327 329 char buf [32]; 328 330 ··· 341 339 * of 'size' bytes. Return the number of bytes the prom accepted. 342 340 */ 343 341 int 344 - prom_setprop(int node, char *pname, char *value, int size) 342 + prom_setprop(int node, const char *pname, char *value, int size) 345 343 { 346 344 if(size == 0) return 0; 347 345 if((pname == 0) || (value == 0)) return 0; ··· 366 364 * FIXME: Should work for v0 as well 367 365 */ 368 366 int 369 - prom_pathtoinode(char *path) 367 + prom_pathtoinode(const char *path) 370 368 { 371 369 int node, inst; 372 370
+5
include/asm-sparc64/cacheflush.h
··· 66 66 #define flush_cache_vmap(start, end) do { } while (0) 67 67 #define flush_cache_vunmap(start, end) do { } while (0) 68 68 69 + #ifdef CONFIG_DEBUG_PAGEALLOC 70 + /* internal debugging function */ 71 + void kernel_map_pages(struct page *page, int numpages, int enable); 72 + #endif 73 + 69 74 #endif /* !__ASSEMBLY__ */ 70 75 71 76 #endif /* _SPARC64_CACHEFLUSH_H */
+10
include/asm-sparc64/cpudata.h
··· 22 22 unsigned int __pad1; 23 23 unsigned long *pte_cache[2]; 24 24 unsigned long *pgd_cache; 25 + 26 + /* Dcache line 3, rarely used */ 27 + unsigned int dcache_size; 28 + unsigned int dcache_line_size; 29 + unsigned int icache_size; 30 + unsigned int icache_line_size; 31 + unsigned int ecache_size; 32 + unsigned int ecache_line_size; 33 + unsigned int __pad2; 34 + unsigned int __pad3; 25 35 } cpuinfo_sparc; 26 36 27 37 DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
+33 -19
include/asm-sparc64/oplib.h
··· 38 38 */ 39 39 extern int prom_chosen_node; 40 40 41 + /* Helper values and strings in arch/sparc64/kernel/head.S */ 42 + extern const char prom_finddev_name[]; 43 + extern const char prom_chosen_path[]; 44 + extern const char prom_getprop_name[]; 45 + extern const char prom_mmu_name[]; 46 + extern const char prom_callmethod_name[]; 47 + extern const char prom_translate_name[]; 48 + extern const char prom_map_name[]; 49 + extern const char prom_unmap_name[]; 50 + extern int prom_mmu_ihandle_cache; 51 + extern unsigned int prom_boot_mapped_pc; 52 + extern unsigned int prom_boot_mapping_mode; 53 + extern unsigned long prom_boot_mapping_phys_high, prom_boot_mapping_phys_low; 54 + 41 55 struct linux_mlist_p1275 { 42 56 struct linux_mlist_p1275 *theres_more; 43 57 unsigned long start_adr; ··· 82 68 * of the string is different on V0 vs. V2->higher proms. The caller must 83 69 * know what he/she is doing! Returns the device descriptor, an int. 84 70 */ 85 - extern int prom_devopen(char *device_string); 71 + extern int prom_devopen(const char *device_string); 86 72 87 73 /* Close a previously opened device described by the passed integer 88 74 * descriptor. ··· 112 98 /* Miscellaneous routines, don't really fit in any category per se. */ 113 99 114 100 /* Reboot the machine with the command line passed. */ 115 - extern void prom_reboot(char *boot_command); 101 + extern void prom_reboot(const char *boot_command); 116 102 117 103 /* Evaluate the forth string passed. */ 118 - extern void prom_feval(char *forth_string); 104 + extern void prom_feval(const char *forth_string); 119 105 120 106 /* Enter the prom, with possibility of continuation with the 'go' 121 107 * command in newer proms. ··· 168 154 extern void prom_putchar(char character); 169 155 170 156 /* Prom's internal routines, don't use in kernel/boot code. */ 171 - extern void prom_printf(char *fmt, ...); 157 + extern void prom_printf(const char *fmt, ...); 172 158 extern void prom_write(const char *buf, unsigned int len); 173 159 174 160 /* Query for input device type */ ··· 229 215 char *buf, int buflen); 230 216 231 217 /* Retain physical memory to the caller across soft resets. */ 232 - extern unsigned long prom_retain(char *name, 218 + extern unsigned long prom_retain(const char *name, 233 219 unsigned long pa_low, unsigned long pa_high, 234 220 long size, long align); 235 221 ··· 283 269 /* Get the length, at the passed node, of the given property type. 284 270 * Returns -1 on error (ie. no such property at this node). 285 271 */ 286 - extern int prom_getproplen(int thisnode, char *property); 272 + extern int prom_getproplen(int thisnode, const char *property); 287 273 288 274 /* Fetch the requested property using the given buffer. Returns 289 275 * the number of bytes the prom put into your buffer or -1 on error. 290 276 */ 291 - extern int prom_getproperty(int thisnode, char *property, 277 + extern int prom_getproperty(int thisnode, const char *property, 292 278 char *prop_buffer, int propbuf_size); 293 279 294 280 /* Acquire an integer property. */ 295 - extern int prom_getint(int node, char *property); 281 + extern int prom_getint(int node, const char *property); 296 282 297 283 /* Acquire an integer property, with a default value. */ 298 - extern int prom_getintdefault(int node, char *property, int defval); 284 + extern int prom_getintdefault(int node, const char *property, int defval); 299 285 300 286 /* Acquire a boolean property, 0=FALSE 1=TRUE. */ 301 - extern int prom_getbool(int node, char *prop); 287 + extern int prom_getbool(int node, const char *prop); 302 288 303 289 /* Acquire a string property, null string on error. */ 304 - extern void prom_getstring(int node, char *prop, char *buf, int bufsize); 290 + extern void prom_getstring(int node, const char *prop, char *buf, int bufsize); 305 291 306 292 /* Does the passed node have the given "name"? YES=1 NO=0 */ 307 - extern int prom_nodematch(int thisnode, char *name); 293 + extern int prom_nodematch(int thisnode, const char *name); 308 294 309 295 /* Puts in buffer a prom name in the form name@x,y or name (x for which_io 310 296 * and y for first regs phys address ··· 314 300 /* Search all siblings starting at the passed node for "name" matching 315 301 * the given string. Returns the node on success, zero on failure. 316 302 */ 317 - extern int prom_searchsiblings(int node_start, char *name); 303 + extern int prom_searchsiblings(int node_start, const char *name); 318 304 319 305 /* Return the first property type, as a string, for the given node. 320 306 * Returns a null string on error. Buffer should be at least 32B long. ··· 324 310 /* Returns the next property after the passed property for the given 325 311 * node. Returns null string on failure. Buffer should be at least 32B long. 326 312 */ 327 - extern char *prom_nextprop(int node, char *prev_property, char *buffer); 313 + extern char *prom_nextprop(int node, const char *prev_property, char *buffer); 328 314 329 315 /* Returns 1 if the specified node has given property. */ 330 - extern int prom_node_has_property(int node, char *property); 316 + extern int prom_node_has_property(int node, const char *property); 331 317 332 318 /* Returns phandle of the path specified */ 333 - extern int prom_finddevice(char *name); 319 + extern int prom_finddevice(const char *name); 334 320 335 321 /* Set the indicated property at the given node with the passed value. 336 322 * Returns the number of bytes of your value that the prom took. 337 323 */ 338 - extern int prom_setprop(int node, char *prop_name, char *prop_value, 324 + extern int prom_setprop(int node, const char *prop_name, char *prop_value, 339 325 int value_size); 340 326 341 - extern int prom_pathtoinode(char *path); 327 + extern int prom_pathtoinode(const char *path); 342 328 extern int prom_inst2pkg(int); 343 329 344 330 /* CPU probing helpers. */ ··· 348 334 /* Client interface level routines. */ 349 335 extern void prom_set_trap_table(unsigned long tba); 350 336 351 - extern long p1275_cmd (char *, long, ...); 337 + extern long p1275_cmd(const char *, long, ...); 352 338 353 339 354 340 #if 0
+4 -3
include/asm-sparc64/pgtable.h
··· 60 60 * table can map 61 61 */ 62 62 #define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3)) 63 - #define PMD_SIZE (1UL << PMD_SHIFT) 63 + #define PMD_SIZE (_AC(1,UL) << PMD_SHIFT) 64 64 #define PMD_MASK (~(PMD_SIZE-1)) 65 65 #define PMD_BITS (PAGE_SHIFT - 2) 66 66 67 67 /* PGDIR_SHIFT determines what a third-level page table entry can map */ 68 68 #define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3) + PMD_BITS) 69 - #define PGDIR_SIZE (1UL << PGDIR_SHIFT) 69 + #define PGDIR_SIZE (_AC(1,UL) << PGDIR_SHIFT) 70 70 #define PGDIR_MASK (~(PGDIR_SIZE-1)) 71 71 #define PGDIR_BITS (PAGE_SHIFT - 2) 72 72 ··· 336 336 #define pte_clear(mm,addr,ptep) \ 337 337 set_pte_at((mm), (addr), (ptep), __pte(0UL)) 338 338 339 - extern pgd_t swapper_pg_dir[1]; 339 + extern pgd_t swapper_pg_dir[2048]; 340 + extern pmd_t swapper_low_pmd_dir[2048]; 340 341 341 342 /* These do nothing with the way I have things setup. */ 342 343 #define mmu_lockarea(vaddr, len) (vaddr)