aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CREDITS4
-rw-r--r--arch/parisc/kernel/cache.c28
-rw-r--r--arch/parisc/kernel/entry.S6
-rw-r--r--arch/parisc/kernel/firmware.c46
-rw-r--r--arch/parisc/kernel/module.c63
-rw-r--r--arch/parisc/kernel/pdc_chassis.c109
-rw-r--r--arch/parisc/kernel/ptrace.c8
-rw-r--r--arch/parisc/kernel/real2.S9
-rw-r--r--arch/parisc/kernel/setup.c5
-rw-r--r--arch/parisc/kernel/signal.c20
-rw-r--r--arch/parisc/kernel/syscall.S14
-rw-r--r--arch/parisc/kernel/time.c18
-rw-r--r--arch/parisc/kernel/traps.c84
-rw-r--r--arch/parisc/kernel/unaligned.c18
-rw-r--r--drivers/parisc/Kconfig33
-rw-r--r--drivers/parisc/pdc_stable.c223
-rw-r--r--drivers/parisc/sba_iommu.c17
-rw-r--r--include/asm-parisc/assembly.h2
-rw-r--r--include/asm-parisc/compat.h11
-rw-r--r--include/asm-parisc/pdc.h21
-rw-r--r--include/asm-parisc/pgtable.h8
-rw-r--r--include/asm-parisc/processor.h14
-rw-r--r--include/asm-parisc/system.h26
-rw-r--r--include/asm-parisc/uaccess.h9
-rw-r--r--include/asm-parisc/unistd.h5
25 files changed, 581 insertions, 220 deletions
diff --git a/CREDITS b/CREDITS
index 85c7c70b7044..66b9e7a9abff 100644
--- a/CREDITS
+++ b/CREDITS
@@ -3401,10 +3401,10 @@ S: Czech Republic
3401 3401
3402N: Thibaut Varene 3402N: Thibaut Varene
3403E: T-Bone@parisc-linux.org 3403E: T-Bone@parisc-linux.org
3404W: http://www.parisc-linux.org/ 3404W: http://www.parisc-linux.org/~varenet/
3405P: 1024D/B7D2F063 E67C 0D43 A75E 12A5 BB1C FA2F 1E32 C3DA B7D2 F063 3405P: 1024D/B7D2F063 E67C 0D43 A75E 12A5 BB1C FA2F 1E32 C3DA B7D2 F063
3406D: PA-RISC port minion, PDC and GSCPS2 drivers, debuglocks and other bits 3406D: PA-RISC port minion, PDC and GSCPS2 drivers, debuglocks and other bits
3407D: Some bits in an ARM port, S1D13XXX FB driver, random patches here and there 3407D: Some ARM at91rm9200 bits, S1D13XXX FB driver, random patches here and there
3408D: AD1889 sound driver 3408D: AD1889 sound driver
3409S: Paris, France 3409S: 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)
97void 97void
98show_cache_info(struct seq_file *m) 98show_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
235void disable_sr_hashing(void) 237void 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
265void flush_dcache_page(struct page *page) 275void 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
1640dbit_spin_20w: 1640dbit_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
1676dbit_spin_11: 1676dbit_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
1716dbit_spin_20: 1716dbit_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 */
260int pdc_chassis_disp(unsigned long disp) 258int 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 */
273int 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 */
398int pdc_model_sysmodel(char *name) 414int 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 */
523int 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
92static 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__
94struct got_entry { 100struct 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
373enum elf_stub_type {
374 ELF_STUB_GOT,
375 ELF_STUB_MILLI,
376 ELF_STUB_DIRECT,
377};
378
367static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, 379static 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
41static int pdc_chassis_old __read_mostly = 0;
42static unsigned int pdc_chassis_enabled __read_mostly = 1; 47static 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
68static void __init pdc_chassis_checkold(void) 73static 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 = {
131void __init parisc_pdc_chassis_init(void) 135void __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
247static 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
279static 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 */
283pc_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
304static int __init parisc_init(void) 304static 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? */
546cas_wouldblock: 534cas_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
70void 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
76static 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) { 90static 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++) 117void 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
142config PDC_CHASSIS 142config 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
160config 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
155config PDC_STABLE 174config 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
77MODULE_AUTHOR("Thibaut VARENE <varenet@parisc-linux.org>"); 87MODULE_AUTHOR("Thibaut VARENE <varenet@parisc-linux.org>");
78MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data"); 88MODULE_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 */
83static unsigned long pdcs_size __read_mostly; 93static unsigned long pdcs_size __read_mostly;
84 94
95/* holds OS ID. Initialized once and for all, hopefully to 0x0006 */
96static 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 */
86struct pdcspath_entry { 99struct 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
609pdcs_osid_read(struct subsystem *entry, char *buf) 622pdcs_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 */
642static ssize_t
643pdcs_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 */
669static ssize_t
670pdcs_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
645pdcs_fastsize_read(struct subsystem *entry, char *buf) 695pdcs_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 */
723static ssize_t
724pdcs_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 */
866static ssize_t
867pdcs_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 */
903static ssize_t
904pdcs_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. */
774static PDCS_ATTR(size, 0444, pdcs_size_read, NULL); 941static PDCS_ATTR(size, 0444, pdcs_size_read, NULL);
775static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write); 942static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write);
776static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write); 943static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write);
777static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL); 944static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL);
778static PDCS_ATTR(osid, 0400, pdcs_osid_read, NULL); 945static PDCS_ATTR(osid, 0444, pdcs_osid_read, NULL);
946static PDCS_ATTR(osdep1, 0600, pdcs_osdep1_read, pdcs_osdep1_write);
947static PDCS_ATTR(diagnostic, 0400, pdcs_diagnostic_read, NULL);
779static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL); 948static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL);
949static PDCS_ATTR(osdep2, 0600, pdcs_osdep2_read, pdcs_osdep2_write);
780 950
781static struct subsys_attribute *pdcs_subsys_attrs[] = { 951static 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
153static inline int __is_compat_task(struct task_struct *t)
154{
155 return personality(t->personality) == PER_LINUX32;
156}
157
158static 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
359struct pdc_tlb_cf { /* for PDC_CACHE (I/D-TLB's) */ 358struct pdc_tlb_cf { /* for PDC_CACHE (I/D-TLB's) */
@@ -719,6 +718,7 @@ void setup_pdc(void); /* in inventory.c */
719int pdc_add_valid(unsigned long address); 718int pdc_add_valid(unsigned long address);
720int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len); 719int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len);
721int pdc_chassis_disp(unsigned long disp); 720int pdc_chassis_disp(unsigned long disp);
721int pdc_chassis_warn(unsigned long *warn);
722int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info); 722int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info);
723int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index, 723int 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);
732int pdc_model_versions(unsigned long *versions, int id); 732int pdc_model_versions(unsigned long *versions, int id);
733int pdc_model_capabilities(unsigned long *capabilities); 733int pdc_model_capabilities(unsigned long *capabilities);
734int pdc_cache_info(struct pdc_cache_info *cache); 734int pdc_cache_info(struct pdc_cache_info *cache);
735int pdc_spaceid_bits(unsigned long *space_bits);
735#ifndef CONFIG_PA20 736#ifndef CONFIG_PA20
736int pdc_btlb_info(struct pdc_btlb_info *btlb); 737int pdc_btlb_info(struct pdc_btlb_info *btlb);
737int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path); 738int 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
776extern void pdc_init(void); 777extern void pdc_init(void);
777 778
779static 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