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

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc:
sparc: Size mondo queues more sanely.
sparc: Access kernel TSB using physical addressing when possible.
sparc: Fix __atomic_add_unless() return value.
sparc: use kbuild-generic support for true asm-generic header files
sparc: Use popc when possible for ffs/__ffs/ffz.
sparc: Set reboot-cmd using reboot data hypervisor call if available.
sparc: Add some missing hypervisor API groups.
sparc: Use hweight64() in popc emulation.
sparc: Use popc if possible for hweight routines.
sparc: Minor tweaks to Niagara page copy/clear.
sparc: Sanitize cpu feature detection and reporting.

+5
arch/sparc/include/asm/Kbuild
··· 16 16 header-y += uctx.h 17 17 header-y += utrap.h 18 18 header-y += watchdog.h 19 + 20 + generic-y += div64.h 21 + generic-y += local64.h 22 + generic-y += irq_regs.h 23 + generic-y += local.h
+8 -41
arch/sparc/include/asm/bitops_64.h
··· 26 26 #define smp_mb__before_clear_bit() barrier() 27 27 #define smp_mb__after_clear_bit() barrier() 28 28 29 - #include <asm-generic/bitops/ffz.h> 30 - #include <asm-generic/bitops/__ffs.h> 31 29 #include <asm-generic/bitops/fls.h> 32 30 #include <asm-generic/bitops/__fls.h> 33 31 #include <asm-generic/bitops/fls64.h> 34 32 35 33 #ifdef __KERNEL__ 36 34 35 + extern int ffs(int x); 36 + extern unsigned long __ffs(unsigned long); 37 + 38 + #include <asm-generic/bitops/ffz.h> 37 39 #include <asm-generic/bitops/sched.h> 38 - #include <asm-generic/bitops/ffs.h> 39 40 40 41 /* 41 42 * hweightN: returns the hamming weight (i.e. the number 42 43 * of bits set) of a N-bit word 43 44 */ 44 45 45 - #ifdef ULTRA_HAS_POPULATION_COUNT 46 + extern unsigned long __arch_hweight64(__u64 w); 47 + extern unsigned int __arch_hweight32(unsigned int w); 48 + extern unsigned int __arch_hweight16(unsigned int w); 49 + extern unsigned int __arch_hweight8(unsigned int w); 46 50 47 - static inline unsigned int __arch_hweight64(unsigned long w) 48 - { 49 - unsigned int res; 50 - 51 - __asm__ ("popc %1,%0" : "=r" (res) : "r" (w)); 52 - return res; 53 - } 54 - 55 - static inline unsigned int __arch_hweight32(unsigned int w) 56 - { 57 - unsigned int res; 58 - 59 - __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffffffff)); 60 - return res; 61 - } 62 - 63 - static inline unsigned int __arch_hweight16(unsigned int w) 64 - { 65 - unsigned int res; 66 - 67 - __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffff)); 68 - return res; 69 - } 70 - 71 - static inline unsigned int __arch_hweight8(unsigned int w) 72 - { 73 - unsigned int res; 74 - 75 - __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xff)); 76 - return res; 77 - } 78 - 79 - #else 80 - 81 - #include <asm-generic/bitops/arch_hweight.h> 82 - 83 - #endif 84 51 #include <asm-generic/bitops/const_hweight.h> 85 52 #include <asm-generic/bitops/lock.h> 86 53 #endif /* __KERNEL__ */
-1
arch/sparc/include/asm/div64.h
··· 1 - #include <asm-generic/div64.h>
+28 -35
arch/sparc/include/asm/elf_64.h
··· 59 59 #define R_SPARC_6 45 60 60 61 61 /* Bits present in AT_HWCAP, primarily for Sparc32. */ 62 + #define HWCAP_SPARC_FLUSH 0x00000001 63 + #define HWCAP_SPARC_STBAR 0x00000002 64 + #define HWCAP_SPARC_SWAP 0x00000004 65 + #define HWCAP_SPARC_MULDIV 0x00000008 66 + #define HWCAP_SPARC_V9 0x00000010 67 + #define HWCAP_SPARC_ULTRA3 0x00000020 68 + #define HWCAP_SPARC_BLKINIT 0x00000040 69 + #define HWCAP_SPARC_N2 0x00000080 62 70 63 - #define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */ 64 - #define HWCAP_SPARC_STBAR 2 65 - #define HWCAP_SPARC_SWAP 4 66 - #define HWCAP_SPARC_MULDIV 8 67 - #define HWCAP_SPARC_V9 16 68 - #define HWCAP_SPARC_ULTRA3 32 69 - #define HWCAP_SPARC_BLKINIT 64 70 - #define HWCAP_SPARC_N2 128 71 + /* Solaris compatible AT_HWCAP bits. */ 72 + #define AV_SPARC_MUL32 0x00000100 /* 32x32 multiply is efficient */ 73 + #define AV_SPARC_DIV32 0x00000200 /* 32x32 divide is efficient */ 74 + #define AV_SPARC_FSMULD 0x00000400 /* 'fsmuld' is efficient */ 75 + #define AV_SPARC_V8PLUS 0x00000800 /* v9 insn available to 32bit */ 76 + #define AV_SPARC_POPC 0x00001000 /* 'popc' is efficient */ 77 + #define AV_SPARC_VIS 0x00002000 /* VIS insns available */ 78 + #define AV_SPARC_VIS2 0x00004000 /* VIS2 insns available */ 79 + #define AV_SPARC_ASI_BLK_INIT 0x00008000 /* block init ASIs available */ 80 + #define AV_SPARC_FMAF 0x00010000 /* fused multiply-add */ 81 + #define AV_SPARC_VIS3 0x00020000 /* VIS3 insns available */ 82 + #define AV_SPARC_HPC 0x00040000 /* HPC insns available */ 83 + #define AV_SPARC_RANDOM 0x00080000 /* 'random' insn available */ 84 + #define AV_SPARC_TRANS 0x00100000 /* transaction insns available */ 85 + #define AV_SPARC_FJFMAU 0x00200000 /* unfused multiply-add */ 86 + #define AV_SPARC_IMA 0x00400000 /* integer multiply-add */ 87 + #define AV_SPARC_ASI_CACHE_SPARING \ 88 + 0x00800000 /* cache sparing ASIs available */ 71 89 72 90 #define CORE_DUMP_USE_REGSET 73 91 ··· 180 162 #define ELF_ET_DYN_BASE 0x0000010000000000UL 181 163 #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL 182 164 183 - 184 - /* This yields a mask that user programs can use to figure out what 185 - instruction set this cpu supports. */ 186 - 187 - /* On Ultra, we support all of the v8 capabilities. */ 188 - static inline unsigned int sparc64_elf_hwcap(void) 189 - { 190 - unsigned int cap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | 191 - HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV | 192 - HWCAP_SPARC_V9); 193 - 194 - if (tlb_type == cheetah || tlb_type == cheetah_plus) 195 - cap |= HWCAP_SPARC_ULTRA3; 196 - else if (tlb_type == hypervisor) { 197 - if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || 198 - sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || 199 - sun4v_chip_type == SUN4V_CHIP_NIAGARA3) 200 - cap |= HWCAP_SPARC_BLKINIT; 201 - if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || 202 - sun4v_chip_type == SUN4V_CHIP_NIAGARA3) 203 - cap |= HWCAP_SPARC_N2; 204 - } 205 - 206 - return cap; 207 - } 208 - 209 - #define ELF_HWCAP sparc64_elf_hwcap() 165 + extern unsigned long sparc64_elf_hwcap; 166 + #define ELF_HWCAP sparc64_elf_hwcap 210 167 211 168 /* This yields a string that ld.so will use to load implementation 212 169 specific libraries for optimization. This is more specific in
+13
arch/sparc/include/asm/hypervisor.h
··· 2927 2927 #define HV_FAST_FIRE_GET_PERFREG 0x120 2928 2928 #define HV_FAST_FIRE_SET_PERFREG 0x121 2929 2929 2930 + #define HV_FAST_REBOOT_DATA_SET 0x172 2931 + 2932 + #ifndef __ASSEMBLY__ 2933 + extern unsigned long sun4v_reboot_data_set(unsigned long ra, 2934 + unsigned long len); 2935 + #endif 2936 + 2930 2937 /* Function numbers for HV_CORE_TRAP. */ 2931 2938 #define HV_CORE_SET_VER 0x00 2932 2939 #define HV_CORE_PUTCHAR 0x01 ··· 2947 2940 #define HV_GRP_CORE 0x0001 2948 2941 #define HV_GRP_INTR 0x0002 2949 2942 #define HV_GRP_SOFT_STATE 0x0003 2943 + #define HV_GRP_TM 0x0080 2950 2944 #define HV_GRP_PCI 0x0100 2951 2945 #define HV_GRP_LDOM 0x0101 2952 2946 #define HV_GRP_SVC_CHAN 0x0102 2953 2947 #define HV_GRP_NCS 0x0103 2954 2948 #define HV_GRP_RNG 0x0104 2949 + #define HV_GRP_PBOOT 0x0105 2950 + #define HV_GRP_TPM 0x0107 2951 + #define HV_GRP_SDIO 0x0108 2952 + #define HV_GRP_SDIO_ERR 0x0109 2953 + #define HV_GRP_REBOOT_DATA 0x0110 2955 2954 #define HV_GRP_NIAG_PERF 0x0200 2956 2955 #define HV_GRP_FIRE_PERF 0x0201 2957 2956 #define HV_GRP_N2_CPU 0x0202
-1
arch/sparc/include/asm/irq_regs.h
··· 1 - #include <asm-generic/irq_regs.h>
-6
arch/sparc/include/asm/local.h
··· 1 - #ifndef _SPARC_LOCAL_H 2 - #define _SPARC_LOCAL_H 3 - 4 - #include <asm-generic/local.h> 5 - 6 - #endif
-1
arch/sparc/include/asm/local64.h
··· 1 - #include <asm-generic/local64.h>
+24 -27
arch/sparc/include/asm/tsb.h
··· 133 133 sub TSB, 0x8, TSB; \ 134 134 TSB_STORE(TSB, TAG); 135 135 136 - #define KTSB_LOAD_QUAD(TSB, REG) \ 137 - ldda [TSB] ASI_NUCLEUS_QUAD_LDD, REG; 138 - 139 - #define KTSB_STORE(ADDR, VAL) \ 140 - stxa VAL, [ADDR] ASI_N; 141 - 142 - #define KTSB_LOCK_TAG(TSB, REG1, REG2) \ 143 - 99: lduwa [TSB] ASI_N, REG1; \ 144 - sethi %hi(TSB_TAG_LOCK_HIGH), REG2;\ 145 - andcc REG1, REG2, %g0; \ 146 - bne,pn %icc, 99b; \ 147 - nop; \ 148 - casa [TSB] ASI_N, REG1, REG2;\ 149 - cmp REG1, REG2; \ 150 - bne,pn %icc, 99b; \ 151 - nop; \ 152 - 153 - #define KTSB_WRITE(TSB, TTE, TAG) \ 154 - add TSB, 0x8, TSB; \ 155 - stxa TTE, [TSB] ASI_N; \ 156 - sub TSB, 0x8, TSB; \ 157 - stxa TAG, [TSB] ASI_N; 158 - 159 136 /* Do a kernel page table walk. Leaves physical PTE pointer in 160 137 * REG1. Jumps to FAIL_LABEL on early page table walk termination. 161 138 * VADDR will not be clobbered, but REG2 will. ··· 216 239 (KERNEL_TSB_SIZE_BYTES / 16) 217 240 #define KERNEL_TSB4M_NENTRIES 4096 218 241 242 + #define KTSB_PHYS_SHIFT 15 243 + 219 244 /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL 220 245 * on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries 221 246 * and the found TTE will be left in REG1. REG3 and REG4 must ··· 226 247 * VADDR and TAG will be preserved and not clobbered by this macro. 227 248 */ 228 249 #define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ 229 - sethi %hi(swapper_tsb), REG1; \ 250 + 661: sethi %hi(swapper_tsb), REG1; \ 230 251 or REG1, %lo(swapper_tsb), REG1; \ 252 + .section .swapper_tsb_phys_patch, "ax"; \ 253 + .word 661b; \ 254 + .previous; \ 255 + 661: nop; \ 256 + .section .tsb_ldquad_phys_patch, "ax"; \ 257 + .word 661b; \ 258 + sllx REG1, KTSB_PHYS_SHIFT, REG1; \ 259 + sllx REG1, KTSB_PHYS_SHIFT, REG1; \ 260 + .previous; \ 231 261 srlx VADDR, PAGE_SHIFT, REG2; \ 232 262 and REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \ 233 263 sllx REG2, 4, REG2; \ 234 264 add REG1, REG2, REG2; \ 235 - KTSB_LOAD_QUAD(REG2, REG3); \ 265 + TSB_LOAD_QUAD(REG2, REG3); \ 236 266 cmp REG3, TAG; \ 237 267 be,a,pt %xcc, OK_LABEL; \ 238 268 mov REG4, REG1; ··· 251 263 * we can make use of that for the index computation. 252 264 */ 253 265 #define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ 254 - sethi %hi(swapper_4m_tsb), REG1; \ 266 + 661: sethi %hi(swapper_4m_tsb), REG1; \ 255 267 or REG1, %lo(swapper_4m_tsb), REG1; \ 268 + .section .swapper_4m_tsb_phys_patch, "ax"; \ 269 + .word 661b; \ 270 + .previous; \ 271 + 661: nop; \ 272 + .section .tsb_ldquad_phys_patch, "ax"; \ 273 + .word 661b; \ 274 + sllx REG1, KTSB_PHYS_SHIFT, REG1; \ 275 + sllx REG1, KTSB_PHYS_SHIFT, REG1; \ 276 + .previous; \ 256 277 and TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \ 257 278 sllx REG2, 4, REG2; \ 258 279 add REG1, REG2, REG2; \ 259 - KTSB_LOAD_QUAD(REG2, REG3); \ 280 + TSB_LOAD_QUAD(REG2, REG3); \ 260 281 cmp REG3, TAG; \ 261 282 be,a,pt %xcc, OK_LABEL; \ 262 283 mov REG4, REG1;
+1
arch/sparc/kernel/cpu.c
··· 396 396 , cpu_data(0).clock_tick 397 397 #endif 398 398 ); 399 + cpucap_info(m); 399 400 #ifdef CONFIG_SMP 400 401 smp_bogo(m); 401 402 #endif
+28 -2
arch/sparc/kernel/ds.c
··· 15 15 #include <linux/reboot.h> 16 16 #include <linux/cpu.h> 17 17 18 + #include <asm/hypervisor.h> 18 19 #include <asm/ldc.h> 19 20 #include <asm/vio.h> 20 21 #include <asm/mdesc.h> 21 22 #include <asm/head.h> 22 23 #include <asm/irq.h> 24 + 25 + #include "kernel.h" 23 26 24 27 #define DRV_MODULE_NAME "ds" 25 28 #define PFX DRV_MODULE_NAME ": " ··· 831 828 } 832 829 } 833 830 831 + static char full_boot_str[256] __attribute__((aligned(32))); 832 + static int reboot_data_supported; 833 + 834 834 void ldom_reboot(const char *boot_command) 835 835 { 836 836 /* Don't bother with any of this if the boot_command 837 837 * is empty. 838 838 */ 839 839 if (boot_command && strlen(boot_command)) { 840 - char full_boot_str[256]; 840 + unsigned long len; 841 841 842 842 strcpy(full_boot_str, "boot "); 843 843 strcpy(full_boot_str + strlen("boot "), boot_command); 844 + len = strlen(full_boot_str); 844 845 845 - ldom_set_var("reboot-command", full_boot_str); 846 + if (reboot_data_supported) { 847 + unsigned long ra = kimage_addr_to_ra(full_boot_str); 848 + unsigned long hv_ret; 849 + 850 + hv_ret = sun4v_reboot_data_set(ra, len); 851 + if (hv_ret != HV_EOK) 852 + pr_err("SUN4V: Unable to set reboot data " 853 + "hv_ret=%lu\n", hv_ret); 854 + } else { 855 + ldom_set_var("reboot-command", full_boot_str); 856 + } 846 857 } 847 858 sun4v_mach_sir(); 848 859 } ··· 1254 1237 1255 1238 static int __init ds_init(void) 1256 1239 { 1240 + unsigned long hv_ret, major, minor; 1241 + 1242 + hv_ret = sun4v_get_version(HV_GRP_REBOOT_DATA, &major, &minor); 1243 + if (hv_ret == HV_EOK) { 1244 + pr_info("SUN4V: Reboot data supported (maj=%lu,min=%lu).\n", 1245 + major, minor); 1246 + reboot_data_supported = 1; 1247 + } 1248 + 1257 1249 kthread_run(ds_thread, NULL, "kldomd"); 1258 1250 1259 1251 return vio_register_driver(&ds_driver);
+14
arch/sparc/kernel/entry.h
··· 42 42 extern void fpload(unsigned long *fpregs, unsigned long *fsr); 43 43 44 44 #else /* CONFIG_SPARC32 */ 45 + struct popc_3insn_patch_entry { 46 + unsigned int addr; 47 + unsigned int insns[3]; 48 + }; 49 + extern struct popc_3insn_patch_entry __popc_3insn_patch, 50 + __popc_3insn_patch_end; 51 + 52 + struct popc_6insn_patch_entry { 53 + unsigned int addr; 54 + unsigned int insns[6]; 55 + }; 56 + extern struct popc_6insn_patch_entry __popc_6insn_patch, 57 + __popc_6insn_patch_end; 58 + 45 59 extern void __init per_cpu_patch(void); 46 60 extern void __init sun4v_patch(void); 47 61 extern void __init boot_cpu_id_too_large(int cpu);
+1 -1
arch/sparc/kernel/head_64.S
··· 559 559 nop 560 560 call niagara_patch_bzero 561 561 nop 562 - call niagara2_patch_pageops 562 + call niagara_patch_pageops 563 563 nop 564 564 565 565 ba,a,pt %xcc, 80f
+6
arch/sparc/kernel/hvapi.c
··· 28 28 { .group = HV_GRP_CORE, .flags = FLAG_PRE_API }, 29 29 { .group = HV_GRP_INTR, }, 30 30 { .group = HV_GRP_SOFT_STATE, }, 31 + { .group = HV_GRP_TM, }, 31 32 { .group = HV_GRP_PCI, .flags = FLAG_PRE_API }, 32 33 { .group = HV_GRP_LDOM, }, 33 34 { .group = HV_GRP_SVC_CHAN, .flags = FLAG_PRE_API }, 34 35 { .group = HV_GRP_NCS, .flags = FLAG_PRE_API }, 35 36 { .group = HV_GRP_RNG, }, 37 + { .group = HV_GRP_PBOOT, }, 38 + { .group = HV_GRP_TPM, }, 39 + { .group = HV_GRP_SDIO, }, 40 + { .group = HV_GRP_SDIO_ERR, }, 41 + { .group = HV_GRP_REBOOT_DATA, }, 36 42 { .group = HV_GRP_NIAG_PERF, .flags = FLAG_PRE_API }, 37 43 { .group = HV_GRP_FIRE_PERF, }, 38 44 { .group = HV_GRP_N2_CPU, },
+7
arch/sparc/kernel/hvcalls.S
··· 798 798 retl 799 799 nop 800 800 ENDPROC(sun4v_niagara2_setperf) 801 + 802 + ENTRY(sun4v_reboot_data_set) 803 + mov HV_FAST_REBOOT_DATA_SET, %o5 804 + ta HV_FAST_TRAP 805 + retl 806 + nop 807 + ENDPROC(sun4v_reboot_data_set)
+15
arch/sparc/kernel/kernel.h
··· 4 4 #include <linux/interrupt.h> 5 5 6 6 #include <asm/traps.h> 7 + #include <asm/head.h> 8 + #include <asm/io.h> 7 9 8 10 /* cpu.c */ 9 11 extern const char *sparc_pmu_type; 10 12 extern unsigned int fsr_storage; 11 13 extern int ncpus_probed; 14 + 15 + #ifdef CONFIG_SPARC64 16 + /* setup_64.c */ 17 + struct seq_file; 18 + extern void cpucap_info(struct seq_file *); 19 + 20 + static inline unsigned long kimage_addr_to_ra(const char *p) 21 + { 22 + unsigned long val = (unsigned long) p; 23 + 24 + return kern_base + (val - KERNBASE); 25 + } 26 + #endif 12 27 13 28 #ifdef CONFIG_SPARC32 14 29 /* cpu.c */
+12 -12
arch/sparc/kernel/ktlb.S
··· 47 47 kvmap_itlb_vmalloc_addr: 48 48 KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_itlb_longpath) 49 49 50 - KTSB_LOCK_TAG(%g1, %g2, %g7) 50 + TSB_LOCK_TAG(%g1, %g2, %g7) 51 51 52 52 /* Load and check PTE. */ 53 53 ldxa [%g5] ASI_PHYS_USE_EC, %g5 54 54 mov 1, %g7 55 55 sllx %g7, TSB_TAG_INVALID_BIT, %g7 56 56 brgez,a,pn %g5, kvmap_itlb_longpath 57 - KTSB_STORE(%g1, %g7) 57 + TSB_STORE(%g1, %g7) 58 58 59 - KTSB_WRITE(%g1, %g5, %g6) 59 + TSB_WRITE(%g1, %g5, %g6) 60 60 61 61 /* fallthrough to TLB load */ 62 62 ··· 102 102 kvmap_itlb_obp: 103 103 OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_itlb_longpath) 104 104 105 - KTSB_LOCK_TAG(%g1, %g2, %g7) 105 + TSB_LOCK_TAG(%g1, %g2, %g7) 106 106 107 - KTSB_WRITE(%g1, %g5, %g6) 107 + TSB_WRITE(%g1, %g5, %g6) 108 108 109 109 ba,pt %xcc, kvmap_itlb_load 110 110 nop ··· 112 112 kvmap_dtlb_obp: 113 113 OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_dtlb_longpath) 114 114 115 - KTSB_LOCK_TAG(%g1, %g2, %g7) 115 + TSB_LOCK_TAG(%g1, %g2, %g7) 116 116 117 - KTSB_WRITE(%g1, %g5, %g6) 117 + TSB_WRITE(%g1, %g5, %g6) 118 118 119 119 ba,pt %xcc, kvmap_dtlb_load 120 120 nop 121 121 122 122 .align 32 123 123 kvmap_dtlb_tsb4m_load: 124 - KTSB_LOCK_TAG(%g1, %g2, %g7) 125 - KTSB_WRITE(%g1, %g5, %g6) 124 + TSB_LOCK_TAG(%g1, %g2, %g7) 125 + TSB_WRITE(%g1, %g5, %g6) 126 126 ba,pt %xcc, kvmap_dtlb_load 127 127 nop 128 128 ··· 222 222 kvmap_dtlb_vmalloc_addr: 223 223 KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_dtlb_longpath) 224 224 225 - KTSB_LOCK_TAG(%g1, %g2, %g7) 225 + TSB_LOCK_TAG(%g1, %g2, %g7) 226 226 227 227 /* Load and check PTE. */ 228 228 ldxa [%g5] ASI_PHYS_USE_EC, %g5 229 229 mov 1, %g7 230 230 sllx %g7, TSB_TAG_INVALID_BIT, %g7 231 231 brgez,a,pn %g5, kvmap_dtlb_longpath 232 - KTSB_STORE(%g1, %g7) 232 + TSB_STORE(%g1, %g7) 233 233 234 - KTSB_WRITE(%g1, %g5, %g6) 234 + TSB_WRITE(%g1, %g5, %g6) 235 235 236 236 /* fallthrough to TLB load */ 237 237
+23 -7
arch/sparc/kernel/mdesc.c
··· 508 508 } 509 509 EXPORT_SYMBOL(mdesc_node_name); 510 510 511 + static u64 max_cpus = 64; 512 + 511 513 static void __init report_platform_properties(void) 512 514 { 513 515 struct mdesc_handle *hp = mdesc_grab(); ··· 545 543 if (v) 546 544 printk("PLATFORM: watchdog-max-timeout [%llu ms]\n", *v); 547 545 v = mdesc_get_property(hp, pn, "max-cpus", NULL); 548 - if (v) 549 - printk("PLATFORM: max-cpus [%llu]\n", *v); 546 + if (v) { 547 + max_cpus = *v; 548 + printk("PLATFORM: max-cpus [%llu]\n", max_cpus); 549 + } 550 550 551 551 #ifdef CONFIG_SMP 552 552 { ··· 719 715 } 720 716 721 717 static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask, 722 - unsigned char def) 718 + unsigned long def, unsigned long max) 723 719 { 724 720 u64 val; 725 721 ··· 729 725 730 726 if (!val || val >= 64) 731 727 goto use_default; 728 + 729 + if (val > max) 730 + val = max; 732 731 733 732 *mask = ((1U << val) * 64U) - 1U; 734 733 return; ··· 743 736 static void __cpuinit get_mondo_data(struct mdesc_handle *hp, u64 mp, 744 737 struct trap_per_cpu *tb) 745 738 { 739 + static int printed; 746 740 const u64 *val; 747 741 748 742 val = mdesc_get_property(hp, mp, "q-cpu-mondo-#bits", NULL); 749 - get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7); 743 + get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7, ilog2(max_cpus * 2)); 750 744 751 745 val = mdesc_get_property(hp, mp, "q-dev-mondo-#bits", NULL); 752 - get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7); 746 + get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7, 8); 753 747 754 748 val = mdesc_get_property(hp, mp, "q-resumable-#bits", NULL); 755 - get_one_mondo_bits(val, &tb->resum_qmask, 6); 749 + get_one_mondo_bits(val, &tb->resum_qmask, 6, 7); 756 750 757 751 val = mdesc_get_property(hp, mp, "q-nonresumable-#bits", NULL); 758 - get_one_mondo_bits(val, &tb->nonresum_qmask, 2); 752 + get_one_mondo_bits(val, &tb->nonresum_qmask, 2, 2); 753 + if (!printed++) { 754 + pr_info("SUN4V: Mondo queue sizes " 755 + "[cpu(%u) dev(%u) r(%u) nr(%u)]\n", 756 + tb->cpu_mondo_qmask + 1, 757 + tb->dev_mondo_qmask + 1, 758 + tb->resum_qmask + 1, 759 + tb->nonresum_qmask + 1); 760 + } 759 761 } 760 762 761 763 static void * __cpuinit mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handle *, u64, int, void *), void *arg, cpumask_t *mask)
+186
arch/sparc/kernel/setup_64.c
··· 29 29 #include <linux/interrupt.h> 30 30 #include <linux/cpu.h> 31 31 #include <linux/initrd.h> 32 + #include <linux/module.h> 32 33 33 34 #include <asm/system.h> 34 35 #include <asm/io.h> ··· 47 46 #include <asm/mmu.h> 48 47 #include <asm/ns87303.h> 49 48 #include <asm/btext.h> 49 + #include <asm/elf.h> 50 + #include <asm/mdesc.h> 50 51 51 52 #ifdef CONFIG_IP_PNP 52 53 #include <net/ipconfig.h> ··· 272 269 sun4v_hvapi_init(); 273 270 } 274 271 272 + static void __init popc_patch(void) 273 + { 274 + struct popc_3insn_patch_entry *p3; 275 + struct popc_6insn_patch_entry *p6; 276 + 277 + p3 = &__popc_3insn_patch; 278 + while (p3 < &__popc_3insn_patch_end) { 279 + unsigned long i, addr = p3->addr; 280 + 281 + for (i = 0; i < 3; i++) { 282 + *(unsigned int *) (addr + (i * 4)) = p3->insns[i]; 283 + wmb(); 284 + __asm__ __volatile__("flush %0" 285 + : : "r" (addr + (i * 4))); 286 + } 287 + 288 + p3++; 289 + } 290 + 291 + p6 = &__popc_6insn_patch; 292 + while (p6 < &__popc_6insn_patch_end) { 293 + unsigned long i, addr = p6->addr; 294 + 295 + for (i = 0; i < 6; i++) { 296 + *(unsigned int *) (addr + (i * 4)) = p6->insns[i]; 297 + wmb(); 298 + __asm__ __volatile__("flush %0" 299 + : : "r" (addr + (i * 4))); 300 + } 301 + 302 + p6++; 303 + } 304 + } 305 + 275 306 #ifdef CONFIG_SMP 276 307 void __init boot_cpu_id_too_large(int cpu) 277 308 { ··· 314 277 prom_halt(); 315 278 } 316 279 #endif 280 + 281 + /* On Ultra, we support all of the v8 capabilities. */ 282 + unsigned long sparc64_elf_hwcap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | 283 + HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV | 284 + HWCAP_SPARC_V9); 285 + EXPORT_SYMBOL(sparc64_elf_hwcap); 286 + 287 + static const char *hwcaps[] = { 288 + "flush", "stbar", "swap", "muldiv", "v9", 289 + "ultra3", "blkinit", "n2", 290 + 291 + /* These strings are as they appear in the machine description 292 + * 'hwcap-list' property for cpu nodes. 293 + */ 294 + "mul32", "div32", "fsmuld", "v8plus", "popc", "vis", "vis2", 295 + "ASIBlkInit", "fmaf", "vis3", "hpc", "random", "trans", "fjfmau", 296 + "ima", "cspare", 297 + }; 298 + 299 + void cpucap_info(struct seq_file *m) 300 + { 301 + unsigned long caps = sparc64_elf_hwcap; 302 + int i, printed = 0; 303 + 304 + seq_puts(m, "cpucaps\t\t: "); 305 + for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { 306 + unsigned long bit = 1UL << i; 307 + if (caps & bit) { 308 + seq_printf(m, "%s%s", 309 + printed ? "," : "", hwcaps[i]); 310 + printed++; 311 + } 312 + } 313 + seq_putc(m, '\n'); 314 + } 315 + 316 + static void __init report_hwcaps(unsigned long caps) 317 + { 318 + int i, printed = 0; 319 + 320 + printk(KERN_INFO "CPU CAPS: ["); 321 + for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { 322 + unsigned long bit = 1UL << i; 323 + if (caps & bit) { 324 + printk(KERN_CONT "%s%s", 325 + printed ? "," : "", hwcaps[i]); 326 + if (++printed == 8) { 327 + printk(KERN_CONT "]\n"); 328 + printk(KERN_INFO "CPU CAPS: ["); 329 + printed = 0; 330 + } 331 + } 332 + } 333 + printk(KERN_CONT "]\n"); 334 + } 335 + 336 + static unsigned long __init mdesc_cpu_hwcap_list(void) 337 + { 338 + struct mdesc_handle *hp; 339 + unsigned long caps = 0; 340 + const char *prop; 341 + int len; 342 + u64 pn; 343 + 344 + hp = mdesc_grab(); 345 + if (!hp) 346 + return 0; 347 + 348 + pn = mdesc_node_by_name(hp, MDESC_NODE_NULL, "cpu"); 349 + if (pn == MDESC_NODE_NULL) 350 + goto out; 351 + 352 + prop = mdesc_get_property(hp, pn, "hwcap-list", &len); 353 + if (!prop) 354 + goto out; 355 + 356 + while (len) { 357 + int i, plen; 358 + 359 + for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { 360 + unsigned long bit = 1UL << i; 361 + 362 + if (!strcmp(prop, hwcaps[i])) { 363 + caps |= bit; 364 + break; 365 + } 366 + } 367 + 368 + plen = strlen(prop) + 1; 369 + prop += plen; 370 + len -= plen; 371 + } 372 + 373 + out: 374 + mdesc_release(hp); 375 + return caps; 376 + } 377 + 378 + /* This yields a mask that user programs can use to figure out what 379 + * instruction set this cpu supports. 380 + */ 381 + static void __init init_sparc64_elf_hwcap(void) 382 + { 383 + unsigned long cap = sparc64_elf_hwcap; 384 + unsigned long mdesc_caps; 385 + 386 + if (tlb_type == cheetah || tlb_type == cheetah_plus) 387 + cap |= HWCAP_SPARC_ULTRA3; 388 + else if (tlb_type == hypervisor) { 389 + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || 390 + sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || 391 + sun4v_chip_type == SUN4V_CHIP_NIAGARA3) 392 + cap |= HWCAP_SPARC_BLKINIT; 393 + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || 394 + sun4v_chip_type == SUN4V_CHIP_NIAGARA3) 395 + cap |= HWCAP_SPARC_N2; 396 + } 397 + 398 + cap |= (AV_SPARC_MUL32 | AV_SPARC_DIV32 | AV_SPARC_V8PLUS); 399 + 400 + mdesc_caps = mdesc_cpu_hwcap_list(); 401 + if (!mdesc_caps) { 402 + if (tlb_type == spitfire) 403 + cap |= AV_SPARC_VIS; 404 + if (tlb_type == cheetah || tlb_type == cheetah_plus) 405 + cap |= AV_SPARC_VIS | AV_SPARC_VIS2; 406 + if (tlb_type == cheetah_plus) 407 + cap |= AV_SPARC_POPC; 408 + if (tlb_type == hypervisor) { 409 + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1) 410 + cap |= AV_SPARC_ASI_BLK_INIT; 411 + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || 412 + sun4v_chip_type == SUN4V_CHIP_NIAGARA3) 413 + cap |= (AV_SPARC_VIS | AV_SPARC_VIS2 | 414 + AV_SPARC_ASI_BLK_INIT | 415 + AV_SPARC_POPC); 416 + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA3) 417 + cap |= (AV_SPARC_VIS3 | AV_SPARC_HPC | 418 + AV_SPARC_FMAF); 419 + } 420 + } 421 + sparc64_elf_hwcap = cap | mdesc_caps; 422 + 423 + report_hwcaps(sparc64_elf_hwcap); 424 + 425 + if (sparc64_elf_hwcap & AV_SPARC_POPC) 426 + popc_patch(); 427 + } 317 428 318 429 void __init setup_arch(char **cmdline_p) 319 430 { ··· 522 337 init_cur_cpu_trap(current_thread_info()); 523 338 524 339 paging_init(); 340 + init_sparc64_elf_hwcap(); 525 341 } 526 342 527 343 extern int stop_a_enabled;
+11
arch/sparc/kernel/sparc_ksyms_64.c
··· 8 8 #include <linux/module.h> 9 9 #include <linux/pci.h> 10 10 #include <linux/init.h> 11 + #include <linux/bitops.h> 11 12 12 13 #include <asm/system.h> 13 14 #include <asm/cpudata.h> ··· 38 37 EXPORT_SYMBOL(sun4v_niagara_setperf); 39 38 EXPORT_SYMBOL(sun4v_niagara2_getperf); 40 39 EXPORT_SYMBOL(sun4v_niagara2_setperf); 40 + 41 + /* from hweight.S */ 42 + EXPORT_SYMBOL(__arch_hweight8); 43 + EXPORT_SYMBOL(__arch_hweight16); 44 + EXPORT_SYMBOL(__arch_hweight32); 45 + EXPORT_SYMBOL(__arch_hweight64); 46 + 47 + /* from ffs_ffz.S */ 48 + EXPORT_SYMBOL(ffs); 49 + EXPORT_SYMBOL(__ffs); 41 50 42 51 /* Exporting a symbol from /init/main.c */ 43 52 EXPORT_SYMBOL(saved_command_line);
+2 -7
arch/sparc/kernel/sstate.c
··· 14 14 #include <asm/head.h> 15 15 #include <asm/io.h> 16 16 17 + #include "kernel.h" 18 + 17 19 static int hv_supports_soft_state; 18 - 19 - static unsigned long kimage_addr_to_ra(const char *p) 20 - { 21 - unsigned long val = (unsigned long) p; 22 - 23 - return kern_base + (val - KERNBASE); 24 - } 25 20 26 21 static void do_set_sstate(unsigned long state, const char *msg) 27 22 {
+4 -11
arch/sparc/kernel/unaligned_64.c
··· 22 22 #include <linux/bitops.h> 23 23 #include <linux/perf_event.h> 24 24 #include <linux/ratelimit.h> 25 + #include <linux/bitops.h> 25 26 #include <asm/fpumacro.h> 26 27 27 28 enum direction { ··· 374 373 } 375 374 } 376 375 377 - static char popc_helper[] = { 378 - 0, 1, 1, 2, 1, 2, 2, 3, 379 - 1, 2, 2, 3, 2, 3, 3, 4, 380 - }; 381 - 382 376 int handle_popc(u32 insn, struct pt_regs *regs) 383 377 { 384 - u64 value; 385 - int ret, i, rd = ((insn >> 25) & 0x1f); 386 378 int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; 379 + int ret, rd = ((insn >> 25) & 0x1f); 380 + u64 value; 387 381 388 382 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0); 389 383 if (insn & 0x2000) { ··· 388 392 maybe_flush_windows(0, insn & 0x1f, rd, from_kernel); 389 393 value = fetch_reg(insn & 0x1f, regs); 390 394 } 391 - for (ret = 0, i = 0; i < 16; i++) { 392 - ret += popc_helper[value & 0xf]; 393 - value >>= 4; 394 - } 395 + ret = hweight64(value); 395 396 if (rd < 16) { 396 397 if (rd) 397 398 regs->u_regs[rd] = ret;
+20 -1
arch/sparc/kernel/vmlinux.lds.S
··· 107 107 *(.sun4v_2insn_patch) 108 108 __sun4v_2insn_patch_end = .; 109 109 } 110 - 110 + .swapper_tsb_phys_patch : { 111 + __swapper_tsb_phys_patch = .; 112 + *(.swapper_tsb_phys_patch) 113 + __swapper_tsb_phys_patch_end = .; 114 + } 115 + .swapper_4m_tsb_phys_patch : { 116 + __swapper_4m_tsb_phys_patch = .; 117 + *(.swapper_4m_tsb_phys_patch) 118 + __swapper_4m_tsb_phys_patch_end = .; 119 + } 120 + .popc_3insn_patch : { 121 + __popc_3insn_patch = .; 122 + *(.popc_3insn_patch) 123 + __popc_3insn_patch_end = .; 124 + } 125 + .popc_6insn_patch : { 126 + __popc_6insn_patch = .; 127 + *(.popc_6insn_patch) 128 + __popc_6insn_patch_end = .; 129 + } 111 130 PERCPU_SECTION(SMP_CACHE_BYTES) 112 131 113 132 . = ALIGN(PAGE_SIZE);
+2 -2
arch/sparc/lib/Makefile
··· 31 31 lib-$(CONFIG_SPARC64) += NGpatch.o NGpage.o NGbzero.o 32 32 33 33 lib-$(CONFIG_SPARC64) += NG2memcpy.o NG2copy_from_user.o NG2copy_to_user.o 34 - lib-$(CONFIG_SPARC64) += NG2patch.o NG2page.o 34 + lib-$(CONFIG_SPARC64) += NG2patch.o 35 35 36 36 lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o 37 37 lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o 38 38 39 39 lib-$(CONFIG_SPARC64) += copy_in_user.o user_fixup.o memmove.o 40 - lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o 40 + lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o 41 41 42 42 obj-y += iomap.o 43 43 obj-$(CONFIG_SPARC32) += atomic32.o
-61
arch/sparc/lib/NG2page.S
··· 1 - /* NG2page.S: Niagara-2 optimized clear and copy page. 2 - * 3 - * Copyright (C) 2007 (davem@davemloft.net) 4 - */ 5 - 6 - #include <asm/asi.h> 7 - #include <asm/page.h> 8 - #include <asm/visasm.h> 9 - 10 - .text 11 - .align 32 12 - 13 - /* This is heavily simplified from the sun4u variants 14 - * because Niagara-2 does not have any D-cache aliasing issues. 15 - */ 16 - NG2copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ 17 - prefetch [%o1 + 0x00], #one_read 18 - prefetch [%o1 + 0x40], #one_read 19 - VISEntryHalf 20 - set PAGE_SIZE, %g7 21 - sub %o0, %o1, %g3 22 - 1: stxa %g0, [%o1 + %g3] ASI_BLK_INIT_QUAD_LDD_P 23 - subcc %g7, 64, %g7 24 - ldda [%o1] ASI_BLK_P, %f0 25 - stda %f0, [%o1 + %g3] ASI_BLK_P 26 - add %o1, 64, %o1 27 - bne,pt %xcc, 1b 28 - prefetch [%o1 + 0x40], #one_read 29 - membar #Sync 30 - VISExitHalf 31 - retl 32 - nop 33 - 34 - #define BRANCH_ALWAYS 0x10680000 35 - #define NOP 0x01000000 36 - #define NG_DO_PATCH(OLD, NEW) \ 37 - sethi %hi(NEW), %g1; \ 38 - or %g1, %lo(NEW), %g1; \ 39 - sethi %hi(OLD), %g2; \ 40 - or %g2, %lo(OLD), %g2; \ 41 - sub %g1, %g2, %g1; \ 42 - sethi %hi(BRANCH_ALWAYS), %g3; \ 43 - sll %g1, 11, %g1; \ 44 - srl %g1, 11 + 2, %g1; \ 45 - or %g3, %lo(BRANCH_ALWAYS), %g3; \ 46 - or %g3, %g1, %g3; \ 47 - stw %g3, [%g2]; \ 48 - sethi %hi(NOP), %g3; \ 49 - or %g3, %lo(NOP), %g3; \ 50 - stw %g3, [%g2 + 0x4]; \ 51 - flush %g2; 52 - 53 - .globl niagara2_patch_pageops 54 - .type niagara2_patch_pageops,#function 55 - niagara2_patch_pageops: 56 - NG_DO_PATCH(copy_user_page, NG2copy_user_page) 57 - NG_DO_PATCH(_clear_page, NGclear_page) 58 - NG_DO_PATCH(clear_user_page, NGclear_user_page) 59 - retl 60 - nop 61 - .size niagara2_patch_pageops,.-niagara2_patch_pageops
+75 -39
arch/sparc/lib/NGpage.S
··· 16 16 */ 17 17 18 18 NGcopy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ 19 - prefetch [%o1 + 0x00], #one_read 20 - mov 8, %g1 21 - mov 16, %g2 22 - mov 24, %g3 19 + save %sp, -192, %sp 20 + rd %asi, %g3 21 + wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi 23 22 set PAGE_SIZE, %g7 23 + prefetch [%i1 + 0x00], #one_read 24 + prefetch [%i1 + 0x40], #one_read 24 25 25 - 1: ldda [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2 26 - ldda [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4 27 - prefetch [%o1 + 0x40], #one_read 28 - add %o1, 32, %o1 29 - stxa %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P 30 - stxa %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P 31 - ldda [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2 32 - stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P 33 - stxa %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P 34 - ldda [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4 35 - add %o1, 32, %o1 36 - add %o0, 32, %o0 37 - stxa %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P 38 - stxa %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P 39 - stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P 40 - stxa %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P 41 - subcc %g7, 64, %g7 26 + 1: prefetch [%i1 + 0x80], #one_read 27 + prefetch [%i1 + 0xc0], #one_read 28 + ldda [%i1 + 0x00] %asi, %o2 29 + ldda [%i1 + 0x10] %asi, %o4 30 + ldda [%i1 + 0x20] %asi, %l2 31 + ldda [%i1 + 0x30] %asi, %l4 32 + stxa %o2, [%i0 + 0x00] %asi 33 + stxa %o3, [%i0 + 0x08] %asi 34 + stxa %o4, [%i0 + 0x10] %asi 35 + stxa %o5, [%i0 + 0x18] %asi 36 + stxa %l2, [%i0 + 0x20] %asi 37 + stxa %l3, [%i0 + 0x28] %asi 38 + stxa %l4, [%i0 + 0x30] %asi 39 + stxa %l5, [%i0 + 0x38] %asi 40 + ldda [%i1 + 0x40] %asi, %o2 41 + ldda [%i1 + 0x50] %asi, %o4 42 + ldda [%i1 + 0x60] %asi, %l2 43 + ldda [%i1 + 0x70] %asi, %l4 44 + stxa %o2, [%i0 + 0x40] %asi 45 + stxa %o3, [%i0 + 0x48] %asi 46 + stxa %o4, [%i0 + 0x50] %asi 47 + stxa %o5, [%i0 + 0x58] %asi 48 + stxa %l2, [%i0 + 0x60] %asi 49 + stxa %l3, [%i0 + 0x68] %asi 50 + stxa %l4, [%i0 + 0x70] %asi 51 + stxa %l5, [%i0 + 0x78] %asi 52 + add %i1, 128, %i1 53 + subcc %g7, 128, %g7 42 54 bne,pt %xcc, 1b 43 - add %o0, 32, %o0 55 + add %i0, 128, %i0 56 + wr %g3, 0x0, %asi 44 57 membar #Sync 45 - retl 46 - nop 58 + ret 59 + restore 47 60 48 - .globl NGclear_page, NGclear_user_page 61 + .align 32 49 62 NGclear_page: /* %o0=dest */ 50 63 NGclear_user_page: /* %o0=dest, %o1=vaddr */ 51 - mov 8, %g1 52 - mov 16, %g2 53 - mov 24, %g3 64 + rd %asi, %g3 65 + wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi 54 66 set PAGE_SIZE, %g7 55 67 56 - 1: stxa %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P 57 - stxa %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P 58 - stxa %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P 59 - stxa %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P 60 - add %o0, 32, %o0 61 - stxa %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P 62 - stxa %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P 63 - stxa %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P 64 - stxa %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P 65 - subcc %g7, 64, %g7 68 + 1: stxa %g0, [%o0 + 0x00] %asi 69 + stxa %g0, [%o0 + 0x08] %asi 70 + stxa %g0, [%o0 + 0x10] %asi 71 + stxa %g0, [%o0 + 0x18] %asi 72 + stxa %g0, [%o0 + 0x20] %asi 73 + stxa %g0, [%o0 + 0x28] %asi 74 + stxa %g0, [%o0 + 0x30] %asi 75 + stxa %g0, [%o0 + 0x38] %asi 76 + stxa %g0, [%o0 + 0x40] %asi 77 + stxa %g0, [%o0 + 0x48] %asi 78 + stxa %g0, [%o0 + 0x50] %asi 79 + stxa %g0, [%o0 + 0x58] %asi 80 + stxa %g0, [%o0 + 0x60] %asi 81 + stxa %g0, [%o0 + 0x68] %asi 82 + stxa %g0, [%o0 + 0x70] %asi 83 + stxa %g0, [%o0 + 0x78] %asi 84 + stxa %g0, [%o0 + 0x80] %asi 85 + stxa %g0, [%o0 + 0x88] %asi 86 + stxa %g0, [%o0 + 0x90] %asi 87 + stxa %g0, [%o0 + 0x98] %asi 88 + stxa %g0, [%o0 + 0xa0] %asi 89 + stxa %g0, [%o0 + 0xa8] %asi 90 + stxa %g0, [%o0 + 0xb0] %asi 91 + stxa %g0, [%o0 + 0xb8] %asi 92 + stxa %g0, [%o0 + 0xc0] %asi 93 + stxa %g0, [%o0 + 0xc8] %asi 94 + stxa %g0, [%o0 + 0xd0] %asi 95 + stxa %g0, [%o0 + 0xd8] %asi 96 + stxa %g0, [%o0 + 0xe0] %asi 97 + stxa %g0, [%o0 + 0xe8] %asi 98 + stxa %g0, [%o0 + 0xf0] %asi 99 + stxa %g0, [%o0 + 0xf8] %asi 100 + subcc %g7, 256, %g7 66 101 bne,pt %xcc, 1b 67 - add %o0, 32, %o0 102 + add %o0, 256, %o0 103 + wr %g3, 0x0, %asi 68 104 membar #Sync 69 105 retl 70 106 nop
+1 -1
arch/sparc/lib/atomic32.c
··· 65 65 if (ret != u) 66 66 v->counter += a; 67 67 spin_unlock_irqrestore(ATOMIC_HASH(v), flags); 68 - return ret != u; 68 + return ret; 69 69 } 70 70 EXPORT_SYMBOL(__atomic_add_unless); 71 71
+84
arch/sparc/lib/ffs.S
··· 1 + #include <linux/linkage.h> 2 + 3 + .register %g2,#scratch 4 + 5 + .text 6 + .align 32 7 + 8 + ENTRY(ffs) 9 + brnz,pt %o0, 1f 10 + mov 1, %o1 11 + retl 12 + clr %o0 13 + nop 14 + nop 15 + ENTRY(__ffs) 16 + sllx %o0, 32, %g1 /* 1 */ 17 + srlx %o0, 32, %g2 18 + 19 + clr %o1 /* 2 */ 20 + movrz %g1, %g2, %o0 21 + 22 + movrz %g1, 32, %o1 /* 3 */ 23 + 1: clr %o2 24 + 25 + sllx %o0, (64 - 16), %g1 /* 4 */ 26 + srlx %o0, 16, %g2 27 + 28 + movrz %g1, %g2, %o0 /* 5 */ 29 + clr %o3 30 + 31 + movrz %g1, 16, %o2 /* 6 */ 32 + clr %o4 33 + 34 + and %o0, 0xff, %g1 /* 7 */ 35 + srlx %o0, 8, %g2 36 + 37 + movrz %g1, %g2, %o0 /* 8 */ 38 + clr %o5 39 + 40 + movrz %g1, 8, %o3 /* 9 */ 41 + add %o2, %o1, %o2 42 + 43 + and %o0, 0xf, %g1 /* 10 */ 44 + srlx %o0, 4, %g2 45 + 46 + movrz %g1, %g2, %o0 /* 11 */ 47 + add %o2, %o3, %o2 48 + 49 + movrz %g1, 4, %o4 /* 12 */ 50 + 51 + and %o0, 0x3, %g1 /* 13 */ 52 + srlx %o0, 2, %g2 53 + 54 + movrz %g1, %g2, %o0 /* 14 */ 55 + add %o2, %o4, %o2 56 + 57 + movrz %g1, 2, %o5 /* 15 */ 58 + 59 + and %o0, 0x1, %g1 /* 16 */ 60 + 61 + add %o2, %o5, %o2 /* 17 */ 62 + xor %g1, 0x1, %g1 63 + 64 + retl /* 18 */ 65 + add %o2, %g1, %o0 66 + ENDPROC(ffs) 67 + ENDPROC(__ffs) 68 + 69 + .section .popc_6insn_patch, "ax" 70 + .word ffs 71 + brz,pn %o0, 98f 72 + neg %o0, %g1 73 + xnor %o0, %g1, %o1 74 + popc %o1, %o0 75 + 98: retl 76 + nop 77 + .word __ffs 78 + neg %o0, %g1 79 + xnor %o0, %g1, %o1 80 + popc %o1, %o0 81 + retl 82 + sub %o0, 1, %o0 83 + nop 84 + .previous
+51
arch/sparc/lib/hweight.S
··· 1 + #include <linux/linkage.h> 2 + 3 + .text 4 + .align 32 5 + ENTRY(__arch_hweight8) 6 + ba,pt %xcc, __sw_hweight8 7 + nop 8 + nop 9 + ENDPROC(__arch_hweight8) 10 + .section .popc_3insn_patch, "ax" 11 + .word __arch_hweight8 12 + sllx %o0, 64-8, %g1 13 + retl 14 + popc %g1, %o0 15 + .previous 16 + 17 + ENTRY(__arch_hweight16) 18 + ba,pt %xcc, __sw_hweight16 19 + nop 20 + nop 21 + ENDPROC(__arch_hweight16) 22 + .section .popc_3insn_patch, "ax" 23 + .word __arch_hweight16 24 + sllx %o0, 64-16, %g1 25 + retl 26 + popc %g1, %o0 27 + .previous 28 + 29 + ENTRY(__arch_hweight32) 30 + ba,pt %xcc, __sw_hweight32 31 + nop 32 + nop 33 + ENDPROC(__arch_hweight32) 34 + .section .popc_3insn_patch, "ax" 35 + .word __arch_hweight32 36 + sllx %o0, 64-32, %g1 37 + retl 38 + popc %g1, %o0 39 + .previous 40 + 41 + ENTRY(__arch_hweight64) 42 + ba,pt %xcc, __sw_hweight64 43 + nop 44 + nop 45 + ENDPROC(__arch_hweight64) 46 + .section .popc_3insn_patch, "ax" 47 + .word __arch_hweight64 48 + retl 49 + popc %o0, %o0 50 + nop 51 + .previous
+39 -1
arch/sparc/mm/init_64.c
··· 1597 1597 static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR]; 1598 1598 extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; 1599 1599 1600 + static void patch_one_ktsb_phys(unsigned int *start, unsigned int *end, unsigned long pa) 1601 + { 1602 + pa >>= KTSB_PHYS_SHIFT; 1603 + 1604 + while (start < end) { 1605 + unsigned int *ia = (unsigned int *)(unsigned long)*start; 1606 + 1607 + ia[0] = (ia[0] & ~0x3fffff) | (pa >> 10); 1608 + __asm__ __volatile__("flush %0" : : "r" (ia)); 1609 + 1610 + ia[1] = (ia[1] & ~0x3ff) | (pa & 0x3ff); 1611 + __asm__ __volatile__("flush %0" : : "r" (ia + 1)); 1612 + 1613 + start++; 1614 + } 1615 + } 1616 + 1617 + static void ktsb_phys_patch(void) 1618 + { 1619 + extern unsigned int __swapper_tsb_phys_patch; 1620 + extern unsigned int __swapper_tsb_phys_patch_end; 1621 + extern unsigned int __swapper_4m_tsb_phys_patch; 1622 + extern unsigned int __swapper_4m_tsb_phys_patch_end; 1623 + unsigned long ktsb_pa; 1624 + 1625 + ktsb_pa = kern_base + ((unsigned long)&swapper_tsb[0] - KERNBASE); 1626 + patch_one_ktsb_phys(&__swapper_tsb_phys_patch, 1627 + &__swapper_tsb_phys_patch_end, ktsb_pa); 1628 + #ifndef CONFIG_DEBUG_PAGEALLOC 1629 + ktsb_pa = (kern_base + 1630 + ((unsigned long)&swapper_4m_tsb[0] - KERNBASE)); 1631 + patch_one_ktsb_phys(&__swapper_4m_tsb_phys_patch, 1632 + &__swapper_4m_tsb_phys_patch_end, ktsb_pa); 1633 + #endif 1634 + } 1635 + 1600 1636 static void __init sun4v_ktsb_init(void) 1601 1637 { 1602 1638 unsigned long ktsb_pa; ··· 1752 1716 sun4u_pgprot_init(); 1753 1717 1754 1718 if (tlb_type == cheetah_plus || 1755 - tlb_type == hypervisor) 1719 + tlb_type == hypervisor) { 1756 1720 tsb_phys_patch(); 1721 + ktsb_phys_patch(); 1722 + } 1757 1723 1758 1724 if (tlb_type == hypervisor) { 1759 1725 sun4v_patch_tlb_handlers();