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:
@@ -97,15 +97,17 @@ update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
|
||||
void
|
||||
show_cache_info(struct seq_file *m)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
seq_printf(m, "I-cache\t\t: %ld KB\n",
|
||||
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_conf.cc_wt ? "WT":"WB"),
|
||||
(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",
|
||||
cache_info.it_size,
|
||||
cache_info.dt_size,
|
||||
@@ -158,11 +160,11 @@ parisc_cache_init(void)
|
||||
cache_info.dc_conf.cc_block,
|
||||
cache_info.dc_conf.cc_line,
|
||||
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_sh,
|
||||
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",
|
||||
cache_info.ic_base,
|
||||
@@ -176,11 +178,11 @@ parisc_cache_init(void)
|
||||
cache_info.ic_conf.cc_block,
|
||||
cache_info.ic_conf.cc_line,
|
||||
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_sh,
|
||||
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",
|
||||
cache_info.dt_conf.tc_sh,
|
||||
@@ -234,7 +236,8 @@ parisc_cache_init(void)
|
||||
|
||||
void disable_sr_hashing(void)
|
||||
{
|
||||
int srhash_type;
|
||||
int srhash_type, retval;
|
||||
unsigned long space_bits;
|
||||
|
||||
switch (boot_cpu_data.cpu_type) {
|
||||
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);
|
||||
|
||||
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)
|
||||
|
@@ -1638,7 +1638,7 @@ dbit_trap_20w:
|
||||
load32 PA(pa_dbit_lock),t0
|
||||
|
||||
dbit_spin_20w:
|
||||
ldcw 0(t0),t1
|
||||
LDCW 0(t0),t1
|
||||
cmpib,= 0,t1,dbit_spin_20w
|
||||
nop
|
||||
|
||||
@@ -1674,7 +1674,7 @@ dbit_trap_11:
|
||||
load32 PA(pa_dbit_lock),t0
|
||||
|
||||
dbit_spin_11:
|
||||
ldcw 0(t0),t1
|
||||
LDCW 0(t0),t1
|
||||
cmpib,= 0,t1,dbit_spin_11
|
||||
nop
|
||||
|
||||
@@ -1714,7 +1714,7 @@ dbit_trap_20:
|
||||
load32 PA(pa_dbit_lock),t0
|
||||
|
||||
dbit_spin_20:
|
||||
ldcw 0(t0),t1
|
||||
LDCW 0(t0),t1
|
||||
cmpib,= 0,t1,dbit_spin_20
|
||||
nop
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
* Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy)
|
||||
* Copyright 2003 Grant Grundler <grundler 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
|
||||
* 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
|
||||
|
||||
/**
|
||||
* pdc_chassis_disp - Updates display
|
||||
* pdc_chassis_disp - Updates chassis code
|
||||
* @retval: -1 on error, 0 on success
|
||||
*
|
||||
* Works on old PDC only (E class, others?)
|
||||
*/
|
||||
int pdc_chassis_disp(unsigned long disp)
|
||||
{
|
||||
@@ -268,6 +266,22 @@ int pdc_chassis_disp(unsigned long disp)
|
||||
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_info: Return buffer address.
|
||||
@@ -393,7 +407,9 @@ int pdc_model_info(struct pdc_model *model)
|
||||
* pdc_model_sysmodel - Get the system model name.
|
||||
* @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)
|
||||
{
|
||||
@@ -498,6 +514,26 @@ int pdc_cache_info(struct pdc_cache_info *cache_info)
|
||||
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
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
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__
|
||||
struct got_entry {
|
||||
@@ -364,8 +370,14 @@ static Elf_Addr get_fdesc(struct module *me, unsigned long value)
|
||||
}
|
||||
#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,
|
||||
int millicode, int init_section)
|
||||
enum elf_stub_type stub_type, int init_section)
|
||||
{
|
||||
unsigned long i;
|
||||
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);
|
||||
|
||||
#else
|
||||
/* for 64-bit we have two kinds of stubs:
|
||||
/* for 64-bit we have three kinds of stubs:
|
||||
* for normal function calls:
|
||||
* ldd 0(%dp),%dp
|
||||
* 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
|
||||
* ldd 10(%r1), %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[1] = 0x53610020; /* ldd 10(%dp),%r1 */
|
||||
stub->insns[2] = 0xe820d000; /* bve (%r1) */
|
||||
stub->insns[3] = 0x537b0030; /* ldd 18(%dp),%dp */
|
||||
|
||||
stub->insns[0] |= reassemble_14(get_got(me, value, addend) & 0x3fff);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
case ELF_STUB_MILLI:
|
||||
stub->insns[0] = 0x20200000; /* ldil 0,%r1 */
|
||||
stub->insns[1] = 0x34210000; /* ldo 0(%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[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
|
||||
|
||||
return (Elf_Addr)stub;
|
||||
@@ -539,14 +566,14 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
|
||||
break;
|
||||
case R_PARISC_PCREL17F:
|
||||
/* 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;
|
||||
CHECK_RELOC(val, 17)
|
||||
*loc = (*loc & ~0x1f1ffd) | reassemble_17(val);
|
||||
break;
|
||||
case R_PARISC_PCREL22F:
|
||||
/* 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",
|
||||
strtab + sym->st_name, (unsigned long)loc, addend,
|
||||
val)
|
||||
@@ -643,13 +670,23 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
|
||||
strtab + sym->st_name,
|
||||
loc, val);
|
||||
/* can we reach it locally? */
|
||||
if(!is_local(me, (void *)val)) {
|
||||
if (strncmp(strtab + sym->st_name, "$$", 2)
|
||||
if(!is_local_section(me, (void *)val, (void *)dot)) {
|
||||
|
||||
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)
|
||||
val = get_stub(me, val, addend, 1,
|
||||
val = get_stub(me, val, addend, ELF_STUB_MILLI,
|
||||
is_init(me, loc));
|
||||
else
|
||||
val = get_stub(me, val, addend, 0,
|
||||
val = get_stub(me, val, addend, ELF_STUB_GOT,
|
||||
is_init(me, loc));
|
||||
}
|
||||
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-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
|
||||
* 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
|
||||
* along with this program; if not, write to the Free Software
|
||||
* 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
|
||||
@@ -30,15 +34,16 @@
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/cache.h>
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
#include <asm/pdc_chassis.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/pdc.h>
|
||||
#include <asm/pdcpat.h>
|
||||
|
||||
#define PDC_CHASSIS_VER "0.05"
|
||||
|
||||
#ifdef CONFIG_PDC_CHASSIS
|
||||
static int pdc_chassis_old __read_mostly = 0;
|
||||
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.
|
||||
* Inspired by Christoph Plattner
|
||||
*/
|
||||
|
||||
#if 0
|
||||
static void __init pdc_chassis_checkold(void)
|
||||
{
|
||||
switch(CPU_HVERSION) {
|
||||
@@ -73,7 +78,6 @@ static void __init pdc_chassis_checkold(void)
|
||||
case 0x482: /* E45 */
|
||||
case 0x483: /* E55 */
|
||||
case 0x516: /* A180 */
|
||||
pdc_chassis_old = 1;
|
||||
break;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
#ifdef CONFIG_PDC_CHASSIS
|
||||
int handle = 0;
|
||||
if (likely(pdc_chassis_enabled)) {
|
||||
DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__);
|
||||
|
||||
/* Let see if we have something to handle... */
|
||||
/* Check for PDC_PAT or old LED Panel */
|
||||
pdc_chassis_checkold();
|
||||
if (is_pdc_pat()) {
|
||||
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;
|
||||
}
|
||||
printk(KERN_INFO "Enabling %s chassis codes support v%s\n",
|
||||
is_pdc_pat() ? "PDC_PAT" : "regular",
|
||||
PDC_CHASSIS_VER);
|
||||
|
||||
if (handle) {
|
||||
/* initialize panic notifier chain */
|
||||
atomic_notifier_chain_register(&panic_notifier_list,
|
||||
&pdc_chassis_panic_block);
|
||||
/* initialize panic notifier chain */
|
||||
atomic_notifier_chain_register(&panic_notifier_list,
|
||||
&pdc_chassis_panic_block);
|
||||
|
||||
/* initialize reboot notifier chain */
|
||||
register_reboot_notifier(&pdc_chassis_reboot_block);
|
||||
}
|
||||
/* initialize reboot notifier chain */
|
||||
register_reboot_notifier(&pdc_chassis_reboot_block);
|
||||
}
|
||||
#endif /* CONFIG_PDC_CHASSIS */
|
||||
}
|
||||
@@ -215,9 +209,12 @@ int pdc_chassis_send_status(int message)
|
||||
}
|
||||
} else retval = -1;
|
||||
#else
|
||||
if (unlikely(pdc_chassis_old)) {
|
||||
if (1) {
|
||||
switch (message) {
|
||||
case PDC_CHASSIS_DIRECT_BSTART:
|
||||
retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_INIT));
|
||||
break;
|
||||
|
||||
case PDC_CHASSIS_DIRECT_BCOMPLETE:
|
||||
retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN));
|
||||
break;
|
||||
@@ -244,3 +241,61 @@ int pdc_chassis_send_status(int message)
|
||||
#endif /* CONFIG_PDC_CHASSIS */
|
||||
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;
|
||||
|
||||
#ifdef __LP64__
|
||||
if (personality(child->personality) == PER_LINUX32) {
|
||||
if (__is_compat_task(child)) {
|
||||
unsigned int tmp;
|
||||
|
||||
addr &= 0xffffffffL;
|
||||
@@ -123,7 +123,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
||||
case PTRACE_POKEDATA:
|
||||
ret = 0;
|
||||
#ifdef __LP64__
|
||||
if (personality(child->personality) == PER_LINUX32) {
|
||||
if (__is_compat_task(child)) {
|
||||
unsigned int tmp = (unsigned int)data;
|
||||
DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n",
|
||||
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: {
|
||||
ret = -EIO;
|
||||
#ifdef __LP64__
|
||||
if (personality(child->personality) == PER_LINUX32) {
|
||||
if (__is_compat_task(child)) {
|
||||
unsigned int tmp;
|
||||
|
||||
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;
|
||||
}
|
||||
#ifdef __LP64__
|
||||
if (personality(child->personality) == PER_LINUX32) {
|
||||
if (__is_compat_task(child)) {
|
||||
if (addr & (sizeof(int)-1))
|
||||
goto out_tsk;
|
||||
if ((addr = translate_usr_offset(addr)) < 0)
|
||||
|
@@ -276,15 +276,6 @@ r64_ret:
|
||||
|
||||
#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
|
||||
.text
|
||||
/* 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)
|
||||
{
|
||||
u32 osid = (OS_ID_LINUX << 16);
|
||||
|
||||
parisc_proc_mkdir();
|
||||
parisc_init_resources();
|
||||
do_device_inventory(); /* probe for hardware */
|
||||
@@ -311,6 +313,9 @@ static int __init parisc_init(void)
|
||||
|
||||
/* set up a new led state on systems shipped LED State panel */
|
||||
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BSTART);
|
||||
|
||||
/* tell PDC we're Linux. Nevermind failure. */
|
||||
pdc_stable_write(0x40, &osid, sizeof(osid));
|
||||
|
||||
processor_init();
|
||||
printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n",
|
||||
|
@@ -76,7 +76,7 @@ sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *r
|
||||
#ifdef __LP64__
|
||||
compat_sigset_t newset32;
|
||||
|
||||
if(personality(current->personality) == PER_LINUX32){
|
||||
if (is_compat_task()) {
|
||||
/* XXX: Don't preclude handling different sized sigset_t's. */
|
||||
if (sigsetsize != sizeof(compat_sigset_t))
|
||||
return -EINVAL;
|
||||
@@ -153,7 +153,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
|
||||
compat_sigset_t compat_set;
|
||||
struct compat_rt_sigframe __user * compat_frame;
|
||||
|
||||
if(personality(current->personality) == PER_LINUX32)
|
||||
if (is_compat_task())
|
||||
sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
|
||||
#endif
|
||||
|
||||
@@ -166,7 +166,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
|
||||
#ifdef __LP64__
|
||||
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");
|
||||
if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set)))
|
||||
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? */
|
||||
#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",
|
||||
&compat_frame->uc.uc_mcontext);
|
||||
// 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;
|
||||
|
||||
if(personality(current->personality) == PER_LINUX32) {
|
||||
if (is_compat_task()) {
|
||||
DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
|
||||
err |= copy_siginfo_to_user32(&compat_frame->info, info);
|
||||
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);
|
||||
/* The sa_handler may be a pointer to a function descriptor */
|
||||
#ifdef __LP64__
|
||||
if(personality(current->personality) == PER_LINUX32) {
|
||||
if (is_compat_task()) {
|
||||
#endif
|
||||
if (haddr & PA_PLABEL_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;
|
||||
#ifdef __LP64__
|
||||
if(personality(current->personality) == PER_LINUX32)
|
||||
if (is_compat_task())
|
||||
sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
|
||||
#endif
|
||||
if (in_syscall) {
|
||||
regs->gr[31] = haddr;
|
||||
#ifdef __LP64__
|
||||
if(personality(current->personality) == PER_LINUX)
|
||||
if (personality(current->personality) == PER_LINUX)
|
||||
sigframe_size |= 1;
|
||||
#endif
|
||||
} else {
|
||||
unsigned long psw = USER_PSW;
|
||||
#ifdef __LP64__
|
||||
if(personality(current->personality) == PER_LINUX)
|
||||
if (personality(current->personality) == PER_LINUX)
|
||||
psw |= PSW_W;
|
||||
#endif
|
||||
|
||||
@@ -464,7 +464,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
regs->gr[26] = sig; /* signal number */
|
||||
|
||||
#ifdef __LP64__
|
||||
if(personality(current->personality) == PER_LINUX32){
|
||||
if (is_compat_task()) {
|
||||
regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */
|
||||
regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */
|
||||
} else
|
||||
|
@@ -29,18 +29,6 @@
|
||||
.level 1.1
|
||||
#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
|
||||
|
||||
.import syscall_exit,code
|
||||
@@ -541,7 +529,7 @@ cas_nocontend:
|
||||
# endif
|
||||
/* 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? */
|
||||
cas_wouldblock:
|
||||
ldo 2(%r0), %r28 /* 2nd case */
|
||||
|
@@ -157,8 +157,22 @@ do_gettimeofday (struct timeval *tv)
|
||||
usec += (xtime.tv_nsec / 1000);
|
||||
} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
|
||||
|
||||
while (usec >= 1000000) {
|
||||
usec -= 1000000;
|
||||
if (unlikely(usec > LONG_MAX)) {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
@@ -66,57 +66,42 @@ int printbinary(char *buf, unsigned long x, int nbits)
|
||||
#else
|
||||
#define RFMT "%08lx"
|
||||
#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;
|
||||
char buf[128], *p;
|
||||
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 */
|
||||
char buf[64];
|
||||
|
||||
printk("%s\n", level);
|
||||
printk("%s YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\n", level);
|
||||
printbinary(buf, regs->gr[0], 32);
|
||||
printk("%sPSW: %s %s\n", level, buf, print_tainted());
|
||||
|
||||
for (i = 0; i < 32; i += 4) {
|
||||
int j;
|
||||
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 < 32; i += 4)
|
||||
PRINTREGS(level, regs->gr, "r", RFMT, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i += 4) {
|
||||
int j;
|
||||
p = buf;
|
||||
p += sprintf(p, "%ssr%d-%d ", level, i, i + 3);
|
||||
for (j = 0; j < 4; j++) {
|
||||
p += sprintf(p, " " RFMT, regs->sr[i + j]);
|
||||
}
|
||||
printk("%s\n", buf);
|
||||
}
|
||||
static void print_fr(char *level, struct pt_regs *regs)
|
||||
{
|
||||
int i;
|
||||
char buf[64];
|
||||
struct { u32 sw[2]; } s;
|
||||
|
||||
/* 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
|
||||
* in our way, otherwise we're screwed.
|
||||
* The fldd is used to restore the T-bit if there was one, as the
|
||||
* store clears it anyway.
|
||||
* BTW, PA2.0 book says "thou shall not use fstw on FPSR/FPERs". */
|
||||
__asm__ (
|
||||
"fstd %%fr0,0(%1) \n\t"
|
||||
"fldd 0(%1),%%fr0 \n\t"
|
||||
: "=m" (s) : "r" (&s) : "%r0"
|
||||
);
|
||||
* PA2.0 book says "thou shall not use fstw on FPSR/FPERs" - T-Bone */
|
||||
asm volatile ("fstd %%fr0,0(%1) \n\t"
|
||||
"fldd 0(%1),%%fr0 \n\t"
|
||||
: "=m" (s) : "r" (&s) : "r0");
|
||||
|
||||
printk("%s\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]);
|
||||
|
||||
/* here we'll print fr0 again, tho it'll be meaningless */
|
||||
for (i = 0; i < 32; i += 4) {
|
||||
int j;
|
||||
p = buf;
|
||||
p += sprintf(p, "%sfr%02d-%02d ", level, i, i + 3);
|
||||
for (j = 0; j < 4; j++)
|
||||
p += sprintf(p, " %016llx", (i+j) == 0 ? 0 : regs->fr[i+j]);
|
||||
printk("%s\n", buf);
|
||||
}
|
||||
for (i = 0; i < 32; i += 4)
|
||||
PRINTREGS(level, regs->fr, "fr", FFMT, i);
|
||||
}
|
||||
|
||||
void show_regs(struct pt_regs *regs)
|
||||
{
|
||||
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);
|
||||
cr31 = mfctl(31);
|
||||
|
@@ -43,6 +43,8 @@
|
||||
"\tldil L%%" #lbl ", %%r1\n" \
|
||||
"\tldo R%%" #lbl "(%%r1), %%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 */
|
||||
#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"
|
||||
: "=r" (val), "=r" (ret)
|
||||
: "0" (val), "r" (saddr), "r" (regs->isr)
|
||||
: "r20" );
|
||||
: "r20", FIXUP_BRANCH_CLOBBER );
|
||||
|
||||
DPRINTF("val = 0x" RFMT "\n", val);
|
||||
|
||||
@@ -202,7 +204,7 @@ static int emulate_ldw(struct pt_regs *regs, int toreg, int flop)
|
||||
" .previous\n"
|
||||
: "=r" (val), "=r" (ret)
|
||||
: "0" (val), "r" (saddr), "r" (regs->isr)
|
||||
: "r19", "r20" );
|
||||
: "r19", "r20", FIXUP_BRANCH_CLOBBER );
|
||||
|
||||
DPRINTF("val = 0x" RFMT "\n", val);
|
||||
|
||||
@@ -253,7 +255,7 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
|
||||
" .previous\n"
|
||||
: "=r" (val), "=r" (ret)
|
||||
: "0" (val), "r" (saddr), "r" (regs->isr)
|
||||
: "r19", "r20" );
|
||||
: "r19", "r20", FIXUP_BRANCH_CLOBBER );
|
||||
#else
|
||||
{
|
||||
unsigned long valh=0,vall=0;
|
||||
@@ -287,7 +289,7 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
|
||||
" .previous\n"
|
||||
: "=r" (valh), "=r" (vall), "=r" (ret)
|
||||
: "0" (valh), "1" (vall), "r" (saddr), "r" (regs->isr)
|
||||
: "r19", "r20" );
|
||||
: "r19", "r20", FIXUP_BRANCH_CLOBBER );
|
||||
val=((__u64)valh<<32)|(__u64)vall;
|
||||
}
|
||||
#endif
|
||||
@@ -335,7 +337,7 @@ static int emulate_sth(struct pt_regs *regs, int frreg)
|
||||
" .previous\n"
|
||||
: "=r" (ret)
|
||||
: "r" (val), "r" (regs->ior), "r" (regs->isr)
|
||||
: "r19" );
|
||||
: "r19", FIXUP_BRANCH_CLOBBER );
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -389,7 +391,7 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop)
|
||||
" .previous\n"
|
||||
: "=r" (ret)
|
||||
: "r" (val), "r" (regs->ior), "r" (regs->isr)
|
||||
: "r19", "r20", "r21", "r22", "r1" );
|
||||
: "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -450,7 +452,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
|
||||
" .previous\n"
|
||||
: "=r" (ret)
|
||||
: "r" (val), "r" (regs->ior), "r" (regs->isr)
|
||||
: "r19", "r20", "r21", "r22", "r1" );
|
||||
: "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER );
|
||||
#else
|
||||
{
|
||||
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"
|
||||
: "=r" (ret)
|
||||
: "r" (valh), "r" (vall), "r" (regs->ior), "r" (regs->isr)
|
||||
: "r19", "r20", "r21", "r1" );
|
||||
: "r19", "r20", "r21", "r1", FIXUP_BRANCH_CLOBBER );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user