diff options
| -rw-r--r-- | arch/sparc/kernel/Makefile | 5 | ||||
| -rw-r--r-- | arch/sparc/kernel/cpu.c | 4 | ||||
| -rw-r--r-- | arch/sparc/kernel/ebus.c | 6 | ||||
| -rw-r--r-- | arch/sparc/kernel/process.c | 2 | ||||
| -rw-r--r-- | arch/sparc/kernel/una_asm.S | 153 | ||||
| -rw-r--r-- | arch/sparc/kernel/unaligned.c | 252 | ||||
| -rw-r--r-- | arch/sparc64/kernel/cpu.c | 4 | ||||
| -rw-r--r-- | arch/sparc64/kernel/process.c | 2 | ||||
| -rw-r--r-- | arch/sparc64/solaris/conv.h | 2 | ||||
| -rw-r--r-- | arch/sparc64/solaris/timod.c | 2 | ||||
| -rw-r--r-- | include/asm-sparc/system.h | 2 | ||||
| -rw-r--r-- | include/asm-sparc64/system.h | 2 |
12 files changed, 216 insertions, 220 deletions
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index e795f282dece..bf1b15d3f6f5 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | # $Id: Makefile,v 1.62 2000/12/15 00:41:17 davem Exp $ | 1 | # |
| 2 | # Makefile for the linux kernel. | 2 | # Makefile for the linux kernel. |
| 3 | # | 3 | # |
| 4 | 4 | ||
| @@ -12,7 +12,8 @@ obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \ | |||
| 12 | sys_sparc.o sunos_asm.o systbls.o \ | 12 | sys_sparc.o sunos_asm.o systbls.o \ |
| 13 | time.o windows.o cpu.o devices.o sclow.o \ | 13 | time.o windows.o cpu.o devices.o sclow.o \ |
| 14 | tadpole.o tick14.o ptrace.o sys_solaris.o \ | 14 | tadpole.o tick14.o ptrace.o sys_solaris.o \ |
| 15 | unaligned.o muldiv.o semaphore.o prom.o of_device.o devres.o | 15 | unaligned.o una_asm.o muldiv.o semaphore.o \ |
| 16 | prom.o of_device.o devres.o | ||
| 16 | 17 | ||
| 17 | devres-y = ../../../kernel/irq/devres.o | 18 | devres-y = ../../../kernel/irq/devres.o |
| 18 | 19 | ||
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c index 259a559d4cea..e7a0edfc1a32 100644 --- a/arch/sparc/kernel/cpu.c +++ b/arch/sparc/kernel/cpu.c | |||
| @@ -32,7 +32,7 @@ struct cpu_fp_info { | |||
| 32 | /* In order to get the fpu type correct, you need to take the IDPROM's | 32 | /* In order to get the fpu type correct, you need to take the IDPROM's |
| 33 | * machine type value into consideration too. I will fix this. | 33 | * machine type value into consideration too. I will fix this. |
| 34 | */ | 34 | */ |
| 35 | struct cpu_fp_info linux_sparc_fpu[] = { | 35 | static struct cpu_fp_info linux_sparc_fpu[] = { |
| 36 | { 0, 0, "Fujitsu MB86910 or Weitek WTL1164/5"}, | 36 | { 0, 0, "Fujitsu MB86910 or Weitek WTL1164/5"}, |
| 37 | { 0, 1, "Fujitsu MB86911 or Weitek WTL1164/5 or LSI L64831"}, | 37 | { 0, 1, "Fujitsu MB86911 or Weitek WTL1164/5 or LSI L64831"}, |
| 38 | { 0, 2, "LSI Logic L64802 or Texas Instruments ACT8847"}, | 38 | { 0, 2, "LSI Logic L64802 or Texas Instruments ACT8847"}, |
| @@ -76,7 +76,7 @@ struct cpu_fp_info linux_sparc_fpu[] = { | |||
| 76 | 76 | ||
| 77 | #define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu) | 77 | #define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu) |
| 78 | 78 | ||
| 79 | struct cpu_iu_info linux_sparc_chips[] = { | 79 | static struct cpu_iu_info linux_sparc_chips[] = { |
| 80 | /* Sun4/100, 4/200, SLC */ | 80 | /* Sun4/100, 4/200, SLC */ |
| 81 | { 0, 0, "Fujitsu MB86900/1A or LSI L64831 SparcKIT-40"}, | 81 | { 0, 0, "Fujitsu MB86900/1A or LSI L64831 SparcKIT-40"}, |
| 82 | /* borned STP1012PGA */ | 82 | /* borned STP1012PGA */ |
diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c index d850785b2080..96344ff2bbe1 100644 --- a/arch/sparc/kernel/ebus.c +++ b/arch/sparc/kernel/ebus.c | |||
| @@ -101,7 +101,7 @@ void __init fill_ebus_child(struct device_node *dp, | |||
| 101 | prom_printf("UGH: property for %s was %d, need < %d\n", | 101 | prom_printf("UGH: property for %s was %d, need < %d\n", |
| 102 | dev->prom_node->name, len, | 102 | dev->prom_node->name, len, |
| 103 | dev->parent->num_addrs); | 103 | dev->parent->num_addrs); |
| 104 | panic(__FUNCTION__); | 104 | panic(__func__); |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | /* XXX resource */ | 107 | /* XXX resource */ |
| @@ -162,7 +162,7 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d | |||
| 162 | prom_printf("UGH: proplen for %s was %d, need multiple of %d\n", | 162 | prom_printf("UGH: proplen for %s was %d, need multiple of %d\n", |
| 163 | dev->prom_node->name, len, | 163 | dev->prom_node->name, len, |
| 164 | (int)sizeof(struct linux_prom_registers)); | 164 | (int)sizeof(struct linux_prom_registers)); |
| 165 | panic(__FUNCTION__); | 165 | panic(__func__); |
| 166 | } | 166 | } |
| 167 | dev->num_addrs = len / sizeof(struct linux_prom_registers); | 167 | dev->num_addrs = len / sizeof(struct linux_prom_registers); |
| 168 | 168 | ||
| @@ -324,7 +324,7 @@ void __init ebus_init(void) | |||
| 324 | regs = of_get_property(dp, "reg", &len); | 324 | regs = of_get_property(dp, "reg", &len); |
| 325 | if (!regs) { | 325 | if (!regs) { |
| 326 | prom_printf("%s: can't find reg property\n", | 326 | prom_printf("%s: can't find reg property\n", |
| 327 | __FUNCTION__); | 327 | __func__); |
| 328 | prom_halt(); | 328 | prom_halt(); |
| 329 | } | 329 | } |
| 330 | nreg = len / sizeof(struct linux_prom_pci_registers); | 330 | nreg = len / sizeof(struct linux_prom_pci_registers); |
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 0bd69d0b5cd7..70c0dd22491d 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c | |||
| @@ -139,8 +139,6 @@ void cpu_idle(void) | |||
| 139 | 139 | ||
| 140 | #endif | 140 | #endif |
| 141 | 141 | ||
| 142 | extern char reboot_command []; | ||
| 143 | |||
| 144 | /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */ | 142 | /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */ |
| 145 | void machine_halt(void) | 143 | void machine_halt(void) |
| 146 | { | 144 | { |
diff --git a/arch/sparc/kernel/una_asm.S b/arch/sparc/kernel/una_asm.S new file mode 100644 index 000000000000..8cc03458eb7e --- /dev/null +++ b/arch/sparc/kernel/una_asm.S | |||
| @@ -0,0 +1,153 @@ | |||
| 1 | /* una_asm.S: Kernel unaligned trap assembler helpers. | ||
| 2 | * | ||
| 3 | * Copyright (C) 1996,2005,2008 David S. Miller (davem@davemloft.net) | ||
| 4 | * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <linux/errno.h> | ||
| 8 | |||
| 9 | .text | ||
| 10 | |||
| 11 | retl_efault: | ||
| 12 | retl | ||
| 13 | mov -EFAULT, %o0 | ||
| 14 | |||
| 15 | /* int __do_int_store(unsigned long *dst_addr, int size, | ||
| 16 | * unsigned long *src_val) | ||
| 17 | * | ||
| 18 | * %o0 = dest_addr | ||
| 19 | * %o1 = size | ||
| 20 | * %o2 = src_val | ||
| 21 | * | ||
| 22 | * Return '0' on success, -EFAULT on failure. | ||
| 23 | */ | ||
| 24 | .globl __do_int_store | ||
| 25 | __do_int_store: | ||
| 26 | ld [%o2], %g1 | ||
| 27 | cmp %1, 2 | ||
| 28 | be 2f | ||
| 29 | cmp %1, 4 | ||
| 30 | be 1f | ||
| 31 | srl %g1, 24, %g2 | ||
| 32 | srl %g1, 16, %g7 | ||
| 33 | 4: stb %g2, [%o0] | ||
| 34 | srl %g1, 8, %g2 | ||
| 35 | 5: stb %g7, [%o0 + 1] | ||
| 36 | ld [%o2 + 4], %g7 | ||
| 37 | 6: stb %g2, [%o0 + 2] | ||
| 38 | srl %g7, 24, %g2 | ||
| 39 | 7: stb %g1, [%o0 + 3] | ||
| 40 | srl %g7, 16, %g1 | ||
| 41 | 8: stb %g2, [%o0 + 4] | ||
| 42 | srl %g7, 8, %g2 | ||
| 43 | 9: stb %g1, [%o0 + 5] | ||
| 44 | 10: stb %g2, [%o0 + 6] | ||
| 45 | b 0f | ||
| 46 | 11: stb %g7, [%o0 + 7] | ||
| 47 | 1: srl %g1, 16, %g7 | ||
| 48 | 12: stb %g2, [%o0] | ||
| 49 | srl %g1, 8, %g2 | ||
| 50 | 13: stb %g7, [%o0 + 1] | ||
| 51 | 14: stb %g2, [%o0 + 2] | ||
| 52 | b 0f | ||
| 53 | 15: stb %g1, [%o0 + 3] | ||
| 54 | 2: srl %g1, 8, %g2 | ||
| 55 | 16: stb %g2, [%o0] | ||
| 56 | 17: stb %g1, [%o0 + 1] | ||
| 57 | 0: retl | ||
| 58 | mov 0, %o0 | ||
| 59 | |||
| 60 | .section __ex_table,#alloc | ||
| 61 | .word 4b, retl_efault | ||
| 62 | .word 5b, retl_efault | ||
| 63 | .word 6b, retl_efault | ||
| 64 | .word 7b, retl_efault | ||
| 65 | .word 8b, retl_efault | ||
| 66 | .word 9b, retl_efault | ||
| 67 | .word 10b, retl_efault | ||
| 68 | .word 11b, retl_efault | ||
| 69 | .word 12b, retl_efault | ||
| 70 | .word 13b, retl_efault | ||
| 71 | .word 14b, retl_efault | ||
| 72 | .word 15b, retl_efault | ||
| 73 | .word 16b, retl_efault | ||
| 74 | .word 17b, retl_efault | ||
| 75 | .previous | ||
| 76 | |||
| 77 | /* int do_int_load(unsigned long *dest_reg, int size, | ||
| 78 | * unsigned long *saddr, int is_signed) | ||
| 79 | * | ||
| 80 | * %o0 = dest_reg | ||
| 81 | * %o1 = size | ||
| 82 | * %o2 = saddr | ||
| 83 | * %o3 = is_signed | ||
| 84 | * | ||
| 85 | * Return '0' on success, -EFAULT on failure. | ||
| 86 | */ | ||
| 87 | .globl do_int_load | ||
| 88 | do_int_load: | ||
| 89 | cmp %o1, 8 | ||
| 90 | be 9f | ||
| 91 | cmp %o1, 4 | ||
| 92 | be 6f | ||
| 93 | 4: ldub [%o2], %g1 | ||
| 94 | 5: ldub [%o2 + 1], %g2 | ||
| 95 | sll %g1, 8, %g1 | ||
| 96 | tst %o3 | ||
| 97 | be 3f | ||
| 98 | or %g1, %g2, %g1 | ||
| 99 | sll %g1, 16, %g1 | ||
| 100 | sra %g1, 16, %g1 | ||
| 101 | 3: b 0f | ||
| 102 | st %g1, [%o0] | ||
| 103 | 6: ldub [%o2 + 1], %g2 | ||
| 104 | sll %g1, 24, %g1 | ||
| 105 | 7: ldub [%o2 + 2], %g7 | ||
| 106 | sll %g2, 16, %g2 | ||
| 107 | 8: ldub [%o2 + 3], %g3 | ||
| 108 | sll %g7, 8, %g7 | ||
| 109 | or %g3, %g2, %g3 | ||
| 110 | or %g7, %g3, %g7 | ||
| 111 | or %g1, %g7, %g1 | ||
| 112 | b 0f | ||
| 113 | st %g1, [%o0] | ||
| 114 | 9: ldub [%o2], %g1 | ||
| 115 | 10: ldub [%o2 + 1], %g2 | ||
| 116 | sll %g1, 24, %g1 | ||
| 117 | 11: ldub [%o2 + 2], %g7 | ||
| 118 | sll %g2, 16, %g2 | ||
| 119 | 12: ldub [%o2 + 3], %g3 | ||
| 120 | sll %g7, 8, %g7 | ||
| 121 | or %g1, %g2, %g1 | ||
| 122 | or %g7, %g3, %g7 | ||
| 123 | or %g1, %g7, %g7 | ||
| 124 | 13: ldub [%o2 + 4], %g1 | ||
| 125 | st %g7, [%o0] | ||
| 126 | 14: ldub [%o2 + 5], %g2 | ||
| 127 | sll %g1, 24, %g1 | ||
| 128 | 15: ldub [%o2 + 6], %g7 | ||
| 129 | sll %g2, 16, %g2 | ||
| 130 | 16: ldub [%o2 + 7], %g3 | ||
| 131 | sll %g7, 8, %g7 | ||
| 132 | or %g1, %g2, %g1 | ||
| 133 | or %g7, %g3, %g7 | ||
| 134 | or %g1, %g7, %g7 | ||
| 135 | st %g7, [%o0 + 4] | ||
| 136 | 0: retl | ||
| 137 | mov 0, %o0 | ||
| 138 | |||
| 139 | .section __ex_table,#alloc | ||
| 140 | .word 4b, retl_efault | ||
| 141 | .word 5b, retl_efault | ||
| 142 | .word 6b, retl_efault | ||
| 143 | .word 7b, retl_efault | ||
| 144 | .word 8b, retl_efault | ||
| 145 | .word 9b, retl_efault | ||
| 146 | .word 10b, retl_efault | ||
| 147 | .word 11b, retl_efault | ||
| 148 | .word 12b, retl_efault | ||
| 149 | .word 13b, retl_efault | ||
| 150 | .word 14b, retl_efault | ||
| 151 | .word 15b, retl_efault | ||
| 152 | .word 16b, retl_efault | ||
| 153 | .previous | ||
diff --git a/arch/sparc/kernel/unaligned.c b/arch/sparc/kernel/unaligned.c index a6330fbc9dd9..33857be16661 100644 --- a/arch/sparc/kernel/unaligned.c +++ b/arch/sparc/kernel/unaligned.c | |||
| @@ -175,157 +175,31 @@ static void unaligned_panic(char *str) | |||
| 175 | panic(str); | 175 | panic(str); |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | #define do_integer_load(dest_reg, size, saddr, is_signed, errh) ({ \ | 178 | /* una_asm.S */ |
| 179 | __asm__ __volatile__ ( \ | 179 | extern int do_int_load(unsigned long *dest_reg, int size, |
| 180 | "cmp %1, 8\n\t" \ | 180 | unsigned long *saddr, int is_signed); |
| 181 | "be 9f\n\t" \ | 181 | extern int __do_int_store(unsigned long *dst_addr, int size, |
| 182 | " cmp %1, 4\n\t" \ | 182 | unsigned long *src_val); |
| 183 | "be 6f\n" \ | 183 | |
| 184 | "4:\t" " ldub [%2], %%l1\n" \ | 184 | static int do_int_store(int reg_num, int size, unsigned long *dst_addr, |
| 185 | "5:\t" "ldub [%2 + 1], %%l2\n\t" \ | 185 | struct pt_regs *regs) |
| 186 | "sll %%l1, 8, %%l1\n\t" \ | 186 | { |
| 187 | "tst %3\n\t" \ | 187 | unsigned long zero[2] = { 0, 0 }; |
| 188 | "be 3f\n\t" \ | 188 | unsigned long *src_val; |
| 189 | " add %%l1, %%l2, %%l1\n\t" \ | 189 | |
| 190 | "sll %%l1, 16, %%l1\n\t" \ | 190 | if (reg_num) |
| 191 | "sra %%l1, 16, %%l1\n" \ | 191 | src_val = fetch_reg_addr(reg_num, regs); |
| 192 | "3:\t" "b 0f\n\t" \ | 192 | else { |
| 193 | " st %%l1, [%0]\n" \ | 193 | src_val = &zero[0]; |
| 194 | "6:\t" "ldub [%2 + 1], %%l2\n\t" \ | 194 | if (size == 8) |
| 195 | "sll %%l1, 24, %%l1\n" \ | 195 | zero[1] = fetch_reg(1, regs); |
| 196 | "7:\t" "ldub [%2 + 2], %%g7\n\t" \ | 196 | } |
| 197 | "sll %%l2, 16, %%l2\n" \ | 197 | return __do_int_store(dst_addr, size, src_val); |
| 198 | "8:\t" "ldub [%2 + 3], %%g1\n\t" \ | 198 | } |
| 199 | "sll %%g7, 8, %%g7\n\t" \ | ||
| 200 | "or %%l1, %%l2, %%l1\n\t" \ | ||
| 201 | "or %%g7, %%g1, %%g7\n\t" \ | ||
| 202 | "or %%l1, %%g7, %%l1\n\t" \ | ||
| 203 | "b 0f\n\t" \ | ||
| 204 | " st %%l1, [%0]\n" \ | ||
| 205 | "9:\t" "ldub [%2], %%l1\n" \ | ||
| 206 | "10:\t" "ldub [%2 + 1], %%l2\n\t" \ | ||
| 207 | "sll %%l1, 24, %%l1\n" \ | ||
| 208 | "11:\t" "ldub [%2 + 2], %%g7\n\t" \ | ||
| 209 | "sll %%l2, 16, %%l2\n" \ | ||
| 210 | "12:\t" "ldub [%2 + 3], %%g1\n\t" \ | ||
| 211 | "sll %%g7, 8, %%g7\n\t" \ | ||
| 212 | "or %%l1, %%l2, %%l1\n\t" \ | ||
| 213 | "or %%g7, %%g1, %%g7\n\t" \ | ||
| 214 | "or %%l1, %%g7, %%g7\n" \ | ||
| 215 | "13:\t" "ldub [%2 + 4], %%l1\n\t" \ | ||
| 216 | "st %%g7, [%0]\n" \ | ||
| 217 | "14:\t" "ldub [%2 + 5], %%l2\n\t" \ | ||
| 218 | "sll %%l1, 24, %%l1\n" \ | ||
| 219 | "15:\t" "ldub [%2 + 6], %%g7\n\t" \ | ||
| 220 | "sll %%l2, 16, %%l2\n" \ | ||
| 221 | "16:\t" "ldub [%2 + 7], %%g1\n\t" \ | ||
| 222 | "sll %%g7, 8, %%g7\n\t" \ | ||
| 223 | "or %%l1, %%l2, %%l1\n\t" \ | ||
| 224 | "or %%g7, %%g1, %%g7\n\t" \ | ||
| 225 | "or %%l1, %%g7, %%g7\n\t" \ | ||
| 226 | "st %%g7, [%0 + 4]\n" \ | ||
| 227 | "0:\n\n\t" \ | ||
| 228 | ".section __ex_table,#alloc\n\t" \ | ||
| 229 | ".word 4b, " #errh "\n\t" \ | ||
| 230 | ".word 5b, " #errh "\n\t" \ | ||
| 231 | ".word 6b, " #errh "\n\t" \ | ||
| 232 | ".word 7b, " #errh "\n\t" \ | ||
| 233 | ".word 8b, " #errh "\n\t" \ | ||
| 234 | ".word 9b, " #errh "\n\t" \ | ||
| 235 | ".word 10b, " #errh "\n\t" \ | ||
| 236 | ".word 11b, " #errh "\n\t" \ | ||
| 237 | ".word 12b, " #errh "\n\t" \ | ||
| 238 | ".word 13b, " #errh "\n\t" \ | ||
| 239 | ".word 14b, " #errh "\n\t" \ | ||
| 240 | ".word 15b, " #errh "\n\t" \ | ||
| 241 | ".word 16b, " #errh "\n\n\t" \ | ||
| 242 | ".previous\n\t" \ | ||
| 243 | : : "r" (dest_reg), "r" (size), "r" (saddr), "r" (is_signed) \ | ||
| 244 | : "l1", "l2", "g7", "g1", "cc"); \ | ||
| 245 | }) | ||
| 246 | |||
| 247 | #define store_common(dst_addr, size, src_val, errh) ({ \ | ||
| 248 | __asm__ __volatile__ ( \ | ||
| 249 | "ld [%2], %%l1\n" \ | ||
| 250 | "cmp %1, 2\n\t" \ | ||
| 251 | "be 2f\n\t" \ | ||
| 252 | " cmp %1, 4\n\t" \ | ||
| 253 | "be 1f\n\t" \ | ||
| 254 | " srl %%l1, 24, %%l2\n\t" \ | ||
| 255 | "srl %%l1, 16, %%g7\n" \ | ||
| 256 | "4:\t" "stb %%l2, [%0]\n\t" \ | ||
| 257 | "srl %%l1, 8, %%l2\n" \ | ||
| 258 | "5:\t" "stb %%g7, [%0 + 1]\n\t" \ | ||
| 259 | "ld [%2 + 4], %%g7\n" \ | ||
| 260 | "6:\t" "stb %%l2, [%0 + 2]\n\t" \ | ||
| 261 | "srl %%g7, 24, %%l2\n" \ | ||
| 262 | "7:\t" "stb %%l1, [%0 + 3]\n\t" \ | ||
| 263 | "srl %%g7, 16, %%l1\n" \ | ||
| 264 | "8:\t" "stb %%l2, [%0 + 4]\n\t" \ | ||
| 265 | "srl %%g7, 8, %%l2\n" \ | ||
| 266 | "9:\t" "stb %%l1, [%0 + 5]\n" \ | ||
| 267 | "10:\t" "stb %%l2, [%0 + 6]\n\t" \ | ||
| 268 | "b 0f\n" \ | ||
| 269 | "11:\t" " stb %%g7, [%0 + 7]\n" \ | ||
| 270 | "1:\t" "srl %%l1, 16, %%g7\n" \ | ||
| 271 | "12:\t" "stb %%l2, [%0]\n\t" \ | ||
| 272 | "srl %%l1, 8, %%l2\n" \ | ||
| 273 | "13:\t" "stb %%g7, [%0 + 1]\n" \ | ||
| 274 | "14:\t" "stb %%l2, [%0 + 2]\n\t" \ | ||
| 275 | "b 0f\n" \ | ||
| 276 | "15:\t" " stb %%l1, [%0 + 3]\n" \ | ||
| 277 | "2:\t" "srl %%l1, 8, %%l2\n" \ | ||
| 278 | "16:\t" "stb %%l2, [%0]\n" \ | ||
| 279 | "17:\t" "stb %%l1, [%0 + 1]\n" \ | ||
| 280 | "0:\n\n\t" \ | ||
| 281 | ".section __ex_table,#alloc\n\t" \ | ||
| 282 | ".word 4b, " #errh "\n\t" \ | ||
| 283 | ".word 5b, " #errh "\n\t" \ | ||
| 284 | ".word 6b, " #errh "\n\t" \ | ||
| 285 | ".word 7b, " #errh "\n\t" \ | ||
| 286 | ".word 8b, " #errh "\n\t" \ | ||
| 287 | ".word 9b, " #errh "\n\t" \ | ||
| 288 | ".word 10b, " #errh "\n\t" \ | ||
| 289 | ".word 11b, " #errh "\n\t" \ | ||
| 290 | ".word 12b, " #errh "\n\t" \ | ||
| 291 | ".word 13b, " #errh "\n\t" \ | ||
| 292 | ".word 14b, " #errh "\n\t" \ | ||
| 293 | ".word 15b, " #errh "\n\t" \ | ||
| 294 | ".word 16b, " #errh "\n\t" \ | ||
| 295 | ".word 17b, " #errh "\n\n\t" \ | ||
| 296 | ".previous\n\t" \ | ||
| 297 | : : "r" (dst_addr), "r" (size), "r" (src_val) \ | ||
| 298 | : "l1", "l2", "g7", "g1", "cc"); \ | ||
| 299 | }) | ||
| 300 | |||
| 301 | #define do_integer_store(reg_num, size, dst_addr, regs, errh) ({ \ | ||
| 302 | unsigned long *src_val; \ | ||
| 303 | static unsigned long zero[2] = { 0, }; \ | ||
| 304 | \ | ||
| 305 | if (reg_num) src_val = fetch_reg_addr(reg_num, regs); \ | ||
| 306 | else { \ | ||
| 307 | src_val = &zero[0]; \ | ||
| 308 | if (size == 8) \ | ||
| 309 | zero[1] = fetch_reg(1, regs); \ | ||
| 310 | } \ | ||
| 311 | store_common(dst_addr, size, src_val, errh); \ | ||
| 312 | }) | ||
| 313 | 199 | ||
| 314 | extern void smp_capture(void); | 200 | extern void smp_capture(void); |
| 315 | extern void smp_release(void); | 201 | extern void smp_release(void); |
| 316 | 202 | ||
| 317 | #define do_atomic(srcdest_reg, mem, errh) ({ \ | ||
| 318 | unsigned long flags, tmp; \ | ||
| 319 | \ | ||
| 320 | smp_capture(); \ | ||
| 321 | local_irq_save(flags); \ | ||
| 322 | tmp = *srcdest_reg; \ | ||
| 323 | do_integer_load(srcdest_reg, 4, mem, 0, errh); \ | ||
| 324 | store_common(mem, 4, &tmp, errh); \ | ||
| 325 | local_irq_restore(flags); \ | ||
| 326 | smp_release(); \ | ||
| 327 | }) | ||
| 328 | |||
| 329 | static inline void advance(struct pt_regs *regs) | 203 | static inline void advance(struct pt_regs *regs) |
| 330 | { | 204 | { |
| 331 | regs->pc = regs->npc; | 205 | regs->pc = regs->npc; |
| @@ -342,9 +216,7 @@ static inline int ok_for_kernel(unsigned int insn) | |||
| 342 | return !floating_point_load_or_store_p(insn); | 216 | return !floating_point_load_or_store_p(insn); |
| 343 | } | 217 | } |
| 344 | 218 | ||
| 345 | void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("kernel_mna_trap_fault"); | 219 | static void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) |
| 346 | |||
| 347 | void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) | ||
| 348 | { | 220 | { |
| 349 | unsigned long g2 = regs->u_regs [UREG_G2]; | 221 | unsigned long g2 = regs->u_regs [UREG_G2]; |
| 350 | unsigned long fixup = search_extables_range(regs->pc, &g2); | 222 | unsigned long fixup = search_extables_range(regs->pc, &g2); |
| @@ -379,48 +251,34 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) | |||
| 379 | printk("Unsupported unaligned load/store trap for kernel at <%08lx>.\n", | 251 | printk("Unsupported unaligned load/store trap for kernel at <%08lx>.\n", |
| 380 | regs->pc); | 252 | regs->pc); |
| 381 | unaligned_panic("Wheee. Kernel does fpu/atomic unaligned load/store."); | 253 | unaligned_panic("Wheee. Kernel does fpu/atomic unaligned load/store."); |
| 382 | |||
| 383 | __asm__ __volatile__ ("\n" | ||
| 384 | "kernel_unaligned_trap_fault:\n\t" | ||
| 385 | "mov %0, %%o0\n\t" | ||
| 386 | "call kernel_mna_trap_fault\n\t" | ||
| 387 | " mov %1, %%o1\n\t" | ||
| 388 | : | ||
| 389 | : "r" (regs), "r" (insn) | ||
| 390 | : "o0", "o1", "o2", "o3", "o4", "o5", "o7", | ||
| 391 | "g1", "g2", "g3", "g4", "g5", "g7", "cc"); | ||
| 392 | } else { | 254 | } else { |
| 393 | unsigned long addr = compute_effective_address(regs, insn); | 255 | unsigned long addr = compute_effective_address(regs, insn); |
| 256 | int err; | ||
| 394 | 257 | ||
| 395 | #ifdef DEBUG_MNA | 258 | #ifdef DEBUG_MNA |
| 396 | printk("KMNA: pc=%08lx [dir=%s addr=%08lx size=%d] retpc[%08lx]\n", | 259 | printk("KMNA: pc=%08lx [dir=%s addr=%08lx size=%d] retpc[%08lx]\n", |
| 397 | regs->pc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]); | 260 | regs->pc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]); |
| 398 | #endif | 261 | #endif |
| 399 | switch(dir) { | 262 | switch (dir) { |
| 400 | case load: | 263 | case load: |
| 401 | do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs), | 264 | err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f), |
| 402 | size, (unsigned long *) addr, | 265 | regs), |
| 403 | decode_signedness(insn), | 266 | size, (unsigned long *) addr, |
| 404 | kernel_unaligned_trap_fault); | 267 | decode_signedness(insn)); |
| 405 | break; | 268 | break; |
| 406 | 269 | ||
| 407 | case store: | 270 | case store: |
| 408 | do_integer_store(((insn>>25)&0x1f), size, | 271 | err = do_int_store(((insn>>25)&0x1f), size, |
| 409 | (unsigned long *) addr, regs, | 272 | (unsigned long *) addr, regs); |
| 410 | kernel_unaligned_trap_fault); | ||
| 411 | break; | 273 | break; |
| 412 | #if 0 /* unsupported */ | ||
| 413 | case both: | ||
| 414 | do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs), | ||
| 415 | (unsigned long *) addr, | ||
| 416 | kernel_unaligned_trap_fault); | ||
| 417 | break; | ||
| 418 | #endif | ||
| 419 | default: | 274 | default: |
| 420 | panic("Impossible kernel unaligned trap."); | 275 | panic("Impossible kernel unaligned trap."); |
| 421 | /* Not reached... */ | 276 | /* Not reached... */ |
| 422 | } | 277 | } |
| 423 | advance(regs); | 278 | if (err) |
| 279 | kernel_mna_trap_fault(regs, insn); | ||
| 280 | else | ||
| 281 | advance(regs); | ||
| 424 | } | 282 | } |
| 425 | } | 283 | } |
| 426 | 284 | ||
| @@ -459,9 +317,7 @@ static inline int ok_for_user(struct pt_regs *regs, unsigned int insn, | |||
| 459 | return 0; | 317 | return 0; |
| 460 | } | 318 | } |
| 461 | 319 | ||
| 462 | void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("user_mna_trap_fault"); | 320 | static void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn) |
| 463 | |||
| 464 | void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn) | ||
| 465 | { | 321 | { |
| 466 | siginfo_t info; | 322 | siginfo_t info; |
| 467 | 323 | ||
| @@ -485,7 +341,7 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn) | |||
| 485 | if(!ok_for_user(regs, insn, dir)) { | 341 | if(!ok_for_user(regs, insn, dir)) { |
| 486 | goto kill_user; | 342 | goto kill_user; |
| 487 | } else { | 343 | } else { |
| 488 | int size = decode_access_size(insn); | 344 | int err, size = decode_access_size(insn); |
| 489 | unsigned long addr; | 345 | unsigned long addr; |
| 490 | 346 | ||
| 491 | if(floating_point_load_or_store_p(insn)) { | 347 | if(floating_point_load_or_store_p(insn)) { |
| @@ -496,48 +352,34 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn) | |||
| 496 | addr = compute_effective_address(regs, insn); | 352 | addr = compute_effective_address(regs, insn); |
| 497 | switch(dir) { | 353 | switch(dir) { |
| 498 | case load: | 354 | case load: |
| 499 | do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs), | 355 | err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f), |
| 500 | size, (unsigned long *) addr, | 356 | regs), |
| 501 | decode_signedness(insn), | 357 | size, (unsigned long *) addr, |
| 502 | user_unaligned_trap_fault); | 358 | decode_signedness(insn)); |
| 503 | break; | 359 | break; |
| 504 | 360 | ||
| 505 | case store: | 361 | case store: |
| 506 | do_integer_store(((insn>>25)&0x1f), size, | 362 | err = do_int_store(((insn>>25)&0x1f), size, |
| 507 | (unsigned long *) addr, regs, | 363 | (unsigned long *) addr, regs); |
| 508 | user_unaligned_trap_fault); | ||
| 509 | break; | 364 | break; |
| 510 | 365 | ||
| 511 | case both: | 366 | case both: |
| 512 | #if 0 /* unsupported */ | ||
| 513 | do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs), | ||
| 514 | (unsigned long *) addr, | ||
| 515 | user_unaligned_trap_fault); | ||
| 516 | #else | ||
| 517 | /* | 367 | /* |
| 518 | * This was supported in 2.4. However, we question | 368 | * This was supported in 2.4. However, we question |
| 519 | * the value of SWAP instruction across word boundaries. | 369 | * the value of SWAP instruction across word boundaries. |
| 520 | */ | 370 | */ |
| 521 | printk("Unaligned SWAP unsupported.\n"); | 371 | printk("Unaligned SWAP unsupported.\n"); |
| 522 | goto kill_user; | 372 | err = -EFAULT; |
| 523 | #endif | ||
| 524 | break; | 373 | break; |
| 525 | 374 | ||
| 526 | default: | 375 | default: |
| 527 | unaligned_panic("Impossible user unaligned trap."); | 376 | unaligned_panic("Impossible user unaligned trap."); |
| 528 | |||
| 529 | __asm__ __volatile__ ("\n" | ||
| 530 | "user_unaligned_trap_fault:\n\t" | ||
| 531 | "mov %0, %%o0\n\t" | ||
| 532 | "call user_mna_trap_fault\n\t" | ||
| 533 | " mov %1, %%o1\n\t" | ||
| 534 | : | ||
| 535 | : "r" (regs), "r" (insn) | ||
| 536 | : "o0", "o1", "o2", "o3", "o4", "o5", "o7", | ||
| 537 | "g1", "g2", "g3", "g4", "g5", "g7", "cc"); | ||
| 538 | goto out; | 377 | goto out; |
| 539 | } | 378 | } |
| 540 | advance(regs); | 379 | if (err) |
| 380 | goto kill_user; | ||
| 381 | else | ||
| 382 | advance(regs); | ||
| 541 | goto out; | 383 | goto out; |
| 542 | } | 384 | } |
| 543 | 385 | ||
diff --git a/arch/sparc64/kernel/cpu.c b/arch/sparc64/kernel/cpu.c index e43db73f2b91..dd5d28e3d798 100644 --- a/arch/sparc64/kernel/cpu.c +++ b/arch/sparc64/kernel/cpu.c | |||
| @@ -30,7 +30,7 @@ struct cpu_fp_info { | |||
| 30 | char* fp_name; | 30 | char* fp_name; |
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | struct cpu_fp_info linux_sparc_fpu[] = { | 33 | static struct cpu_fp_info linux_sparc_fpu[] = { |
| 34 | { 0x17, 0x10, 0, "UltraSparc I integrated FPU"}, | 34 | { 0x17, 0x10, 0, "UltraSparc I integrated FPU"}, |
| 35 | { 0x22, 0x10, 0, "UltraSparc I integrated FPU"}, | 35 | { 0x22, 0x10, 0, "UltraSparc I integrated FPU"}, |
| 36 | { 0x17, 0x11, 0, "UltraSparc II integrated FPU"}, | 36 | { 0x17, 0x11, 0, "UltraSparc II integrated FPU"}, |
| @@ -46,7 +46,7 @@ struct cpu_fp_info linux_sparc_fpu[] = { | |||
| 46 | 46 | ||
| 47 | #define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu) | 47 | #define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu) |
| 48 | 48 | ||
| 49 | struct cpu_iu_info linux_sparc_chips[] = { | 49 | static struct cpu_iu_info linux_sparc_chips[] = { |
| 50 | { 0x17, 0x10, "TI UltraSparc I (SpitFire)"}, | 50 | { 0x17, 0x10, "TI UltraSparc I (SpitFire)"}, |
| 51 | { 0x22, 0x10, "TI UltraSparc I (SpitFire)"}, | 51 | { 0x22, 0x10, "TI UltraSparc I (SpitFire)"}, |
| 52 | { 0x17, 0x11, "TI UltraSparc II (BlackBird)"}, | 52 | { 0x17, 0x11, "TI UltraSparc II (BlackBird)"}, |
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 2aafce7dfc0e..e116e38b160e 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c | |||
| @@ -114,8 +114,6 @@ void cpu_idle(void) | |||
| 114 | } | 114 | } |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | extern char reboot_command []; | ||
| 118 | |||
| 119 | void machine_halt(void) | 117 | void machine_halt(void) |
| 120 | { | 118 | { |
| 121 | sstate_halt(); | 119 | sstate_halt(); |
diff --git a/arch/sparc64/solaris/conv.h b/arch/sparc64/solaris/conv.h index 5faf59a9de39..50e58232cf2b 100644 --- a/arch/sparc64/solaris/conv.h +++ b/arch/sparc64/solaris/conv.h | |||
| @@ -28,7 +28,7 @@ extern unsigned sunos_sys_table[]; | |||
| 28 | #define SUNOS(x) ((long)sunos_sys_table[x]) | 28 | #define SUNOS(x) ((long)sunos_sys_table[x]) |
| 29 | 29 | ||
| 30 | #ifdef DEBUG_SOLARIS | 30 | #ifdef DEBUG_SOLARIS |
| 31 | #define SOLD(s) printk("%s,%d,%s(): %s\n",__FILE__,__LINE__,__FUNCTION__,(s)) | 31 | #define SOLD(s) printk("%s,%d,%s(): %s\n",__FILE__,__LINE__,__func__,(s)) |
| 32 | #define SOLDD(s) printk("solaris: "); printk s | 32 | #define SOLDD(s) printk("solaris: "); printk s |
| 33 | #else | 33 | #else |
| 34 | #define SOLD(s) | 34 | #define SOLD(s) |
diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c index f53123c02c2b..15234fcd191a 100644 --- a/arch/sparc64/solaris/timod.c +++ b/arch/sparc64/solaris/timod.c | |||
| @@ -81,7 +81,7 @@ void mykfree(void *p) | |||
| 81 | #define MKCTL_MAGIC 0xDEADBABEBADC0DEDL | 81 | #define MKCTL_MAGIC 0xDEADBABEBADC0DEDL |
| 82 | #define PUT_MAGIC(a,m) do{(*(u64*)(a))=(m);}while(0) | 82 | #define PUT_MAGIC(a,m) do{(*(u64*)(a))=(m);}while(0) |
| 83 | #define SCHECK_MAGIC(a,m) do{if((*(u64*)(a))!=(m))printk("%s,%u,%s(): magic %08x at %p corrupted!\n",\ | 83 | #define SCHECK_MAGIC(a,m) do{if((*(u64*)(a))!=(m))printk("%s,%u,%s(): magic %08x at %p corrupted!\n",\ |
| 84 | __FILE__,__LINE__,__FUNCTION__,(m),(a));}while(0) | 84 | __FILE__,__LINE__,__func__,(m),(a));}while(0) |
| 85 | #define BUF_OFFSET sizeof(u64) | 85 | #define BUF_OFFSET sizeof(u64) |
| 86 | #define MKCTL_TRAILER sizeof(u64) | 86 | #define MKCTL_TRAILER sizeof(u64) |
| 87 | 87 | ||
diff --git a/include/asm-sparc/system.h b/include/asm-sparc/system.h index 45e47c159a6e..4e08210cd4c2 100644 --- a/include/asm-sparc/system.h +++ b/include/asm-sparc/system.h | |||
| @@ -44,6 +44,8 @@ extern enum sparc_cpu sparc_cpu_model; | |||
| 44 | 44 | ||
| 45 | #define SUN4M_NCPUS 4 /* Architectural limit of sun4m. */ | 45 | #define SUN4M_NCPUS 4 /* Architectural limit of sun4m. */ |
| 46 | 46 | ||
| 47 | extern char reboot_command[]; | ||
| 48 | |||
| 47 | extern struct thread_info *current_set[NR_CPUS]; | 49 | extern struct thread_info *current_set[NR_CPUS]; |
| 48 | 50 | ||
| 49 | extern unsigned long empty_bad_page; | 51 | extern unsigned long empty_bad_page; |
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h index ed91a5d8d4f0..53eae091a171 100644 --- a/include/asm-sparc64/system.h +++ b/include/asm-sparc64/system.h | |||
| @@ -30,6 +30,8 @@ enum sparc_cpu { | |||
| 30 | #define ARCH_SUN4C_SUN4 0 | 30 | #define ARCH_SUN4C_SUN4 0 |
| 31 | #define ARCH_SUN4 0 | 31 | #define ARCH_SUN4 0 |
| 32 | 32 | ||
| 33 | extern char reboot_command[]; | ||
| 34 | |||
| 33 | /* These are here in an effort to more fully work around Spitfire Errata | 35 | /* These are here in an effort to more fully work around Spitfire Errata |
| 34 | * #51. Essentially, if a memory barrier occurs soon after a mispredicted | 36 | * #51. Essentially, if a memory barrier occurs soon after a mispredicted |
| 35 | * branch, the chip can stop executing instructions until a trap occurs. | 37 | * branch, the chip can stop executing instructions until a trap occurs. |
