From 64f495323c9a902b3e59fe0a588585102bb3b13e Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Sat, 22 Apr 2006 00:48:22 -0600 Subject: [PARISC] Ensure all ldcw uses are ldcw,co on pa2.0 ldcw,co should always be used on pa2.0, otherwise the strict cache width alignment requirement is not relaxed. Signed-off-by: Kyle McMartin --- include/asm-parisc/assembly.h | 2 ++ include/asm-parisc/system.h | 26 ++++++++++++++------------ 2 files changed, 16 insertions(+), 12 deletions(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h index 3ce3440d1b0c..1a7bfe699e0c 100644 --- a/include/asm-parisc/assembly.h +++ b/include/asm-parisc/assembly.h @@ -48,6 +48,7 @@ #define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE) #ifdef CONFIG_PA20 +#define LDCW ldcw,co #define BL b,l # ifdef CONFIG_64BIT # define LEVEL 2.0w @@ -55,6 +56,7 @@ # define LEVEL 2.0 # endif #else +#define LDCW ldcw #define BL bl #define LEVEL 1.1 #endif diff --git a/include/asm-parisc/system.h b/include/asm-parisc/system.h index 863876134b2c..5fe2d2329ab5 100644 --- a/include/asm-parisc/system.h +++ b/include/asm-parisc/system.h @@ -155,13 +155,14 @@ static inline void set_eiem(unsigned long val) type and dynamically select the 16-byte aligned int from the array for the semaphore. */ -#define __PA_LDCW_ALIGNMENT 16 -#define __ldcw_align(a) ({ \ - unsigned long __ret = (unsigned long) &(a)->lock[0]; \ - __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); \ - (volatile unsigned int *) __ret; \ +#define __PA_LDCW_ALIGNMENT 16 +#define __ldcw_align(a) ({ \ + unsigned long __ret = (unsigned long) &(a)->lock[0]; \ + __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) \ + & ~(__PA_LDCW_ALIGNMENT - 1); \ + (volatile unsigned int *) __ret; \ }) -#define LDCW "ldcw" +#define __LDCW "ldcw" #else /*CONFIG_PA20*/ /* From: "Jim Hull" @@ -171,17 +172,18 @@ static inline void set_eiem(unsigned long val) they only require "natural" alignment (4-byte for ldcw, 8-byte for ldcd). */ -#define __PA_LDCW_ALIGNMENT 4 +#define __PA_LDCW_ALIGNMENT 4 #define __ldcw_align(a) ((volatile unsigned int *)a) -#define LDCW "ldcw,co" +#define __LDCW "ldcw,co" #endif /*!CONFIG_PA20*/ /* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */ -#define __ldcw(a) ({ \ - unsigned __ret; \ - __asm__ __volatile__(LDCW " 0(%1),%0" : "=r" (__ret) : "r" (a)); \ - __ret; \ +#define __ldcw(a) ({ \ + unsigned __ret; \ + __asm__ __volatile__(__LDCW " 0(%1),%0" \ + : "=r" (__ret) : "r" (a)); \ + __ret; \ }) #ifdef CONFIG_SMP -- cgit v1.2.3 From c8224e0074f1dce12e95e53ca469f6fe49cc9101 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 21 Apr 2006 02:20:37 +0000 Subject: [PARISC] Whitespace clean up in asm/pgtable.h Signed-off-by: Kyle McMartin --- include/asm-parisc/pgtable.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h index b6bcc672ba80..5066c54dae0a 100644 --- a/include/asm-parisc/pgtable.h +++ b/include/asm-parisc/pgtable.h @@ -506,13 +506,13 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, /* TLB page size encoding - see table 3-1 in parisc20.pdf */ #define _PAGE_SIZE_ENCODING_4K 0 -#define _PAGE_SIZE_ENCODING_16K 1 -#define _PAGE_SIZE_ENCODING_64K 2 +#define _PAGE_SIZE_ENCODING_16K 1 +#define _PAGE_SIZE_ENCODING_64K 2 #define _PAGE_SIZE_ENCODING_256K 3 #define _PAGE_SIZE_ENCODING_1M 4 #define _PAGE_SIZE_ENCODING_4M 5 -#define _PAGE_SIZE_ENCODING_16M 6 -#define _PAGE_SIZE_ENCODING_64M 7 +#define _PAGE_SIZE_ENCODING_16M 6 +#define _PAGE_SIZE_ENCODING_64M 7 #if defined(CONFIG_PARISC_PAGE_SIZE_4KB) # define _PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_4K -- cgit v1.2.3 From 3fd3a74f45c935f7d6d5c2fb48f06324b18826b7 Mon Sep 17 00:00:00 2001 From: Carlos O'Donell Date: Sat, 22 Apr 2006 14:47:21 -0600 Subject: [PARISC] Use FIXUP_BRANCH_CLOBBER to asm clobber list Joel Soete noticed correctly that the fixup's clobbers must be listed as the ASM clobbers. FIXUP_BRANCH in unaligned.c has a new macro which lists all the clobbers in the fixup, we use this throughout the file to simplify the process of listing clobbers in the future. A missing "r1" clobber is added to our uaccess.h for the 64-bit __put_kernel_asm. Interestingly this is a pretty serious bug since gcc generates pretty good use of r1 as a temporary and the uses of __put_kernel_asm are varied and dangerous if r1 is scratched during an invalid write. Signed-off-by: Joel Soete Signed-off-by: Carlos O'Donell Signed-off-by: Kyle McMartin --- arch/parisc/kernel/unaligned.c | 18 ++++++++++-------- include/asm-parisc/uaccess.h | 9 +++++++-- 2 files changed, 17 insertions(+), 10 deletions(-) (limited to 'include/asm-parisc') diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c index de0a1b21cb40..92328fbddb3e 100644 --- a/arch/parisc/kernel/unaligned.c +++ b/arch/parisc/kernel/unaligned.c @@ -43,6 +43,8 @@ "\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 diff --git a/include/asm-parisc/uaccess.h b/include/asm-parisc/uaccess.h index f6c417c8c484..d973e8b3466c 100644 --- a/include/asm-parisc/uaccess.h +++ b/include/asm-parisc/uaccess.h @@ -172,7 +172,11 @@ struct exception_data { /* * 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 - * 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__ @@ -183,7 +187,8 @@ struct exception_data { "\t.dword\t1b,fixup_put_user_skip_1\n" \ "\t.previous" \ : "=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) \ __asm__ __volatile__ ( \ -- cgit v1.2.3 From 1b6d1b5e073ad9313ad64da49dff649f5c06e546 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 19 May 2006 20:18:17 +0000 Subject: [PARISC] Use MFIA in current_text_addr on pa2.0 processors Signed-off-by: Kyle McMartin --- include/asm-parisc/processor.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h index ca49dc91f4fc..b73626f040da 100644 --- a/include/asm-parisc/processor.h +++ b/include/asm-parisc/processor.h @@ -26,14 +26,12 @@ * Default implementation of macro that returns current * instruction pointer ("program counter"). */ - -/* We cannot use MFIA as it was added for PA2.0 - prumpf - - At one point there were no "0f/0b" type local symbols in gas for - PA-RISC. This is no longer true, but this still seems like the - nicest way to implement this. */ - -#define current_text_addr() ({ void *pc; __asm__("\n\tblr 0,%0\n\tnop":"=r" (pc)); pc; }) +#ifdef CONFIG_PA20 +#define current_ia(x) __asm__("mfia %0" : "=r"(x)) +#else /* mfia added in pa2.0 */ +#define current_ia(x) __asm__("blr 0,%0\n\tnop" : "=r"(x)) +#endif +#define current_text_addr() ({ void *pc; current_ia(pc); pc; }) #define TASK_SIZE (current->thread.task_size) #define TASK_UNMAPPED_BASE (current->thread.map_base) -- cgit v1.2.3 From c95f2e5f2f6f61d734a025414c9eb81872a5c831 Mon Sep 17 00:00:00 2001 From: Carlos O'Donell Date: Wed, 21 Jun 2006 03:43:52 +0000 Subject: [PARISC] Remove unconditional #define PIC in syscall macros Signed-off-by: Carlos O'Donell Signed-off-by: Kyle McMartin --- include/asm-parisc/unistd.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h index 12b867238a47..27bcfad1c3e3 100644 --- a/include/asm-parisc/unistd.h +++ b/include/asm-parisc/unistd.h @@ -797,11 +797,6 @@ #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 # define ASM_LINE_SEP ; #endif -- cgit v1.2.3 From 8ffaeaf42e91930888df09d696a8a6ebe056d0e0 Mon Sep 17 00:00:00 2001 From: Thibaut Varene Date: Wed, 3 May 2006 17:27:35 -0600 Subject: [PARISC] PDC_CHASSIS is implemented on all machines This patch removes a limitation of the original code, so that CHASSIS codes can be sent to all machines. On machines with a LCD panel, this code displays "INI" during bootup, "RUN" when the system is booted and running, "FLT" when a panic occurs, etc. This part of the code can be enabled/disabled through CONFIG_PDC_CHASSIS This patch also adds minimalistic support for Chassis warnings, through a proc entry '/proc/chassis', which will reflect the warnings status (PSU or fans failure when they happen, NVRAM battery level and temperature thresholds overflows). This part of the code can be enabled/disabled through CONFIG_PDC_CHASSIS_WARN Signed-off-by: Thibaut VARENE Signed-off-by: Kyle McMartin --- arch/parisc/kernel/firmware.c | 22 +++++++++--- arch/parisc/kernel/pdc_chassis.c | 73 ++++++++++++++++++++++++++++++++++------ drivers/parisc/Kconfig | 33 ++++++++++++++---- include/asm-parisc/pdc.h | 1 + 4 files changed, 107 insertions(+), 22 deletions(-) (limited to 'include/asm-parisc') diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index 2dc06b8e1817..0596f27340cc 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -11,7 +11,7 @@ * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy) * Copyright 2003 Grant Grundler * Copyright 2003,2004 Ryan Bradetich - * Copyright 2004 Thibaut VARENE + * Copyright 2004,2006 Thibaut VARENE * * 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. diff --git a/arch/parisc/kernel/pdc_chassis.c b/arch/parisc/kernel/pdc_chassis.c index a45e2e2ffd9f..51e86c0365c1 100644 --- a/arch/parisc/kernel/pdc_chassis.c +++ b/arch/parisc/kernel/pdc_chassis.c @@ -1,8 +1,8 @@ /* - * interfaces to log Chassis Codes via PDC (firmware) + * interfaces to Chassis Codes via PDC (firmware) * * Copyright (C) 2002 Laurent Canet - * Copyright (C) 2002-2004 Thibaut VARENE + * Copyright (C) 2002-2006 Thibaut VARENE * * 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,9 @@ * 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. */ #undef PDC_CHASSIS_DEBUG @@ -30,6 +33,7 @@ #include #include #include +#include #include #include @@ -38,7 +42,6 @@ #ifdef CONFIG_PDC_CHASSIS -static int pdc_chassis_old __read_mostly = 0; static unsigned int pdc_chassis_enabled __read_mostly = 1; @@ -64,7 +67,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 +76,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 +83,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. @@ -136,14 +138,13 @@ void __init parisc_pdc_chassis_init(void) 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(); + /* Check for PDC_PAT */ 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"); + else { + printk(KERN_INFO "Enabling regular chassis codes support.\n"); handle = 1; } @@ -215,9 +216,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 +248,50 @@ 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) +{ + printk(KERN_INFO "Enabling PDC chassis warnings support.\n"); + 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 */ diff --git a/drivers/parisc/Kconfig b/drivers/parisc/Kconfig index 3f5de867acd7..1d3b84b4af3f 100644 --- a/drivers/parisc/Kconfig +++ b/drivers/parisc/Kconfig @@ -140,18 +140,37 @@ config CHASSIS_LCD_LED If unsure, say Y. config PDC_CHASSIS - bool "PDC chassis State Panel support" + bool "PDC chassis state codes support" default y help - Say Y here if you want to enable support for the LED State front - panel as found on E class, and support for the GSP Virtual Front - Panel (LED State and 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. + Say Y here if you want to enable support for Chassis codes. + That includes support for LED State front panel as found on E + class, and support for the GSP Virtual Front Panel (LED State and + message logging) as found on high end servers such as A, L and + N-class. + 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. + +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 tristate "PDC Stable Storage support" depends on SYSFS diff --git a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h index 08364f957e7a..7d8a71a28546 100644 --- a/include/asm-parisc/pdc.h +++ b/include/asm-parisc/pdc.h @@ -719,6 +719,7 @@ void setup_pdc(void); /* in inventory.c */ 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_disp(unsigned long disp); +int pdc_chassis_warn(unsigned long *warn); int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info); int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index, void *iodc_data, unsigned int iodc_data_size); -- cgit v1.2.3 From a3ea84fabacd9cc5bcc3fda67c35e692ca10dc8c Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 16 Jun 2006 19:10:02 +0000 Subject: [PARISC] Add is_compat_task() helper ... And convert signal.c and ptrace.c to use it instead of open coded equivalents. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/ptrace.c | 8 ++++---- arch/parisc/kernel/signal.c | 20 ++++++++++---------- include/asm-parisc/compat.h | 11 +++++++++++ 3 files changed, 25 insertions(+), 14 deletions(-) (limited to 'include/asm-parisc') diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index 413292f1a4a3..3f28de974556 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c @@ -91,7 +91,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) 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) diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index cc38edfd90c5..bb83880c5ee3 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -76,7 +76,7 @@ sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *r #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 diff --git a/include/asm-parisc/compat.h b/include/asm-parisc/compat.h index 289624d8b2d4..71b4eeea205a 100644 --- a/include/asm-parisc/compat.h +++ b/include/asm-parisc/compat.h @@ -5,6 +5,7 @@ */ #include #include +#include #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]; } +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 */ -- cgit v1.2.3 From e5a2e7fdb53028ce187c0ce0ae0d45ca7546fd5e Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Wed, 14 Jun 2006 20:26:25 +0000 Subject: [PARISC] Match show_cache_info with reality show_cache_info and struct pdc_cache_cf were out of sync with published documentation. Fix the reporting of cache associativity and update the pdc_cache_cf bitfields to match documentation. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/cache.c | 18 ++++++++++-------- include/asm-parisc/pdc.h | 4 ++-- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'include/asm-parisc') diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index c057ad7605ba..851519cbad6f 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -97,15 +97,17 @@ update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) 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, diff --git a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h index 7d8a71a28546..592f13bcc987 100644 --- a/include/asm-parisc/pdc.h +++ b/include/asm-parisc/pdc.h @@ -352,8 +352,8 @@ struct pdc_cache_cf { /* for PDC_CACHE (I/D-caches) */ cc_wt : 1, /* 0 = WT-Dcache, 1 = WB-Dcache */ 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_pad1 : 5, /* reserved */ - cc_assoc: 8; /* associativity of I/D-cache */ + cc_pad1 : 10, /* reserved */ + cc_hv : 3; /* hversion dependent */ }; struct pdc_tlb_cf { /* for PDC_CACHE (I/D-TLB's) */ -- cgit v1.2.3 From a9d2d386c42b816a81eb1d02dfb7b502ba8cea82 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 16 Jun 2006 18:20:00 -0400 Subject: [PARISC] Ensure Space ID hashing is turned off Check PDC_CACHE to see if spaceid hashing is turned on, and fail to boot if that is the case. However, some old machines do not implement the PDC_CACHE_RET_SPID firmware call, so continue to boot if the call fails because of PDC_BAD_OPTION (but fail in all other error returns). Signed-off-by: Kyle McMartin --- arch/parisc/kernel/cache.c | 10 +++++++++- arch/parisc/kernel/firmware.c | 20 ++++++++++++++++++++ include/asm-parisc/pdc.h | 1 + 3 files changed, 30 insertions(+), 1 deletion(-) (limited to 'include/asm-parisc') diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index 851519cbad6f..bc7c4a4e26a1 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -236,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. */ @@ -262,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) diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index 0596f27340cc..c80c277454f3 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -512,6 +512,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. diff --git a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h index 592f13bcc987..3d3446ec207e 100644 --- a/include/asm-parisc/pdc.h +++ b/include/asm-parisc/pdc.h @@ -733,6 +733,7 @@ int pdc_model_cpuid(unsigned long *cpu_id); int pdc_model_versions(unsigned long *versions, int id); int pdc_model_capabilities(unsigned long *capabilities); int pdc_cache_info(struct pdc_cache_info *cache); +int pdc_spaceid_bits(unsigned long *space_bits); #ifndef CONFIG_PA20 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); -- cgit v1.2.3 From ec1fdc24c2ae012b078ba0187ceef208e08a3aec Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Wed, 21 Jun 2006 19:27:29 +0000 Subject: [PARISC] OS_ID_LINUX == 0x0006 We were assigned an OS_ID of 0x0006. Consistently use OS_ID_LINUX instead of using the magic number. Also update the OS_ID_ defines in asm/pdc.h to reflect this. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/firmware.c | 4 +++- arch/parisc/kernel/setup.c | 2 +- drivers/parisc/pdc_stable.c | 4 ++-- include/asm-parisc/pdc.h | 3 +-- 4 files changed, 7 insertions(+), 6 deletions(-) (limited to 'include/asm-parisc') diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index c80c277454f3..4398d2a95789 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -407,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) { diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index 8471486a7565..278f4b9f6a38 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -303,7 +303,7 @@ extern void eisa_init(void); static int __init parisc_init(void) { - u32 osid = (0x0006 << 16); + u32 osid = (OS_ID_LINUX << 16); parisc_proc_mkdir(); parisc_init_resources(); diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index a1094210cd1f..97b345858043 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c @@ -884,7 +884,7 @@ pdcs_osdep1_write(struct subsystem *entry, const char *buf, size_t count) if (!entry || !buf || !count) return -EINVAL; - if (unlikely(pdcs_osid != 0x0006)) + if (unlikely(pdcs_osid != OS_ID_LINUX)) return -EPERM; if (count > 16) @@ -926,7 +926,7 @@ pdcs_osdep2_write(struct subsystem *entry, const char *buf, size_t count) if (unlikely(pdcs_size <= 224)) return -ENOSYS; - if (unlikely(pdcs_osid != 0x0006)) + if (unlikely(pdcs_osid != OS_ID_LINUX)) return -EPERM; size = pdcs_size - 224; diff --git a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h index 3d3446ec207e..33bff615d6e1 100644 --- a/include/asm-parisc/pdc.h +++ b/include/asm-parisc/pdc.h @@ -278,12 +278,11 @@ typedef struct { /* constants for OS (NVM...) */ #define OS_ID_NONE 0 /* Undefined OS ID */ #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_OSF 3 /* OSF OS */ #define OS_ID_HPRT 4 /* HP-RT 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 */ -- cgit v1.2.3 From 67a061a191017f984a1ef0ff73ae988b9b15f6d3 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Sun, 25 Jun 2006 16:58:57 +0000 Subject: [PARISC] Add os_id_to_string helper Add a helper to asm/pdc.h to translate OS_ID values to strings and use it in the pdc_stable driver. Signed-off-by: Kyle McMartin --- drivers/parisc/pdc_stable.c | 14 ++------------ include/asm-parisc/pdc.h | 13 +++++++++++++ 2 files changed, 15 insertions(+), 12 deletions(-) (limited to 'include/asm-parisc') diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index 97b345858043..ea1b7a63598e 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c @@ -622,22 +622,12 @@ static ssize_t pdcs_osid_read(struct subsystem *entry, char *buf) { char *out = buf; - char *tmpstr = NULL; if (!entry || !buf) return -EINVAL; - switch (pdcs_osid) { - case 0x0000: tmpstr = "No OS"; break; - case 0x0001: tmpstr = "HP-UX"; break; - case 0x0002: tmpstr = "MPE-iX"; break; - case 0x0003: tmpstr = "OSF"; break; - case 0x0004: tmpstr = "HP-RT"; break; - case 0x0005: tmpstr = "Novell Netware"; break; - case 0x0006: tmpstr = "Linux"; break; - default: tmpstr = "Unknown"; break; - } - out += sprintf(out, "%s dependent data (0x%.4x)\n", tmpstr, pdcs_osid); + out += sprintf(out, "%s dependent data (0x%.4x)\n", + os_id_to_string(pdcs_osid), pdcs_osid); return out - buf; } diff --git a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h index 33bff615d6e1..7a21f106ade6 100644 --- a/include/asm-parisc/pdc.h +++ b/include/asm-parisc/pdc.h @@ -284,6 +284,19 @@ typedef struct { #define OS_ID_NOVEL 5 /* NOVELL OS */ #define OS_ID_LINUX 6 /* Linux */ +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"; + } +} + /* constants for PDC_CHASSIS */ #define OSTAT_OFF 0 -- cgit v1.2.3 From c1a7a755be26f68d7f21ee769584149a96185ea8 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Mon, 26 Jun 2006 11:28:09 -0400 Subject: [PARISC] Move os_id_to_string() inside #ifndef __ASSEMBLY__ Assembly files should be protected from os_id_to_string()... Pass me a brown paper bag, please. Signed-off-by: Kyle McMartin --- include/asm-parisc/pdc.h | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h index 7a21f106ade6..c9b2e35326ee 100644 --- a/include/asm-parisc/pdc.h +++ b/include/asm-parisc/pdc.h @@ -284,19 +284,6 @@ typedef struct { #define OS_ID_NOVEL 5 /* NOVELL OS */ #define OS_ID_LINUX 6 /* Linux */ -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"; - } -} - /* constants for PDC_CHASSIS */ #define OSTAT_OFF 0 @@ -789,6 +776,18 @@ int pdc_sti_call(unsigned long func, unsigned long flags, 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 /* _PARISC_PDC_H */ -- cgit v1.2.3