diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-29 14:30:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-29 14:30:45 -0400 |
commit | 4d3ce21fa9d2eaeda113aa2f9c2da80d972bef64 (patch) | |
tree | 9ffa5af467d6e9f6f6c8eb496489bf882613a459 | |
parent | b026188e8214ce87790730a56f3017d0bd222751 (diff) | |
parent | c1a7a755be26f68d7f21ee769584149a96185ea8 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/kyle/parisc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/kyle/parisc-2.6: (23 commits)
[PARISC] Move os_id_to_string() inside #ifndef __ASSEMBLY__
[PARISC] Fix do_gettimeofday() hang
[PARISC] Fix PCREL22F relocation problem for most modules
[PARISC] Refactor show_regs in traps.c
[PARISC] Add os_id_to_string helper
[PARISC] OS_ID_LINUX == 0x0006
[PARISC] Ensure Space ID hashing is turned off
[PARISC] Match show_cache_info with reality
[PARISC] Remove unused macro fixup_branch in syscall.S
[PARISC] Add is_compat_task() helper
[PARISC] Update Thibaut Varene's CREDITS entry
[PARISC] Reduce data footprint in pdc_stable.c
[PARISC] pdc_stable version 0.30
[PARISC] Work around machines which do not support chassis warnings
[PARISC] PDC_CHASSIS is implemented on all machines
[PARISC] Remove unconditional #define PIC in syscall macros
[PARISC] Use MFIA in current_text_addr on pa2.0 processors
[PARISC] Remove dead function pc_in_user_space
[PARISC] Test ioc_needs_fdc variable instead of open coding
[PARISC] Fix gcc 4.1 warnings in sba_iommu.c
...
-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 |