diff options
| -rw-r--r-- | CREDITS | 4 | ||||
| -rw-r--r-- | arch/parisc/kernel/cache.c | 28 | ||||
| -rw-r--r-- | arch/parisc/kernel/entry.S | 6 | ||||
| -rw-r--r-- | arch/parisc/kernel/firmware.c | 46 | ||||
| -rw-r--r-- | arch/parisc/kernel/module.c | 63 | ||||
| -rw-r--r-- | arch/parisc/kernel/pdc_chassis.c | 109 | ||||
| -rw-r--r-- | arch/parisc/kernel/ptrace.c | 8 | ||||
| -rw-r--r-- | arch/parisc/kernel/real2.S | 9 | ||||
| -rw-r--r-- | arch/parisc/kernel/setup.c | 5 | ||||
| -rw-r--r-- | arch/parisc/kernel/signal.c | 20 | ||||
| -rw-r--r-- | arch/parisc/kernel/syscall.S | 14 | ||||
| -rw-r--r-- | arch/parisc/kernel/time.c | 18 | ||||
| -rw-r--r-- | arch/parisc/kernel/traps.c | 84 | ||||
| -rw-r--r-- | arch/parisc/kernel/unaligned.c | 18 | ||||
| -rw-r--r-- | drivers/parisc/Kconfig | 33 | ||||
| -rw-r--r-- | drivers/parisc/pdc_stable.c | 223 | ||||
| -rw-r--r-- | drivers/parisc/sba_iommu.c | 17 | ||||
| -rw-r--r-- | include/asm-parisc/assembly.h | 2 | ||||
| -rw-r--r-- | include/asm-parisc/compat.h | 11 | ||||
| -rw-r--r-- | include/asm-parisc/pdc.h | 21 | ||||
| -rw-r--r-- | include/asm-parisc/pgtable.h | 8 | ||||
| -rw-r--r-- | include/asm-parisc/processor.h | 14 | ||||
| -rw-r--r-- | include/asm-parisc/system.h | 26 | ||||
| -rw-r--r-- | include/asm-parisc/uaccess.h | 9 | ||||
| -rw-r--r-- | include/asm-parisc/unistd.h | 5 |
25 files changed, 581 insertions, 220 deletions
| @@ -3401,10 +3401,10 @@ S: Czech Republic | |||
| 3401 | 3401 | ||
| 3402 | N: Thibaut Varene | 3402 | N: Thibaut Varene |
| 3403 | E: T-Bone@parisc-linux.org | 3403 | E: T-Bone@parisc-linux.org |
| 3404 | W: http://www.parisc-linux.org/ | 3404 | W: http://www.parisc-linux.org/~varenet/ |
| 3405 | P: 1024D/B7D2F063 E67C 0D43 A75E 12A5 BB1C FA2F 1E32 C3DA B7D2 F063 | 3405 | P: 1024D/B7D2F063 E67C 0D43 A75E 12A5 BB1C FA2F 1E32 C3DA B7D2 F063 |
| 3406 | D: PA-RISC port minion, PDC and GSCPS2 drivers, debuglocks and other bits | 3406 | D: PA-RISC port minion, PDC and GSCPS2 drivers, debuglocks and other bits |
| 3407 | D: Some bits in an ARM port, S1D13XXX FB driver, random patches here and there | 3407 | D: Some ARM at91rm9200 bits, S1D13XXX FB driver, random patches here and there |
| 3408 | D: AD1889 sound driver | 3408 | D: AD1889 sound driver |
| 3409 | S: Paris, France | 3409 | S: Paris, France |
| 3410 | 3410 | ||
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index c057ad7605ba..bc7c4a4e26a1 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c | |||
| @@ -97,15 +97,17 @@ update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) | |||
| 97 | void | 97 | void |
| 98 | show_cache_info(struct seq_file *m) | 98 | show_cache_info(struct seq_file *m) |
| 99 | { | 99 | { |
| 100 | char buf[32]; | ||
| 101 | |||
| 100 | seq_printf(m, "I-cache\t\t: %ld KB\n", | 102 | seq_printf(m, "I-cache\t\t: %ld KB\n", |
| 101 | cache_info.ic_size/1024 ); | 103 | cache_info.ic_size/1024 ); |
| 102 | seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %d-way associative)\n", | 104 | if (cache_info.dc_loop == 1) |
| 105 | snprintf(buf, 32, "%lu-way associative", cache_info.dc_loop); | ||
| 106 | seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %s)\n", | ||
| 103 | cache_info.dc_size/1024, | 107 | cache_info.dc_size/1024, |
| 104 | (cache_info.dc_conf.cc_wt ? "WT":"WB"), | 108 | (cache_info.dc_conf.cc_wt ? "WT":"WB"), |
| 105 | (cache_info.dc_conf.cc_sh ? ", shared I/D":""), | 109 | (cache_info.dc_conf.cc_sh ? ", shared I/D":""), |
| 106 | (cache_info.dc_conf.cc_assoc) | 110 | ((cache_info.dc_loop == 1) ? "direct mapped" : buf)); |
| 107 | ); | ||
| 108 | |||
| 109 | seq_printf(m, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n", | 111 | seq_printf(m, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n", |
| 110 | cache_info.it_size, | 112 | cache_info.it_size, |
| 111 | cache_info.dt_size, | 113 | cache_info.dt_size, |
| @@ -158,11 +160,11 @@ parisc_cache_init(void) | |||
| 158 | cache_info.dc_conf.cc_block, | 160 | cache_info.dc_conf.cc_block, |
| 159 | cache_info.dc_conf.cc_line, | 161 | cache_info.dc_conf.cc_line, |
| 160 | cache_info.dc_conf.cc_shift); | 162 | cache_info.dc_conf.cc_shift); |
| 161 | printk(" wt %d sh %d cst %d assoc %d\n", | 163 | printk(" wt %d sh %d cst %d hv %d\n", |
| 162 | cache_info.dc_conf.cc_wt, | 164 | cache_info.dc_conf.cc_wt, |
| 163 | cache_info.dc_conf.cc_sh, | 165 | cache_info.dc_conf.cc_sh, |
| 164 | cache_info.dc_conf.cc_cst, | 166 | cache_info.dc_conf.cc_cst, |
| 165 | cache_info.dc_conf.cc_assoc); | 167 | cache_info.dc_conf.cc_hv); |
| 166 | 168 | ||
| 167 | printk("IC base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx\n", | 169 | printk("IC base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx\n", |
| 168 | cache_info.ic_base, | 170 | cache_info.ic_base, |
| @@ -176,11 +178,11 @@ parisc_cache_init(void) | |||
| 176 | cache_info.ic_conf.cc_block, | 178 | cache_info.ic_conf.cc_block, |
| 177 | cache_info.ic_conf.cc_line, | 179 | cache_info.ic_conf.cc_line, |
| 178 | cache_info.ic_conf.cc_shift); | 180 | cache_info.ic_conf.cc_shift); |
| 179 | printk(" wt %d sh %d cst %d assoc %d\n", | 181 | printk(" wt %d sh %d cst %d hv %d\n", |
| 180 | cache_info.ic_conf.cc_wt, | 182 | cache_info.ic_conf.cc_wt, |
| 181 | cache_info.ic_conf.cc_sh, | 183 | cache_info.ic_conf.cc_sh, |
| 182 | cache_info.ic_conf.cc_cst, | 184 | cache_info.ic_conf.cc_cst, |
| 183 | cache_info.ic_conf.cc_assoc); | 185 | cache_info.ic_conf.cc_hv); |
| 184 | 186 | ||
| 185 | printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n", | 187 | printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n", |
| 186 | cache_info.dt_conf.tc_sh, | 188 | cache_info.dt_conf.tc_sh, |
| @@ -234,7 +236,8 @@ parisc_cache_init(void) | |||
| 234 | 236 | ||
| 235 | void disable_sr_hashing(void) | 237 | void disable_sr_hashing(void) |
| 236 | { | 238 | { |
| 237 | int srhash_type; | 239 | int srhash_type, retval; |
| 240 | unsigned long space_bits; | ||
| 238 | 241 | ||
| 239 | switch (boot_cpu_data.cpu_type) { | 242 | switch (boot_cpu_data.cpu_type) { |
| 240 | case pcx: /* We shouldn't get this far. setup.c should prevent it. */ | 243 | case pcx: /* We shouldn't get this far. setup.c should prevent it. */ |
| @@ -260,6 +263,13 @@ void disable_sr_hashing(void) | |||
| 260 | } | 263 | } |
| 261 | 264 | ||
| 262 | disable_sr_hashing_asm(srhash_type); | 265 | disable_sr_hashing_asm(srhash_type); |
| 266 | |||
| 267 | retval = pdc_spaceid_bits(&space_bits); | ||
| 268 | /* If this procedure isn't implemented, don't panic. */ | ||
| 269 | if (retval < 0 && retval != PDC_BAD_OPTION) | ||
| 270 | panic("pdc_spaceid_bits call failed.\n"); | ||
| 271 | if (space_bits != 0) | ||
| 272 | panic("SpaceID hashing is still on!\n"); | ||
| 263 | } | 273 | } |
| 264 | 274 | ||
| 265 | void flush_dcache_page(struct page *page) | 275 | void flush_dcache_page(struct page *page) |
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index d9e53cf0372b..630730c32a5a 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S | |||
| @@ -1638,7 +1638,7 @@ dbit_trap_20w: | |||
| 1638 | load32 PA(pa_dbit_lock),t0 | 1638 | load32 PA(pa_dbit_lock),t0 |
| 1639 | 1639 | ||
| 1640 | dbit_spin_20w: | 1640 | dbit_spin_20w: |
| 1641 | ldcw 0(t0),t1 | 1641 | LDCW 0(t0),t1 |
| 1642 | cmpib,= 0,t1,dbit_spin_20w | 1642 | cmpib,= 0,t1,dbit_spin_20w |
| 1643 | nop | 1643 | nop |
| 1644 | 1644 | ||
| @@ -1674,7 +1674,7 @@ dbit_trap_11: | |||
| 1674 | load32 PA(pa_dbit_lock),t0 | 1674 | load32 PA(pa_dbit_lock),t0 |
| 1675 | 1675 | ||
| 1676 | dbit_spin_11: | 1676 | dbit_spin_11: |
| 1677 | ldcw 0(t0),t1 | 1677 | LDCW 0(t0),t1 |
| 1678 | cmpib,= 0,t1,dbit_spin_11 | 1678 | cmpib,= 0,t1,dbit_spin_11 |
| 1679 | nop | 1679 | nop |
| 1680 | 1680 | ||
| @@ -1714,7 +1714,7 @@ dbit_trap_20: | |||
| 1714 | load32 PA(pa_dbit_lock),t0 | 1714 | load32 PA(pa_dbit_lock),t0 |
| 1715 | 1715 | ||
| 1716 | dbit_spin_20: | 1716 | dbit_spin_20: |
| 1717 | ldcw 0(t0),t1 | 1717 | LDCW 0(t0),t1 |
| 1718 | cmpib,= 0,t1,dbit_spin_20 | 1718 | cmpib,= 0,t1,dbit_spin_20 |
| 1719 | nop | 1719 | nop |
| 1720 | 1720 | ||
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index 2dc06b8e1817..4398d2a95789 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy) | 11 | * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy) |
| 12 | * Copyright 2003 Grant Grundler <grundler parisc-linux org> | 12 | * Copyright 2003 Grant Grundler <grundler parisc-linux org> |
| 13 | * Copyright 2003,2004 Ryan Bradetich <rbrad@parisc-linux.org> | 13 | * Copyright 2003,2004 Ryan Bradetich <rbrad@parisc-linux.org> |
| 14 | * Copyright 2004 Thibaut VARENE <varenet@parisc-linux.org> | 14 | * Copyright 2004,2006 Thibaut VARENE <varenet@parisc-linux.org> |
| 15 | * | 15 | * |
| 16 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
| 17 | * it under the terms of the GNU General Public License as published by | 17 | * it under the terms of the GNU General Public License as published by |
| @@ -252,10 +252,8 @@ int pdc_pat_chassis_send_log(unsigned long state, unsigned long data) | |||
| 252 | #endif | 252 | #endif |
| 253 | 253 | ||
| 254 | /** | 254 | /** |
| 255 | * pdc_chassis_disp - Updates display | 255 | * pdc_chassis_disp - Updates chassis code |
| 256 | * @retval: -1 on error, 0 on success | 256 | * @retval: -1 on error, 0 on success |
| 257 | * | ||
| 258 | * Works on old PDC only (E class, others?) | ||
| 259 | */ | 257 | */ |
| 260 | int pdc_chassis_disp(unsigned long disp) | 258 | int pdc_chassis_disp(unsigned long disp) |
| 261 | { | 259 | { |
| @@ -269,6 +267,22 @@ int pdc_chassis_disp(unsigned long disp) | |||
| 269 | } | 267 | } |
| 270 | 268 | ||
| 271 | /** | 269 | /** |
| 270 | * pdc_chassis_warn - Fetches chassis warnings | ||
| 271 | * @retval: -1 on error, 0 on success | ||
| 272 | */ | ||
| 273 | int pdc_chassis_warn(unsigned long *warn) | ||
| 274 | { | ||
| 275 | int retval = 0; | ||
| 276 | |||
| 277 | spin_lock_irq(&pdc_lock); | ||
| 278 | retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_WARN, __pa(pdc_result)); | ||
| 279 | *warn = pdc_result[0]; | ||
| 280 | spin_unlock_irq(&pdc_lock); | ||
| 281 | |||
| 282 | return retval; | ||
| 283 | } | ||
| 284 | |||
| 285 | /** | ||
| 272 | * pdc_coproc_cfg - To identify coprocessors attached to the processor. | 286 | * pdc_coproc_cfg - To identify coprocessors attached to the processor. |
| 273 | * @pdc_coproc_info: Return buffer address. | 287 | * @pdc_coproc_info: Return buffer address. |
| 274 | * | 288 | * |
| @@ -393,7 +407,9 @@ int pdc_model_info(struct pdc_model *model) | |||
| 393 | * pdc_model_sysmodel - Get the system model name. | 407 | * pdc_model_sysmodel - Get the system model name. |
| 394 | * @name: A char array of at least 81 characters. | 408 | * @name: A char array of at least 81 characters. |
| 395 | * | 409 | * |
| 396 | * Get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L) | 410 | * Get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L). |
| 411 | * Using OS_ID_HPUX will return the equivalent of the 'modelname' command | ||
| 412 | * on HP/UX. | ||
| 397 | */ | 413 | */ |
| 398 | int pdc_model_sysmodel(char *name) | 414 | int pdc_model_sysmodel(char *name) |
| 399 | { | 415 | { |
| @@ -498,6 +514,26 @@ int pdc_cache_info(struct pdc_cache_info *cache_info) | |||
| 498 | return retval; | 514 | return retval; |
| 499 | } | 515 | } |
| 500 | 516 | ||
| 517 | /** | ||
| 518 | * pdc_spaceid_bits - Return whether Space ID hashing is turned on. | ||
| 519 | * @space_bits: Should be 0, if not, bad mojo! | ||
| 520 | * | ||
| 521 | * Returns information about Space ID hashing. | ||
| 522 | */ | ||
| 523 | int pdc_spaceid_bits(unsigned long *space_bits) | ||
| 524 | { | ||
| 525 | int retval; | ||
| 526 | |||
| 527 | spin_lock_irq(&pdc_lock); | ||
| 528 | pdc_result[0] = 0; | ||
| 529 | retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_RET_SPID, __pa(pdc_result), 0); | ||
| 530 | convert_to_wide(pdc_result); | ||
| 531 | *space_bits = pdc_result[0]; | ||
| 532 | spin_unlock_irq(&pdc_lock); | ||
| 533 | |||
| 534 | return retval; | ||
| 535 | } | ||
| 536 | |||
| 501 | #ifndef CONFIG_PA20 | 537 | #ifndef CONFIG_PA20 |
| 502 | /** | 538 | /** |
| 503 | * pdc_btlb_info - Return block TLB information. | 539 | * pdc_btlb_info - Return block TLB information. |
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index f27cfe4771b8..aee311884f3f 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c | |||
| @@ -89,6 +89,12 @@ static inline int is_local(struct module *me, void *loc) | |||
| 89 | return is_init(me, loc) || is_core(me, loc); | 89 | return is_init(me, loc) || is_core(me, loc); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | static inline int is_local_section(struct module *me, void *loc, void *dot) | ||
| 93 | { | ||
| 94 | return (is_init(me, loc) && is_init(me, dot)) || | ||
| 95 | (is_core(me, loc) && is_core(me, dot)); | ||
| 96 | } | ||
| 97 | |||
| 92 | 98 | ||
| 93 | #ifndef __LP64__ | 99 | #ifndef __LP64__ |
| 94 | struct got_entry { | 100 | struct got_entry { |
| @@ -364,8 +370,14 @@ static Elf_Addr get_fdesc(struct module *me, unsigned long value) | |||
| 364 | } | 370 | } |
| 365 | #endif /* __LP64__ */ | 371 | #endif /* __LP64__ */ |
| 366 | 372 | ||
| 373 | enum elf_stub_type { | ||
| 374 | ELF_STUB_GOT, | ||
| 375 | ELF_STUB_MILLI, | ||
| 376 | ELF_STUB_DIRECT, | ||
| 377 | }; | ||
| 378 | |||
| 367 | static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, | 379 | static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, |
| 368 | int millicode, int init_section) | 380 | enum elf_stub_type stub_type, int init_section) |
| 369 | { | 381 | { |
| 370 | unsigned long i; | 382 | unsigned long i; |
| 371 | struct stub_entry *stub; | 383 | struct stub_entry *stub; |
| @@ -396,7 +408,7 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, | |||
| 396 | stub->insns[1] |= reassemble_17(rrsel(value, addend) / 4); | 408 | stub->insns[1] |= reassemble_17(rrsel(value, addend) / 4); |
| 397 | 409 | ||
| 398 | #else | 410 | #else |
| 399 | /* for 64-bit we have two kinds of stubs: | 411 | /* for 64-bit we have three kinds of stubs: |
| 400 | * for normal function calls: | 412 | * for normal function calls: |
| 401 | * ldd 0(%dp),%dp | 413 | * ldd 0(%dp),%dp |
| 402 | * ldd 10(%dp), %r1 | 414 | * ldd 10(%dp), %r1 |
| @@ -408,18 +420,23 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, | |||
| 408 | * ldo 0(%r1), %r1 | 420 | * ldo 0(%r1), %r1 |
| 409 | * ldd 10(%r1), %r1 | 421 | * ldd 10(%r1), %r1 |
| 410 | * bve,n (%r1) | 422 | * bve,n (%r1) |
| 423 | * | ||
| 424 | * for direct branches (jumps between different section of the | ||
| 425 | * same module): | ||
| 426 | * ldil 0, %r1 | ||
| 427 | * ldo 0(%r1), %r1 | ||
| 428 | * bve,n (%r1) | ||
| 411 | */ | 429 | */ |
| 412 | if (!millicode) | 430 | switch (stub_type) { |
| 413 | { | 431 | case ELF_STUB_GOT: |
| 414 | stub->insns[0] = 0x537b0000; /* ldd 0(%dp),%dp */ | 432 | stub->insns[0] = 0x537b0000; /* ldd 0(%dp),%dp */ |
| 415 | stub->insns[1] = 0x53610020; /* ldd 10(%dp),%r1 */ | 433 | stub->insns[1] = 0x53610020; /* ldd 10(%dp),%r1 */ |
| 416 | stub->insns[2] = 0xe820d000; /* bve (%r1) */ | 434 | stub->insns[2] = 0xe820d000; /* bve (%r1) */ |
| 417 | stub->insns[3] = 0x537b0030; /* ldd 18(%dp),%dp */ | 435 | stub->insns[3] = 0x537b0030; /* ldd 18(%dp),%dp */ |
| 418 | 436 | ||
| 419 | stub->insns[0] |= reassemble_14(get_got(me, value, addend) & 0x3fff); | 437 | stub->insns[0] |= reassemble_14(get_got(me, value, addend) & 0x3fff); |
| 420 | } | 438 | break; |
| 421 | else | 439 | case ELF_STUB_MILLI: |
| 422 | { | ||
| 423 | stub->insns[0] = 0x20200000; /* ldil 0,%r1 */ | 440 | stub->insns[0] = 0x20200000; /* ldil 0,%r1 */ |
| 424 | stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */ | 441 | stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */ |
| 425 | stub->insns[2] = 0x50210020; /* ldd 10(%r1),%r1 */ | 442 | stub->insns[2] = 0x50210020; /* ldd 10(%r1),%r1 */ |
| @@ -427,7 +444,17 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, | |||
| 427 | 444 | ||
| 428 | stub->insns[0] |= reassemble_21(lrsel(value, addend)); | 445 | stub->insns[0] |= reassemble_21(lrsel(value, addend)); |
| 429 | stub->insns[1] |= reassemble_14(rrsel(value, addend)); | 446 | stub->insns[1] |= reassemble_14(rrsel(value, addend)); |
| 447 | break; | ||
| 448 | case ELF_STUB_DIRECT: | ||
| 449 | stub->insns[0] = 0x20200000; /* ldil 0,%r1 */ | ||
| 450 | stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */ | ||
| 451 | stub->insns[2] = 0xe820d002; /* bve,n (%r1) */ | ||
| 452 | |||
| 453 | stub->insns[0] |= reassemble_21(lrsel(value, addend)); | ||
| 454 | stub->insns[1] |= reassemble_14(rrsel(value, addend)); | ||
| 455 | break; | ||
| 430 | } | 456 | } |
| 457 | |||
| 431 | #endif | 458 | #endif |
| 432 | 459 | ||
| 433 | return (Elf_Addr)stub; | 460 | return (Elf_Addr)stub; |
| @@ -539,14 +566,14 @@ int apply_relocate_add(Elf_Shdr *sechdrs, | |||
| 539 | break; | 566 | break; |
| 540 | case R_PARISC_PCREL17F: | 567 | case R_PARISC_PCREL17F: |
| 541 | /* 17-bit PC relative address */ | 568 | /* 17-bit PC relative address */ |
| 542 | val = get_stub(me, val, addend, 0, is_init(me, loc)); | 569 | val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc)); |
| 543 | val = (val - dot - 8)/4; | 570 | val = (val - dot - 8)/4; |
| 544 | CHECK_RELOC(val, 17) | 571 | CHECK_RELOC(val, 17) |
| 545 | *loc = (*loc & ~0x1f1ffd) | reassemble_17(val); | 572 | *loc = (*loc & ~0x1f1ffd) | reassemble_17(val); |
| 546 | break; | 573 | break; |
| 547 | case R_PARISC_PCREL22F: | 574 | case R_PARISC_PCREL22F: |
| 548 | /* 22-bit PC relative address; only defined for pa20 */ | 575 | /* 22-bit PC relative address; only defined for pa20 */ |
| 549 | val = get_stub(me, val, addend, 0, is_init(me, loc)); | 576 | val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc)); |
| 550 | DEBUGP("STUB FOR %s loc %lx+%lx at %lx\n", | 577 | DEBUGP("STUB FOR %s loc %lx+%lx at %lx\n", |
| 551 | strtab + sym->st_name, (unsigned long)loc, addend, | 578 | strtab + sym->st_name, (unsigned long)loc, addend, |
| 552 | val) | 579 | val) |
| @@ -643,13 +670,23 @@ int apply_relocate_add(Elf_Shdr *sechdrs, | |||
| 643 | strtab + sym->st_name, | 670 | strtab + sym->st_name, |
| 644 | loc, val); | 671 | loc, val); |
| 645 | /* can we reach it locally? */ | 672 | /* can we reach it locally? */ |
| 646 | if(!is_local(me, (void *)val)) { | 673 | if(!is_local_section(me, (void *)val, (void *)dot)) { |
| 647 | if (strncmp(strtab + sym->st_name, "$$", 2) | 674 | |
| 675 | if (is_local(me, (void *)val)) | ||
| 676 | /* this is the case where the | ||
| 677 | * symbol is local to the | ||
| 678 | * module, but in a different | ||
| 679 | * section, so stub the jump | ||
| 680 | * in case it's more than 22 | ||
| 681 | * bits away */ | ||
| 682 | val = get_stub(me, val, addend, ELF_STUB_DIRECT, | ||
| 683 | is_init(me, loc)); | ||
| 684 | else if (strncmp(strtab + sym->st_name, "$$", 2) | ||
| 648 | == 0) | 685 | == 0) |
| 649 | val = get_stub(me, val, addend, 1, | 686 | val = get_stub(me, val, addend, ELF_STUB_MILLI, |
| 650 | is_init(me, loc)); | 687 | is_init(me, loc)); |
| 651 | else | 688 | else |
| 652 | val = get_stub(me, val, addend, 0, | 689 | val = get_stub(me, val, addend, ELF_STUB_GOT, |
| 653 | is_init(me, loc)); | 690 | is_init(me, loc)); |
| 654 | } | 691 | } |
| 655 | DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n", | 692 | DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n", |
diff --git a/arch/parisc/kernel/pdc_chassis.c b/arch/parisc/kernel/pdc_chassis.c index a45e2e2ffd9f..d47ba1aa8253 100644 --- a/arch/parisc/kernel/pdc_chassis.c +++ b/arch/parisc/kernel/pdc_chassis.c | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * interfaces to log Chassis Codes via PDC (firmware) | 2 | * interfaces to Chassis Codes via PDC (firmware) |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2002 Laurent Canet <canetl@esiee.fr> | 4 | * Copyright (C) 2002 Laurent Canet <canetl@esiee.fr> |
| 5 | * Copyright (C) 2002-2004 Thibaut VARENE <varenet@parisc-linux.org> | 5 | * Copyright (C) 2002-2006 Thibaut VARENE <varenet@parisc-linux.org> |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License, version 2, as | 8 | * it under the terms of the GNU General Public License, version 2, as |
| @@ -16,6 +16,10 @@ | |||
| 16 | * You should have received a copy of the GNU General Public License | 16 | * You should have received a copy of the GNU General Public License |
| 17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 19 | * | ||
| 20 | * TODO: poll chassis warns, trigger (configurable) machine shutdown when | ||
| 21 | * needed. | ||
| 22 | * Find out how to get Chassis warnings out of PAT boxes? | ||
| 19 | */ | 23 | */ |
| 20 | 24 | ||
| 21 | #undef PDC_CHASSIS_DEBUG | 25 | #undef PDC_CHASSIS_DEBUG |
| @@ -30,15 +34,16 @@ | |||
| 30 | #include <linux/reboot.h> | 34 | #include <linux/reboot.h> |
| 31 | #include <linux/notifier.h> | 35 | #include <linux/notifier.h> |
| 32 | #include <linux/cache.h> | 36 | #include <linux/cache.h> |
| 37 | #include <linux/proc_fs.h> | ||
| 33 | 38 | ||
| 34 | #include <asm/pdc_chassis.h> | 39 | #include <asm/pdc_chassis.h> |
| 35 | #include <asm/processor.h> | 40 | #include <asm/processor.h> |
| 36 | #include <asm/pdc.h> | 41 | #include <asm/pdc.h> |
| 37 | #include <asm/pdcpat.h> | 42 | #include <asm/pdcpat.h> |
| 38 | 43 | ||
| 44 | #define PDC_CHASSIS_VER "0.05" | ||
| 39 | 45 | ||
| 40 | #ifdef CONFIG_PDC_CHASSIS | 46 | #ifdef CONFIG_PDC_CHASSIS |
| 41 | static int pdc_chassis_old __read_mostly = 0; | ||
| 42 | static unsigned int pdc_chassis_enabled __read_mostly = 1; | 47 | static unsigned int pdc_chassis_enabled __read_mostly = 1; |
| 43 | 48 | ||
| 44 | 49 | ||
| @@ -64,7 +69,7 @@ __setup("pdcchassis=", pdc_chassis_setup); | |||
| 64 | * Currently, only E class and A180 are known to work with this. | 69 | * Currently, only E class and A180 are known to work with this. |
| 65 | * Inspired by Christoph Plattner | 70 | * Inspired by Christoph Plattner |
| 66 | */ | 71 | */ |
| 67 | 72 | #if 0 | |
| 68 | static void __init pdc_chassis_checkold(void) | 73 | static void __init pdc_chassis_checkold(void) |
| 69 | { | 74 | { |
| 70 | switch(CPU_HVERSION) { | 75 | switch(CPU_HVERSION) { |
| @@ -73,7 +78,6 @@ static void __init pdc_chassis_checkold(void) | |||
| 73 | case 0x482: /* E45 */ | 78 | case 0x482: /* E45 */ |
| 74 | case 0x483: /* E55 */ | 79 | case 0x483: /* E55 */ |
| 75 | case 0x516: /* A180 */ | 80 | case 0x516: /* A180 */ |
| 76 | pdc_chassis_old = 1; | ||
| 77 | break; | 81 | break; |
| 78 | 82 | ||
| 79 | default: | 83 | default: |
| @@ -81,7 +85,7 @@ static void __init pdc_chassis_checkold(void) | |||
| 81 | } | 85 | } |
| 82 | DPRINTK(KERN_DEBUG "%s: pdc_chassis_checkold(); pdc_chassis_old = %d\n", __FILE__, pdc_chassis_old); | 86 | DPRINTK(KERN_DEBUG "%s: pdc_chassis_checkold(); pdc_chassis_old = %d\n", __FILE__, pdc_chassis_old); |
| 83 | } | 87 | } |
| 84 | 88 | #endif | |
| 85 | 89 | ||
| 86 | /** | 90 | /** |
| 87 | * pdc_chassis_panic_event() - Called by the panic handler. | 91 | * pdc_chassis_panic_event() - Called by the panic handler. |
| @@ -131,30 +135,20 @@ static struct notifier_block pdc_chassis_reboot_block = { | |||
| 131 | void __init parisc_pdc_chassis_init(void) | 135 | void __init parisc_pdc_chassis_init(void) |
| 132 | { | 136 | { |
| 133 | #ifdef CONFIG_PDC_CHASSIS | 137 | #ifdef CONFIG_PDC_CHASSIS |
| 134 | int handle = 0; | ||
| 135 | if (likely(pdc_chassis_enabled)) { | 138 | if (likely(pdc_chassis_enabled)) { |
| 136 | DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__); | 139 | DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__); |
| 137 | 140 | ||
| 138 | /* Let see if we have something to handle... */ | 141 | /* Let see if we have something to handle... */ |
| 139 | /* Check for PDC_PAT or old LED Panel */ | 142 | printk(KERN_INFO "Enabling %s chassis codes support v%s\n", |
| 140 | pdc_chassis_checkold(); | 143 | is_pdc_pat() ? "PDC_PAT" : "regular", |
| 141 | if (is_pdc_pat()) { | 144 | PDC_CHASSIS_VER); |
| 142 | printk(KERN_INFO "Enabling PDC_PAT chassis codes support.\n"); | 145 | |
| 143 | handle = 1; | 146 | /* initialize panic notifier chain */ |
| 144 | } | 147 | atomic_notifier_chain_register(&panic_notifier_list, |
| 145 | else if (unlikely(pdc_chassis_old)) { | 148 | &pdc_chassis_panic_block); |
| 146 | printk(KERN_INFO "Enabling old style chassis LED panel support.\n"); | 149 | |
| 147 | handle = 1; | 150 | /* initialize reboot notifier chain */ |
| 148 | } | 151 | register_reboot_notifier(&pdc_chassis_reboot_block); |
| 149 | |||
| 150 | if (handle) { | ||
| 151 | /* initialize panic notifier chain */ | ||
| 152 | atomic_notifier_chain_register(&panic_notifier_list, | ||
| 153 | &pdc_chassis_panic_block); | ||
| 154 | |||
| 155 | /* initialize reboot notifier chain */ | ||
| 156 | register_reboot_notifier(&pdc_chassis_reboot_block); | ||
| 157 | } | ||
| 158 | } | 152 | } |
| 159 | #endif /* CONFIG_PDC_CHASSIS */ | 153 | #endif /* CONFIG_PDC_CHASSIS */ |
| 160 | } | 154 | } |
| @@ -215,9 +209,12 @@ int pdc_chassis_send_status(int message) | |||
| 215 | } | 209 | } |
| 216 | } else retval = -1; | 210 | } else retval = -1; |
| 217 | #else | 211 | #else |
| 218 | if (unlikely(pdc_chassis_old)) { | 212 | if (1) { |
| 219 | switch (message) { | 213 | switch (message) { |
| 220 | case PDC_CHASSIS_DIRECT_BSTART: | 214 | case PDC_CHASSIS_DIRECT_BSTART: |
| 215 | retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_INIT)); | ||
| 216 | break; | ||
| 217 | |||
| 221 | case PDC_CHASSIS_DIRECT_BCOMPLETE: | 218 | case PDC_CHASSIS_DIRECT_BCOMPLETE: |
| 222 | retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN)); | 219 | retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN)); |
| 223 | break; | 220 | break; |
| @@ -244,3 +241,61 @@ int pdc_chassis_send_status(int message) | |||
| 244 | #endif /* CONFIG_PDC_CHASSIS */ | 241 | #endif /* CONFIG_PDC_CHASSIS */ |
| 245 | return retval; | 242 | return retval; |
| 246 | } | 243 | } |
| 244 | |||
| 245 | #ifdef CONFIG_PDC_CHASSIS_WARN | ||
| 246 | #ifdef CONFIG_PROC_FS | ||
| 247 | static int pdc_chassis_warn_pread(char *page, char **start, off_t off, | ||
| 248 | int count, int *eof, void *data) | ||
| 249 | { | ||
| 250 | char *out = page; | ||
| 251 | int len, ret; | ||
| 252 | unsigned long warn; | ||
| 253 | u32 warnreg; | ||
| 254 | |||
| 255 | ret = pdc_chassis_warn(&warn); | ||
| 256 | if (ret != PDC_OK) | ||
| 257 | return -EIO; | ||
| 258 | |||
| 259 | warnreg = (warn & 0xFFFFFFFF); | ||
| 260 | |||
| 261 | if ((warnreg >> 24) & 0xFF) | ||
| 262 | out += sprintf(out, "Chassis component failure! (eg fan or PSU): 0x%.2x\n", ((warnreg >> 24) & 0xFF)); | ||
| 263 | |||
| 264 | out += sprintf(out, "Battery: %s\n", (warnreg & 0x04) ? "Low!" : "OK"); | ||
| 265 | out += sprintf(out, "Temp low: %s\n", (warnreg & 0x02) ? "Exceeded!" : "OK"); | ||
| 266 | out += sprintf(out, "Temp mid: %s\n", (warnreg & 0x01) ? "Exceeded!" : "OK"); | ||
| 267 | |||
| 268 | len = out - page - off; | ||
| 269 | if (len < count) { | ||
| 270 | *eof = 1; | ||
| 271 | if (len <= 0) return 0; | ||
| 272 | } else { | ||
| 273 | len = count; | ||
| 274 | } | ||
| 275 | *start = page + off; | ||
| 276 | return len; | ||
| 277 | } | ||
| 278 | |||
| 279 | static int __init pdc_chassis_create_procfs(void) | ||
| 280 | { | ||
| 281 | unsigned long test; | ||
| 282 | int ret; | ||
| 283 | |||
| 284 | ret = pdc_chassis_warn(&test); | ||
| 285 | if ((ret == PDC_BAD_PROC) || (ret == PDC_BAD_OPTION)) { | ||
| 286 | /* seems that some boxes (eg L1000) do not implement this */ | ||
| 287 | printk(KERN_INFO "Chassis warnings not supported.\n"); | ||
| 288 | return 0; | ||
| 289 | } | ||
| 290 | |||
| 291 | printk(KERN_INFO "Enabling PDC chassis warnings support v%s\n", | ||
| 292 | PDC_CHASSIS_VER); | ||
| 293 | create_proc_read_entry("chassis", 0400, NULL, pdc_chassis_warn_pread, | ||
| 294 | NULL); | ||
| 295 | return 0; | ||
| 296 | } | ||
| 297 | |||
| 298 | __initcall(pdc_chassis_create_procfs); | ||
| 299 | |||
| 300 | #endif /* CONFIG_PROC_FS */ | ||
| 301 | #endif /* CONFIG_PDC_CHASSIS_WARN */ | ||
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index 413292f1a4a3..3f28de974556 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c | |||
| @@ -91,7 +91,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
| 91 | int copied; | 91 | int copied; |
| 92 | 92 | ||
| 93 | #ifdef __LP64__ | 93 | #ifdef __LP64__ |
| 94 | if (personality(child->personality) == PER_LINUX32) { | 94 | if (__is_compat_task(child)) { |
| 95 | unsigned int tmp; | 95 | unsigned int tmp; |
| 96 | 96 | ||
| 97 | addr &= 0xffffffffL; | 97 | addr &= 0xffffffffL; |
| @@ -123,7 +123,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
| 123 | case PTRACE_POKEDATA: | 123 | case PTRACE_POKEDATA: |
| 124 | ret = 0; | 124 | ret = 0; |
| 125 | #ifdef __LP64__ | 125 | #ifdef __LP64__ |
| 126 | if (personality(child->personality) == PER_LINUX32) { | 126 | if (__is_compat_task(child)) { |
| 127 | unsigned int tmp = (unsigned int)data; | 127 | unsigned int tmp = (unsigned int)data; |
| 128 | DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n", | 128 | DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n", |
| 129 | request == PTRACE_POKETEXT ? "TEXT" : "DATA", | 129 | request == PTRACE_POKETEXT ? "TEXT" : "DATA", |
| @@ -146,7 +146,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
| 146 | case PTRACE_PEEKUSR: { | 146 | case PTRACE_PEEKUSR: { |
| 147 | ret = -EIO; | 147 | ret = -EIO; |
| 148 | #ifdef __LP64__ | 148 | #ifdef __LP64__ |
| 149 | if (personality(child->personality) == PER_LINUX32) { | 149 | if (__is_compat_task(child)) { |
| 150 | unsigned int tmp; | 150 | unsigned int tmp; |
| 151 | 151 | ||
| 152 | if (addr & (sizeof(int)-1)) | 152 | if (addr & (sizeof(int)-1)) |
| @@ -205,7 +205,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
| 205 | goto out_tsk; | 205 | goto out_tsk; |
| 206 | } | 206 | } |
| 207 | #ifdef __LP64__ | 207 | #ifdef __LP64__ |
| 208 | if (personality(child->personality) == PER_LINUX32) { | 208 | if (__is_compat_task(child)) { |
| 209 | if (addr & (sizeof(int)-1)) | 209 | if (addr & (sizeof(int)-1)) |
| 210 | goto out_tsk; | 210 | goto out_tsk; |
| 211 | if ((addr = translate_usr_offset(addr)) < 0) | 211 | if ((addr = translate_usr_offset(addr)) < 0) |
diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S index 8c2859cca77e..453d01a9f971 100644 --- a/arch/parisc/kernel/real2.S +++ b/arch/parisc/kernel/real2.S | |||
| @@ -276,15 +276,6 @@ r64_ret: | |||
| 276 | 276 | ||
| 277 | #endif | 277 | #endif |
| 278 | 278 | ||
| 279 | .export pc_in_user_space | ||
| 280 | .text | ||
| 281 | /* Doesn't belong here but I couldn't find a nicer spot. */ | ||
| 282 | /* Should never get called, only used by profile stuff in time.c */ | ||
| 283 | pc_in_user_space: | ||
| 284 | bv,n 0(%rp) | ||
| 285 | nop | ||
| 286 | |||
| 287 | |||
| 288 | .export __canonicalize_funcptr_for_compare | 279 | .export __canonicalize_funcptr_for_compare |
| 289 | .text | 280 | .text |
| 290 | /* http://lists.parisc-linux.org/hypermail/parisc-linux/10916.html | 281 | /* http://lists.parisc-linux.org/hypermail/parisc-linux/10916.html |
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index 4a36ec3f6ac1..278f4b9f6a38 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c | |||
| @@ -303,6 +303,8 @@ extern void eisa_init(void); | |||
| 303 | 303 | ||
| 304 | static int __init parisc_init(void) | 304 | static int __init parisc_init(void) |
| 305 | { | 305 | { |
| 306 | u32 osid = (OS_ID_LINUX << 16); | ||
| 307 | |||
| 306 | parisc_proc_mkdir(); | 308 | parisc_proc_mkdir(); |
| 307 | parisc_init_resources(); | 309 | parisc_init_resources(); |
| 308 | do_device_inventory(); /* probe for hardware */ | 310 | do_device_inventory(); /* probe for hardware */ |
| @@ -311,6 +313,9 @@ static int __init parisc_init(void) | |||
| 311 | 313 | ||
| 312 | /* set up a new led state on systems shipped LED State panel */ | 314 | /* set up a new led state on systems shipped LED State panel */ |
| 313 | pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BSTART); | 315 | pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BSTART); |
| 316 | |||
| 317 | /* tell PDC we're Linux. Nevermind failure. */ | ||
| 318 | pdc_stable_write(0x40, &osid, sizeof(osid)); | ||
| 314 | 319 | ||
| 315 | processor_init(); | 320 | processor_init(); |
| 316 | printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n", | 321 | printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n", |
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index cc38edfd90c5..bb83880c5ee3 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c | |||
| @@ -76,7 +76,7 @@ sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *r | |||
| 76 | #ifdef __LP64__ | 76 | #ifdef __LP64__ |
| 77 | compat_sigset_t newset32; | 77 | compat_sigset_t newset32; |
| 78 | 78 | ||
| 79 | if(personality(current->personality) == PER_LINUX32){ | 79 | if (is_compat_task()) { |
| 80 | /* XXX: Don't preclude handling different sized sigset_t's. */ | 80 | /* XXX: Don't preclude handling different sized sigset_t's. */ |
| 81 | if (sigsetsize != sizeof(compat_sigset_t)) | 81 | if (sigsetsize != sizeof(compat_sigset_t)) |
| 82 | return -EINVAL; | 82 | return -EINVAL; |
| @@ -153,7 +153,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) | |||
| 153 | compat_sigset_t compat_set; | 153 | compat_sigset_t compat_set; |
| 154 | struct compat_rt_sigframe __user * compat_frame; | 154 | struct compat_rt_sigframe __user * compat_frame; |
| 155 | 155 | ||
| 156 | if(personality(current->personality) == PER_LINUX32) | 156 | if (is_compat_task()) |
| 157 | sigframe_size = PARISC_RT_SIGFRAME_SIZE32; | 157 | sigframe_size = PARISC_RT_SIGFRAME_SIZE32; |
| 158 | #endif | 158 | #endif |
| 159 | 159 | ||
| @@ -166,7 +166,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) | |||
| 166 | #ifdef __LP64__ | 166 | #ifdef __LP64__ |
| 167 | compat_frame = (struct compat_rt_sigframe __user *)frame; | 167 | compat_frame = (struct compat_rt_sigframe __user *)frame; |
| 168 | 168 | ||
| 169 | if(personality(current->personality) == PER_LINUX32){ | 169 | if (is_compat_task()) { |
| 170 | DBG(2,"sys_rt_sigreturn: ELF32 process.\n"); | 170 | DBG(2,"sys_rt_sigreturn: ELF32 process.\n"); |
| 171 | if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set))) | 171 | if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set))) |
| 172 | goto give_sigsegv; | 172 | goto give_sigsegv; |
| @@ -186,7 +186,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) | |||
| 186 | 186 | ||
| 187 | /* Good thing we saved the old gr[30], eh? */ | 187 | /* Good thing we saved the old gr[30], eh? */ |
| 188 | #ifdef __LP64__ | 188 | #ifdef __LP64__ |
| 189 | if(personality(current->personality) == PER_LINUX32){ | 189 | if (is_compat_task()) { |
| 190 | DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n", | 190 | DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n", |
| 191 | &compat_frame->uc.uc_mcontext); | 191 | &compat_frame->uc.uc_mcontext); |
| 192 | // FIXME: Load upper half from register file | 192 | // FIXME: Load upper half from register file |
| @@ -315,7 +315,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 315 | 315 | ||
| 316 | compat_frame = (struct compat_rt_sigframe __user *)frame; | 316 | compat_frame = (struct compat_rt_sigframe __user *)frame; |
| 317 | 317 | ||
| 318 | if(personality(current->personality) == PER_LINUX32) { | 318 | if (is_compat_task()) { |
| 319 | DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info); | 319 | DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info); |
| 320 | err |= copy_siginfo_to_user32(&compat_frame->info, info); | 320 | err |= copy_siginfo_to_user32(&compat_frame->info, info); |
| 321 | DBG(1,"SETUP_RT_FRAME: 1\n"); | 321 | DBG(1,"SETUP_RT_FRAME: 1\n"); |
| @@ -392,7 +392,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 392 | haddr = A(ka->sa.sa_handler); | 392 | haddr = A(ka->sa.sa_handler); |
| 393 | /* The sa_handler may be a pointer to a function descriptor */ | 393 | /* The sa_handler may be a pointer to a function descriptor */ |
| 394 | #ifdef __LP64__ | 394 | #ifdef __LP64__ |
| 395 | if(personality(current->personality) == PER_LINUX32) { | 395 | if (is_compat_task()) { |
| 396 | #endif | 396 | #endif |
| 397 | if (haddr & PA_PLABEL_FDESC) { | 397 | if (haddr & PA_PLABEL_FDESC) { |
| 398 | Elf32_Fdesc fdesc; | 398 | Elf32_Fdesc fdesc; |
| @@ -427,19 +427,19 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 427 | */ | 427 | */ |
| 428 | sigframe_size = PARISC_RT_SIGFRAME_SIZE; | 428 | sigframe_size = PARISC_RT_SIGFRAME_SIZE; |
| 429 | #ifdef __LP64__ | 429 | #ifdef __LP64__ |
| 430 | if(personality(current->personality) == PER_LINUX32) | 430 | if (is_compat_task()) |
| 431 | sigframe_size = PARISC_RT_SIGFRAME_SIZE32; | 431 | sigframe_size = PARISC_RT_SIGFRAME_SIZE32; |
| 432 | #endif | 432 | #endif |
| 433 | if (in_syscall) { | 433 | if (in_syscall) { |
| 434 | regs->gr[31] = haddr; | 434 | regs->gr[31] = haddr; |
| 435 | #ifdef __LP64__ | 435 | #ifdef __LP64__ |
| 436 | if(personality(current->personality) == PER_LINUX) | 436 | if (personality(current->personality) == PER_LINUX) |
| 437 | sigframe_size |= 1; | 437 | sigframe_size |= 1; |
| 438 | #endif | 438 | #endif |
| 439 | } else { | 439 | } else { |
| 440 | unsigned long psw = USER_PSW; | 440 | unsigned long psw = USER_PSW; |
| 441 | #ifdef __LP64__ | 441 | #ifdef __LP64__ |
| 442 | if(personality(current->personality) == PER_LINUX) | 442 | if (personality(current->personality) == PER_LINUX) |
| 443 | psw |= PSW_W; | 443 | psw |= PSW_W; |
| 444 | #endif | 444 | #endif |
| 445 | 445 | ||
| @@ -464,7 +464,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 464 | regs->gr[26] = sig; /* signal number */ | 464 | regs->gr[26] = sig; /* signal number */ |
| 465 | 465 | ||
| 466 | #ifdef __LP64__ | 466 | #ifdef __LP64__ |
| 467 | if(personality(current->personality) == PER_LINUX32){ | 467 | if (is_compat_task()) { |
| 468 | regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */ | 468 | regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */ |
| 469 | regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */ | 469 | regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */ |
| 470 | } else | 470 | } else |
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 479d9a017cd1..9670a89c77fe 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S | |||
| @@ -29,18 +29,6 @@ | |||
| 29 | .level 1.1 | 29 | .level 1.1 |
| 30 | #endif | 30 | #endif |
| 31 | 31 | ||
| 32 | #ifndef CONFIG_64BIT | ||
| 33 | .macro fixup_branch,lbl | ||
| 34 | b \lbl | ||
| 35 | .endm | ||
| 36 | #else | ||
| 37 | .macro fixup_branch,lbl | ||
| 38 | ldil L%\lbl, %r1 | ||
| 39 | ldo R%\lbl(%r1), %r1 | ||
| 40 | bv,n %r0(%r1) | ||
| 41 | .endm | ||
| 42 | #endif | ||
| 43 | |||
| 44 | .text | 32 | .text |
| 45 | 33 | ||
| 46 | .import syscall_exit,code | 34 | .import syscall_exit,code |
| @@ -541,7 +529,7 @@ cas_nocontend: | |||
| 541 | # endif | 529 | # endif |
| 542 | /* ENABLE_LWS_DEBUG */ | 530 | /* ENABLE_LWS_DEBUG */ |
| 543 | 531 | ||
| 544 | ldcw 0(%sr2,%r20), %r28 /* Try to acquire the lock */ | 532 | LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */ |
| 545 | cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */ | 533 | cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */ |
| 546 | cas_wouldblock: | 534 | cas_wouldblock: |
| 547 | ldo 2(%r0), %r28 /* 2nd case */ | 535 | ldo 2(%r0), %r28 /* 2nd case */ |
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 594930bc4bcf..eb35e1c0bb53 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c | |||
| @@ -157,8 +157,22 @@ do_gettimeofday (struct timeval *tv) | |||
| 157 | usec += (xtime.tv_nsec / 1000); | 157 | usec += (xtime.tv_nsec / 1000); |
| 158 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); | 158 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); |
| 159 | 159 | ||
| 160 | while (usec >= 1000000) { | 160 | if (unlikely(usec > LONG_MAX)) { |
| 161 | usec -= 1000000; | 161 | /* This can happen if the gettimeoffset adjustment is |
| 162 | * negative and xtime.tv_nsec is smaller than the | ||
| 163 | * adjustment */ | ||
| 164 | printk(KERN_ERR "do_gettimeofday() spurious xtime.tv_nsec of %ld\n", usec); | ||
| 165 | usec += USEC_PER_SEC; | ||
| 166 | --sec; | ||
| 167 | /* This should never happen, it means the negative | ||
| 168 | * time adjustment was more than a second, so there's | ||
| 169 | * something seriously wrong */ | ||
| 170 | BUG_ON(usec > LONG_MAX); | ||
| 171 | } | ||
| 172 | |||
| 173 | |||
| 174 | while (usec >= USEC_PER_SEC) { | ||
| 175 | usec -= USEC_PER_SEC; | ||
| 162 | ++sec; | 176 | ++sec; |
| 163 | } | 177 | } |
| 164 | 178 | ||
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index ff200608c851..348344a84bf7 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c | |||
| @@ -66,57 +66,42 @@ int printbinary(char *buf, unsigned long x, int nbits) | |||
| 66 | #else | 66 | #else |
| 67 | #define RFMT "%08lx" | 67 | #define RFMT "%08lx" |
| 68 | #endif | 68 | #endif |
| 69 | #define FFMT "%016llx" /* fpregs are 64-bit always */ | ||
| 69 | 70 | ||
| 70 | void show_regs(struct pt_regs *regs) | 71 | #define PRINTREGS(lvl,r,f,fmt,x) \ |
| 72 | printk("%s%s%02d-%02d " fmt " " fmt " " fmt " " fmt "\n", \ | ||
| 73 | lvl, f, (x), (x+3), (r)[(x)+0], (r)[(x)+1], \ | ||
| 74 | (r)[(x)+2], (r)[(x)+3]) | ||
| 75 | |||
| 76 | static void print_gr(char *level, struct pt_regs *regs) | ||
| 71 | { | 77 | { |
| 72 | int i; | 78 | int i; |
| 73 | char buf[128], *p; | 79 | char buf[64]; |
| 74 | char *level; | ||
| 75 | unsigned long cr30; | ||
| 76 | unsigned long cr31; | ||
| 77 | /* carlos says that gcc understands better memory in a struct, | ||
| 78 | * and it makes our life easier with fpregs -- T-Bone */ | ||
| 79 | struct { u32 sw[2]; } s; | ||
| 80 | |||
| 81 | level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT; | ||
| 82 | |||
| 83 | printk("%s\n", level); /* don't want to have that pretty register dump messed up */ | ||
| 84 | 80 | ||
| 81 | printk("%s\n", level); | ||
| 85 | printk("%s YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\n", level); | 82 | printk("%s YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\n", level); |
| 86 | printbinary(buf, regs->gr[0], 32); | 83 | printbinary(buf, regs->gr[0], 32); |
| 87 | printk("%sPSW: %s %s\n", level, buf, print_tainted()); | 84 | printk("%sPSW: %s %s\n", level, buf, print_tainted()); |
| 88 | 85 | ||
| 89 | for (i = 0; i < 32; i += 4) { | 86 | for (i = 0; i < 32; i += 4) |
| 90 | int j; | 87 | PRINTREGS(level, regs->gr, "r", RFMT, i); |
| 91 | p = buf; | 88 | } |
| 92 | p += sprintf(p, "%sr%02d-%02d ", level, i, i + 3); | ||
| 93 | for (j = 0; j < 4; j++) { | ||
| 94 | p += sprintf(p, " " RFMT, (i+j) == 0 ? 0 : regs->gr[i + j]); | ||
| 95 | } | ||
| 96 | printk("%s\n", buf); | ||
| 97 | } | ||
| 98 | 89 | ||
| 99 | for (i = 0; i < 8; i += 4) { | 90 | static void print_fr(char *level, struct pt_regs *regs) |
| 100 | int j; | 91 | { |
| 101 | p = buf; | 92 | int i; |
| 102 | p += sprintf(p, "%ssr%d-%d ", level, i, i + 3); | 93 | char buf[64]; |
| 103 | for (j = 0; j < 4; j++) { | 94 | struct { u32 sw[2]; } s; |
| 104 | p += sprintf(p, " " RFMT, regs->sr[i + j]); | ||
| 105 | } | ||
| 106 | printk("%s\n", buf); | ||
| 107 | } | ||
| 108 | 95 | ||
| 109 | /* FR are 64bit everywhere. Need to use asm to get the content | 96 | /* FR are 64bit everywhere. Need to use asm to get the content |
| 110 | * of fpsr/fper1, and we assume that we won't have a FP Identify | 97 | * of fpsr/fper1, and we assume that we won't have a FP Identify |
| 111 | * in our way, otherwise we're screwed. | 98 | * in our way, otherwise we're screwed. |
| 112 | * The fldd is used to restore the T-bit if there was one, as the | 99 | * The fldd is used to restore the T-bit if there was one, as the |
| 113 | * store clears it anyway. | 100 | * store clears it anyway. |
| 114 | * BTW, PA2.0 book says "thou shall not use fstw on FPSR/FPERs". */ | 101 | * PA2.0 book says "thou shall not use fstw on FPSR/FPERs" - T-Bone */ |
| 115 | __asm__ ( | 102 | asm volatile ("fstd %%fr0,0(%1) \n\t" |
| 116 | "fstd %%fr0,0(%1) \n\t" | 103 | "fldd 0(%1),%%fr0 \n\t" |
| 117 | "fldd 0(%1),%%fr0 \n\t" | 104 | : "=m" (s) : "r" (&s) : "r0"); |
| 118 | : "=m" (s) : "r" (&s) : "%r0" | ||
| 119 | ); | ||
| 120 | 105 | ||
| 121 | printk("%s\n", level); | 106 | printk("%s\n", level); |
| 122 | printk("%s VZOUICununcqcqcqcqcqcrmunTDVZOUI\n", level); | 107 | printk("%s VZOUICununcqcqcqcqcqcrmunTDVZOUI\n", level); |
| @@ -125,14 +110,25 @@ void show_regs(struct pt_regs *regs) | |||
| 125 | printk("%sFPER1: %08x\n", level, s.sw[1]); | 110 | printk("%sFPER1: %08x\n", level, s.sw[1]); |
| 126 | 111 | ||
| 127 | /* here we'll print fr0 again, tho it'll be meaningless */ | 112 | /* here we'll print fr0 again, tho it'll be meaningless */ |
| 128 | for (i = 0; i < 32; i += 4) { | 113 | for (i = 0; i < 32; i += 4) |
| 129 | int j; | 114 | PRINTREGS(level, regs->fr, "fr", FFMT, i); |
| 130 | p = buf; | 115 | } |
| 131 | p += sprintf(p, "%sfr%02d-%02d ", level, i, i + 3); | 116 | |
| 132 | for (j = 0; j < 4; j++) | 117 | void show_regs(struct pt_regs *regs) |
| 133 | p += sprintf(p, " %016llx", (i+j) == 0 ? 0 : regs->fr[i+j]); | 118 | { |
| 134 | printk("%s\n", buf); | 119 | int i; |
| 135 | } | 120 | char *level; |
| 121 | unsigned long cr30, cr31; | ||
| 122 | |||
| 123 | level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT; | ||
| 124 | |||
| 125 | print_gr(level, regs); | ||
| 126 | |||
| 127 | for (i = 0; i < 8; i += 4) | ||
| 128 | PRINTREGS(level, regs->sr, "sr", RFMT, i); | ||
| 129 | |||
| 130 | if (user_mode(regs)) | ||
| 131 | print_fr(level, regs); | ||
| 136 | 132 | ||
| 137 | cr30 = mfctl(30); | 133 | cr30 = mfctl(30); |
| 138 | cr31 = mfctl(31); | 134 | cr31 = mfctl(31); |
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c index de0a1b21cb40..92328fbddb3e 100644 --- a/arch/parisc/kernel/unaligned.c +++ b/arch/parisc/kernel/unaligned.c | |||
| @@ -43,6 +43,8 @@ | |||
| 43 | "\tldil L%%" #lbl ", %%r1\n" \ | 43 | "\tldil L%%" #lbl ", %%r1\n" \ |
| 44 | "\tldo R%%" #lbl "(%%r1), %%r1\n" \ | 44 | "\tldo R%%" #lbl "(%%r1), %%r1\n" \ |
| 45 | "\tbv,n %%r0(%%r1)\n" | 45 | "\tbv,n %%r0(%%r1)\n" |
| 46 | /* If you use FIXUP_BRANCH, then you must list this clobber */ | ||
| 47 | #define FIXUP_BRANCH_CLOBBER "r1" | ||
| 46 | 48 | ||
| 47 | /* 1111 1100 0000 0000 0001 0011 1100 0000 */ | 49 | /* 1111 1100 0000 0000 0001 0011 1100 0000 */ |
| 48 | #define OPCODE1(a,b,c) ((a)<<26|(b)<<12|(c)<<6) | 50 | #define OPCODE1(a,b,c) ((a)<<26|(b)<<12|(c)<<6) |
| @@ -157,7 +159,7 @@ static int emulate_ldh(struct pt_regs *regs, int toreg) | |||
| 157 | " .previous\n" | 159 | " .previous\n" |
| 158 | : "=r" (val), "=r" (ret) | 160 | : "=r" (val), "=r" (ret) |
| 159 | : "0" (val), "r" (saddr), "r" (regs->isr) | 161 | : "0" (val), "r" (saddr), "r" (regs->isr) |
| 160 | : "r20" ); | 162 | : "r20", FIXUP_BRANCH_CLOBBER ); |
| 161 | 163 | ||
| 162 | DPRINTF("val = 0x" RFMT "\n", val); | 164 | DPRINTF("val = 0x" RFMT "\n", val); |
| 163 | 165 | ||
| @@ -202,7 +204,7 @@ static int emulate_ldw(struct pt_regs *regs, int toreg, int flop) | |||
| 202 | " .previous\n" | 204 | " .previous\n" |
| 203 | : "=r" (val), "=r" (ret) | 205 | : "=r" (val), "=r" (ret) |
| 204 | : "0" (val), "r" (saddr), "r" (regs->isr) | 206 | : "0" (val), "r" (saddr), "r" (regs->isr) |
| 205 | : "r19", "r20" ); | 207 | : "r19", "r20", FIXUP_BRANCH_CLOBBER ); |
| 206 | 208 | ||
| 207 | DPRINTF("val = 0x" RFMT "\n", val); | 209 | DPRINTF("val = 0x" RFMT "\n", val); |
| 208 | 210 | ||
| @@ -253,7 +255,7 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop) | |||
| 253 | " .previous\n" | 255 | " .previous\n" |
| 254 | : "=r" (val), "=r" (ret) | 256 | : "=r" (val), "=r" (ret) |
| 255 | : "0" (val), "r" (saddr), "r" (regs->isr) | 257 | : "0" (val), "r" (saddr), "r" (regs->isr) |
| 256 | : "r19", "r20" ); | 258 | : "r19", "r20", FIXUP_BRANCH_CLOBBER ); |
| 257 | #else | 259 | #else |
| 258 | { | 260 | { |
| 259 | unsigned long valh=0,vall=0; | 261 | unsigned long valh=0,vall=0; |
| @@ -287,7 +289,7 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop) | |||
| 287 | " .previous\n" | 289 | " .previous\n" |
| 288 | : "=r" (valh), "=r" (vall), "=r" (ret) | 290 | : "=r" (valh), "=r" (vall), "=r" (ret) |
| 289 | : "0" (valh), "1" (vall), "r" (saddr), "r" (regs->isr) | 291 | : "0" (valh), "1" (vall), "r" (saddr), "r" (regs->isr) |
| 290 | : "r19", "r20" ); | 292 | : "r19", "r20", FIXUP_BRANCH_CLOBBER ); |
| 291 | val=((__u64)valh<<32)|(__u64)vall; | 293 | val=((__u64)valh<<32)|(__u64)vall; |
| 292 | } | 294 | } |
| 293 | #endif | 295 | #endif |
| @@ -335,7 +337,7 @@ static int emulate_sth(struct pt_regs *regs, int frreg) | |||
| 335 | " .previous\n" | 337 | " .previous\n" |
| 336 | : "=r" (ret) | 338 | : "=r" (ret) |
| 337 | : "r" (val), "r" (regs->ior), "r" (regs->isr) | 339 | : "r" (val), "r" (regs->ior), "r" (regs->isr) |
| 338 | : "r19" ); | 340 | : "r19", FIXUP_BRANCH_CLOBBER ); |
| 339 | 341 | ||
| 340 | return ret; | 342 | return ret; |
| 341 | } | 343 | } |
| @@ -389,7 +391,7 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop) | |||
| 389 | " .previous\n" | 391 | " .previous\n" |
| 390 | : "=r" (ret) | 392 | : "=r" (ret) |
| 391 | : "r" (val), "r" (regs->ior), "r" (regs->isr) | 393 | : "r" (val), "r" (regs->ior), "r" (regs->isr) |
| 392 | : "r19", "r20", "r21", "r22", "r1" ); | 394 | : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER ); |
| 393 | 395 | ||
| 394 | return 0; | 396 | return 0; |
| 395 | } | 397 | } |
| @@ -450,7 +452,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) | |||
| 450 | " .previous\n" | 452 | " .previous\n" |
| 451 | : "=r" (ret) | 453 | : "=r" (ret) |
| 452 | : "r" (val), "r" (regs->ior), "r" (regs->isr) | 454 | : "r" (val), "r" (regs->ior), "r" (regs->isr) |
| 453 | : "r19", "r20", "r21", "r22", "r1" ); | 455 | : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER ); |
| 454 | #else | 456 | #else |
| 455 | { | 457 | { |
| 456 | unsigned long valh=(val>>32),vall=(val&0xffffffffl); | 458 | unsigned long valh=(val>>32),vall=(val&0xffffffffl); |
| @@ -495,7 +497,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) | |||
| 495 | " .previous\n" | 497 | " .previous\n" |
| 496 | : "=r" (ret) | 498 | : "=r" (ret) |
| 497 | : "r" (valh), "r" (vall), "r" (regs->ior), "r" (regs->isr) | 499 | : "r" (valh), "r" (vall), "r" (regs->ior), "r" (regs->isr) |
| 498 | : "r19", "r20", "r21", "r1" ); | 500 | : "r19", "r20", "r21", "r1", FIXUP_BRANCH_CLOBBER ); |
| 499 | } | 501 | } |
| 500 | #endif | 502 | #endif |
| 501 | 503 | ||
diff --git a/drivers/parisc/Kconfig b/drivers/parisc/Kconfig index 3f5de867acd7..1d3b84b4af3f 100644 --- a/drivers/parisc/Kconfig +++ b/drivers/parisc/Kconfig | |||
| @@ -140,18 +140,37 @@ config CHASSIS_LCD_LED | |||
| 140 | If unsure, say Y. | 140 | If unsure, say Y. |
| 141 | 141 | ||
| 142 | config PDC_CHASSIS | 142 | config PDC_CHASSIS |
| 143 | bool "PDC chassis State Panel support" | 143 | bool "PDC chassis state codes support" |
| 144 | default y | 144 | default y |
| 145 | help | 145 | help |
| 146 | Say Y here if you want to enable support for the LED State front | 146 | Say Y here if you want to enable support for Chassis codes. |
| 147 | panel as found on E class, and support for the GSP Virtual Front | 147 | That includes support for LED State front panel as found on E |
| 148 | Panel (LED State and message logging) as found on high end | 148 | class, and support for the GSP Virtual Front Panel (LED State and |
| 149 | servers such as A, L and N-class. | 149 | message logging) as found on high end servers such as A, L and |
| 150 | 150 | N-class. | |
| 151 | This has nothing to do with Chassis LCD and LED support. | 151 | This driver will also display progress messages on LCD display, |
| 152 | such as "INI", "RUN" and "FLT", and might thus clobber messages | ||
| 153 | shown by the LED/LCD driver. | ||
| 154 | This driver updates the state panel (LED and/or LCD) upon system | ||
| 155 | state change (eg: boot, shutdown or panic). | ||
| 152 | 156 | ||
| 153 | If unsure, say Y. | 157 | If unsure, say Y. |
| 154 | 158 | ||
| 159 | |||
| 160 | config PDC_CHASSIS_WARN | ||
| 161 | bool "PDC chassis warnings support" | ||
| 162 | depends on PROC_FS | ||
| 163 | default y | ||
| 164 | help | ||
| 165 | Say Y here if you want to enable support for Chassis warnings. | ||
| 166 | This will add a proc entry '/proc/chassis' giving some information | ||
| 167 | about the overall health state of the system. | ||
| 168 | This includes NVRAM battery level, overtemp or failures such as | ||
| 169 | fans or power units. | ||
| 170 | |||
| 171 | If unsure, say Y. | ||
| 172 | |||
| 173 | |||
| 155 | config PDC_STABLE | 174 | config PDC_STABLE |
| 156 | tristate "PDC Stable Storage support" | 175 | tristate "PDC Stable Storage support" |
| 157 | depends on SYSFS | 176 | depends on SYSFS |
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index bbeabe3fc4c6..ea1b7a63598e 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c | |||
| @@ -28,8 +28,15 @@ | |||
| 28 | * following code can deal with just 96 bytes of Stable Storage, and all | 28 | * following code can deal with just 96 bytes of Stable Storage, and all |
| 29 | * sizes between 96 and 192 bytes (provided they are multiple of struct | 29 | * sizes between 96 and 192 bytes (provided they are multiple of struct |
| 30 | * device_path size, eg: 128, 160 and 192) to provide full information. | 30 | * device_path size, eg: 128, 160 and 192) to provide full information. |
| 31 | * The code makes no use of data above 192 bytes. One last word: there's one | 31 | * One last word: there's one path we can always count on: the primary path. |
| 32 | * path we can always count on: the primary path. | 32 | * Anything above 224 bytes is used for 'osdep2' OS-dependent storage area. |
| 33 | * | ||
| 34 | * The first OS-dependent area should always be available. Obviously, this is | ||
| 35 | * not true for the other one. Also bear in mind that reading/writing from/to | ||
| 36 | * osdep2 is much more expensive than from/to osdep1. | ||
| 37 | * NOTE: We do not handle the 2 bytes OS-dep area at 0x5D, nor the first | ||
| 38 | * 2 bytes of storage available right after OSID. That's a total of 4 bytes | ||
| 39 | * sacrificed: -ETOOLAZY :P | ||
| 33 | * | 40 | * |
| 34 | * The current policy wrt file permissions is: | 41 | * The current policy wrt file permissions is: |
| 35 | * - write: root only | 42 | * - write: root only |
| @@ -64,15 +71,18 @@ | |||
| 64 | #include <asm/uaccess.h> | 71 | #include <asm/uaccess.h> |
| 65 | #include <asm/hardware.h> | 72 | #include <asm/hardware.h> |
| 66 | 73 | ||
| 67 | #define PDCS_VERSION "0.22" | 74 | #define PDCS_VERSION "0.30" |
| 68 | #define PDCS_PREFIX "PDC Stable Storage" | 75 | #define PDCS_PREFIX "PDC Stable Storage" |
| 69 | 76 | ||
| 70 | #define PDCS_ADDR_PPRI 0x00 | 77 | #define PDCS_ADDR_PPRI 0x00 |
| 71 | #define PDCS_ADDR_OSID 0x40 | 78 | #define PDCS_ADDR_OSID 0x40 |
| 79 | #define PDCS_ADDR_OSD1 0x48 | ||
| 80 | #define PDCS_ADDR_DIAG 0x58 | ||
| 72 | #define PDCS_ADDR_FSIZ 0x5C | 81 | #define PDCS_ADDR_FSIZ 0x5C |
| 73 | #define PDCS_ADDR_PCON 0x60 | 82 | #define PDCS_ADDR_PCON 0x60 |
| 74 | #define PDCS_ADDR_PALT 0x80 | 83 | #define PDCS_ADDR_PALT 0x80 |
| 75 | #define PDCS_ADDR_PKBD 0xA0 | 84 | #define PDCS_ADDR_PKBD 0xA0 |
| 85 | #define PDCS_ADDR_OSD2 0xE0 | ||
| 76 | 86 | ||
| 77 | MODULE_AUTHOR("Thibaut VARENE <varenet@parisc-linux.org>"); | 87 | MODULE_AUTHOR("Thibaut VARENE <varenet@parisc-linux.org>"); |
| 78 | MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data"); | 88 | MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data"); |
| @@ -82,6 +92,9 @@ MODULE_VERSION(PDCS_VERSION); | |||
| 82 | /* holds Stable Storage size. Initialized once and for all, no lock needed */ | 92 | /* holds Stable Storage size. Initialized once and for all, no lock needed */ |
| 83 | static unsigned long pdcs_size __read_mostly; | 93 | static unsigned long pdcs_size __read_mostly; |
| 84 | 94 | ||
| 95 | /* holds OS ID. Initialized once and for all, hopefully to 0x0006 */ | ||
| 96 | static u16 pdcs_osid __read_mostly; | ||
| 97 | |||
| 85 | /* This struct defines what we need to deal with a parisc pdc path entry */ | 98 | /* This struct defines what we need to deal with a parisc pdc path entry */ |
| 86 | struct pdcspath_entry { | 99 | struct pdcspath_entry { |
| 87 | rwlock_t rw_lock; /* to protect path entry access */ | 100 | rwlock_t rw_lock; /* to protect path entry access */ |
| @@ -609,27 +622,64 @@ static ssize_t | |||
| 609 | pdcs_osid_read(struct subsystem *entry, char *buf) | 622 | pdcs_osid_read(struct subsystem *entry, char *buf) |
| 610 | { | 623 | { |
| 611 | char *out = buf; | 624 | char *out = buf; |
| 612 | __u32 result; | ||
| 613 | char *tmpstr = NULL; | ||
| 614 | 625 | ||
| 615 | if (!entry || !buf) | 626 | if (!entry || !buf) |
| 616 | return -EINVAL; | 627 | return -EINVAL; |
| 617 | 628 | ||
| 618 | /* get OSID */ | 629 | out += sprintf(out, "%s dependent data (0x%.4x)\n", |
| 619 | if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK) | 630 | os_id_to_string(pdcs_osid), pdcs_osid); |
| 631 | |||
| 632 | return out - buf; | ||
| 633 | } | ||
| 634 | |||
| 635 | /** | ||
| 636 | * pdcs_osdep1_read - Stable Storage OS-Dependent data area 1 output. | ||
| 637 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
| 638 | * @buf: The output buffer to write to. | ||
| 639 | * | ||
| 640 | * This can hold 16 bytes of OS-Dependent data. | ||
| 641 | */ | ||
| 642 | static ssize_t | ||
| 643 | pdcs_osdep1_read(struct subsystem *entry, char *buf) | ||
| 644 | { | ||
| 645 | char *out = buf; | ||
| 646 | u32 result[4]; | ||
| 647 | |||
| 648 | if (!entry || !buf) | ||
| 649 | return -EINVAL; | ||
| 650 | |||
| 651 | if (pdc_stable_read(PDCS_ADDR_OSD1, &result, sizeof(result)) != PDC_OK) | ||
| 620 | return -EIO; | 652 | return -EIO; |
| 621 | 653 | ||
| 622 | /* the actual result is 16 bits away */ | 654 | out += sprintf(out, "0x%.8x\n", result[0]); |
| 623 | switch (result >> 16) { | 655 | out += sprintf(out, "0x%.8x\n", result[1]); |
| 624 | case 0x0000: tmpstr = "No OS-dependent data"; break; | 656 | out += sprintf(out, "0x%.8x\n", result[2]); |
| 625 | case 0x0001: tmpstr = "HP-UX dependent data"; break; | 657 | out += sprintf(out, "0x%.8x\n", result[3]); |
| 626 | case 0x0002: tmpstr = "MPE-iX dependent data"; break; | 658 | |
| 627 | case 0x0003: tmpstr = "OSF dependent data"; break; | 659 | return out - buf; |
| 628 | case 0x0004: tmpstr = "HP-RT dependent data"; break; | 660 | } |
| 629 | case 0x0005: tmpstr = "Novell Netware dependent data"; break; | 661 | |
| 630 | default: tmpstr = "Unknown"; break; | 662 | /** |
| 631 | } | 663 | * pdcs_diagnostic_read - Stable Storage Diagnostic register output. |
| 632 | out += sprintf(out, "%s (0x%.4x)\n", tmpstr, (result >> 16)); | 664 | * @entry: An allocated and populated subsytem struct. We don't use it tho. |
| 665 | * @buf: The output buffer to write to. | ||
| 666 | * | ||
| 667 | * I have NFC how to interpret the content of that register ;-). | ||
| 668 | */ | ||
| 669 | static ssize_t | ||
| 670 | pdcs_diagnostic_read(struct subsystem *entry, char *buf) | ||
| 671 | { | ||
| 672 | char *out = buf; | ||
| 673 | u32 result; | ||
| 674 | |||
| 675 | if (!entry || !buf) | ||
| 676 | return -EINVAL; | ||
| 677 | |||
| 678 | /* get diagnostic */ | ||
| 679 | if (pdc_stable_read(PDCS_ADDR_DIAG, &result, sizeof(result)) != PDC_OK) | ||
| 680 | return -EIO; | ||
| 681 | |||
| 682 | out += sprintf(out, "0x%.4x\n", (result >> 16)); | ||
| 633 | 683 | ||
| 634 | return out - buf; | 684 | return out - buf; |
| 635 | } | 685 | } |
| @@ -645,7 +695,7 @@ static ssize_t | |||
| 645 | pdcs_fastsize_read(struct subsystem *entry, char *buf) | 695 | pdcs_fastsize_read(struct subsystem *entry, char *buf) |
| 646 | { | 696 | { |
| 647 | char *out = buf; | 697 | char *out = buf; |
| 648 | __u32 result; | 698 | u32 result; |
| 649 | 699 | ||
| 650 | if (!entry || !buf) | 700 | if (!entry || !buf) |
| 651 | return -EINVAL; | 701 | return -EINVAL; |
| @@ -664,6 +714,39 @@ pdcs_fastsize_read(struct subsystem *entry, char *buf) | |||
| 664 | } | 714 | } |
| 665 | 715 | ||
| 666 | /** | 716 | /** |
| 717 | * pdcs_osdep2_read - Stable Storage OS-Dependent data area 2 output. | ||
| 718 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
| 719 | * @buf: The output buffer to write to. | ||
| 720 | * | ||
| 721 | * This can hold pdcs_size - 224 bytes of OS-Dependent data, when available. | ||
| 722 | */ | ||
| 723 | static ssize_t | ||
| 724 | pdcs_osdep2_read(struct subsystem *entry, char *buf) | ||
| 725 | { | ||
| 726 | char *out = buf; | ||
| 727 | unsigned long size; | ||
| 728 | unsigned short i; | ||
| 729 | u32 result; | ||
| 730 | |||
| 731 | if (unlikely(pdcs_size <= 224)) | ||
| 732 | return -ENODATA; | ||
| 733 | |||
| 734 | size = pdcs_size - 224; | ||
| 735 | |||
| 736 | if (!entry || !buf) | ||
| 737 | return -EINVAL; | ||
| 738 | |||
| 739 | for (i=0; i<size; i+=4) { | ||
| 740 | if (unlikely(pdc_stable_read(PDCS_ADDR_OSD2 + i, &result, | ||
| 741 | sizeof(result)) != PDC_OK)) | ||
| 742 | return -EIO; | ||
| 743 | out += sprintf(out, "0x%.8x\n", result); | ||
| 744 | } | ||
| 745 | |||
| 746 | return out - buf; | ||
| 747 | } | ||
| 748 | |||
| 749 | /** | ||
| 667 | * pdcs_auto_write - This function handles autoboot/search flag modifying. | 750 | * pdcs_auto_write - This function handles autoboot/search flag modifying. |
| 668 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | 751 | * @entry: An allocated and populated subsytem struct. We don't use it tho. |
| 669 | * @buf: The input buffer to read from. | 752 | * @buf: The input buffer to read from. |
| @@ -770,13 +853,100 @@ pdcs_autosearch_write(struct subsystem *entry, const char *buf, size_t count) | |||
| 770 | return pdcs_auto_write(entry, buf, count, PF_AUTOSEARCH); | 853 | return pdcs_auto_write(entry, buf, count, PF_AUTOSEARCH); |
| 771 | } | 854 | } |
| 772 | 855 | ||
| 856 | /** | ||
| 857 | * pdcs_osdep1_write - Stable Storage OS-Dependent data area 1 input. | ||
| 858 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
| 859 | * @buf: The input buffer to read from. | ||
| 860 | * @count: The number of bytes to be read. | ||
| 861 | * | ||
| 862 | * This can store 16 bytes of OS-Dependent data. We use a byte-by-byte | ||
| 863 | * write approach. It's up to userspace to deal with it when constructing | ||
| 864 | * its input buffer. | ||
| 865 | */ | ||
| 866 | static ssize_t | ||
| 867 | pdcs_osdep1_write(struct subsystem *entry, const char *buf, size_t count) | ||
| 868 | { | ||
| 869 | u8 in[16]; | ||
| 870 | |||
| 871 | if (!capable(CAP_SYS_ADMIN)) | ||
| 872 | return -EACCES; | ||
| 873 | |||
| 874 | if (!entry || !buf || !count) | ||
| 875 | return -EINVAL; | ||
| 876 | |||
| 877 | if (unlikely(pdcs_osid != OS_ID_LINUX)) | ||
| 878 | return -EPERM; | ||
| 879 | |||
| 880 | if (count > 16) | ||
| 881 | return -EMSGSIZE; | ||
| 882 | |||
| 883 | /* We'll use a local copy of buf */ | ||
| 884 | memset(in, 0, 16); | ||
| 885 | memcpy(in, buf, count); | ||
| 886 | |||
| 887 | if (pdc_stable_write(PDCS_ADDR_OSD1, &in, sizeof(in)) != PDC_OK) | ||
| 888 | return -EIO; | ||
| 889 | |||
| 890 | return count; | ||
| 891 | } | ||
| 892 | |||
| 893 | /** | ||
| 894 | * pdcs_osdep2_write - Stable Storage OS-Dependent data area 2 input. | ||
| 895 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
| 896 | * @buf: The input buffer to read from. | ||
| 897 | * @count: The number of bytes to be read. | ||
| 898 | * | ||
| 899 | * This can store pdcs_size - 224 bytes of OS-Dependent data. We use a | ||
| 900 | * byte-by-byte write approach. It's up to userspace to deal with it when | ||
| 901 | * constructing its input buffer. | ||
| 902 | */ | ||
| 903 | static ssize_t | ||
| 904 | pdcs_osdep2_write(struct subsystem *entry, const char *buf, size_t count) | ||
| 905 | { | ||
| 906 | unsigned long size; | ||
| 907 | unsigned short i; | ||
| 908 | u8 in[4]; | ||
| 909 | |||
| 910 | if (!capable(CAP_SYS_ADMIN)) | ||
| 911 | return -EACCES; | ||
| 912 | |||
| 913 | if (!entry || !buf || !count) | ||
| 914 | return -EINVAL; | ||
| 915 | |||
| 916 | if (unlikely(pdcs_size <= 224)) | ||
| 917 | return -ENOSYS; | ||
| 918 | |||
| 919 | if (unlikely(pdcs_osid != OS_ID_LINUX)) | ||
| 920 | return -EPERM; | ||
| 921 | |||
| 922 | size = pdcs_size - 224; | ||
| 923 | |||
| 924 | if (count > size) | ||
| 925 | return -EMSGSIZE; | ||
| 926 | |||
| 927 | /* We'll use a local copy of buf */ | ||
| 928 | |||
| 929 | for (i=0; i<count; i+=4) { | ||
| 930 | memset(in, 0, 4); | ||
| 931 | memcpy(in, buf+i, (count-i < 4) ? count-i : 4); | ||
| 932 | if (unlikely(pdc_stable_write(PDCS_ADDR_OSD2 + i, &in, | ||
| 933 | sizeof(in)) != PDC_OK)) | ||
| 934 | return -EIO; | ||
| 935 | } | ||
| 936 | |||
| 937 | return count; | ||
| 938 | } | ||
| 939 | |||
| 773 | /* The remaining attributes. */ | 940 | /* The remaining attributes. */ |
| 774 | static PDCS_ATTR(size, 0444, pdcs_size_read, NULL); | 941 | static PDCS_ATTR(size, 0444, pdcs_size_read, NULL); |
| 775 | static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write); | 942 | static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write); |
| 776 | static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write); | 943 | static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write); |
| 777 | static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL); | 944 | static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL); |
| 778 | static PDCS_ATTR(osid, 0400, pdcs_osid_read, NULL); | 945 | static PDCS_ATTR(osid, 0444, pdcs_osid_read, NULL); |
| 946 | static PDCS_ATTR(osdep1, 0600, pdcs_osdep1_read, pdcs_osdep1_write); | ||
| 947 | static PDCS_ATTR(diagnostic, 0400, pdcs_diagnostic_read, NULL); | ||
| 779 | static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL); | 948 | static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL); |
| 949 | static PDCS_ATTR(osdep2, 0600, pdcs_osdep2_read, pdcs_osdep2_write); | ||
| 780 | 950 | ||
| 781 | static struct subsys_attribute *pdcs_subsys_attrs[] = { | 951 | static struct subsys_attribute *pdcs_subsys_attrs[] = { |
| 782 | &pdcs_attr_size, | 952 | &pdcs_attr_size, |
| @@ -784,7 +954,10 @@ static struct subsys_attribute *pdcs_subsys_attrs[] = { | |||
| 784 | &pdcs_attr_autosearch, | 954 | &pdcs_attr_autosearch, |
| 785 | &pdcs_attr_timer, | 955 | &pdcs_attr_timer, |
| 786 | &pdcs_attr_osid, | 956 | &pdcs_attr_osid, |
| 957 | &pdcs_attr_osdep1, | ||
| 958 | &pdcs_attr_diagnostic, | ||
| 787 | &pdcs_attr_fastsize, | 959 | &pdcs_attr_fastsize, |
| 960 | &pdcs_attr_osdep2, | ||
| 788 | NULL, | 961 | NULL, |
| 789 | }; | 962 | }; |
| 790 | 963 | ||
| @@ -865,6 +1038,7 @@ pdc_stable_init(void) | |||
| 865 | { | 1038 | { |
| 866 | struct subsys_attribute *attr; | 1039 | struct subsys_attribute *attr; |
| 867 | int i, rc = 0, error = 0; | 1040 | int i, rc = 0, error = 0; |
| 1041 | u32 result; | ||
| 868 | 1042 | ||
| 869 | /* find the size of the stable storage */ | 1043 | /* find the size of the stable storage */ |
| 870 | if (pdc_stable_get_size(&pdcs_size) != PDC_OK) | 1044 | if (pdc_stable_get_size(&pdcs_size) != PDC_OK) |
| @@ -876,6 +1050,13 @@ pdc_stable_init(void) | |||
| 876 | 1050 | ||
| 877 | printk(KERN_INFO PDCS_PREFIX " facility v%s\n", PDCS_VERSION); | 1051 | printk(KERN_INFO PDCS_PREFIX " facility v%s\n", PDCS_VERSION); |
| 878 | 1052 | ||
| 1053 | /* get OSID */ | ||
| 1054 | if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK) | ||
| 1055 | return -EIO; | ||
| 1056 | |||
| 1057 | /* the actual result is 16 bits away */ | ||
| 1058 | pdcs_osid = (u16)(result >> 16); | ||
| 1059 | |||
| 879 | /* For now we'll register the stable subsys within this driver */ | 1060 | /* For now we'll register the stable subsys within this driver */ |
| 880 | if ((rc = firmware_register(&stable_subsys))) | 1061 | if ((rc = firmware_register(&stable_subsys))) |
| 881 | goto fail_firmreg; | 1062 | goto fail_firmreg; |
| @@ -887,7 +1068,7 @@ pdc_stable_init(void) | |||
| 887 | 1068 | ||
| 888 | /* register the paths subsys as a subsystem of stable subsys */ | 1069 | /* register the paths subsys as a subsystem of stable subsys */ |
| 889 | kset_set_kset_s(&paths_subsys, stable_subsys); | 1070 | kset_set_kset_s(&paths_subsys, stable_subsys); |
| 890 | if ((rc= subsystem_register(&paths_subsys))) | 1071 | if ((rc = subsystem_register(&paths_subsys))) |
| 891 | goto fail_subsysreg; | 1072 | goto fail_subsysreg; |
| 892 | 1073 | ||
| 893 | /* now we create all "files" for the paths subsys */ | 1074 | /* now we create all "files" for the paths subsys */ |
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index 278f325021ee..d09e39e39c60 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c | |||
| @@ -316,10 +316,10 @@ static int reserve_sba_gart = 1; | |||
| 316 | ** | 316 | ** |
| 317 | ** Superdome (in particular, REO) allows only 64-bit CSR accesses. | 317 | ** Superdome (in particular, REO) allows only 64-bit CSR accesses. |
| 318 | */ | 318 | */ |
| 319 | #define READ_REG32(addr) le32_to_cpu(__raw_readl(addr)) | 319 | #define READ_REG32(addr) readl(addr) |
| 320 | #define READ_REG64(addr) le64_to_cpu(__raw_readq(addr)) | 320 | #define READ_REG64(addr) readq(addr) |
| 321 | #define WRITE_REG32(val, addr) __raw_writel(cpu_to_le32(val), addr) | 321 | #define WRITE_REG32(val, addr) writel((val), (addr)) |
| 322 | #define WRITE_REG64(val, addr) __raw_writeq(cpu_to_le64(val), addr) | 322 | #define WRITE_REG64(val, addr) writeq((val), (addr)) |
| 323 | 323 | ||
| 324 | #ifdef CONFIG_64BIT | 324 | #ifdef CONFIG_64BIT |
| 325 | #define READ_REG(addr) READ_REG64(addr) | 325 | #define READ_REG(addr) READ_REG64(addr) |
| @@ -1427,7 +1427,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) | |||
| 1427 | iov_order = get_order(iova_space_size >> (IOVP_SHIFT - PAGE_SHIFT)); | 1427 | iov_order = get_order(iova_space_size >> (IOVP_SHIFT - PAGE_SHIFT)); |
| 1428 | ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64); | 1428 | ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64); |
| 1429 | 1429 | ||
| 1430 | DBG_INIT("%s() hpa 0x%lx IOV %dMB (%d bits)\n", | 1430 | DBG_INIT("%s() hpa 0x%p IOV %dMB (%d bits)\n", |
| 1431 | __FUNCTION__, ioc->ioc_hpa, iova_space_size >> 20, | 1431 | __FUNCTION__, ioc->ioc_hpa, iova_space_size >> 20, |
| 1432 | iov_order + PAGE_SHIFT); | 1432 | iov_order + PAGE_SHIFT); |
| 1433 | 1433 | ||
| @@ -1764,7 +1764,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, | |||
| 1764 | 1764 | ||
| 1765 | sba_dev->num_ioc = num_ioc; | 1765 | sba_dev->num_ioc = num_ioc; |
| 1766 | for (i = 0; i < num_ioc; i++) { | 1766 | for (i = 0; i < num_ioc; i++) { |
| 1767 | unsigned long ioc_hpa = sba_dev->ioc[i].ioc_hpa; | 1767 | void __iomem *ioc_hpa = sba_dev->ioc[i].ioc_hpa; |
| 1768 | unsigned int j; | 1768 | unsigned int j; |
| 1769 | 1769 | ||
| 1770 | for (j=0; j < sizeof(u64) * ROPES_PER_IOC; j+=sizeof(u64)) { | 1770 | for (j=0; j < sizeof(u64) * ROPES_PER_IOC; j+=sizeof(u64)) { |
| @@ -1776,7 +1776,8 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, | |||
| 1776 | * Improves netperf UDP_STREAM by ~10% for bcm5701. | 1776 | * Improves netperf UDP_STREAM by ~10% for bcm5701. |
| 1777 | */ | 1777 | */ |
| 1778 | if (IS_PLUTO(sba_dev->iodc)) { | 1778 | if (IS_PLUTO(sba_dev->iodc)) { |
| 1779 | unsigned long rope_cfg, cfg_val; | 1779 | void __iomem *rope_cfg; |
| 1780 | unsigned long cfg_val; | ||
| 1780 | 1781 | ||
| 1781 | rope_cfg = ioc_hpa + IOC_ROPE0_CFG + j; | 1782 | rope_cfg = ioc_hpa + IOC_ROPE0_CFG + j; |
| 1782 | cfg_val = READ_REG(rope_cfg); | 1783 | cfg_val = READ_REG(rope_cfg); |
| @@ -1902,7 +1903,7 @@ sba_common_init(struct sba_device *sba_dev) | |||
| 1902 | * (bit #61, big endian), we have to flush and sync every time | 1903 | * (bit #61, big endian), we have to flush and sync every time |
| 1903 | * IO-PDIR is changed in Ike/Astro. | 1904 | * IO-PDIR is changed in Ike/Astro. |
| 1904 | */ | 1905 | */ |
| 1905 | if (boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC) { | 1906 | if (ioc_needs_fdc) { |
| 1906 | printk(KERN_INFO MODULE_NAME " FDC/SYNC required.\n"); | 1907 | printk(KERN_INFO MODULE_NAME " FDC/SYNC required.\n"); |
| 1907 | } else { | 1908 | } else { |
| 1908 | printk(KERN_INFO MODULE_NAME " IOC has cache coherent PDIR.\n"); | 1909 | printk(KERN_INFO MODULE_NAME " IOC has cache coherent PDIR.\n"); |
diff --git a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h index 3ce3440d1b0c..1a7bfe699e0c 100644 --- a/include/asm-parisc/assembly.h +++ b/include/asm-parisc/assembly.h | |||
| @@ -48,6 +48,7 @@ | |||
| 48 | #define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE) | 48 | #define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE) |
| 49 | 49 | ||
| 50 | #ifdef CONFIG_PA20 | 50 | #ifdef CONFIG_PA20 |
| 51 | #define LDCW ldcw,co | ||
| 51 | #define BL b,l | 52 | #define BL b,l |
| 52 | # ifdef CONFIG_64BIT | 53 | # ifdef CONFIG_64BIT |
| 53 | # define LEVEL 2.0w | 54 | # define LEVEL 2.0w |
| @@ -55,6 +56,7 @@ | |||
| 55 | # define LEVEL 2.0 | 56 | # define LEVEL 2.0 |
| 56 | # endif | 57 | # endif |
| 57 | #else | 58 | #else |
| 59 | #define LDCW ldcw | ||
| 58 | #define BL bl | 60 | #define BL bl |
| 59 | #define LEVEL 1.1 | 61 | #define LEVEL 1.1 |
| 60 | #endif | 62 | #endif |
diff --git a/include/asm-parisc/compat.h b/include/asm-parisc/compat.h index 289624d8b2d4..71b4eeea205a 100644 --- a/include/asm-parisc/compat.h +++ b/include/asm-parisc/compat.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | */ | 5 | */ |
| 6 | #include <linux/types.h> | 6 | #include <linux/types.h> |
| 7 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
| 8 | #include <linux/personality.h> | ||
| 8 | 9 | ||
| 9 | #define COMPAT_USER_HZ 100 | 10 | #define COMPAT_USER_HZ 100 |
| 10 | 11 | ||
| @@ -149,4 +150,14 @@ static __inline__ void __user *compat_alloc_user_space(long len) | |||
| 149 | return (void __user *)regs->gr[30]; | 150 | return (void __user *)regs->gr[30]; |
| 150 | } | 151 | } |
| 151 | 152 | ||
| 153 | static inline int __is_compat_task(struct task_struct *t) | ||
| 154 | { | ||
| 155 | return personality(t->personality) == PER_LINUX32; | ||
| 156 | } | ||
| 157 | |||
| 158 | static inline int is_compat_task(void) | ||
| 159 | { | ||
| 160 | return __is_compat_task(current); | ||
| 161 | } | ||
| 162 | |||
| 152 | #endif /* _ASM_PARISC_COMPAT_H */ | 163 | #endif /* _ASM_PARISC_COMPAT_H */ |
diff --git a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h index 08364f957e7a..c9b2e35326ee 100644 --- a/include/asm-parisc/pdc.h +++ b/include/asm-parisc/pdc.h | |||
| @@ -278,12 +278,11 @@ typedef struct { | |||
| 278 | /* constants for OS (NVM...) */ | 278 | /* constants for OS (NVM...) */ |
| 279 | #define OS_ID_NONE 0 /* Undefined OS ID */ | 279 | #define OS_ID_NONE 0 /* Undefined OS ID */ |
| 280 | #define OS_ID_HPUX 1 /* HP-UX OS */ | 280 | #define OS_ID_HPUX 1 /* HP-UX OS */ |
| 281 | #define OS_ID_LINUX OS_ID_HPUX /* just use the same value as hpux */ | ||
| 282 | #define OS_ID_MPEXL 2 /* MPE XL OS */ | 281 | #define OS_ID_MPEXL 2 /* MPE XL OS */ |
| 283 | #define OS_ID_OSF 3 /* OSF OS */ | 282 | #define OS_ID_OSF 3 /* OSF OS */ |
| 284 | #define OS_ID_HPRT 4 /* HP-RT OS */ | 283 | #define OS_ID_HPRT 4 /* HP-RT OS */ |
| 285 | #define OS_ID_NOVEL 5 /* NOVELL OS */ | 284 | #define OS_ID_NOVEL 5 /* NOVELL OS */ |
| 286 | #define OS_ID_NT 6 /* NT OS */ | 285 | #define OS_ID_LINUX 6 /* Linux */ |
| 287 | 286 | ||
| 288 | 287 | ||
| 289 | /* constants for PDC_CHASSIS */ | 288 | /* constants for PDC_CHASSIS */ |
| @@ -352,8 +351,8 @@ struct pdc_cache_cf { /* for PDC_CACHE (I/D-caches) */ | |||
| 352 | cc_wt : 1, /* 0 = WT-Dcache, 1 = WB-Dcache */ | 351 | cc_wt : 1, /* 0 = WT-Dcache, 1 = WB-Dcache */ |
| 353 | cc_sh : 2, /* 0 = separate I/D-cache, else shared I/D-cache */ | 352 | cc_sh : 2, /* 0 = separate I/D-cache, else shared I/D-cache */ |
| 354 | cc_cst : 3, /* 0 = incoherent D-cache, 1=coherent D-cache */ | 353 | cc_cst : 3, /* 0 = incoherent D-cache, 1=coherent D-cache */ |
| 355 | cc_pad1 : 5, /* reserved */ | 354 | cc_pad1 : 10, /* reserved */ |
| 356 | cc_assoc: 8; /* associativity of I/D-cache */ | 355 | cc_hv : 3; /* hversion dependent */ |
| 357 | }; | 356 | }; |
| 358 | 357 | ||
| 359 | struct pdc_tlb_cf { /* for PDC_CACHE (I/D-TLB's) */ | 358 | struct pdc_tlb_cf { /* for PDC_CACHE (I/D-TLB's) */ |
| @@ -719,6 +718,7 @@ void setup_pdc(void); /* in inventory.c */ | |||
| 719 | int pdc_add_valid(unsigned long address); | 718 | int pdc_add_valid(unsigned long address); |
| 720 | int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len); | 719 | int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len); |
| 721 | int pdc_chassis_disp(unsigned long disp); | 720 | int pdc_chassis_disp(unsigned long disp); |
| 721 | int pdc_chassis_warn(unsigned long *warn); | ||
| 722 | int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info); | 722 | int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info); |
| 723 | int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index, | 723 | int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index, |
| 724 | void *iodc_data, unsigned int iodc_data_size); | 724 | void *iodc_data, unsigned int iodc_data_size); |
| @@ -732,6 +732,7 @@ int pdc_model_cpuid(unsigned long *cpu_id); | |||
| 732 | int pdc_model_versions(unsigned long *versions, int id); | 732 | int pdc_model_versions(unsigned long *versions, int id); |
| 733 | int pdc_model_capabilities(unsigned long *capabilities); | 733 | int pdc_model_capabilities(unsigned long *capabilities); |
| 734 | int pdc_cache_info(struct pdc_cache_info *cache); | 734 | int pdc_cache_info(struct pdc_cache_info *cache); |
| 735 | int pdc_spaceid_bits(unsigned long *space_bits); | ||
| 735 | #ifndef CONFIG_PA20 | 736 | #ifndef CONFIG_PA20 |
| 736 | int pdc_btlb_info(struct pdc_btlb_info *btlb); | 737 | int pdc_btlb_info(struct pdc_btlb_info *btlb); |
| 737 | int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path); | 738 | int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path); |
| @@ -775,6 +776,18 @@ int pdc_sti_call(unsigned long func, unsigned long flags, | |||
| 775 | 776 | ||
| 776 | extern void pdc_init(void); | 777 | extern void pdc_init(void); |
| 777 | 778 | ||
| 779 | static inline char * os_id_to_string(u16 os_id) { | ||
| 780 | switch(os_id) { | ||
| 781 | case OS_ID_NONE: return "No OS"; | ||
| 782 | case OS_ID_HPUX: return "HP-UX"; | ||
| 783 | case OS_ID_MPEXL: return "MPE-iX"; | ||
| 784 | case OS_ID_OSF: return "OSF"; | ||
| 785 | case OS_ID_HPRT: return "HP-RT"; | ||
| 786 | case OS_ID_NOVEL: return "Novell Netware"; | ||
| 787 | case OS_ID_LINUX: return "Linux"; | ||
| 788 | default: return "Unknown"; | ||
| 789 | } | ||
| 790 | } | ||
| 778 | #endif /* __ASSEMBLY__ */ | 791 | #endif /* __ASSEMBLY__ */ |
| 779 | 792 | ||
| 780 | #endif /* _PARISC_PDC_H */ | 793 | #endif /* _PARISC_PDC_H */ |
diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h index b6bcc672ba80..5066c54dae0a 100644 --- a/include/asm-parisc/pgtable.h +++ b/include/asm-parisc/pgtable.h | |||
| @@ -506,13 +506,13 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, | |||
| 506 | 506 | ||
| 507 | /* TLB page size encoding - see table 3-1 in parisc20.pdf */ | 507 | /* TLB page size encoding - see table 3-1 in parisc20.pdf */ |
| 508 | #define _PAGE_SIZE_ENCODING_4K 0 | 508 | #define _PAGE_SIZE_ENCODING_4K 0 |
| 509 | #define _PAGE_SIZE_ENCODING_16K 1 | 509 | #define _PAGE_SIZE_ENCODING_16K 1 |
| 510 | #define _PAGE_SIZE_ENCODING_64K 2 | 510 | #define _PAGE_SIZE_ENCODING_64K 2 |
| 511 | #define _PAGE_SIZE_ENCODING_256K 3 | 511 | #define _PAGE_SIZE_ENCODING_256K 3 |
| 512 | #define _PAGE_SIZE_ENCODING_1M 4 | 512 | #define _PAGE_SIZE_ENCODING_1M 4 |
| 513 | #define _PAGE_SIZE_ENCODING_4M 5 | 513 | #define _PAGE_SIZE_ENCODING_4M 5 |
| 514 | #define _PAGE_SIZE_ENCODING_16M 6 | 514 | #define _PAGE_SIZE_ENCODING_16M 6 |
| 515 | #define _PAGE_SIZE_ENCODING_64M 7 | 515 | #define _PAGE_SIZE_ENCODING_64M 7 |
| 516 | 516 | ||
| 517 | #if defined(CONFIG_PARISC_PAGE_SIZE_4KB) | 517 | #if defined(CONFIG_PARISC_PAGE_SIZE_4KB) |
| 518 | # define _PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_4K | 518 | # define _PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_4K |
diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h index ca49dc91f4fc..b73626f040da 100644 --- a/include/asm-parisc/processor.h +++ b/include/asm-parisc/processor.h | |||
| @@ -26,14 +26,12 @@ | |||
| 26 | * Default implementation of macro that returns current | 26 | * Default implementation of macro that returns current |
| 27 | * instruction pointer ("program counter"). | 27 | * instruction pointer ("program counter"). |
| 28 | */ | 28 | */ |
| 29 | 29 | #ifdef CONFIG_PA20 | |
| 30 | /* We cannot use MFIA as it was added for PA2.0 - prumpf | 30 | #define current_ia(x) __asm__("mfia %0" : "=r"(x)) |
| 31 | 31 | #else /* mfia added in pa2.0 */ | |
| 32 | At one point there were no "0f/0b" type local symbols in gas for | 32 | #define current_ia(x) __asm__("blr 0,%0\n\tnop" : "=r"(x)) |
| 33 | PA-RISC. This is no longer true, but this still seems like the | 33 | #endif |
| 34 | nicest way to implement this. */ | 34 | #define current_text_addr() ({ void *pc; current_ia(pc); pc; }) |
| 35 | |||
| 36 | #define current_text_addr() ({ void *pc; __asm__("\n\tblr 0,%0\n\tnop":"=r" (pc)); pc; }) | ||
| 37 | 35 | ||
| 38 | #define TASK_SIZE (current->thread.task_size) | 36 | #define TASK_SIZE (current->thread.task_size) |
| 39 | #define TASK_UNMAPPED_BASE (current->thread.map_base) | 37 | #define TASK_UNMAPPED_BASE (current->thread.map_base) |
diff --git a/include/asm-parisc/system.h b/include/asm-parisc/system.h index 863876134b2c..5fe2d2329ab5 100644 --- a/include/asm-parisc/system.h +++ b/include/asm-parisc/system.h | |||
| @@ -155,13 +155,14 @@ static inline void set_eiem(unsigned long val) | |||
| 155 | type and dynamically select the 16-byte aligned int from the array | 155 | type and dynamically select the 16-byte aligned int from the array |
| 156 | for the semaphore. */ | 156 | for the semaphore. */ |
| 157 | 157 | ||
| 158 | #define __PA_LDCW_ALIGNMENT 16 | 158 | #define __PA_LDCW_ALIGNMENT 16 |
| 159 | #define __ldcw_align(a) ({ \ | 159 | #define __ldcw_align(a) ({ \ |
| 160 | unsigned long __ret = (unsigned long) &(a)->lock[0]; \ | 160 | unsigned long __ret = (unsigned long) &(a)->lock[0]; \ |
| 161 | __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); \ | 161 | __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) \ |
| 162 | (volatile unsigned int *) __ret; \ | 162 | & ~(__PA_LDCW_ALIGNMENT - 1); \ |
| 163 | (volatile unsigned int *) __ret; \ | ||
| 163 | }) | 164 | }) |
| 164 | #define LDCW "ldcw" | 165 | #define __LDCW "ldcw" |
| 165 | 166 | ||
| 166 | #else /*CONFIG_PA20*/ | 167 | #else /*CONFIG_PA20*/ |
| 167 | /* From: "Jim Hull" <jim.hull of hp.com> | 168 | /* From: "Jim Hull" <jim.hull of hp.com> |
| @@ -171,17 +172,18 @@ static inline void set_eiem(unsigned long val) | |||
| 171 | they only require "natural" alignment (4-byte for ldcw, 8-byte for | 172 | they only require "natural" alignment (4-byte for ldcw, 8-byte for |
| 172 | ldcd). */ | 173 | ldcd). */ |
| 173 | 174 | ||
| 174 | #define __PA_LDCW_ALIGNMENT 4 | 175 | #define __PA_LDCW_ALIGNMENT 4 |
| 175 | #define __ldcw_align(a) ((volatile unsigned int *)a) | 176 | #define __ldcw_align(a) ((volatile unsigned int *)a) |
| 176 | #define LDCW "ldcw,co" | 177 | #define __LDCW "ldcw,co" |
| 177 | 178 | ||
| 178 | #endif /*!CONFIG_PA20*/ | 179 | #endif /*!CONFIG_PA20*/ |
| 179 | 180 | ||
| 180 | /* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */ | 181 | /* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */ |
| 181 | #define __ldcw(a) ({ \ | 182 | #define __ldcw(a) ({ \ |
| 182 | unsigned __ret; \ | 183 | unsigned __ret; \ |
| 183 | __asm__ __volatile__(LDCW " 0(%1),%0" : "=r" (__ret) : "r" (a)); \ | 184 | __asm__ __volatile__(__LDCW " 0(%1),%0" \ |
| 184 | __ret; \ | 185 | : "=r" (__ret) : "r" (a)); \ |
| 186 | __ret; \ | ||
| 185 | }) | 187 | }) |
| 186 | 188 | ||
| 187 | #ifdef CONFIG_SMP | 189 | #ifdef CONFIG_SMP |
diff --git a/include/asm-parisc/uaccess.h b/include/asm-parisc/uaccess.h index f6c417c8c484..d973e8b3466c 100644 --- a/include/asm-parisc/uaccess.h +++ b/include/asm-parisc/uaccess.h | |||
| @@ -172,7 +172,11 @@ struct exception_data { | |||
| 172 | /* | 172 | /* |
| 173 | * The "__put_user/kernel_asm()" macros tell gcc they read from memory | 173 | * The "__put_user/kernel_asm()" macros tell gcc they read from memory |
| 174 | * instead of writing. This is because they do not write to any memory | 174 | * instead of writing. This is because they do not write to any memory |
| 175 | * gcc knows about, so there are no aliasing issues. | 175 | * gcc knows about, so there are no aliasing issues. These macros must |
| 176 | * also be aware that "fixup_put_user_skip_[12]" are executed in the | ||
| 177 | * context of the fault, and any registers used there must be listed | ||
| 178 | * as clobbers. In this case only "r1" is used by the current routines. | ||
| 179 | * r8/r9 are already listed as err/val. | ||
| 176 | */ | 180 | */ |
| 177 | 181 | ||
| 178 | #ifdef __LP64__ | 182 | #ifdef __LP64__ |
| @@ -183,7 +187,8 @@ struct exception_data { | |||
| 183 | "\t.dword\t1b,fixup_put_user_skip_1\n" \ | 187 | "\t.dword\t1b,fixup_put_user_skip_1\n" \ |
| 184 | "\t.previous" \ | 188 | "\t.previous" \ |
| 185 | : "=r"(__pu_err) \ | 189 | : "=r"(__pu_err) \ |
| 186 | : "r"(ptr), "r"(x), "0"(__pu_err)) | 190 | : "r"(ptr), "r"(x), "0"(__pu_err) \ |
| 191 | : "r1") | ||
| 187 | 192 | ||
| 188 | #define __put_user_asm(stx,x,ptr) \ | 193 | #define __put_user_asm(stx,x,ptr) \ |
| 189 | __asm__ __volatile__ ( \ | 194 | __asm__ __volatile__ ( \ |
diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h index 12b867238a47..27bcfad1c3e3 100644 --- a/include/asm-parisc/unistd.h +++ b/include/asm-parisc/unistd.h | |||
| @@ -797,11 +797,6 @@ | |||
| 797 | 797 | ||
| 798 | #define SYS_ify(syscall_name) __NR_##syscall_name | 798 | #define SYS_ify(syscall_name) __NR_##syscall_name |
| 799 | 799 | ||
| 800 | /* Assume all syscalls are done from PIC code just to be | ||
| 801 | * safe. The worst case scenario is that you lose a register | ||
| 802 | * and save/restore r19 across the syscall. */ | ||
| 803 | #define PIC | ||
| 804 | |||
| 805 | #ifndef ASM_LINE_SEP | 800 | #ifndef ASM_LINE_SEP |
| 806 | # define ASM_LINE_SEP ; | 801 | # define ASM_LINE_SEP ; |
| 807 | #endif | 802 | #endif |
