forked from Minki/linux
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 ...
This commit is contained in:
commit
4d3ce21fa9
4
CREDITS
4
CREDITS
@ -3401,10 +3401,10 @@ S: Czech Republic
|
|||||||
|
|
||||||
N: Thibaut Varene
|
N: Thibaut Varene
|
||||||
E: T-Bone@parisc-linux.org
|
E: T-Bone@parisc-linux.org
|
||||||
W: http://www.parisc-linux.org/
|
W: http://www.parisc-linux.org/~varenet/
|
||||||
P: 1024D/B7D2F063 E67C 0D43 A75E 12A5 BB1C FA2F 1E32 C3DA B7D2 F063
|
P: 1024D/B7D2F063 E67C 0D43 A75E 12A5 BB1C FA2F 1E32 C3DA B7D2 F063
|
||||||
D: PA-RISC port minion, PDC and GSCPS2 drivers, debuglocks and other bits
|
D: PA-RISC port minion, PDC and GSCPS2 drivers, debuglocks and other bits
|
||||||
D: Some bits in an ARM port, S1D13XXX FB driver, random patches here and there
|
D: Some ARM at91rm9200 bits, S1D13XXX FB driver, random patches here and there
|
||||||
D: AD1889 sound driver
|
D: AD1889 sound driver
|
||||||
S: Paris, France
|
S: Paris, France
|
||||||
|
|
||||||
|
@ -97,15 +97,17 @@ update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
|
|||||||
void
|
void
|
||||||
show_cache_info(struct seq_file *m)
|
show_cache_info(struct seq_file *m)
|
||||||
{
|
{
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
seq_printf(m, "I-cache\t\t: %ld KB\n",
|
seq_printf(m, "I-cache\t\t: %ld KB\n",
|
||||||
cache_info.ic_size/1024 );
|
cache_info.ic_size/1024 );
|
||||||
seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %d-way associative)\n",
|
if (cache_info.dc_loop == 1)
|
||||||
|
snprintf(buf, 32, "%lu-way associative", cache_info.dc_loop);
|
||||||
|
seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %s)\n",
|
||||||
cache_info.dc_size/1024,
|
cache_info.dc_size/1024,
|
||||||
(cache_info.dc_conf.cc_wt ? "WT":"WB"),
|
(cache_info.dc_conf.cc_wt ? "WT":"WB"),
|
||||||
(cache_info.dc_conf.cc_sh ? ", shared I/D":""),
|
(cache_info.dc_conf.cc_sh ? ", shared I/D":""),
|
||||||
(cache_info.dc_conf.cc_assoc)
|
((cache_info.dc_loop == 1) ? "direct mapped" : buf));
|
||||||
);
|
|
||||||
|
|
||||||
seq_printf(m, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n",
|
seq_printf(m, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n",
|
||||||
cache_info.it_size,
|
cache_info.it_size,
|
||||||
cache_info.dt_size,
|
cache_info.dt_size,
|
||||||
@ -158,11 +160,11 @@ parisc_cache_init(void)
|
|||||||
cache_info.dc_conf.cc_block,
|
cache_info.dc_conf.cc_block,
|
||||||
cache_info.dc_conf.cc_line,
|
cache_info.dc_conf.cc_line,
|
||||||
cache_info.dc_conf.cc_shift);
|
cache_info.dc_conf.cc_shift);
|
||||||
printk(" wt %d sh %d cst %d assoc %d\n",
|
printk(" wt %d sh %d cst %d hv %d\n",
|
||||||
cache_info.dc_conf.cc_wt,
|
cache_info.dc_conf.cc_wt,
|
||||||
cache_info.dc_conf.cc_sh,
|
cache_info.dc_conf.cc_sh,
|
||||||
cache_info.dc_conf.cc_cst,
|
cache_info.dc_conf.cc_cst,
|
||||||
cache_info.dc_conf.cc_assoc);
|
cache_info.dc_conf.cc_hv);
|
||||||
|
|
||||||
printk("IC base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx\n",
|
printk("IC base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx\n",
|
||||||
cache_info.ic_base,
|
cache_info.ic_base,
|
||||||
@ -176,11 +178,11 @@ parisc_cache_init(void)
|
|||||||
cache_info.ic_conf.cc_block,
|
cache_info.ic_conf.cc_block,
|
||||||
cache_info.ic_conf.cc_line,
|
cache_info.ic_conf.cc_line,
|
||||||
cache_info.ic_conf.cc_shift);
|
cache_info.ic_conf.cc_shift);
|
||||||
printk(" wt %d sh %d cst %d assoc %d\n",
|
printk(" wt %d sh %d cst %d hv %d\n",
|
||||||
cache_info.ic_conf.cc_wt,
|
cache_info.ic_conf.cc_wt,
|
||||||
cache_info.ic_conf.cc_sh,
|
cache_info.ic_conf.cc_sh,
|
||||||
cache_info.ic_conf.cc_cst,
|
cache_info.ic_conf.cc_cst,
|
||||||
cache_info.ic_conf.cc_assoc);
|
cache_info.ic_conf.cc_hv);
|
||||||
|
|
||||||
printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n",
|
printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n",
|
||||||
cache_info.dt_conf.tc_sh,
|
cache_info.dt_conf.tc_sh,
|
||||||
@ -234,7 +236,8 @@ parisc_cache_init(void)
|
|||||||
|
|
||||||
void disable_sr_hashing(void)
|
void disable_sr_hashing(void)
|
||||||
{
|
{
|
||||||
int srhash_type;
|
int srhash_type, retval;
|
||||||
|
unsigned long space_bits;
|
||||||
|
|
||||||
switch (boot_cpu_data.cpu_type) {
|
switch (boot_cpu_data.cpu_type) {
|
||||||
case pcx: /* We shouldn't get this far. setup.c should prevent it. */
|
case pcx: /* We shouldn't get this far. setup.c should prevent it. */
|
||||||
@ -260,6 +263,13 @@ void disable_sr_hashing(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
disable_sr_hashing_asm(srhash_type);
|
disable_sr_hashing_asm(srhash_type);
|
||||||
|
|
||||||
|
retval = pdc_spaceid_bits(&space_bits);
|
||||||
|
/* If this procedure isn't implemented, don't panic. */
|
||||||
|
if (retval < 0 && retval != PDC_BAD_OPTION)
|
||||||
|
panic("pdc_spaceid_bits call failed.\n");
|
||||||
|
if (space_bits != 0)
|
||||||
|
panic("SpaceID hashing is still on!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush_dcache_page(struct page *page)
|
void flush_dcache_page(struct page *page)
|
||||||
|
@ -1638,7 +1638,7 @@ dbit_trap_20w:
|
|||||||
load32 PA(pa_dbit_lock),t0
|
load32 PA(pa_dbit_lock),t0
|
||||||
|
|
||||||
dbit_spin_20w:
|
dbit_spin_20w:
|
||||||
ldcw 0(t0),t1
|
LDCW 0(t0),t1
|
||||||
cmpib,= 0,t1,dbit_spin_20w
|
cmpib,= 0,t1,dbit_spin_20w
|
||||||
nop
|
nop
|
||||||
|
|
||||||
@ -1674,7 +1674,7 @@ dbit_trap_11:
|
|||||||
load32 PA(pa_dbit_lock),t0
|
load32 PA(pa_dbit_lock),t0
|
||||||
|
|
||||||
dbit_spin_11:
|
dbit_spin_11:
|
||||||
ldcw 0(t0),t1
|
LDCW 0(t0),t1
|
||||||
cmpib,= 0,t1,dbit_spin_11
|
cmpib,= 0,t1,dbit_spin_11
|
||||||
nop
|
nop
|
||||||
|
|
||||||
@ -1714,7 +1714,7 @@ dbit_trap_20:
|
|||||||
load32 PA(pa_dbit_lock),t0
|
load32 PA(pa_dbit_lock),t0
|
||||||
|
|
||||||
dbit_spin_20:
|
dbit_spin_20:
|
||||||
ldcw 0(t0),t1
|
LDCW 0(t0),t1
|
||||||
cmpib,= 0,t1,dbit_spin_20
|
cmpib,= 0,t1,dbit_spin_20
|
||||||
nop
|
nop
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
* Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy)
|
* Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy)
|
||||||
* Copyright 2003 Grant Grundler <grundler parisc-linux org>
|
* Copyright 2003 Grant Grundler <grundler parisc-linux org>
|
||||||
* Copyright 2003,2004 Ryan Bradetich <rbrad@parisc-linux.org>
|
* Copyright 2003,2004 Ryan Bradetich <rbrad@parisc-linux.org>
|
||||||
* Copyright 2004 Thibaut VARENE <varenet@parisc-linux.org>
|
* Copyright 2004,2006 Thibaut VARENE <varenet@parisc-linux.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* 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)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pdc_chassis_disp - Updates display
|
* pdc_chassis_disp - Updates chassis code
|
||||||
* @retval: -1 on error, 0 on success
|
* @retval: -1 on error, 0 on success
|
||||||
*
|
|
||||||
* Works on old PDC only (E class, others?)
|
|
||||||
*/
|
*/
|
||||||
int pdc_chassis_disp(unsigned long disp)
|
int pdc_chassis_disp(unsigned long disp)
|
||||||
{
|
{
|
||||||
@ -268,6 +266,22 @@ int pdc_chassis_disp(unsigned long disp)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pdc_chassis_warn - Fetches chassis warnings
|
||||||
|
* @retval: -1 on error, 0 on success
|
||||||
|
*/
|
||||||
|
int pdc_chassis_warn(unsigned long *warn)
|
||||||
|
{
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
|
spin_lock_irq(&pdc_lock);
|
||||||
|
retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_WARN, __pa(pdc_result));
|
||||||
|
*warn = pdc_result[0];
|
||||||
|
spin_unlock_irq(&pdc_lock);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pdc_coproc_cfg - To identify coprocessors attached to the processor.
|
* pdc_coproc_cfg - To identify coprocessors attached to the processor.
|
||||||
* @pdc_coproc_info: Return buffer address.
|
* @pdc_coproc_info: Return buffer address.
|
||||||
@ -393,7 +407,9 @@ int pdc_model_info(struct pdc_model *model)
|
|||||||
* pdc_model_sysmodel - Get the system model name.
|
* pdc_model_sysmodel - Get the system model name.
|
||||||
* @name: A char array of at least 81 characters.
|
* @name: A char array of at least 81 characters.
|
||||||
*
|
*
|
||||||
* Get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L)
|
* Get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L).
|
||||||
|
* Using OS_ID_HPUX will return the equivalent of the 'modelname' command
|
||||||
|
* on HP/UX.
|
||||||
*/
|
*/
|
||||||
int pdc_model_sysmodel(char *name)
|
int pdc_model_sysmodel(char *name)
|
||||||
{
|
{
|
||||||
@ -498,6 +514,26 @@ int pdc_cache_info(struct pdc_cache_info *cache_info)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pdc_spaceid_bits - Return whether Space ID hashing is turned on.
|
||||||
|
* @space_bits: Should be 0, if not, bad mojo!
|
||||||
|
*
|
||||||
|
* Returns information about Space ID hashing.
|
||||||
|
*/
|
||||||
|
int pdc_spaceid_bits(unsigned long *space_bits)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
spin_lock_irq(&pdc_lock);
|
||||||
|
pdc_result[0] = 0;
|
||||||
|
retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_RET_SPID, __pa(pdc_result), 0);
|
||||||
|
convert_to_wide(pdc_result);
|
||||||
|
*space_bits = pdc_result[0];
|
||||||
|
spin_unlock_irq(&pdc_lock);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_PA20
|
#ifndef CONFIG_PA20
|
||||||
/**
|
/**
|
||||||
* pdc_btlb_info - Return block TLB information.
|
* pdc_btlb_info - Return block TLB information.
|
||||||
|
@ -89,6 +89,12 @@ static inline int is_local(struct module *me, void *loc)
|
|||||||
return is_init(me, loc) || is_core(me, loc);
|
return is_init(me, loc) || is_core(me, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int is_local_section(struct module *me, void *loc, void *dot)
|
||||||
|
{
|
||||||
|
return (is_init(me, loc) && is_init(me, dot)) ||
|
||||||
|
(is_core(me, loc) && is_core(me, dot));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef __LP64__
|
#ifndef __LP64__
|
||||||
struct got_entry {
|
struct got_entry {
|
||||||
@ -364,8 +370,14 @@ static Elf_Addr get_fdesc(struct module *me, unsigned long value)
|
|||||||
}
|
}
|
||||||
#endif /* __LP64__ */
|
#endif /* __LP64__ */
|
||||||
|
|
||||||
|
enum elf_stub_type {
|
||||||
|
ELF_STUB_GOT,
|
||||||
|
ELF_STUB_MILLI,
|
||||||
|
ELF_STUB_DIRECT,
|
||||||
|
};
|
||||||
|
|
||||||
static Elf_Addr get_stub(struct module *me, unsigned long value, long addend,
|
static Elf_Addr get_stub(struct module *me, unsigned long value, long addend,
|
||||||
int millicode, int init_section)
|
enum elf_stub_type stub_type, int init_section)
|
||||||
{
|
{
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
struct stub_entry *stub;
|
struct stub_entry *stub;
|
||||||
@ -396,7 +408,7 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend,
|
|||||||
stub->insns[1] |= reassemble_17(rrsel(value, addend) / 4);
|
stub->insns[1] |= reassemble_17(rrsel(value, addend) / 4);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/* for 64-bit we have two kinds of stubs:
|
/* for 64-bit we have three kinds of stubs:
|
||||||
* for normal function calls:
|
* for normal function calls:
|
||||||
* ldd 0(%dp),%dp
|
* ldd 0(%dp),%dp
|
||||||
* ldd 10(%dp), %r1
|
* ldd 10(%dp), %r1
|
||||||
@ -408,18 +420,23 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend,
|
|||||||
* ldo 0(%r1), %r1
|
* ldo 0(%r1), %r1
|
||||||
* ldd 10(%r1), %r1
|
* ldd 10(%r1), %r1
|
||||||
* bve,n (%r1)
|
* bve,n (%r1)
|
||||||
|
*
|
||||||
|
* for direct branches (jumps between different section of the
|
||||||
|
* same module):
|
||||||
|
* ldil 0, %r1
|
||||||
|
* ldo 0(%r1), %r1
|
||||||
|
* bve,n (%r1)
|
||||||
*/
|
*/
|
||||||
if (!millicode)
|
switch (stub_type) {
|
||||||
{
|
case ELF_STUB_GOT:
|
||||||
stub->insns[0] = 0x537b0000; /* ldd 0(%dp),%dp */
|
stub->insns[0] = 0x537b0000; /* ldd 0(%dp),%dp */
|
||||||
stub->insns[1] = 0x53610020; /* ldd 10(%dp),%r1 */
|
stub->insns[1] = 0x53610020; /* ldd 10(%dp),%r1 */
|
||||||
stub->insns[2] = 0xe820d000; /* bve (%r1) */
|
stub->insns[2] = 0xe820d000; /* bve (%r1) */
|
||||||
stub->insns[3] = 0x537b0030; /* ldd 18(%dp),%dp */
|
stub->insns[3] = 0x537b0030; /* ldd 18(%dp),%dp */
|
||||||
|
|
||||||
stub->insns[0] |= reassemble_14(get_got(me, value, addend) & 0x3fff);
|
stub->insns[0] |= reassemble_14(get_got(me, value, addend) & 0x3fff);
|
||||||
}
|
break;
|
||||||
else
|
case ELF_STUB_MILLI:
|
||||||
{
|
|
||||||
stub->insns[0] = 0x20200000; /* ldil 0,%r1 */
|
stub->insns[0] = 0x20200000; /* ldil 0,%r1 */
|
||||||
stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */
|
stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */
|
||||||
stub->insns[2] = 0x50210020; /* ldd 10(%r1),%r1 */
|
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,
|
|||||||
|
|
||||||
stub->insns[0] |= reassemble_21(lrsel(value, addend));
|
stub->insns[0] |= reassemble_21(lrsel(value, addend));
|
||||||
stub->insns[1] |= reassemble_14(rrsel(value, addend));
|
stub->insns[1] |= reassemble_14(rrsel(value, addend));
|
||||||
|
break;
|
||||||
|
case ELF_STUB_DIRECT:
|
||||||
|
stub->insns[0] = 0x20200000; /* ldil 0,%r1 */
|
||||||
|
stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */
|
||||||
|
stub->insns[2] = 0xe820d002; /* bve,n (%r1) */
|
||||||
|
|
||||||
|
stub->insns[0] |= reassemble_21(lrsel(value, addend));
|
||||||
|
stub->insns[1] |= reassemble_14(rrsel(value, addend));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (Elf_Addr)stub;
|
return (Elf_Addr)stub;
|
||||||
@ -539,14 +566,14 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
|
|||||||
break;
|
break;
|
||||||
case R_PARISC_PCREL17F:
|
case R_PARISC_PCREL17F:
|
||||||
/* 17-bit PC relative address */
|
/* 17-bit PC relative address */
|
||||||
val = get_stub(me, val, addend, 0, is_init(me, loc));
|
val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc));
|
||||||
val = (val - dot - 8)/4;
|
val = (val - dot - 8)/4;
|
||||||
CHECK_RELOC(val, 17)
|
CHECK_RELOC(val, 17)
|
||||||
*loc = (*loc & ~0x1f1ffd) | reassemble_17(val);
|
*loc = (*loc & ~0x1f1ffd) | reassemble_17(val);
|
||||||
break;
|
break;
|
||||||
case R_PARISC_PCREL22F:
|
case R_PARISC_PCREL22F:
|
||||||
/* 22-bit PC relative address; only defined for pa20 */
|
/* 22-bit PC relative address; only defined for pa20 */
|
||||||
val = get_stub(me, val, addend, 0, is_init(me, loc));
|
val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc));
|
||||||
DEBUGP("STUB FOR %s loc %lx+%lx at %lx\n",
|
DEBUGP("STUB FOR %s loc %lx+%lx at %lx\n",
|
||||||
strtab + sym->st_name, (unsigned long)loc, addend,
|
strtab + sym->st_name, (unsigned long)loc, addend,
|
||||||
val)
|
val)
|
||||||
@ -643,13 +670,23 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
|
|||||||
strtab + sym->st_name,
|
strtab + sym->st_name,
|
||||||
loc, val);
|
loc, val);
|
||||||
/* can we reach it locally? */
|
/* can we reach it locally? */
|
||||||
if(!is_local(me, (void *)val)) {
|
if(!is_local_section(me, (void *)val, (void *)dot)) {
|
||||||
if (strncmp(strtab + sym->st_name, "$$", 2)
|
|
||||||
|
if (is_local(me, (void *)val))
|
||||||
|
/* this is the case where the
|
||||||
|
* symbol is local to the
|
||||||
|
* module, but in a different
|
||||||
|
* section, so stub the jump
|
||||||
|
* in case it's more than 22
|
||||||
|
* bits away */
|
||||||
|
val = get_stub(me, val, addend, ELF_STUB_DIRECT,
|
||||||
|
is_init(me, loc));
|
||||||
|
else if (strncmp(strtab + sym->st_name, "$$", 2)
|
||||||
== 0)
|
== 0)
|
||||||
val = get_stub(me, val, addend, 1,
|
val = get_stub(me, val, addend, ELF_STUB_MILLI,
|
||||||
is_init(me, loc));
|
is_init(me, loc));
|
||||||
else
|
else
|
||||||
val = get_stub(me, val, addend, 0,
|
val = get_stub(me, val, addend, ELF_STUB_GOT,
|
||||||
is_init(me, loc));
|
is_init(me, loc));
|
||||||
}
|
}
|
||||||
DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n",
|
DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n",
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* interfaces to log Chassis Codes via PDC (firmware)
|
* interfaces to Chassis Codes via PDC (firmware)
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002 Laurent Canet <canetl@esiee.fr>
|
* Copyright (C) 2002 Laurent Canet <canetl@esiee.fr>
|
||||||
* Copyright (C) 2002-2004 Thibaut VARENE <varenet@parisc-linux.org>
|
* Copyright (C) 2002-2006 Thibaut VARENE <varenet@parisc-linux.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2, as
|
* it under the terms of the GNU General Public License, version 2, as
|
||||||
@ -16,6 +16,10 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* TODO: poll chassis warns, trigger (configurable) machine shutdown when
|
||||||
|
* needed.
|
||||||
|
* Find out how to get Chassis warnings out of PAT boxes?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#undef PDC_CHASSIS_DEBUG
|
#undef PDC_CHASSIS_DEBUG
|
||||||
@ -30,15 +34,16 @@
|
|||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
#include <linux/notifier.h>
|
#include <linux/notifier.h>
|
||||||
#include <linux/cache.h>
|
#include <linux/cache.h>
|
||||||
|
#include <linux/proc_fs.h>
|
||||||
|
|
||||||
#include <asm/pdc_chassis.h>
|
#include <asm/pdc_chassis.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/pdc.h>
|
#include <asm/pdc.h>
|
||||||
#include <asm/pdcpat.h>
|
#include <asm/pdcpat.h>
|
||||||
|
|
||||||
|
#define PDC_CHASSIS_VER "0.05"
|
||||||
|
|
||||||
#ifdef CONFIG_PDC_CHASSIS
|
#ifdef CONFIG_PDC_CHASSIS
|
||||||
static int pdc_chassis_old __read_mostly = 0;
|
|
||||||
static unsigned int pdc_chassis_enabled __read_mostly = 1;
|
static unsigned int pdc_chassis_enabled __read_mostly = 1;
|
||||||
|
|
||||||
|
|
||||||
@ -64,7 +69,7 @@ __setup("pdcchassis=", pdc_chassis_setup);
|
|||||||
* Currently, only E class and A180 are known to work with this.
|
* Currently, only E class and A180 are known to work with this.
|
||||||
* Inspired by Christoph Plattner
|
* Inspired by Christoph Plattner
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
static void __init pdc_chassis_checkold(void)
|
static void __init pdc_chassis_checkold(void)
|
||||||
{
|
{
|
||||||
switch(CPU_HVERSION) {
|
switch(CPU_HVERSION) {
|
||||||
@ -73,7 +78,6 @@ static void __init pdc_chassis_checkold(void)
|
|||||||
case 0x482: /* E45 */
|
case 0x482: /* E45 */
|
||||||
case 0x483: /* E55 */
|
case 0x483: /* E55 */
|
||||||
case 0x516: /* A180 */
|
case 0x516: /* A180 */
|
||||||
pdc_chassis_old = 1;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -81,7 +85,7 @@ static void __init pdc_chassis_checkold(void)
|
|||||||
}
|
}
|
||||||
DPRINTK(KERN_DEBUG "%s: pdc_chassis_checkold(); pdc_chassis_old = %d\n", __FILE__, pdc_chassis_old);
|
DPRINTK(KERN_DEBUG "%s: pdc_chassis_checkold(); pdc_chassis_old = %d\n", __FILE__, pdc_chassis_old);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pdc_chassis_panic_event() - Called by the panic handler.
|
* pdc_chassis_panic_event() - Called by the panic handler.
|
||||||
@ -131,30 +135,20 @@ static struct notifier_block pdc_chassis_reboot_block = {
|
|||||||
void __init parisc_pdc_chassis_init(void)
|
void __init parisc_pdc_chassis_init(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_PDC_CHASSIS
|
#ifdef CONFIG_PDC_CHASSIS
|
||||||
int handle = 0;
|
|
||||||
if (likely(pdc_chassis_enabled)) {
|
if (likely(pdc_chassis_enabled)) {
|
||||||
DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__);
|
DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__);
|
||||||
|
|
||||||
/* Let see if we have something to handle... */
|
/* Let see if we have something to handle... */
|
||||||
/* Check for PDC_PAT or old LED Panel */
|
printk(KERN_INFO "Enabling %s chassis codes support v%s\n",
|
||||||
pdc_chassis_checkold();
|
is_pdc_pat() ? "PDC_PAT" : "regular",
|
||||||
if (is_pdc_pat()) {
|
PDC_CHASSIS_VER);
|
||||||
printk(KERN_INFO "Enabling PDC_PAT chassis codes support.\n");
|
|
||||||
handle = 1;
|
|
||||||
}
|
|
||||||
else if (unlikely(pdc_chassis_old)) {
|
|
||||||
printk(KERN_INFO "Enabling old style chassis LED panel support.\n");
|
|
||||||
handle = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handle) {
|
/* initialize panic notifier chain */
|
||||||
/* initialize panic notifier chain */
|
atomic_notifier_chain_register(&panic_notifier_list,
|
||||||
atomic_notifier_chain_register(&panic_notifier_list,
|
&pdc_chassis_panic_block);
|
||||||
&pdc_chassis_panic_block);
|
|
||||||
|
|
||||||
/* initialize reboot notifier chain */
|
/* initialize reboot notifier chain */
|
||||||
register_reboot_notifier(&pdc_chassis_reboot_block);
|
register_reboot_notifier(&pdc_chassis_reboot_block);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PDC_CHASSIS */
|
#endif /* CONFIG_PDC_CHASSIS */
|
||||||
}
|
}
|
||||||
@ -215,9 +209,12 @@ int pdc_chassis_send_status(int message)
|
|||||||
}
|
}
|
||||||
} else retval = -1;
|
} else retval = -1;
|
||||||
#else
|
#else
|
||||||
if (unlikely(pdc_chassis_old)) {
|
if (1) {
|
||||||
switch (message) {
|
switch (message) {
|
||||||
case PDC_CHASSIS_DIRECT_BSTART:
|
case PDC_CHASSIS_DIRECT_BSTART:
|
||||||
|
retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_INIT));
|
||||||
|
break;
|
||||||
|
|
||||||
case PDC_CHASSIS_DIRECT_BCOMPLETE:
|
case PDC_CHASSIS_DIRECT_BCOMPLETE:
|
||||||
retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN));
|
retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN));
|
||||||
break;
|
break;
|
||||||
@ -244,3 +241,61 @@ int pdc_chassis_send_status(int message)
|
|||||||
#endif /* CONFIG_PDC_CHASSIS */
|
#endif /* CONFIG_PDC_CHASSIS */
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PDC_CHASSIS_WARN
|
||||||
|
#ifdef CONFIG_PROC_FS
|
||||||
|
static int pdc_chassis_warn_pread(char *page, char **start, off_t off,
|
||||||
|
int count, int *eof, void *data)
|
||||||
|
{
|
||||||
|
char *out = page;
|
||||||
|
int len, ret;
|
||||||
|
unsigned long warn;
|
||||||
|
u32 warnreg;
|
||||||
|
|
||||||
|
ret = pdc_chassis_warn(&warn);
|
||||||
|
if (ret != PDC_OK)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
warnreg = (warn & 0xFFFFFFFF);
|
||||||
|
|
||||||
|
if ((warnreg >> 24) & 0xFF)
|
||||||
|
out += sprintf(out, "Chassis component failure! (eg fan or PSU): 0x%.2x\n", ((warnreg >> 24) & 0xFF));
|
||||||
|
|
||||||
|
out += sprintf(out, "Battery: %s\n", (warnreg & 0x04) ? "Low!" : "OK");
|
||||||
|
out += sprintf(out, "Temp low: %s\n", (warnreg & 0x02) ? "Exceeded!" : "OK");
|
||||||
|
out += sprintf(out, "Temp mid: %s\n", (warnreg & 0x01) ? "Exceeded!" : "OK");
|
||||||
|
|
||||||
|
len = out - page - off;
|
||||||
|
if (len < count) {
|
||||||
|
*eof = 1;
|
||||||
|
if (len <= 0) return 0;
|
||||||
|
} else {
|
||||||
|
len = count;
|
||||||
|
}
|
||||||
|
*start = page + off;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init pdc_chassis_create_procfs(void)
|
||||||
|
{
|
||||||
|
unsigned long test;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = pdc_chassis_warn(&test);
|
||||||
|
if ((ret == PDC_BAD_PROC) || (ret == PDC_BAD_OPTION)) {
|
||||||
|
/* seems that some boxes (eg L1000) do not implement this */
|
||||||
|
printk(KERN_INFO "Chassis warnings not supported.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printk(KERN_INFO "Enabling PDC chassis warnings support v%s\n",
|
||||||
|
PDC_CHASSIS_VER);
|
||||||
|
create_proc_read_entry("chassis", 0400, NULL, pdc_chassis_warn_pread,
|
||||||
|
NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__initcall(pdc_chassis_create_procfs);
|
||||||
|
|
||||||
|
#endif /* CONFIG_PROC_FS */
|
||||||
|
#endif /* CONFIG_PDC_CHASSIS_WARN */
|
||||||
|
@ -91,7 +91,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
|||||||
int copied;
|
int copied;
|
||||||
|
|
||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
if (personality(child->personality) == PER_LINUX32) {
|
if (__is_compat_task(child)) {
|
||||||
unsigned int tmp;
|
unsigned int tmp;
|
||||||
|
|
||||||
addr &= 0xffffffffL;
|
addr &= 0xffffffffL;
|
||||||
@ -123,7 +123,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
|||||||
case PTRACE_POKEDATA:
|
case PTRACE_POKEDATA:
|
||||||
ret = 0;
|
ret = 0;
|
||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
if (personality(child->personality) == PER_LINUX32) {
|
if (__is_compat_task(child)) {
|
||||||
unsigned int tmp = (unsigned int)data;
|
unsigned int tmp = (unsigned int)data;
|
||||||
DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n",
|
DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n",
|
||||||
request == PTRACE_POKETEXT ? "TEXT" : "DATA",
|
request == PTRACE_POKETEXT ? "TEXT" : "DATA",
|
||||||
@ -146,7 +146,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
|||||||
case PTRACE_PEEKUSR: {
|
case PTRACE_PEEKUSR: {
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
if (personality(child->personality) == PER_LINUX32) {
|
if (__is_compat_task(child)) {
|
||||||
unsigned int tmp;
|
unsigned int tmp;
|
||||||
|
|
||||||
if (addr & (sizeof(int)-1))
|
if (addr & (sizeof(int)-1))
|
||||||
@ -205,7 +205,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
|||||||
goto out_tsk;
|
goto out_tsk;
|
||||||
}
|
}
|
||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
if (personality(child->personality) == PER_LINUX32) {
|
if (__is_compat_task(child)) {
|
||||||
if (addr & (sizeof(int)-1))
|
if (addr & (sizeof(int)-1))
|
||||||
goto out_tsk;
|
goto out_tsk;
|
||||||
if ((addr = translate_usr_offset(addr)) < 0)
|
if ((addr = translate_usr_offset(addr)) < 0)
|
||||||
|
@ -276,15 +276,6 @@ r64_ret:
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
.export pc_in_user_space
|
|
||||||
.text
|
|
||||||
/* Doesn't belong here but I couldn't find a nicer spot. */
|
|
||||||
/* Should never get called, only used by profile stuff in time.c */
|
|
||||||
pc_in_user_space:
|
|
||||||
bv,n 0(%rp)
|
|
||||||
nop
|
|
||||||
|
|
||||||
|
|
||||||
.export __canonicalize_funcptr_for_compare
|
.export __canonicalize_funcptr_for_compare
|
||||||
.text
|
.text
|
||||||
/* http://lists.parisc-linux.org/hypermail/parisc-linux/10916.html
|
/* http://lists.parisc-linux.org/hypermail/parisc-linux/10916.html
|
||||||
|
@ -303,6 +303,8 @@ extern void eisa_init(void);
|
|||||||
|
|
||||||
static int __init parisc_init(void)
|
static int __init parisc_init(void)
|
||||||
{
|
{
|
||||||
|
u32 osid = (OS_ID_LINUX << 16);
|
||||||
|
|
||||||
parisc_proc_mkdir();
|
parisc_proc_mkdir();
|
||||||
parisc_init_resources();
|
parisc_init_resources();
|
||||||
do_device_inventory(); /* probe for hardware */
|
do_device_inventory(); /* probe for hardware */
|
||||||
@ -312,6 +314,9 @@ static int __init parisc_init(void)
|
|||||||
/* set up a new led state on systems shipped LED State panel */
|
/* set up a new led state on systems shipped LED State panel */
|
||||||
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BSTART);
|
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BSTART);
|
||||||
|
|
||||||
|
/* tell PDC we're Linux. Nevermind failure. */
|
||||||
|
pdc_stable_write(0x40, &osid, sizeof(osid));
|
||||||
|
|
||||||
processor_init();
|
processor_init();
|
||||||
printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n",
|
printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n",
|
||||||
boot_cpu_data.cpu_count,
|
boot_cpu_data.cpu_count,
|
||||||
|
@ -76,7 +76,7 @@ sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *r
|
|||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
compat_sigset_t newset32;
|
compat_sigset_t newset32;
|
||||||
|
|
||||||
if(personality(current->personality) == PER_LINUX32){
|
if (is_compat_task()) {
|
||||||
/* XXX: Don't preclude handling different sized sigset_t's. */
|
/* XXX: Don't preclude handling different sized sigset_t's. */
|
||||||
if (sigsetsize != sizeof(compat_sigset_t))
|
if (sigsetsize != sizeof(compat_sigset_t))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -153,7 +153,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
|
|||||||
compat_sigset_t compat_set;
|
compat_sigset_t compat_set;
|
||||||
struct compat_rt_sigframe __user * compat_frame;
|
struct compat_rt_sigframe __user * compat_frame;
|
||||||
|
|
||||||
if(personality(current->personality) == PER_LINUX32)
|
if (is_compat_task())
|
||||||
sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
|
sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -166,7 +166,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
|
|||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
compat_frame = (struct compat_rt_sigframe __user *)frame;
|
compat_frame = (struct compat_rt_sigframe __user *)frame;
|
||||||
|
|
||||||
if(personality(current->personality) == PER_LINUX32){
|
if (is_compat_task()) {
|
||||||
DBG(2,"sys_rt_sigreturn: ELF32 process.\n");
|
DBG(2,"sys_rt_sigreturn: ELF32 process.\n");
|
||||||
if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set)))
|
if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set)))
|
||||||
goto give_sigsegv;
|
goto give_sigsegv;
|
||||||
@ -186,7 +186,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
|
|||||||
|
|
||||||
/* Good thing we saved the old gr[30], eh? */
|
/* Good thing we saved the old gr[30], eh? */
|
||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
if(personality(current->personality) == PER_LINUX32){
|
if (is_compat_task()) {
|
||||||
DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n",
|
DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n",
|
||||||
&compat_frame->uc.uc_mcontext);
|
&compat_frame->uc.uc_mcontext);
|
||||||
// FIXME: Load upper half from register file
|
// FIXME: Load upper half from register file
|
||||||
@ -315,7 +315,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||||||
|
|
||||||
compat_frame = (struct compat_rt_sigframe __user *)frame;
|
compat_frame = (struct compat_rt_sigframe __user *)frame;
|
||||||
|
|
||||||
if(personality(current->personality) == PER_LINUX32) {
|
if (is_compat_task()) {
|
||||||
DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
|
DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
|
||||||
err |= copy_siginfo_to_user32(&compat_frame->info, info);
|
err |= copy_siginfo_to_user32(&compat_frame->info, info);
|
||||||
DBG(1,"SETUP_RT_FRAME: 1\n");
|
DBG(1,"SETUP_RT_FRAME: 1\n");
|
||||||
@ -392,7 +392,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||||||
haddr = A(ka->sa.sa_handler);
|
haddr = A(ka->sa.sa_handler);
|
||||||
/* The sa_handler may be a pointer to a function descriptor */
|
/* The sa_handler may be a pointer to a function descriptor */
|
||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
if(personality(current->personality) == PER_LINUX32) {
|
if (is_compat_task()) {
|
||||||
#endif
|
#endif
|
||||||
if (haddr & PA_PLABEL_FDESC) {
|
if (haddr & PA_PLABEL_FDESC) {
|
||||||
Elf32_Fdesc fdesc;
|
Elf32_Fdesc fdesc;
|
||||||
@ -427,19 +427,19 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||||||
*/
|
*/
|
||||||
sigframe_size = PARISC_RT_SIGFRAME_SIZE;
|
sigframe_size = PARISC_RT_SIGFRAME_SIZE;
|
||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
if(personality(current->personality) == PER_LINUX32)
|
if (is_compat_task())
|
||||||
sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
|
sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
|
||||||
#endif
|
#endif
|
||||||
if (in_syscall) {
|
if (in_syscall) {
|
||||||
regs->gr[31] = haddr;
|
regs->gr[31] = haddr;
|
||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
if(personality(current->personality) == PER_LINUX)
|
if (personality(current->personality) == PER_LINUX)
|
||||||
sigframe_size |= 1;
|
sigframe_size |= 1;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
unsigned long psw = USER_PSW;
|
unsigned long psw = USER_PSW;
|
||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
if(personality(current->personality) == PER_LINUX)
|
if (personality(current->personality) == PER_LINUX)
|
||||||
psw |= PSW_W;
|
psw |= PSW_W;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -464,7 +464,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||||||
regs->gr[26] = sig; /* signal number */
|
regs->gr[26] = sig; /* signal number */
|
||||||
|
|
||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
if(personality(current->personality) == PER_LINUX32){
|
if (is_compat_task()) {
|
||||||
regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */
|
regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */
|
||||||
regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */
|
regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */
|
||||||
} else
|
} else
|
||||||
|
@ -29,18 +29,6 @@
|
|||||||
.level 1.1
|
.level 1.1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_64BIT
|
|
||||||
.macro fixup_branch,lbl
|
|
||||||
b \lbl
|
|
||||||
.endm
|
|
||||||
#else
|
|
||||||
.macro fixup_branch,lbl
|
|
||||||
ldil L%\lbl, %r1
|
|
||||||
ldo R%\lbl(%r1), %r1
|
|
||||||
bv,n %r0(%r1)
|
|
||||||
.endm
|
|
||||||
#endif
|
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
.import syscall_exit,code
|
.import syscall_exit,code
|
||||||
@ -541,7 +529,7 @@ cas_nocontend:
|
|||||||
# endif
|
# endif
|
||||||
/* ENABLE_LWS_DEBUG */
|
/* ENABLE_LWS_DEBUG */
|
||||||
|
|
||||||
ldcw 0(%sr2,%r20), %r28 /* Try to acquire the lock */
|
LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */
|
||||||
cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */
|
cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */
|
||||||
cas_wouldblock:
|
cas_wouldblock:
|
||||||
ldo 2(%r0), %r28 /* 2nd case */
|
ldo 2(%r0), %r28 /* 2nd case */
|
||||||
|
@ -157,8 +157,22 @@ do_gettimeofday (struct timeval *tv)
|
|||||||
usec += (xtime.tv_nsec / 1000);
|
usec += (xtime.tv_nsec / 1000);
|
||||||
} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
|
} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
|
||||||
|
|
||||||
while (usec >= 1000000) {
|
if (unlikely(usec > LONG_MAX)) {
|
||||||
usec -= 1000000;
|
/* This can happen if the gettimeoffset adjustment is
|
||||||
|
* negative and xtime.tv_nsec is smaller than the
|
||||||
|
* adjustment */
|
||||||
|
printk(KERN_ERR "do_gettimeofday() spurious xtime.tv_nsec of %ld\n", usec);
|
||||||
|
usec += USEC_PER_SEC;
|
||||||
|
--sec;
|
||||||
|
/* This should never happen, it means the negative
|
||||||
|
* time adjustment was more than a second, so there's
|
||||||
|
* something seriously wrong */
|
||||||
|
BUG_ON(usec > LONG_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
while (usec >= USEC_PER_SEC) {
|
||||||
|
usec -= USEC_PER_SEC;
|
||||||
++sec;
|
++sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,57 +66,42 @@ int printbinary(char *buf, unsigned long x, int nbits)
|
|||||||
#else
|
#else
|
||||||
#define RFMT "%08lx"
|
#define RFMT "%08lx"
|
||||||
#endif
|
#endif
|
||||||
|
#define FFMT "%016llx" /* fpregs are 64-bit always */
|
||||||
|
|
||||||
void show_regs(struct pt_regs *regs)
|
#define PRINTREGS(lvl,r,f,fmt,x) \
|
||||||
|
printk("%s%s%02d-%02d " fmt " " fmt " " fmt " " fmt "\n", \
|
||||||
|
lvl, f, (x), (x+3), (r)[(x)+0], (r)[(x)+1], \
|
||||||
|
(r)[(x)+2], (r)[(x)+3])
|
||||||
|
|
||||||
|
static void print_gr(char *level, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char buf[128], *p;
|
char buf[64];
|
||||||
char *level;
|
|
||||||
unsigned long cr30;
|
|
||||||
unsigned long cr31;
|
|
||||||
/* carlos says that gcc understands better memory in a struct,
|
|
||||||
* and it makes our life easier with fpregs -- T-Bone */
|
|
||||||
struct { u32 sw[2]; } s;
|
|
||||||
|
|
||||||
level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT;
|
|
||||||
|
|
||||||
printk("%s\n", level); /* don't want to have that pretty register dump messed up */
|
|
||||||
|
|
||||||
|
printk("%s\n", level);
|
||||||
printk("%s YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\n", level);
|
printk("%s YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\n", level);
|
||||||
printbinary(buf, regs->gr[0], 32);
|
printbinary(buf, regs->gr[0], 32);
|
||||||
printk("%sPSW: %s %s\n", level, buf, print_tainted());
|
printk("%sPSW: %s %s\n", level, buf, print_tainted());
|
||||||
|
|
||||||
for (i = 0; i < 32; i += 4) {
|
for (i = 0; i < 32; i += 4)
|
||||||
int j;
|
PRINTREGS(level, regs->gr, "r", RFMT, i);
|
||||||
p = buf;
|
}
|
||||||
p += sprintf(p, "%sr%02d-%02d ", level, i, i + 3);
|
|
||||||
for (j = 0; j < 4; j++) {
|
|
||||||
p += sprintf(p, " " RFMT, (i+j) == 0 ? 0 : regs->gr[i + j]);
|
|
||||||
}
|
|
||||||
printk("%s\n", buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 8; i += 4) {
|
static void print_fr(char *level, struct pt_regs *regs)
|
||||||
int j;
|
{
|
||||||
p = buf;
|
int i;
|
||||||
p += sprintf(p, "%ssr%d-%d ", level, i, i + 3);
|
char buf[64];
|
||||||
for (j = 0; j < 4; j++) {
|
struct { u32 sw[2]; } s;
|
||||||
p += sprintf(p, " " RFMT, regs->sr[i + j]);
|
|
||||||
}
|
|
||||||
printk("%s\n", buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FR are 64bit everywhere. Need to use asm to get the content
|
/* FR are 64bit everywhere. Need to use asm to get the content
|
||||||
* of fpsr/fper1, and we assume that we won't have a FP Identify
|
* of fpsr/fper1, and we assume that we won't have a FP Identify
|
||||||
* in our way, otherwise we're screwed.
|
* in our way, otherwise we're screwed.
|
||||||
* The fldd is used to restore the T-bit if there was one, as the
|
* The fldd is used to restore the T-bit if there was one, as the
|
||||||
* store clears it anyway.
|
* store clears it anyway.
|
||||||
* BTW, PA2.0 book says "thou shall not use fstw on FPSR/FPERs". */
|
* PA2.0 book says "thou shall not use fstw on FPSR/FPERs" - T-Bone */
|
||||||
__asm__ (
|
asm volatile ("fstd %%fr0,0(%1) \n\t"
|
||||||
"fstd %%fr0,0(%1) \n\t"
|
"fldd 0(%1),%%fr0 \n\t"
|
||||||
"fldd 0(%1),%%fr0 \n\t"
|
: "=m" (s) : "r" (&s) : "r0");
|
||||||
: "=m" (s) : "r" (&s) : "%r0"
|
|
||||||
);
|
|
||||||
|
|
||||||
printk("%s\n", level);
|
printk("%s\n", level);
|
||||||
printk("%s VZOUICununcqcqcqcqcqcrmunTDVZOUI\n", level);
|
printk("%s VZOUICununcqcqcqcqcqcrmunTDVZOUI\n", level);
|
||||||
@ -125,14 +110,25 @@ void show_regs(struct pt_regs *regs)
|
|||||||
printk("%sFPER1: %08x\n", level, s.sw[1]);
|
printk("%sFPER1: %08x\n", level, s.sw[1]);
|
||||||
|
|
||||||
/* here we'll print fr0 again, tho it'll be meaningless */
|
/* here we'll print fr0 again, tho it'll be meaningless */
|
||||||
for (i = 0; i < 32; i += 4) {
|
for (i = 0; i < 32; i += 4)
|
||||||
int j;
|
PRINTREGS(level, regs->fr, "fr", FFMT, i);
|
||||||
p = buf;
|
}
|
||||||
p += sprintf(p, "%sfr%02d-%02d ", level, i, i + 3);
|
|
||||||
for (j = 0; j < 4; j++)
|
void show_regs(struct pt_regs *regs)
|
||||||
p += sprintf(p, " %016llx", (i+j) == 0 ? 0 : regs->fr[i+j]);
|
{
|
||||||
printk("%s\n", buf);
|
int i;
|
||||||
}
|
char *level;
|
||||||
|
unsigned long cr30, cr31;
|
||||||
|
|
||||||
|
level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT;
|
||||||
|
|
||||||
|
print_gr(level, regs);
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i += 4)
|
||||||
|
PRINTREGS(level, regs->sr, "sr", RFMT, i);
|
||||||
|
|
||||||
|
if (user_mode(regs))
|
||||||
|
print_fr(level, regs);
|
||||||
|
|
||||||
cr30 = mfctl(30);
|
cr30 = mfctl(30);
|
||||||
cr31 = mfctl(31);
|
cr31 = mfctl(31);
|
||||||
|
@ -43,6 +43,8 @@
|
|||||||
"\tldil L%%" #lbl ", %%r1\n" \
|
"\tldil L%%" #lbl ", %%r1\n" \
|
||||||
"\tldo R%%" #lbl "(%%r1), %%r1\n" \
|
"\tldo R%%" #lbl "(%%r1), %%r1\n" \
|
||||||
"\tbv,n %%r0(%%r1)\n"
|
"\tbv,n %%r0(%%r1)\n"
|
||||||
|
/* If you use FIXUP_BRANCH, then you must list this clobber */
|
||||||
|
#define FIXUP_BRANCH_CLOBBER "r1"
|
||||||
|
|
||||||
/* 1111 1100 0000 0000 0001 0011 1100 0000 */
|
/* 1111 1100 0000 0000 0001 0011 1100 0000 */
|
||||||
#define OPCODE1(a,b,c) ((a)<<26|(b)<<12|(c)<<6)
|
#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)
|
|||||||
" .previous\n"
|
" .previous\n"
|
||||||
: "=r" (val), "=r" (ret)
|
: "=r" (val), "=r" (ret)
|
||||||
: "0" (val), "r" (saddr), "r" (regs->isr)
|
: "0" (val), "r" (saddr), "r" (regs->isr)
|
||||||
: "r20" );
|
: "r20", FIXUP_BRANCH_CLOBBER );
|
||||||
|
|
||||||
DPRINTF("val = 0x" RFMT "\n", val);
|
DPRINTF("val = 0x" RFMT "\n", val);
|
||||||
|
|
||||||
@ -202,7 +204,7 @@ static int emulate_ldw(struct pt_regs *regs, int toreg, int flop)
|
|||||||
" .previous\n"
|
" .previous\n"
|
||||||
: "=r" (val), "=r" (ret)
|
: "=r" (val), "=r" (ret)
|
||||||
: "0" (val), "r" (saddr), "r" (regs->isr)
|
: "0" (val), "r" (saddr), "r" (regs->isr)
|
||||||
: "r19", "r20" );
|
: "r19", "r20", FIXUP_BRANCH_CLOBBER );
|
||||||
|
|
||||||
DPRINTF("val = 0x" RFMT "\n", val);
|
DPRINTF("val = 0x" RFMT "\n", val);
|
||||||
|
|
||||||
@ -253,7 +255,7 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
|
|||||||
" .previous\n"
|
" .previous\n"
|
||||||
: "=r" (val), "=r" (ret)
|
: "=r" (val), "=r" (ret)
|
||||||
: "0" (val), "r" (saddr), "r" (regs->isr)
|
: "0" (val), "r" (saddr), "r" (regs->isr)
|
||||||
: "r19", "r20" );
|
: "r19", "r20", FIXUP_BRANCH_CLOBBER );
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
unsigned long valh=0,vall=0;
|
unsigned long valh=0,vall=0;
|
||||||
@ -287,7 +289,7 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
|
|||||||
" .previous\n"
|
" .previous\n"
|
||||||
: "=r" (valh), "=r" (vall), "=r" (ret)
|
: "=r" (valh), "=r" (vall), "=r" (ret)
|
||||||
: "0" (valh), "1" (vall), "r" (saddr), "r" (regs->isr)
|
: "0" (valh), "1" (vall), "r" (saddr), "r" (regs->isr)
|
||||||
: "r19", "r20" );
|
: "r19", "r20", FIXUP_BRANCH_CLOBBER );
|
||||||
val=((__u64)valh<<32)|(__u64)vall;
|
val=((__u64)valh<<32)|(__u64)vall;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -335,7 +337,7 @@ static int emulate_sth(struct pt_regs *regs, int frreg)
|
|||||||
" .previous\n"
|
" .previous\n"
|
||||||
: "=r" (ret)
|
: "=r" (ret)
|
||||||
: "r" (val), "r" (regs->ior), "r" (regs->isr)
|
: "r" (val), "r" (regs->ior), "r" (regs->isr)
|
||||||
: "r19" );
|
: "r19", FIXUP_BRANCH_CLOBBER );
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -389,7 +391,7 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop)
|
|||||||
" .previous\n"
|
" .previous\n"
|
||||||
: "=r" (ret)
|
: "=r" (ret)
|
||||||
: "r" (val), "r" (regs->ior), "r" (regs->isr)
|
: "r" (val), "r" (regs->ior), "r" (regs->isr)
|
||||||
: "r19", "r20", "r21", "r22", "r1" );
|
: "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -450,7 +452,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
|
|||||||
" .previous\n"
|
" .previous\n"
|
||||||
: "=r" (ret)
|
: "=r" (ret)
|
||||||
: "r" (val), "r" (regs->ior), "r" (regs->isr)
|
: "r" (val), "r" (regs->ior), "r" (regs->isr)
|
||||||
: "r19", "r20", "r21", "r22", "r1" );
|
: "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER );
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
unsigned long valh=(val>>32),vall=(val&0xffffffffl);
|
unsigned long valh=(val>>32),vall=(val&0xffffffffl);
|
||||||
@ -495,7 +497,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
|
|||||||
" .previous\n"
|
" .previous\n"
|
||||||
: "=r" (ret)
|
: "=r" (ret)
|
||||||
: "r" (valh), "r" (vall), "r" (regs->ior), "r" (regs->isr)
|
: "r" (valh), "r" (vall), "r" (regs->ior), "r" (regs->isr)
|
||||||
: "r19", "r20", "r21", "r1" );
|
: "r19", "r20", "r21", "r1", FIXUP_BRANCH_CLOBBER );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -140,18 +140,37 @@ config CHASSIS_LCD_LED
|
|||||||
If unsure, say Y.
|
If unsure, say Y.
|
||||||
|
|
||||||
config PDC_CHASSIS
|
config PDC_CHASSIS
|
||||||
bool "PDC chassis State Panel support"
|
bool "PDC chassis state codes support"
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
Say Y here if you want to enable support for the LED State front
|
Say Y here if you want to enable support for Chassis codes.
|
||||||
panel as found on E class, and support for the GSP Virtual Front
|
That includes support for LED State front panel as found on E
|
||||||
Panel (LED State and message logging) as found on high end
|
class, and support for the GSP Virtual Front Panel (LED State and
|
||||||
servers such as A, L and N-class.
|
message logging) as found on high end servers such as A, L and
|
||||||
|
N-class.
|
||||||
This has nothing to do with Chassis LCD and LED support.
|
This driver will also display progress messages on LCD display,
|
||||||
|
such as "INI", "RUN" and "FLT", and might thus clobber messages
|
||||||
|
shown by the LED/LCD driver.
|
||||||
|
This driver updates the state panel (LED and/or LCD) upon system
|
||||||
|
state change (eg: boot, shutdown or panic).
|
||||||
|
|
||||||
If unsure, say Y.
|
If unsure, say Y.
|
||||||
|
|
||||||
|
|
||||||
|
config PDC_CHASSIS_WARN
|
||||||
|
bool "PDC chassis warnings support"
|
||||||
|
depends on PROC_FS
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Say Y here if you want to enable support for Chassis warnings.
|
||||||
|
This will add a proc entry '/proc/chassis' giving some information
|
||||||
|
about the overall health state of the system.
|
||||||
|
This includes NVRAM battery level, overtemp or failures such as
|
||||||
|
fans or power units.
|
||||||
|
|
||||||
|
If unsure, say Y.
|
||||||
|
|
||||||
|
|
||||||
config PDC_STABLE
|
config PDC_STABLE
|
||||||
tristate "PDC Stable Storage support"
|
tristate "PDC Stable Storage support"
|
||||||
depends on SYSFS
|
depends on SYSFS
|
||||||
|
@ -28,8 +28,15 @@
|
|||||||
* following code can deal with just 96 bytes of Stable Storage, and all
|
* following code can deal with just 96 bytes of Stable Storage, and all
|
||||||
* sizes between 96 and 192 bytes (provided they are multiple of struct
|
* sizes between 96 and 192 bytes (provided they are multiple of struct
|
||||||
* device_path size, eg: 128, 160 and 192) to provide full information.
|
* device_path size, eg: 128, 160 and 192) to provide full information.
|
||||||
* The code makes no use of data above 192 bytes. One last word: there's one
|
* One last word: there's one path we can always count on: the primary path.
|
||||||
* path we can always count on: the primary path.
|
* Anything above 224 bytes is used for 'osdep2' OS-dependent storage area.
|
||||||
|
*
|
||||||
|
* The first OS-dependent area should always be available. Obviously, this is
|
||||||
|
* not true for the other one. Also bear in mind that reading/writing from/to
|
||||||
|
* osdep2 is much more expensive than from/to osdep1.
|
||||||
|
* NOTE: We do not handle the 2 bytes OS-dep area at 0x5D, nor the first
|
||||||
|
* 2 bytes of storage available right after OSID. That's a total of 4 bytes
|
||||||
|
* sacrificed: -ETOOLAZY :P
|
||||||
*
|
*
|
||||||
* The current policy wrt file permissions is:
|
* The current policy wrt file permissions is:
|
||||||
* - write: root only
|
* - write: root only
|
||||||
@ -64,15 +71,18 @@
|
|||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/hardware.h>
|
#include <asm/hardware.h>
|
||||||
|
|
||||||
#define PDCS_VERSION "0.22"
|
#define PDCS_VERSION "0.30"
|
||||||
#define PDCS_PREFIX "PDC Stable Storage"
|
#define PDCS_PREFIX "PDC Stable Storage"
|
||||||
|
|
||||||
#define PDCS_ADDR_PPRI 0x00
|
#define PDCS_ADDR_PPRI 0x00
|
||||||
#define PDCS_ADDR_OSID 0x40
|
#define PDCS_ADDR_OSID 0x40
|
||||||
|
#define PDCS_ADDR_OSD1 0x48
|
||||||
|
#define PDCS_ADDR_DIAG 0x58
|
||||||
#define PDCS_ADDR_FSIZ 0x5C
|
#define PDCS_ADDR_FSIZ 0x5C
|
||||||
#define PDCS_ADDR_PCON 0x60
|
#define PDCS_ADDR_PCON 0x60
|
||||||
#define PDCS_ADDR_PALT 0x80
|
#define PDCS_ADDR_PALT 0x80
|
||||||
#define PDCS_ADDR_PKBD 0xA0
|
#define PDCS_ADDR_PKBD 0xA0
|
||||||
|
#define PDCS_ADDR_OSD2 0xE0
|
||||||
|
|
||||||
MODULE_AUTHOR("Thibaut VARENE <varenet@parisc-linux.org>");
|
MODULE_AUTHOR("Thibaut VARENE <varenet@parisc-linux.org>");
|
||||||
MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data");
|
MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data");
|
||||||
@ -82,6 +92,9 @@ MODULE_VERSION(PDCS_VERSION);
|
|||||||
/* holds Stable Storage size. Initialized once and for all, no lock needed */
|
/* holds Stable Storage size. Initialized once and for all, no lock needed */
|
||||||
static unsigned long pdcs_size __read_mostly;
|
static unsigned long pdcs_size __read_mostly;
|
||||||
|
|
||||||
|
/* holds OS ID. Initialized once and for all, hopefully to 0x0006 */
|
||||||
|
static u16 pdcs_osid __read_mostly;
|
||||||
|
|
||||||
/* This struct defines what we need to deal with a parisc pdc path entry */
|
/* This struct defines what we need to deal with a parisc pdc path entry */
|
||||||
struct pdcspath_entry {
|
struct pdcspath_entry {
|
||||||
rwlock_t rw_lock; /* to protect path entry access */
|
rwlock_t rw_lock; /* to protect path entry access */
|
||||||
@ -609,27 +622,64 @@ static ssize_t
|
|||||||
pdcs_osid_read(struct subsystem *entry, char *buf)
|
pdcs_osid_read(struct subsystem *entry, char *buf)
|
||||||
{
|
{
|
||||||
char *out = buf;
|
char *out = buf;
|
||||||
__u32 result;
|
|
||||||
char *tmpstr = NULL;
|
|
||||||
|
|
||||||
if (!entry || !buf)
|
if (!entry || !buf)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* get OSID */
|
out += sprintf(out, "%s dependent data (0x%.4x)\n",
|
||||||
if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK)
|
os_id_to_string(pdcs_osid), pdcs_osid);
|
||||||
|
|
||||||
|
return out - buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pdcs_osdep1_read - Stable Storage OS-Dependent data area 1 output.
|
||||||
|
* @entry: An allocated and populated subsytem struct. We don't use it tho.
|
||||||
|
* @buf: The output buffer to write to.
|
||||||
|
*
|
||||||
|
* This can hold 16 bytes of OS-Dependent data.
|
||||||
|
*/
|
||||||
|
static ssize_t
|
||||||
|
pdcs_osdep1_read(struct subsystem *entry, char *buf)
|
||||||
|
{
|
||||||
|
char *out = buf;
|
||||||
|
u32 result[4];
|
||||||
|
|
||||||
|
if (!entry || !buf)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (pdc_stable_read(PDCS_ADDR_OSD1, &result, sizeof(result)) != PDC_OK)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
/* the actual result is 16 bits away */
|
out += sprintf(out, "0x%.8x\n", result[0]);
|
||||||
switch (result >> 16) {
|
out += sprintf(out, "0x%.8x\n", result[1]);
|
||||||
case 0x0000: tmpstr = "No OS-dependent data"; break;
|
out += sprintf(out, "0x%.8x\n", result[2]);
|
||||||
case 0x0001: tmpstr = "HP-UX dependent data"; break;
|
out += sprintf(out, "0x%.8x\n", result[3]);
|
||||||
case 0x0002: tmpstr = "MPE-iX dependent data"; break;
|
|
||||||
case 0x0003: tmpstr = "OSF dependent data"; break;
|
return out - buf;
|
||||||
case 0x0004: tmpstr = "HP-RT dependent data"; break;
|
}
|
||||||
case 0x0005: tmpstr = "Novell Netware dependent data"; break;
|
|
||||||
default: tmpstr = "Unknown"; break;
|
/**
|
||||||
}
|
* pdcs_diagnostic_read - Stable Storage Diagnostic register output.
|
||||||
out += sprintf(out, "%s (0x%.4x)\n", tmpstr, (result >> 16));
|
* @entry: An allocated and populated subsytem struct. We don't use it tho.
|
||||||
|
* @buf: The output buffer to write to.
|
||||||
|
*
|
||||||
|
* I have NFC how to interpret the content of that register ;-).
|
||||||
|
*/
|
||||||
|
static ssize_t
|
||||||
|
pdcs_diagnostic_read(struct subsystem *entry, char *buf)
|
||||||
|
{
|
||||||
|
char *out = buf;
|
||||||
|
u32 result;
|
||||||
|
|
||||||
|
if (!entry || !buf)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* get diagnostic */
|
||||||
|
if (pdc_stable_read(PDCS_ADDR_DIAG, &result, sizeof(result)) != PDC_OK)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
out += sprintf(out, "0x%.4x\n", (result >> 16));
|
||||||
|
|
||||||
return out - buf;
|
return out - buf;
|
||||||
}
|
}
|
||||||
@ -645,7 +695,7 @@ static ssize_t
|
|||||||
pdcs_fastsize_read(struct subsystem *entry, char *buf)
|
pdcs_fastsize_read(struct subsystem *entry, char *buf)
|
||||||
{
|
{
|
||||||
char *out = buf;
|
char *out = buf;
|
||||||
__u32 result;
|
u32 result;
|
||||||
|
|
||||||
if (!entry || !buf)
|
if (!entry || !buf)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -663,6 +713,39 @@ pdcs_fastsize_read(struct subsystem *entry, char *buf)
|
|||||||
return out - buf;
|
return out - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pdcs_osdep2_read - Stable Storage OS-Dependent data area 2 output.
|
||||||
|
* @entry: An allocated and populated subsytem struct. We don't use it tho.
|
||||||
|
* @buf: The output buffer to write to.
|
||||||
|
*
|
||||||
|
* This can hold pdcs_size - 224 bytes of OS-Dependent data, when available.
|
||||||
|
*/
|
||||||
|
static ssize_t
|
||||||
|
pdcs_osdep2_read(struct subsystem *entry, char *buf)
|
||||||
|
{
|
||||||
|
char *out = buf;
|
||||||
|
unsigned long size;
|
||||||
|
unsigned short i;
|
||||||
|
u32 result;
|
||||||
|
|
||||||
|
if (unlikely(pdcs_size <= 224))
|
||||||
|
return -ENODATA;
|
||||||
|
|
||||||
|
size = pdcs_size - 224;
|
||||||
|
|
||||||
|
if (!entry || !buf)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
for (i=0; i<size; i+=4) {
|
||||||
|
if (unlikely(pdc_stable_read(PDCS_ADDR_OSD2 + i, &result,
|
||||||
|
sizeof(result)) != PDC_OK))
|
||||||
|
return -EIO;
|
||||||
|
out += sprintf(out, "0x%.8x\n", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out - buf;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pdcs_auto_write - This function handles autoboot/search flag modifying.
|
* pdcs_auto_write - This function handles autoboot/search flag modifying.
|
||||||
* @entry: An allocated and populated subsytem struct. We don't use it tho.
|
* @entry: An allocated and populated subsytem struct. We don't use it tho.
|
||||||
@ -770,13 +853,100 @@ pdcs_autosearch_write(struct subsystem *entry, const char *buf, size_t count)
|
|||||||
return pdcs_auto_write(entry, buf, count, PF_AUTOSEARCH);
|
return pdcs_auto_write(entry, buf, count, PF_AUTOSEARCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pdcs_osdep1_write - Stable Storage OS-Dependent data area 1 input.
|
||||||
|
* @entry: An allocated and populated subsytem struct. We don't use it tho.
|
||||||
|
* @buf: The input buffer to read from.
|
||||||
|
* @count: The number of bytes to be read.
|
||||||
|
*
|
||||||
|
* This can store 16 bytes of OS-Dependent data. We use a byte-by-byte
|
||||||
|
* write approach. It's up to userspace to deal with it when constructing
|
||||||
|
* its input buffer.
|
||||||
|
*/
|
||||||
|
static ssize_t
|
||||||
|
pdcs_osdep1_write(struct subsystem *entry, const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
u8 in[16];
|
||||||
|
|
||||||
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
|
return -EACCES;
|
||||||
|
|
||||||
|
if (!entry || !buf || !count)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (unlikely(pdcs_osid != OS_ID_LINUX))
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
if (count > 16)
|
||||||
|
return -EMSGSIZE;
|
||||||
|
|
||||||
|
/* We'll use a local copy of buf */
|
||||||
|
memset(in, 0, 16);
|
||||||
|
memcpy(in, buf, count);
|
||||||
|
|
||||||
|
if (pdc_stable_write(PDCS_ADDR_OSD1, &in, sizeof(in)) != PDC_OK)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pdcs_osdep2_write - Stable Storage OS-Dependent data area 2 input.
|
||||||
|
* @entry: An allocated and populated subsytem struct. We don't use it tho.
|
||||||
|
* @buf: The input buffer to read from.
|
||||||
|
* @count: The number of bytes to be read.
|
||||||
|
*
|
||||||
|
* This can store pdcs_size - 224 bytes of OS-Dependent data. We use a
|
||||||
|
* byte-by-byte write approach. It's up to userspace to deal with it when
|
||||||
|
* constructing its input buffer.
|
||||||
|
*/
|
||||||
|
static ssize_t
|
||||||
|
pdcs_osdep2_write(struct subsystem *entry, const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
unsigned long size;
|
||||||
|
unsigned short i;
|
||||||
|
u8 in[4];
|
||||||
|
|
||||||
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
|
return -EACCES;
|
||||||
|
|
||||||
|
if (!entry || !buf || !count)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (unlikely(pdcs_size <= 224))
|
||||||
|
return -ENOSYS;
|
||||||
|
|
||||||
|
if (unlikely(pdcs_osid != OS_ID_LINUX))
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
size = pdcs_size - 224;
|
||||||
|
|
||||||
|
if (count > size)
|
||||||
|
return -EMSGSIZE;
|
||||||
|
|
||||||
|
/* We'll use a local copy of buf */
|
||||||
|
|
||||||
|
for (i=0; i<count; i+=4) {
|
||||||
|
memset(in, 0, 4);
|
||||||
|
memcpy(in, buf+i, (count-i < 4) ? count-i : 4);
|
||||||
|
if (unlikely(pdc_stable_write(PDCS_ADDR_OSD2 + i, &in,
|
||||||
|
sizeof(in)) != PDC_OK))
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
/* The remaining attributes. */
|
/* The remaining attributes. */
|
||||||
static PDCS_ATTR(size, 0444, pdcs_size_read, NULL);
|
static PDCS_ATTR(size, 0444, pdcs_size_read, NULL);
|
||||||
static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write);
|
static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write);
|
||||||
static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write);
|
static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write);
|
||||||
static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL);
|
static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL);
|
||||||
static PDCS_ATTR(osid, 0400, pdcs_osid_read, NULL);
|
static PDCS_ATTR(osid, 0444, pdcs_osid_read, NULL);
|
||||||
|
static PDCS_ATTR(osdep1, 0600, pdcs_osdep1_read, pdcs_osdep1_write);
|
||||||
|
static PDCS_ATTR(diagnostic, 0400, pdcs_diagnostic_read, NULL);
|
||||||
static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL);
|
static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL);
|
||||||
|
static PDCS_ATTR(osdep2, 0600, pdcs_osdep2_read, pdcs_osdep2_write);
|
||||||
|
|
||||||
static struct subsys_attribute *pdcs_subsys_attrs[] = {
|
static struct subsys_attribute *pdcs_subsys_attrs[] = {
|
||||||
&pdcs_attr_size,
|
&pdcs_attr_size,
|
||||||
@ -784,7 +954,10 @@ static struct subsys_attribute *pdcs_subsys_attrs[] = {
|
|||||||
&pdcs_attr_autosearch,
|
&pdcs_attr_autosearch,
|
||||||
&pdcs_attr_timer,
|
&pdcs_attr_timer,
|
||||||
&pdcs_attr_osid,
|
&pdcs_attr_osid,
|
||||||
|
&pdcs_attr_osdep1,
|
||||||
|
&pdcs_attr_diagnostic,
|
||||||
&pdcs_attr_fastsize,
|
&pdcs_attr_fastsize,
|
||||||
|
&pdcs_attr_osdep2,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -865,6 +1038,7 @@ pdc_stable_init(void)
|
|||||||
{
|
{
|
||||||
struct subsys_attribute *attr;
|
struct subsys_attribute *attr;
|
||||||
int i, rc = 0, error = 0;
|
int i, rc = 0, error = 0;
|
||||||
|
u32 result;
|
||||||
|
|
||||||
/* find the size of the stable storage */
|
/* find the size of the stable storage */
|
||||||
if (pdc_stable_get_size(&pdcs_size) != PDC_OK)
|
if (pdc_stable_get_size(&pdcs_size) != PDC_OK)
|
||||||
@ -876,6 +1050,13 @@ pdc_stable_init(void)
|
|||||||
|
|
||||||
printk(KERN_INFO PDCS_PREFIX " facility v%s\n", PDCS_VERSION);
|
printk(KERN_INFO PDCS_PREFIX " facility v%s\n", PDCS_VERSION);
|
||||||
|
|
||||||
|
/* get OSID */
|
||||||
|
if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
/* the actual result is 16 bits away */
|
||||||
|
pdcs_osid = (u16)(result >> 16);
|
||||||
|
|
||||||
/* For now we'll register the stable subsys within this driver */
|
/* For now we'll register the stable subsys within this driver */
|
||||||
if ((rc = firmware_register(&stable_subsys)))
|
if ((rc = firmware_register(&stable_subsys)))
|
||||||
goto fail_firmreg;
|
goto fail_firmreg;
|
||||||
@ -887,7 +1068,7 @@ pdc_stable_init(void)
|
|||||||
|
|
||||||
/* register the paths subsys as a subsystem of stable subsys */
|
/* register the paths subsys as a subsystem of stable subsys */
|
||||||
kset_set_kset_s(&paths_subsys, stable_subsys);
|
kset_set_kset_s(&paths_subsys, stable_subsys);
|
||||||
if ((rc= subsystem_register(&paths_subsys)))
|
if ((rc = subsystem_register(&paths_subsys)))
|
||||||
goto fail_subsysreg;
|
goto fail_subsysreg;
|
||||||
|
|
||||||
/* now we create all "files" for the paths subsys */
|
/* now we create all "files" for the paths subsys */
|
||||||
|
@ -316,10 +316,10 @@ static int reserve_sba_gart = 1;
|
|||||||
**
|
**
|
||||||
** Superdome (in particular, REO) allows only 64-bit CSR accesses.
|
** Superdome (in particular, REO) allows only 64-bit CSR accesses.
|
||||||
*/
|
*/
|
||||||
#define READ_REG32(addr) le32_to_cpu(__raw_readl(addr))
|
#define READ_REG32(addr) readl(addr)
|
||||||
#define READ_REG64(addr) le64_to_cpu(__raw_readq(addr))
|
#define READ_REG64(addr) readq(addr)
|
||||||
#define WRITE_REG32(val, addr) __raw_writel(cpu_to_le32(val), addr)
|
#define WRITE_REG32(val, addr) writel((val), (addr))
|
||||||
#define WRITE_REG64(val, addr) __raw_writeq(cpu_to_le64(val), addr)
|
#define WRITE_REG64(val, addr) writeq((val), (addr))
|
||||||
|
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
#define READ_REG(addr) READ_REG64(addr)
|
#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)
|
|||||||
iov_order = get_order(iova_space_size >> (IOVP_SHIFT - PAGE_SHIFT));
|
iov_order = get_order(iova_space_size >> (IOVP_SHIFT - PAGE_SHIFT));
|
||||||
ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64);
|
ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64);
|
||||||
|
|
||||||
DBG_INIT("%s() hpa 0x%lx IOV %dMB (%d bits)\n",
|
DBG_INIT("%s() hpa 0x%p IOV %dMB (%d bits)\n",
|
||||||
__FUNCTION__, ioc->ioc_hpa, iova_space_size >> 20,
|
__FUNCTION__, ioc->ioc_hpa, iova_space_size >> 20,
|
||||||
iov_order + PAGE_SHIFT);
|
iov_order + PAGE_SHIFT);
|
||||||
|
|
||||||
@ -1764,7 +1764,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
|
|||||||
|
|
||||||
sba_dev->num_ioc = num_ioc;
|
sba_dev->num_ioc = num_ioc;
|
||||||
for (i = 0; i < num_ioc; i++) {
|
for (i = 0; i < num_ioc; i++) {
|
||||||
unsigned long ioc_hpa = sba_dev->ioc[i].ioc_hpa;
|
void __iomem *ioc_hpa = sba_dev->ioc[i].ioc_hpa;
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
|
|
||||||
for (j=0; j < sizeof(u64) * ROPES_PER_IOC; j+=sizeof(u64)) {
|
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,
|
|||||||
* Improves netperf UDP_STREAM by ~10% for bcm5701.
|
* Improves netperf UDP_STREAM by ~10% for bcm5701.
|
||||||
*/
|
*/
|
||||||
if (IS_PLUTO(sba_dev->iodc)) {
|
if (IS_PLUTO(sba_dev->iodc)) {
|
||||||
unsigned long rope_cfg, cfg_val;
|
void __iomem *rope_cfg;
|
||||||
|
unsigned long cfg_val;
|
||||||
|
|
||||||
rope_cfg = ioc_hpa + IOC_ROPE0_CFG + j;
|
rope_cfg = ioc_hpa + IOC_ROPE0_CFG + j;
|
||||||
cfg_val = READ_REG(rope_cfg);
|
cfg_val = READ_REG(rope_cfg);
|
||||||
@ -1902,7 +1903,7 @@ sba_common_init(struct sba_device *sba_dev)
|
|||||||
* (bit #61, big endian), we have to flush and sync every time
|
* (bit #61, big endian), we have to flush and sync every time
|
||||||
* IO-PDIR is changed in Ike/Astro.
|
* IO-PDIR is changed in Ike/Astro.
|
||||||
*/
|
*/
|
||||||
if (boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC) {
|
if (ioc_needs_fdc) {
|
||||||
printk(KERN_INFO MODULE_NAME " FDC/SYNC required.\n");
|
printk(KERN_INFO MODULE_NAME " FDC/SYNC required.\n");
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_INFO MODULE_NAME " IOC has cache coherent PDIR.\n");
|
printk(KERN_INFO MODULE_NAME " IOC has cache coherent PDIR.\n");
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE)
|
#define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE)
|
||||||
|
|
||||||
#ifdef CONFIG_PA20
|
#ifdef CONFIG_PA20
|
||||||
|
#define LDCW ldcw,co
|
||||||
#define BL b,l
|
#define BL b,l
|
||||||
# ifdef CONFIG_64BIT
|
# ifdef CONFIG_64BIT
|
||||||
# define LEVEL 2.0w
|
# define LEVEL 2.0w
|
||||||
@ -55,6 +56,7 @@
|
|||||||
# define LEVEL 2.0
|
# define LEVEL 2.0
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
|
#define LDCW ldcw
|
||||||
#define BL bl
|
#define BL bl
|
||||||
#define LEVEL 1.1
|
#define LEVEL 1.1
|
||||||
#endif
|
#endif
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
#include <linux/personality.h>
|
||||||
|
|
||||||
#define COMPAT_USER_HZ 100
|
#define COMPAT_USER_HZ 100
|
||||||
|
|
||||||
@ -149,4 +150,14 @@ static __inline__ void __user *compat_alloc_user_space(long len)
|
|||||||
return (void __user *)regs->gr[30];
|
return (void __user *)regs->gr[30];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int __is_compat_task(struct task_struct *t)
|
||||||
|
{
|
||||||
|
return personality(t->personality) == PER_LINUX32;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int is_compat_task(void)
|
||||||
|
{
|
||||||
|
return __is_compat_task(current);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _ASM_PARISC_COMPAT_H */
|
#endif /* _ASM_PARISC_COMPAT_H */
|
||||||
|
@ -278,12 +278,11 @@ typedef struct {
|
|||||||
/* constants for OS (NVM...) */
|
/* constants for OS (NVM...) */
|
||||||
#define OS_ID_NONE 0 /* Undefined OS ID */
|
#define OS_ID_NONE 0 /* Undefined OS ID */
|
||||||
#define OS_ID_HPUX 1 /* HP-UX OS */
|
#define OS_ID_HPUX 1 /* HP-UX OS */
|
||||||
#define OS_ID_LINUX OS_ID_HPUX /* just use the same value as hpux */
|
|
||||||
#define OS_ID_MPEXL 2 /* MPE XL OS */
|
#define OS_ID_MPEXL 2 /* MPE XL OS */
|
||||||
#define OS_ID_OSF 3 /* OSF OS */
|
#define OS_ID_OSF 3 /* OSF OS */
|
||||||
#define OS_ID_HPRT 4 /* HP-RT OS */
|
#define OS_ID_HPRT 4 /* HP-RT OS */
|
||||||
#define OS_ID_NOVEL 5 /* NOVELL OS */
|
#define OS_ID_NOVEL 5 /* NOVELL OS */
|
||||||
#define OS_ID_NT 6 /* NT OS */
|
#define OS_ID_LINUX 6 /* Linux */
|
||||||
|
|
||||||
|
|
||||||
/* constants for PDC_CHASSIS */
|
/* constants for PDC_CHASSIS */
|
||||||
@ -352,8 +351,8 @@ struct pdc_cache_cf { /* for PDC_CACHE (I/D-caches) */
|
|||||||
cc_wt : 1, /* 0 = WT-Dcache, 1 = WB-Dcache */
|
cc_wt : 1, /* 0 = WT-Dcache, 1 = WB-Dcache */
|
||||||
cc_sh : 2, /* 0 = separate I/D-cache, else shared I/D-cache */
|
cc_sh : 2, /* 0 = separate I/D-cache, else shared I/D-cache */
|
||||||
cc_cst : 3, /* 0 = incoherent D-cache, 1=coherent D-cache */
|
cc_cst : 3, /* 0 = incoherent D-cache, 1=coherent D-cache */
|
||||||
cc_pad1 : 5, /* reserved */
|
cc_pad1 : 10, /* reserved */
|
||||||
cc_assoc: 8; /* associativity of I/D-cache */
|
cc_hv : 3; /* hversion dependent */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pdc_tlb_cf { /* for PDC_CACHE (I/D-TLB's) */
|
struct pdc_tlb_cf { /* for PDC_CACHE (I/D-TLB's) */
|
||||||
@ -719,6 +718,7 @@ void setup_pdc(void); /* in inventory.c */
|
|||||||
int pdc_add_valid(unsigned long address);
|
int pdc_add_valid(unsigned long address);
|
||||||
int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len);
|
int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len);
|
||||||
int pdc_chassis_disp(unsigned long disp);
|
int pdc_chassis_disp(unsigned long disp);
|
||||||
|
int pdc_chassis_warn(unsigned long *warn);
|
||||||
int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info);
|
int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info);
|
||||||
int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index,
|
int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index,
|
||||||
void *iodc_data, unsigned int iodc_data_size);
|
void *iodc_data, unsigned int iodc_data_size);
|
||||||
@ -732,6 +732,7 @@ int pdc_model_cpuid(unsigned long *cpu_id);
|
|||||||
int pdc_model_versions(unsigned long *versions, int id);
|
int pdc_model_versions(unsigned long *versions, int id);
|
||||||
int pdc_model_capabilities(unsigned long *capabilities);
|
int pdc_model_capabilities(unsigned long *capabilities);
|
||||||
int pdc_cache_info(struct pdc_cache_info *cache);
|
int pdc_cache_info(struct pdc_cache_info *cache);
|
||||||
|
int pdc_spaceid_bits(unsigned long *space_bits);
|
||||||
#ifndef CONFIG_PA20
|
#ifndef CONFIG_PA20
|
||||||
int pdc_btlb_info(struct pdc_btlb_info *btlb);
|
int pdc_btlb_info(struct pdc_btlb_info *btlb);
|
||||||
int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path);
|
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,
|
|||||||
|
|
||||||
extern void pdc_init(void);
|
extern void pdc_init(void);
|
||||||
|
|
||||||
|
static inline char * os_id_to_string(u16 os_id) {
|
||||||
|
switch(os_id) {
|
||||||
|
case OS_ID_NONE: return "No OS";
|
||||||
|
case OS_ID_HPUX: return "HP-UX";
|
||||||
|
case OS_ID_MPEXL: return "MPE-iX";
|
||||||
|
case OS_ID_OSF: return "OSF";
|
||||||
|
case OS_ID_HPRT: return "HP-RT";
|
||||||
|
case OS_ID_NOVEL: return "Novell Netware";
|
||||||
|
case OS_ID_LINUX: return "Linux";
|
||||||
|
default: return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#endif /* _PARISC_PDC_H */
|
#endif /* _PARISC_PDC_H */
|
||||||
|
@ -506,13 +506,13 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
|
|||||||
|
|
||||||
/* TLB page size encoding - see table 3-1 in parisc20.pdf */
|
/* TLB page size encoding - see table 3-1 in parisc20.pdf */
|
||||||
#define _PAGE_SIZE_ENCODING_4K 0
|
#define _PAGE_SIZE_ENCODING_4K 0
|
||||||
#define _PAGE_SIZE_ENCODING_16K 1
|
#define _PAGE_SIZE_ENCODING_16K 1
|
||||||
#define _PAGE_SIZE_ENCODING_64K 2
|
#define _PAGE_SIZE_ENCODING_64K 2
|
||||||
#define _PAGE_SIZE_ENCODING_256K 3
|
#define _PAGE_SIZE_ENCODING_256K 3
|
||||||
#define _PAGE_SIZE_ENCODING_1M 4
|
#define _PAGE_SIZE_ENCODING_1M 4
|
||||||
#define _PAGE_SIZE_ENCODING_4M 5
|
#define _PAGE_SIZE_ENCODING_4M 5
|
||||||
#define _PAGE_SIZE_ENCODING_16M 6
|
#define _PAGE_SIZE_ENCODING_16M 6
|
||||||
#define _PAGE_SIZE_ENCODING_64M 7
|
#define _PAGE_SIZE_ENCODING_64M 7
|
||||||
|
|
||||||
#if defined(CONFIG_PARISC_PAGE_SIZE_4KB)
|
#if defined(CONFIG_PARISC_PAGE_SIZE_4KB)
|
||||||
# define _PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_4K
|
# define _PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_4K
|
||||||
|
@ -26,14 +26,12 @@
|
|||||||
* Default implementation of macro that returns current
|
* Default implementation of macro that returns current
|
||||||
* instruction pointer ("program counter").
|
* instruction pointer ("program counter").
|
||||||
*/
|
*/
|
||||||
|
#ifdef CONFIG_PA20
|
||||||
/* We cannot use MFIA as it was added for PA2.0 - prumpf
|
#define current_ia(x) __asm__("mfia %0" : "=r"(x))
|
||||||
|
#else /* mfia added in pa2.0 */
|
||||||
At one point there were no "0f/0b" type local symbols in gas for
|
#define current_ia(x) __asm__("blr 0,%0\n\tnop" : "=r"(x))
|
||||||
PA-RISC. This is no longer true, but this still seems like the
|
#endif
|
||||||
nicest way to implement this. */
|
#define current_text_addr() ({ void *pc; current_ia(pc); pc; })
|
||||||
|
|
||||||
#define current_text_addr() ({ void *pc; __asm__("\n\tblr 0,%0\n\tnop":"=r" (pc)); pc; })
|
|
||||||
|
|
||||||
#define TASK_SIZE (current->thread.task_size)
|
#define TASK_SIZE (current->thread.task_size)
|
||||||
#define TASK_UNMAPPED_BASE (current->thread.map_base)
|
#define TASK_UNMAPPED_BASE (current->thread.map_base)
|
||||||
|
@ -155,13 +155,14 @@ static inline void set_eiem(unsigned long val)
|
|||||||
type and dynamically select the 16-byte aligned int from the array
|
type and dynamically select the 16-byte aligned int from the array
|
||||||
for the semaphore. */
|
for the semaphore. */
|
||||||
|
|
||||||
#define __PA_LDCW_ALIGNMENT 16
|
#define __PA_LDCW_ALIGNMENT 16
|
||||||
#define __ldcw_align(a) ({ \
|
#define __ldcw_align(a) ({ \
|
||||||
unsigned long __ret = (unsigned long) &(a)->lock[0]; \
|
unsigned long __ret = (unsigned long) &(a)->lock[0]; \
|
||||||
__ret = (__ret + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); \
|
__ret = (__ret + __PA_LDCW_ALIGNMENT - 1) \
|
||||||
(volatile unsigned int *) __ret; \
|
& ~(__PA_LDCW_ALIGNMENT - 1); \
|
||||||
|
(volatile unsigned int *) __ret; \
|
||||||
})
|
})
|
||||||
#define LDCW "ldcw"
|
#define __LDCW "ldcw"
|
||||||
|
|
||||||
#else /*CONFIG_PA20*/
|
#else /*CONFIG_PA20*/
|
||||||
/* From: "Jim Hull" <jim.hull of hp.com>
|
/* From: "Jim Hull" <jim.hull of hp.com>
|
||||||
@ -171,17 +172,18 @@ static inline void set_eiem(unsigned long val)
|
|||||||
they only require "natural" alignment (4-byte for ldcw, 8-byte for
|
they only require "natural" alignment (4-byte for ldcw, 8-byte for
|
||||||
ldcd). */
|
ldcd). */
|
||||||
|
|
||||||
#define __PA_LDCW_ALIGNMENT 4
|
#define __PA_LDCW_ALIGNMENT 4
|
||||||
#define __ldcw_align(a) ((volatile unsigned int *)a)
|
#define __ldcw_align(a) ((volatile unsigned int *)a)
|
||||||
#define LDCW "ldcw,co"
|
#define __LDCW "ldcw,co"
|
||||||
|
|
||||||
#endif /*!CONFIG_PA20*/
|
#endif /*!CONFIG_PA20*/
|
||||||
|
|
||||||
/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */
|
/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */
|
||||||
#define __ldcw(a) ({ \
|
#define __ldcw(a) ({ \
|
||||||
unsigned __ret; \
|
unsigned __ret; \
|
||||||
__asm__ __volatile__(LDCW " 0(%1),%0" : "=r" (__ret) : "r" (a)); \
|
__asm__ __volatile__(__LDCW " 0(%1),%0" \
|
||||||
__ret; \
|
: "=r" (__ret) : "r" (a)); \
|
||||||
|
__ret; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
|
@ -172,7 +172,11 @@ struct exception_data {
|
|||||||
/*
|
/*
|
||||||
* The "__put_user/kernel_asm()" macros tell gcc they read from memory
|
* The "__put_user/kernel_asm()" macros tell gcc they read from memory
|
||||||
* instead of writing. This is because they do not write to any memory
|
* instead of writing. This is because they do not write to any memory
|
||||||
* gcc knows about, so there are no aliasing issues.
|
* gcc knows about, so there are no aliasing issues. These macros must
|
||||||
|
* also be aware that "fixup_put_user_skip_[12]" are executed in the
|
||||||
|
* context of the fault, and any registers used there must be listed
|
||||||
|
* as clobbers. In this case only "r1" is used by the current routines.
|
||||||
|
* r8/r9 are already listed as err/val.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
@ -183,7 +187,8 @@ struct exception_data {
|
|||||||
"\t.dword\t1b,fixup_put_user_skip_1\n" \
|
"\t.dword\t1b,fixup_put_user_skip_1\n" \
|
||||||
"\t.previous" \
|
"\t.previous" \
|
||||||
: "=r"(__pu_err) \
|
: "=r"(__pu_err) \
|
||||||
: "r"(ptr), "r"(x), "0"(__pu_err))
|
: "r"(ptr), "r"(x), "0"(__pu_err) \
|
||||||
|
: "r1")
|
||||||
|
|
||||||
#define __put_user_asm(stx,x,ptr) \
|
#define __put_user_asm(stx,x,ptr) \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
|
@ -797,11 +797,6 @@
|
|||||||
|
|
||||||
#define SYS_ify(syscall_name) __NR_##syscall_name
|
#define SYS_ify(syscall_name) __NR_##syscall_name
|
||||||
|
|
||||||
/* Assume all syscalls are done from PIC code just to be
|
|
||||||
* safe. The worst case scenario is that you lose a register
|
|
||||||
* and save/restore r19 across the syscall. */
|
|
||||||
#define PIC
|
|
||||||
|
|
||||||
#ifndef ASM_LINE_SEP
|
#ifndef ASM_LINE_SEP
|
||||||
# define ASM_LINE_SEP ;
|
# define ASM_LINE_SEP ;
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user