* Re: [PATCH] m8xx_wdt: software watchdog reset/interrupt select\
From: Florian Schirmer @ 2005-11-15 6:11 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: obi, carjay, linux-ppc-embedded
In-Reply-To: <20051114160302.GC29411@logos.cnet>
Hi,
> Actually, drivers/char/watchdog/mpc8xx_wdt.c is a module, while
> some of the initialization code must reside in the kernel image.
>
> Thats the reason for the split - not sure if merging the two
> files is worth?
If you have a short timeout (like the 2 secs we had) then you need to
have the handler ready long before the module could be loaded.
Best,
Florian
^ permalink raw reply
* interrupts limit??
From: zjznliang @ 2005-11-15 5:26 UTC (permalink / raw)
To: linuxppc-embedded
SGkgLGxpbnV4cHBjLWVtYmVkZGVkIKOhDQoNCgkJICBJIGhhdmUgZG9uZSB0aGUgaW50ZXJydXB0
IHJlcXVlc3QgYnkgcmVxdWVzdF9pcnEoKSBvbiB0aGUgTGludXggMi40LjI1ICx3aGVuIHR5cGlu
ZyB0aGUgJ2NhdCAvcHJvYy9pbnRlcnJ1cHRzJywgSSBjYW4gc2VlIHRoZSBpbmZvcm1hdGlvbiBh
cyBmb2xsb3cgOg0KDQovcHJvYyAjIGNhdCBpbnRlcnJ1cHRzDQogICAgICAgICAgIENQVTANCiAg
MjogICAgICAgMzQyMCAgIDh4eCBTSVUgICBFZGdlICAgICAgd2JnYV9pbnRlcnJ1cHQNCiAgNTog
ICAgICAgICAgMCAgIDh4eCBTSVUgICBFZGdlICAgICAgQ1BNIGNhc2NhZGUNCiAxNTogICAgICAg
ICAgMCAgIDh4eCBTSVUgICBFZGdlICAgICAgdGJpbnQNCiAxNjogICAgICAgICAgMCAgIENQTSAg
ICAgICBFZGdlICAgICAgZXJyb3INCiAyMDogICAgICAgIDgwMSAgIENQTSAgICAgICBFZGdlICAg
ICAgU01DMQ0KDQphbmQgSSBjYW4gc2VlIHRoZSBudW1iZXIgb2Ygd2JnYV9pbnRlcnJ1cHQgaXMg
aW5jcmVhc2luZy4gQnV0IGEgZmV3IG1pbnV0ZXMgbGF0ZXIgLHRoZSBudW1iZXIgaXMgbG9ja2Vk
IGF0IDEyODAwMCBhcyBmb2xsb3c6DQoNCi9wcm9jICMgY2F0IGludGVycnVwdHMNCiAgICAgICAg
ICAgQ1BVMA0KICAyOiAgICAgMTI4MDAwICAgOHh4IFNJVSAgIEVkZ2UgICAgICB3YmdhX2ludGVy
cnVwdA0KICA1OiAgICAgICAgICAwICAgOHh4IFNJVSAgIEVkZ2UgICAgICBDUE0gY2FzY2FkZQ0K
IDE1OiAgICAgICAgICAwICAgOHh4IFNJVSAgIEVkZ2UgICAgICB0YmludA0KIDE2OiAgICAgICAg
ICAwICAgQ1BNICAgICAgIEVkZ2UgICAgICBlcnJvcg0KIDIwOiAgICAgICAgODMzICAgQ1BNICAg
ICAgIEVkZ2UgICAgICBTTUMxDQoNCmFuZCB0aGVyZSBpcyBubyB3YmdhX2ludGVycnVwdCBhbnkg
bW9yZS4uLi53aGF0J3MgdGhlIG1hdHRlciB3aXRoIHRoZSBpbnRlcnJ1cHQ/d2h5IGlzIDEyODAw
MD8/PyANCg0KDQqhoaGhemp6bmxpYW5nDQqhoaGhoaGhoaGhoaGhoaGhemp6bmxpYW5nX3BvcG9A
MTYzLmNvbQ0KoaGhoaGhoaGhoaGhoaGhoaGhoaEyMDA1LTExLTE1DQo=
^ permalink raw reply
* Re: [PATCH] powerpc: Merge align.c
From: Benjamin Herrenschmidt @ 2005-11-15 5:35 UTC (permalink / raw)
To: Becky Bruce; +Cc: linuxppc64-dev, linuxppc-dev list
In-Reply-To: <269d7972781989e47cc114f8e2124b80@freescale.com>
On Mon, 2005-11-14 at 23:10 -0600, Becky Bruce wrote:
> Ben,
>
> I've just done some basic testing of lmw/stmw, lwz/stw, lhx/sth,
> lfs/stfs, and lfd/stfd misaligned across a doubleword boundary, and
> everything looks good so far. I'll check out the byte reversals and a
> few other forms tomorrow.
Excellent, thanks ! BTW. Make sure you test these one CPUs that actually
trap on misaligned accesses :) Best is probably to do the misaligned
access accross a page boundary, that's what most CPUs can do.
Ben.
^ permalink raw reply
* Re: [PATCH] powerpc: Merge align.c
From: Becky Bruce @ 2005-11-15 5:10 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc64-dev, linuxppc-dev list
In-Reply-To: <1132001719.5504.204.camel@gaston>
Ben,
I've just done some basic testing of lmw/stmw, lwz/stw, lhx/sth,=20
lfs/stfs, and lfd/stfd misaligned across a doubleword boundary, and=20
everything looks good so far. I'll check out the byte reversals and a=20=
few other forms tomorrow.
Cheers,
B
On Nov 14, 2005, at 2:55 PM, Benjamin Herrenschmidt wrote:
> On Mon, 2005-11-14 at 13:53 -0600, Becky Bruce wrote:
> > Ben,
> >
> > I talked to Kumar about this a little bit (I had started a merge of
> > this file, but got distracted!) and he doesn't have any test cases.=A0=
> > I'll put something together and test this out on some of the 32-bit
> > systems I have here in my lab.=A0 It won't be complete, but it will =
be
> > something.......
>
> Thanks,
> Ben.
>
^ permalink raw reply
* [PATCH] powerpc: Merge align.c (#2)
From: Benjamin Herrenschmidt @ 2005-11-15 3:34 UTC (permalink / raw)
To: linuxppc-dev list, linuxppc64-dev
Need testing !!!
This patch merges align.c, the result isn't quite what was in ppc64 nor
what was in ppc32 :) It should implement all the functionalities of both
though. Kumar, since you played with that in the past, I suppose you
have some test cases for verifying that it works properly before I dig
out the 601 machine ? :)
Since it's likely that I won't be able to test all scenario, code
inspection is much welcome.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
No difference, just rebased on current -git
Index: linux-work/arch/powerpc/kernel/Makefile
===================================================================
--- linux-work.orig/arch/powerpc/kernel/Makefile 2005-11-15 13:31:57.000000000 +1100
+++ linux-work/arch/powerpc/kernel/Makefile 2005-11-15 14:31:22.000000000 +1100
@@ -12,7 +12,7 @@
endif
obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
- irq.o signal_32.o pmc.o vdso.o
+ irq.o align.o signal_32.o pmc.o vdso.o
obj-y += vdso32/
obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
signal_64.o ptrace32.o systbl.o \
Index: linux-work/arch/powerpc/kernel/align.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-work/arch/powerpc/kernel/align.c 2005-11-15 14:31:22.000000000 +1100
@@ -0,0 +1,513 @@
+/* align.c - handle alignment exceptions for the Power PC.
+ *
+ * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Copyright (c) 1998-1999 TiVo, Inc.
+ * PowerPC 403GCX modifications.
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * PowerPC 403GCX/405GP modifications.
+ * Copyright (c) 2001-2002 PPC64 team, IBM Corp
+ * 64-bit and Power4 support
+ * Copyright (c) 2005 Benjamin Herrenschmidt, IBM Corp
+ * <benh@kernel.crashing.org>
+ * Merge ppc32 and ppc64 implementations
+ *
+ * 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 the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/cache.h>
+#include <asm/cputable.h>
+
+struct aligninfo {
+ unsigned char len;
+ unsigned char flags;
+};
+
+#define IS_XFORM(inst) (((inst) >> 26) == 31)
+#define IS_DSFORM(inst) (((inst) >> 26) >= 56)
+
+#define INVALID { 0, 0 }
+
+#define LD 1 /* load */
+#define ST 2 /* store */
+#define SE 4 /* sign-extend value */
+#define F 8 /* to/from fp regs */
+#define U 0x10 /* update index register */
+#define M 0x20 /* multiple load/store */
+#define SW 0x40 /* byte swap int or ... */
+#define S 0x40 /* ... single-precision fp */
+#define SX 0x40 /* byte count in XER */
+#define HARD 0x80 /* string, stwcx. */
+
+#define DCBZ 0x5f /* 8xx/82xx dcbz faults when cache not enabled */
+
+#define SWAP(a, b) (t = (a), (a) = (b), (b) = t)
+
+/*
+ * The PowerPC stores certain bits of the instruction that caused the
+ * alignment exception in the DSISR register. This array maps those
+ * bits to information about the operand length and what the
+ * instruction would do.
+ */
+static struct aligninfo aligninfo[128] = {
+ { 4, LD }, /* 00 0 0000: lwz / lwarx */
+ INVALID, /* 00 0 0001 */
+ { 4, ST }, /* 00 0 0010: stw */
+ INVALID, /* 00 0 0011 */
+ { 2, LD }, /* 00 0 0100: lhz */
+ { 2, LD+SE }, /* 00 0 0101: lha */
+ { 2, ST }, /* 00 0 0110: sth */
+ { 4, LD+M }, /* 00 0 0111: lmw */
+ { 4, LD+F+S }, /* 00 0 1000: lfs */
+ { 8, LD+F }, /* 00 0 1001: lfd */
+ { 4, ST+F+S }, /* 00 0 1010: stfs */
+ { 8, ST+F }, /* 00 0 1011: stfd */
+ INVALID, /* 00 0 1100 */
+ { 8, LD }, /* 00 0 1101: ld/ldu/lwa */
+ INVALID, /* 00 0 1110 */
+ { 8, ST }, /* 00 0 1111: std/stdu */
+ { 4, LD+U }, /* 00 1 0000: lwzu */
+ INVALID, /* 00 1 0001 */
+ { 4, ST+U }, /* 00 1 0010: stwu */
+ INVALID, /* 00 1 0011 */
+ { 2, LD+U }, /* 00 1 0100: lhzu */
+ { 2, LD+SE+U }, /* 00 1 0101: lhau */
+ { 2, ST+U }, /* 00 1 0110: sthu */
+ { 4, ST+M }, /* 00 1 0111: stmw */
+ { 4, LD+F+S+U }, /* 00 1 1000: lfsu */
+ { 8, LD+F+U }, /* 00 1 1001: lfdu */
+ { 4, ST+F+S+U }, /* 00 1 1010: stfsu */
+ { 8, ST+F+U }, /* 00 1 1011: stfdu */
+ INVALID, /* 00 1 1100 */
+ INVALID, /* 00 1 1101 */
+ INVALID, /* 00 1 1110 */
+ INVALID, /* 00 1 1111 */
+ { 8, LD }, /* 01 0 0000: ldx */
+ INVALID, /* 01 0 0001 */
+ { 8, ST }, /* 01 0 0010: stdx */
+ INVALID, /* 01 0 0011 */
+ INVALID, /* 01 0 0100 */
+ { 4, LD+SE }, /* 01 0 0101: lwax */
+ INVALID, /* 01 0 0110 */
+ INVALID, /* 01 0 0111 */
+ { 4, LD+M+HARD+SX }, /* 01 0 1000: lswx */
+ { 4, LD+M+HARD }, /* 01 0 1001: lswi */
+ { 4, ST+M+HARD+SX }, /* 01 0 1010: stswx */
+ { 4, ST+M+HARD }, /* 01 0 1011: stswi */
+ INVALID, /* 01 0 1100 */
+ { 8, LD+U }, /* 01 0 1101: ldu */
+ INVALID, /* 01 0 1110 */
+ { 8, ST+U }, /* 01 0 1111: stdu */
+ { 8, LD+U }, /* 01 1 0000: ldux */
+ INVALID, /* 01 1 0001 */
+ { 8, ST+U }, /* 01 1 0010: stdux */
+ INVALID, /* 01 1 0011 */
+ INVALID, /* 01 1 0100 */
+ { 4, LD+SE+U }, /* 01 1 0101: lwaux */
+ INVALID, /* 01 1 0110 */
+ INVALID, /* 01 1 0111 */
+ INVALID, /* 01 1 1000 */
+ INVALID, /* 01 1 1001 */
+ INVALID, /* 01 1 1010 */
+ INVALID, /* 01 1 1011 */
+ INVALID, /* 01 1 1100 */
+ INVALID, /* 01 1 1101 */
+ INVALID, /* 01 1 1110 */
+ INVALID, /* 01 1 1111 */
+ INVALID, /* 10 0 0000 */
+ INVALID, /* 10 0 0001 */
+ INVALID, /* 10 0 0010: stwcx. */
+ INVALID, /* 10 0 0011 */
+ INVALID, /* 10 0 0100 */
+ INVALID, /* 10 0 0101 */
+ INVALID, /* 10 0 0110 */
+ INVALID, /* 10 0 0111 */
+ { 4, LD+SW }, /* 10 0 1000: lwbrx */
+ INVALID, /* 10 0 1001 */
+ { 4, ST+SW }, /* 10 0 1010: stwbrx */
+ INVALID, /* 10 0 1011 */
+ { 2, LD+SW }, /* 10 0 1100: lhbrx */
+ { 4, LD+SE }, /* 10 0 1101 lwa */
+ { 2, ST+SW }, /* 10 0 1110: sthbrx */
+ INVALID, /* 10 0 1111 */
+ INVALID, /* 10 1 0000 */
+ INVALID, /* 10 1 0001 */
+ INVALID, /* 10 1 0010 */
+ INVALID, /* 10 1 0011 */
+ INVALID, /* 10 1 0100 */
+ INVALID, /* 10 1 0101 */
+ INVALID, /* 10 1 0110 */
+ INVALID, /* 10 1 0111 */
+ INVALID, /* 10 1 1000 */
+ INVALID, /* 10 1 1001 */
+ INVALID, /* 10 1 1010 */
+ INVALID, /* 10 1 1011 */
+ INVALID, /* 10 1 1100 */
+ INVALID, /* 10 1 1101 */
+ INVALID, /* 10 1 1110 */
+ { 0, ST+HARD }, /* 10 1 1111: dcbz */
+ { 4, LD }, /* 11 0 0000: lwzx */
+ INVALID, /* 11 0 0001 */
+ { 4, ST }, /* 11 0 0010: stwx */
+ INVALID, /* 11 0 0011 */
+ { 2, LD }, /* 11 0 0100: lhzx */
+ { 2, LD+SE }, /* 11 0 0101: lhax */
+ { 2, ST }, /* 11 0 0110: sthx */
+ INVALID, /* 11 0 0111 */
+ { 4, LD+F+S }, /* 11 0 1000: lfsx */
+ { 8, LD+F }, /* 11 0 1001: lfdx */
+ { 4, ST+F+S }, /* 11 0 1010: stfsx */
+ { 8, ST+F }, /* 11 0 1011: stfdx */
+ INVALID, /* 11 0 1100 */
+ { 8, LD+M }, /* 11 0 1101: lmd */
+ INVALID, /* 11 0 1110 */
+ { 8, ST+M }, /* 11 0 1111: stmd */
+ { 4, LD+U }, /* 11 1 0000: lwzux */
+ INVALID, /* 11 1 0001 */
+ { 4, ST+U }, /* 11 1 0010: stwux */
+ INVALID, /* 11 1 0011 */
+ { 2, LD+U }, /* 11 1 0100: lhzux */
+ { 2, LD+SE+U }, /* 11 1 0101: lhaux */
+ { 2, ST+U }, /* 11 1 0110: sthux */
+ INVALID, /* 11 1 0111 */
+ { 4, LD+F+S+U }, /* 11 1 1000: lfsux */
+ { 8, LD+F+U }, /* 11 1 1001: lfdux */
+ { 4, ST+F+S+U }, /* 11 1 1010: stfsux */
+ { 8, ST+F+U }, /* 11 1 1011: stfdux */
+ INVALID, /* 11 1 1100 */
+ INVALID, /* 11 1 1101 */
+ INVALID, /* 11 1 1110 */
+ INVALID, /* 11 1 1111 */
+};
+
+/*
+ * Create a DSISR value from the instruction
+ */
+static inline unsigned make_dsisr(unsigned instr)
+{
+ unsigned dsisr;
+
+
+ /* bits 6:15 --> 22:31 */
+ dsisr = (instr & 0x03ff0000) >> 16;
+
+ if ( IS_XFORM(instr) ) {
+ /* bits 29:30 --> 15:16 */
+ dsisr |= (instr & 0x00000006) << 14;
+ /* bit 25 --> 17 */
+ dsisr |= (instr & 0x00000040) << 8;
+ /* bits 21:24 --> 18:21 */
+ dsisr |= (instr & 0x00000780) << 3;
+ }
+ else {
+ /* bit 5 --> 17 */
+ dsisr |= (instr & 0x04000000) >> 12;
+ /* bits 1: 4 --> 18:21 */
+ dsisr |= (instr & 0x78000000) >> 17;
+ /* bits 30:31 --> 12:13 */
+ if ( IS_DSFORM(instr) )
+ dsisr |= (instr & 0x00000003) << 18;
+ }
+
+ return dsisr;
+}
+
+/*
+ * The dcbz (data cache block zero) instruction
+ * gives an alignment fault if used on non-cacheable
+ * memory. We handle the fault mainly for the
+ * case when we are running with the cache disabled
+ * for debugging.
+ */
+static int emulate_dcbz(struct pt_regs *regs, unsigned char __user *addr)
+{
+ long __user *p;
+ int i, size;
+
+#ifdef __powerpc64__
+ size = ppc64_caches.dline_size;
+#else
+ size = L1_CACHE_BYTES;
+#endif
+ p = (long __user *) (regs->dar & -size);
+ if (user_mode(regs) && !access_ok(VERIFY_WRITE, p, size))
+ return -EFAULT;
+ for (i = 0; i < size / sizeof(long); ++i)
+ if (__put_user(0, p+i))
+ return -EFAULT;
+ return 1;
+}
+
+/*
+ * Emulate load & store multiple instructions
+ */
+static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr,
+ unsigned int reg, unsigned int nb,
+ unsigned int flags, unsigned int instr)
+{
+ unsigned char *rptr;
+ int nb0, i;
+
+ /*
+ * We do not try to emulate 8 bytes multiple as they aren't really
+ * available in our operating environments and we don't try to
+ * emulate multiples operations in kernel land as they should never
+ * be used/generated there at least not on unaligned boundaries
+ */
+ if (unlikely((nb > 4) || !user_mode(regs)))
+ return 0;
+
+ /* lmw, stmw, lswi/x, stswi/x */
+ nb0 = 0;
+ if (flags & HARD) {
+ if (flags & SX) {
+ nb = regs->xer & 127;
+ if (nb == 0)
+ return 1;
+ } else {
+ if (__get_user(instr,
+ (unsigned int __user *)regs->nip))
+ return -EFAULT;
+ nb = (instr >> 11) & 0x1f;
+ if (nb == 0)
+ nb = 32;
+ }
+ if (nb + reg * 4 > 128) {
+ nb0 = nb + reg * 4 - 128;
+ nb = 128 - reg * 4;
+ }
+ } else {
+ /* lwm, stmw */
+ nb = (32 - reg) * 4;
+ }
+
+ if (!access_ok((flags & ST ? VERIFY_WRITE: VERIFY_READ), addr, nb+nb0))
+ return -EFAULT; /* bad address */
+
+ rptr = (unsigned char *) ®s->gpr[reg];
+ if (flags & LD) {
+ for (i = 0; i < nb; ++i)
+ if (__get_user(rptr[i], addr + i))
+ return -EFAULT;
+ if (nb0 > 0) {
+ rptr = (unsigned char *) ®s->gpr[0];
+ addr += nb;
+ for (i = 0; i < nb0; ++i)
+ if (__get_user(rptr[i], addr + i))
+ return -EFAULT;
+ }
+ for (; (i & 3) != 0; ++i)
+ rptr[i] = 0;
+ } else {
+ for (i = 0; i < nb; ++i)
+ if (__put_user(rptr[i], addr + i))
+ return -EFAULT;
+ if (nb0 > 0) {
+ rptr = (unsigned char *) ®s->gpr[0];
+ addr += nb;
+ for (i = 0; i < nb0; ++i)
+ if (__put_user(rptr[i], addr + i))
+ return -EFAULT;
+ }
+ }
+ return 1;
+}
+
+
+/*
+ * Called on alignment exception. Attempts to fixup
+ *
+ * Return 1 on success
+ * Return 0 if unable to handle the interrupt
+ * Return -EFAULT if data address is bad
+ */
+
+int fix_alignment(struct pt_regs *regs)
+{
+ unsigned int instr, nb, flags;
+ unsigned int reg, areg;
+ unsigned int dsisr;
+ unsigned char __user *addr;
+ unsigned char __user *p;
+ int ret, t;
+ union {
+ long ll;
+ double dd;
+ unsigned char v[8];
+ struct {
+ unsigned hi32;
+ int low32;
+ } x32;
+ struct {
+ unsigned char hi48[6];
+ short low16;
+ } x16;
+ } data;
+
+ /*
+ * We require a complete register set, if not, then our assembly
+ * is broken
+ */
+ CHECK_FULL_REGS(regs);
+
+ dsisr = regs->dsisr;
+
+ /* Some processors don't provide us with a DSISR we can use here,
+ * let's make one up from the instruction
+ */
+ if (cpu_has_feature(CPU_FTR_NODSISRALIGN)) {
+ unsigned int real_instr;
+ if (unlikely(__get_user(real_instr,
+ (unsigned int __user *)regs->nip)))
+ return -EFAULT;
+ dsisr = make_dsisr(real_instr);
+ }
+
+ /* extract the operation and registers from the dsisr */
+ reg = (dsisr >> 5) & 0x1f; /* source/dest register */
+ areg = dsisr & 0x1f; /* register to update */
+ instr = (dsisr >> 10) & 0x7f;
+ instr |= (dsisr >> 13) & 0x60;
+
+ /* Lookup the operation in our table */
+ nb = aligninfo[instr].len;
+ flags = aligninfo[instr].flags;
+
+ /* DAR has the operand effective address */
+ addr = (unsigned char __user *)regs->dar;
+
+ /* A size of 0 indicates an instruction we don't support, with
+ * the exception of DCBZ which is handled as a special case here
+ */
+ if (instr == DCBZ)
+ return emulate_dcbz(regs, addr);
+ if (unlikely(nb == 0))
+ return 0;
+
+ /* Load/Store Multiple instructions are handled in their own
+ * function
+ */
+ if (flags & M)
+ return emulate_multiple(regs, addr, reg, nb, flags, instr);
+
+ /* Verify the address of the operand */
+ if (unlikely(user_mode(regs) &&
+ !access_ok((flags & ST ? VERIFY_WRITE : VERIFY_READ),
+ addr, nb)))
+ return -EFAULT;
+
+ /* Force the fprs into the save area so we can reference them */
+ if (flags & F) {
+ /* userland only */
+ if (unlikely(!user_mode(regs)))
+ return 0;
+ flush_fp_to_thread(current);
+ }
+
+ /* If we are loading, get the data from user space, else
+ * get it from register values
+ */
+ if (flags & LD) {
+ data.ll = 0;
+ ret = 0;
+ p = addr;
+ switch (nb) {
+ case 8:
+ ret |= __get_user(data.v[0], p++);
+ ret |= __get_user(data.v[1], p++);
+ ret |= __get_user(data.v[2], p++);
+ ret |= __get_user(data.v[3], p++);
+ case 4:
+ ret |= __get_user(data.v[4], p++);
+ ret |= __get_user(data.v[5], p++);
+ case 2:
+ ret |= __get_user(data.v[6], p++);
+ ret |= __get_user(data.v[7], p++);
+ if (unlikely(ret))
+ return -EFAULT;
+ }
+ } else if (flags & F)
+ data.dd = current->thread.fpr[reg];
+ else
+ data.ll = regs->gpr[reg];
+
+ /* Perform other misc operations like sign extension, byteswap,
+ * or floating point single precision conversion
+ */
+ switch (flags & ~U) {
+ case LD+SE: /* sign extend */
+ if ( nb == 2 )
+ data.ll = data.x16.low16;
+ else /* nb must be 4 */
+ data.ll = data.x32.low32;
+ break;
+ case LD+S: /* byte-swap */
+ case ST+S:
+ if (nb == 2) {
+ SWAP(data.v[6], data.v[7]);
+ } else {
+ SWAP(data.v[4], data.v[7]);
+ SWAP(data.v[5], data.v[6]);
+ }
+ break;
+
+ /* Single-precision FP load and store require conversions... */
+ case LD+F+S:
+#ifdef CONFIG_PPC_FPU
+ preempt_disable();
+ enable_kernel_fp();
+ cvt_fd((float *)&data.v[4], &data.dd, ¤t->thread);
+ preempt_enable();
+#else
+ return 0;
+#endif
+ break;
+ case ST+F+S:
+#ifdef CONFIG_PPC_FPU
+ preempt_disable();
+ enable_kernel_fp();
+ cvt_df(&data.dd, (float *)&data.v[4], ¤t->thread);
+ preempt_enable();
+#else
+ return 0;
+#endif
+ break;
+ }
+
+ /* Store result to memory or update registers */
+ if (flags & ST) {
+ ret = 0;
+ p = addr;
+ switch (nb) {
+ case 8:
+ ret |= __put_user(data.v[0], p++);
+ ret |= __put_user(data.v[1], p++);
+ ret |= __put_user(data.v[2], p++);
+ ret |= __put_user(data.v[3], p++);
+ case 4:
+ ret |= __put_user(data.v[4], p++);
+ ret |= __put_user(data.v[5], p++);
+ case 2:
+ ret |= __put_user(data.v[6], p++);
+ ret |= __put_user(data.v[7], p++);
+ }
+ if (unlikely(ret))
+ return -EFAULT;
+ } else if (flags & F)
+ current->thread.fpr[reg] = data.dd;
+ else
+ regs->gpr[reg] = data.ll;
+
+ /* Update RA as needed */
+ if (flags & U)
+ regs->gpr[areg] = regs->dar;
+
+ return 1;
+}
Index: linux-work/arch/ppc/kernel/Makefile
===================================================================
--- linux-work.orig/arch/ppc/kernel/Makefile 2005-11-11 10:14:48.000000000 +1100
+++ linux-work/arch/ppc/kernel/Makefile 2005-11-15 14:31:22.000000000 +1100
@@ -13,7 +13,7 @@
extra-y += vmlinux.lds
obj-y := entry.o traps.o idle.o time.o misc.o \
- process.o align.o \
+ process.o \
setup.o \
ppc_htab.o
obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
Index: linux-work/arch/ppc64/kernel/Makefile
===================================================================
--- linux-work.orig/arch/ppc64/kernel/Makefile 2005-11-15 14:30:34.000000000 +1100
+++ linux-work/arch/ppc64/kernel/Makefile 2005-11-15 14:31:37.000000000 +1100
@@ -2,6 +2,6 @@
# Makefile for the linux ppc64 kernel.
#
-obj-y += idle.o align.o
+obj-y += idle.o
obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o
Index: linux-work/include/asm-powerpc/cputable.h
===================================================================
--- linux-work.orig/include/asm-powerpc/cputable.h 2005-11-11 10:14:49.000000000 +1100
+++ linux-work/include/asm-powerpc/cputable.h 2005-11-15 14:31:22.000000000 +1100
@@ -90,6 +90,7 @@
#define CPU_FTR_NEED_COHERENT ASM_CONST(0x0000000000020000)
#define CPU_FTR_NO_BTIC ASM_CONST(0x0000000000040000)
#define CPU_FTR_BIG_PHYS ASM_CONST(0x0000000000080000)
+#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000000000100000)
#ifdef __powerpc64__
/* Add the 64b processor unique features in the top half of the word */
@@ -97,7 +98,6 @@
#define CPU_FTR_16M_PAGE ASM_CONST(0x0000000200000000)
#define CPU_FTR_TLBIEL ASM_CONST(0x0000000400000000)
#define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000800000000)
-#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000001000000000)
#define CPU_FTR_IABR ASM_CONST(0x0000002000000000)
#define CPU_FTR_MMCRA ASM_CONST(0x0000004000000000)
#define CPU_FTR_CTRL ASM_CONST(0x0000008000000000)
@@ -113,7 +113,6 @@
#define CPU_FTR_16M_PAGE ASM_CONST(0x0)
#define CPU_FTR_TLBIEL ASM_CONST(0x0)
#define CPU_FTR_NOEXECUTE ASM_CONST(0x0)
-#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0)
#define CPU_FTR_IABR ASM_CONST(0x0)
#define CPU_FTR_MMCRA ASM_CONST(0x0)
#define CPU_FTR_CTRL ASM_CONST(0x0)
@@ -273,18 +272,21 @@
CPU_FTRS_POWER3_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
CPU_FTRS_POWER4_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
- CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+ CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_NODSISRALIGN,
CPU_FTRS_970_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE |
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_ALTIVEC_COMP |
- CPU_FTR_MAYBE_CAN_NAP,
+ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN,
CPU_FTRS_8XX = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
- CPU_FTRS_40X = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
- CPU_FTRS_44X = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
- CPU_FTRS_E200 = CPU_FTR_USE_TB,
- CPU_FTRS_E500 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+ CPU_FTRS_40X = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_NODSISRALIGN,
+ CPU_FTRS_44X = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_NODSISRALIGN,
+ CPU_FTRS_E200 = CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN,
+ CPU_FTRS_E500 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
+ CPU_FTR_NODSISRALIGN,
CPU_FTRS_E500_2 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
- CPU_FTR_BIG_PHYS,
- CPU_FTRS_GENERIC_32 = CPU_FTR_COMMON,
+ CPU_FTR_BIG_PHYS | CPU_FTR_NODSISRALIGN,
+ CPU_FTRS_GENERIC_32 = CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN,
#ifdef __powerpc64__
CPU_FTRS_POWER3 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
CPU_FTR_HPTE_TABLE | CPU_FTR_IABR,
Index: linux-work/arch/ppc64/kernel/align.c
===================================================================
--- linux-work.orig/arch/ppc64/kernel/align.c 2005-11-15 14:30:34.000000000 +1100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,396 +0,0 @@
-/* align.c - handle alignment exceptions for the Power PC.
- *
- * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
- * Copyright (c) 1998-1999 TiVo, Inc.
- * PowerPC 403GCX modifications.
- * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
- * PowerPC 403GCX/405GP modifications.
- * Copyright (c) 2001-2002 PPC64 team, IBM Corp
- * 64-bit and Power4 support
- *
- * 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 the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/cache.h>
-#include <asm/cputable.h>
-
-struct aligninfo {
- unsigned char len;
- unsigned char flags;
-};
-
-#define IS_XFORM(inst) (((inst) >> 26) == 31)
-#define IS_DSFORM(inst) (((inst) >> 26) >= 56)
-
-#define INVALID { 0, 0 }
-
-#define LD 1 /* load */
-#define ST 2 /* store */
-#define SE 4 /* sign-extend value */
-#define F 8 /* to/from fp regs */
-#define U 0x10 /* update index register */
-#define M 0x20 /* multiple load/store */
-#define SW 0x40 /* byte swap */
-
-#define DCBZ 0x5f /* 8xx/82xx dcbz faults when cache not enabled */
-
-/*
- * The PowerPC stores certain bits of the instruction that caused the
- * alignment exception in the DSISR register. This array maps those
- * bits to information about the operand length and what the
- * instruction would do.
- */
-static struct aligninfo aligninfo[128] = {
- { 4, LD }, /* 00 0 0000: lwz / lwarx */
- INVALID, /* 00 0 0001 */
- { 4, ST }, /* 00 0 0010: stw */
- INVALID, /* 00 0 0011 */
- { 2, LD }, /* 00 0 0100: lhz */
- { 2, LD+SE }, /* 00 0 0101: lha */
- { 2, ST }, /* 00 0 0110: sth */
- { 4, LD+M }, /* 00 0 0111: lmw */
- { 4, LD+F }, /* 00 0 1000: lfs */
- { 8, LD+F }, /* 00 0 1001: lfd */
- { 4, ST+F }, /* 00 0 1010: stfs */
- { 8, ST+F }, /* 00 0 1011: stfd */
- INVALID, /* 00 0 1100 */
- { 8, LD }, /* 00 0 1101: ld */
- INVALID, /* 00 0 1110 */
- { 8, ST }, /* 00 0 1111: std */
- { 4, LD+U }, /* 00 1 0000: lwzu */
- INVALID, /* 00 1 0001 */
- { 4, ST+U }, /* 00 1 0010: stwu */
- INVALID, /* 00 1 0011 */
- { 2, LD+U }, /* 00 1 0100: lhzu */
- { 2, LD+SE+U }, /* 00 1 0101: lhau */
- { 2, ST+U }, /* 00 1 0110: sthu */
- { 4, ST+M }, /* 00 1 0111: stmw */
- { 4, LD+F+U }, /* 00 1 1000: lfsu */
- { 8, LD+F+U }, /* 00 1 1001: lfdu */
- { 4, ST+F+U }, /* 00 1 1010: stfsu */
- { 8, ST+F+U }, /* 00 1 1011: stfdu */
- INVALID, /* 00 1 1100 */
- INVALID, /* 00 1 1101 */
- INVALID, /* 00 1 1110 */
- INVALID, /* 00 1 1111 */
- { 8, LD }, /* 01 0 0000: ldx */
- INVALID, /* 01 0 0001 */
- { 8, ST }, /* 01 0 0010: stdx */
- INVALID, /* 01 0 0011 */
- INVALID, /* 01 0 0100 */
- { 4, LD+SE }, /* 01 0 0101: lwax */
- INVALID, /* 01 0 0110 */
- INVALID, /* 01 0 0111 */
- { 0, LD }, /* 01 0 1000: lswx */
- { 0, LD }, /* 01 0 1001: lswi */
- { 0, ST }, /* 01 0 1010: stswx */
- { 0, ST }, /* 01 0 1011: stswi */
- INVALID, /* 01 0 1100 */
- { 8, LD+U }, /* 01 0 1101: ldu */
- INVALID, /* 01 0 1110 */
- { 8, ST+U }, /* 01 0 1111: stdu */
- { 8, LD+U }, /* 01 1 0000: ldux */
- INVALID, /* 01 1 0001 */
- { 8, ST+U }, /* 01 1 0010: stdux */
- INVALID, /* 01 1 0011 */
- INVALID, /* 01 1 0100 */
- { 4, LD+SE+U }, /* 01 1 0101: lwaux */
- INVALID, /* 01 1 0110 */
- INVALID, /* 01 1 0111 */
- INVALID, /* 01 1 1000 */
- INVALID, /* 01 1 1001 */
- INVALID, /* 01 1 1010 */
- INVALID, /* 01 1 1011 */
- INVALID, /* 01 1 1100 */
- INVALID, /* 01 1 1101 */
- INVALID, /* 01 1 1110 */
- INVALID, /* 01 1 1111 */
- INVALID, /* 10 0 0000 */
- INVALID, /* 10 0 0001 */
- { 0, ST }, /* 10 0 0010: stwcx. */
- INVALID, /* 10 0 0011 */
- INVALID, /* 10 0 0100 */
- INVALID, /* 10 0 0101 */
- INVALID, /* 10 0 0110 */
- INVALID, /* 10 0 0111 */
- { 4, LD+SW }, /* 10 0 1000: lwbrx */
- INVALID, /* 10 0 1001 */
- { 4, ST+SW }, /* 10 0 1010: stwbrx */
- INVALID, /* 10 0 1011 */
- { 2, LD+SW }, /* 10 0 1100: lhbrx */
- { 4, LD+SE }, /* 10 0 1101 lwa */
- { 2, ST+SW }, /* 10 0 1110: sthbrx */
- INVALID, /* 10 0 1111 */
- INVALID, /* 10 1 0000 */
- INVALID, /* 10 1 0001 */
- INVALID, /* 10 1 0010 */
- INVALID, /* 10 1 0011 */
- INVALID, /* 10 1 0100 */
- INVALID, /* 10 1 0101 */
- INVALID, /* 10 1 0110 */
- INVALID, /* 10 1 0111 */
- INVALID, /* 10 1 1000 */
- INVALID, /* 10 1 1001 */
- INVALID, /* 10 1 1010 */
- INVALID, /* 10 1 1011 */
- INVALID, /* 10 1 1100 */
- INVALID, /* 10 1 1101 */
- INVALID, /* 10 1 1110 */
- { L1_CACHE_BYTES, ST }, /* 10 1 1111: dcbz */
- { 4, LD }, /* 11 0 0000: lwzx */
- INVALID, /* 11 0 0001 */
- { 4, ST }, /* 11 0 0010: stwx */
- INVALID, /* 11 0 0011 */
- { 2, LD }, /* 11 0 0100: lhzx */
- { 2, LD+SE }, /* 11 0 0101: lhax */
- { 2, ST }, /* 11 0 0110: sthx */
- INVALID, /* 11 0 0111 */
- { 4, LD+F }, /* 11 0 1000: lfsx */
- { 8, LD+F }, /* 11 0 1001: lfdx */
- { 4, ST+F }, /* 11 0 1010: stfsx */
- { 8, ST+F }, /* 11 0 1011: stfdx */
- INVALID, /* 11 0 1100 */
- { 8, LD+M }, /* 11 0 1101: lmd */
- INVALID, /* 11 0 1110 */
- { 8, ST+M }, /* 11 0 1111: stmd */
- { 4, LD+U }, /* 11 1 0000: lwzux */
- INVALID, /* 11 1 0001 */
- { 4, ST+U }, /* 11 1 0010: stwux */
- INVALID, /* 11 1 0011 */
- { 2, LD+U }, /* 11 1 0100: lhzux */
- { 2, LD+SE+U }, /* 11 1 0101: lhaux */
- { 2, ST+U }, /* 11 1 0110: sthux */
- INVALID, /* 11 1 0111 */
- { 4, LD+F+U }, /* 11 1 1000: lfsux */
- { 8, LD+F+U }, /* 11 1 1001: lfdux */
- { 4, ST+F+U }, /* 11 1 1010: stfsux */
- { 8, ST+F+U }, /* 11 1 1011: stfdux */
- INVALID, /* 11 1 1100 */
- INVALID, /* 11 1 1101 */
- INVALID, /* 11 1 1110 */
- INVALID, /* 11 1 1111 */
-};
-
-#define SWAP(a, b) (t = (a), (a) = (b), (b) = t)
-
-static inline unsigned make_dsisr(unsigned instr)
-{
- unsigned dsisr;
-
- /* create a DSISR value from the instruction */
- dsisr = (instr & 0x03ff0000) >> 16; /* bits 6:15 --> 22:31 */
-
- if ( IS_XFORM(instr) ) {
- dsisr |= (instr & 0x00000006) << 14; /* bits 29:30 --> 15:16 */
- dsisr |= (instr & 0x00000040) << 8; /* bit 25 --> 17 */
- dsisr |= (instr & 0x00000780) << 3; /* bits 21:24 --> 18:21 */
- }
- else {
- dsisr |= (instr & 0x04000000) >> 12; /* bit 5 --> 17 */
- dsisr |= (instr & 0x78000000) >> 17; /* bits 1: 4 --> 18:21 */
- if ( IS_DSFORM(instr) ) {
- dsisr |= (instr & 0x00000003) << 18; /* bits 30:31 --> 12:13 */
- }
- }
-
- return dsisr;
-}
-
-int
-fix_alignment(struct pt_regs *regs)
-{
- unsigned int instr, nb, flags;
- int t;
- unsigned long reg, areg;
- unsigned long i;
- int ret;
- unsigned dsisr;
- unsigned char __user *addr;
- unsigned char __user *p;
- unsigned long __user *lp;
- union {
- long ll;
- double dd;
- unsigned char v[8];
- struct {
- unsigned hi32;
- int low32;
- } x32;
- struct {
- unsigned char hi48[6];
- short low16;
- } x16;
- } data;
-
- /*
- * Return 1 on success
- * Return 0 if unable to handle the interrupt
- * Return -EFAULT if data address is bad
- */
-
- dsisr = regs->dsisr;
-
- if (cpu_has_feature(CPU_FTR_NODSISRALIGN)) {
- unsigned int real_instr;
- if (__get_user(real_instr, (unsigned int __user *)regs->nip))
- return 0;
- dsisr = make_dsisr(real_instr);
- }
-
- /* extract the operation and registers from the dsisr */
- reg = (dsisr >> 5) & 0x1f; /* source/dest register */
- areg = dsisr & 0x1f; /* register to update */
- instr = (dsisr >> 10) & 0x7f;
- instr |= (dsisr >> 13) & 0x60;
-
- /* Lookup the operation in our table */
- nb = aligninfo[instr].len;
- flags = aligninfo[instr].flags;
-
- /* DAR has the operand effective address */
- addr = (unsigned char __user *)regs->dar;
-
- /* A size of 0 indicates an instruction we don't support */
- /* we also don't support the multiples (lmw, stmw, lmd, stmd) */
- if ((nb == 0) || (flags & M))
- return 0; /* too hard or invalid instruction */
-
- /*
- * Special handling for dcbz
- * dcbz may give an alignment exception for accesses to caching inhibited
- * storage
- */
- if (instr == DCBZ)
- addr = (unsigned char __user *) ((unsigned long)addr & -L1_CACHE_BYTES);
-
- /* Verify the address of the operand */
- if (user_mode(regs)) {
- if (!access_ok((flags & ST? VERIFY_WRITE: VERIFY_READ), addr, nb))
- return -EFAULT; /* bad address */
- }
-
- /* Force the fprs into the save area so we can reference them */
- if (flags & F) {
- if (!user_mode(regs))
- return 0;
- flush_fp_to_thread(current);
- }
-
- /* If we are loading, get the data from user space */
- if (flags & LD) {
- data.ll = 0;
- ret = 0;
- p = addr;
- switch (nb) {
- case 8:
- ret |= __get_user(data.v[0], p++);
- ret |= __get_user(data.v[1], p++);
- ret |= __get_user(data.v[2], p++);
- ret |= __get_user(data.v[3], p++);
- case 4:
- ret |= __get_user(data.v[4], p++);
- ret |= __get_user(data.v[5], p++);
- case 2:
- ret |= __get_user(data.v[6], p++);
- ret |= __get_user(data.v[7], p++);
- if (ret)
- return -EFAULT;
- }
- }
-
- /* If we are storing, get the data from the saved gpr or fpr */
- if (flags & ST) {
- if (flags & F) {
- if (nb == 4) {
- /* Doing stfs, have to convert to single */
- preempt_disable();
- enable_kernel_fp();
- cvt_df(¤t->thread.fpr[reg], (float *)&data.v[4], ¤t->thread);
- disable_kernel_fp();
- preempt_enable();
- }
- else
- data.dd = current->thread.fpr[reg];
- }
- else
- data.ll = regs->gpr[reg];
- }
-
- /* Swap bytes as needed */
- if (flags & SW) {
- if (nb == 2)
- SWAP(data.v[6], data.v[7]);
- else { /* nb must be 4 */
- SWAP(data.v[4], data.v[7]);
- SWAP(data.v[5], data.v[6]);
- }
- }
-
- /* Sign extend as needed */
- if (flags & SE) {
- if ( nb == 2 )
- data.ll = data.x16.low16;
- else /* nb must be 4 */
- data.ll = data.x32.low32;
- }
-
- /* If we are loading, move the data to the gpr or fpr */
- if (flags & LD) {
- if (flags & F) {
- if (nb == 4) {
- /* Doing lfs, have to convert to double */
- preempt_disable();
- enable_kernel_fp();
- cvt_fd((float *)&data.v[4], ¤t->thread.fpr[reg], ¤t->thread);
- disable_kernel_fp();
- preempt_enable();
- }
- else
- current->thread.fpr[reg] = data.dd;
- }
- else
- regs->gpr[reg] = data.ll;
- }
-
- /* If we are storing, copy the data to the user */
- if (flags & ST) {
- ret = 0;
- p = addr;
- switch (nb) {
- case 128: /* Special case - must be dcbz */
- lp = (unsigned long __user *)p;
- for (i = 0; i < L1_CACHE_BYTES / sizeof(long); ++i)
- ret |= __put_user(0, lp++);
- break;
- case 8:
- ret |= __put_user(data.v[0], p++);
- ret |= __put_user(data.v[1], p++);
- ret |= __put_user(data.v[2], p++);
- ret |= __put_user(data.v[3], p++);
- case 4:
- ret |= __put_user(data.v[4], p++);
- ret |= __put_user(data.v[5], p++);
- case 2:
- ret |= __put_user(data.v[6], p++);
- ret |= __put_user(data.v[7], p++);
- }
- if (ret)
- return -EFAULT;
- }
-
- /* Update RA as needed */
- if (flags & U) {
- regs->gpr[areg] = regs->dar;
- }
-
- return 1;
-}
-
^ permalink raw reply
* Re: [Edson.Seabra@cyclades.com: Re: BDI and 85xx]
From: Dan Malek @ 2005-11-15 0:27 UTC (permalink / raw)
To: Kumar Gala; +Cc: linux-ppc-embedded
In-Reply-To: <475D0B8F-FF5A-44DC-9D03-7156AFE2AAB0@kernel.crashing.org>
On Nov 14, 2005, at 5:50 PM, Kumar Gala wrote:
> I'm not 100% sure this is even possible on some of the book-e variants.
I suspect we could if we didn't just keep whacking
the MSR with some constant value :-) What
happens if we just leave DE set all of the time?
I know as part of ptrace, etc. it can get manipulated,
but if we are debugging through COP we shouldn't
get to these software functions.
-- Dan
^ permalink raw reply
* Re: [RFC] Attempt to clean up sigsuspend et al
From: David Woodhouse @ 2005-11-15 0:19 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <17270.58406.370195.733887@cargo.ozlabs.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 772 bytes --]
On Sun, 2005-11-13 at 17:58 +1100, Paul Mackerras wrote:
> I'll be upset if you can shorten it by a lot - I thought I had it
> pretty tight already. :)
The patch appears to speed up a null syscall benchmark by about 3%.
With the old kernel I get an average of 5863600 cycles for 100000
getpid() calls; with the new kernel it's 5695256 cycles.
I still haven't done much testing for correctness, but it needs at least
this (d'oh)...
--- arch/powerpc/kernel/entry_64.S~ 2005-11-14 23:41:22.000000000 +0000
+++ arch/powerpc/kernel/entry_64.S 2005-11-14 23:45:35.000000000 +0000
@@ -295,7 +295,7 @@ save_user_nvgprs:
ori r10,r10,MSR_EE
mtmsrd r10,1
- ld r10,TI_SIGFRAME(r9)
+ ld r10,TI_SIGFRAME(r12)
andi. r0,r9,_TIF_32BIT
beq- save_user_nvgprs_64
--
dwmw2
[-- Attachment #2: newkernel.txt --]
[-- Type: text/plain, Size: 2040 bytes --]
Used 5687730 cycles
Used 5721828 cycles
Used 5686992 cycles
Used 5658466 cycles
Used 5630346 cycles
Used 5640494 cycles
Used 5709830 cycles
Used 5654279 cycles
Used 5659045 cycles
Used 5747328 cycles
Used 5635214 cycles
Used 5694711 cycles
Used 5646751 cycles
Used 5738407 cycles
Used 5898139 cycles
Used 5787047 cycles
Used 5670900 cycles
Used 5707616 cycles
Used 5694654 cycles
Used 5722101 cycles
Used 5666626 cycles
Used 5702401 cycles
Used 5723496 cycles
Used 5708662 cycles
Used 5675878 cycles
Used 5772019 cycles
Used 5653936 cycles
Used 5675029 cycles
Used 5657729 cycles
Used 5694485 cycles
Used 5781104 cycles
Used 5687276 cycles
Used 5668391 cycles
Used 5661477 cycles
Used 5729791 cycles
Used 5667902 cycles
Used 5669606 cycles
Used 5655594 cycles
Used 5703992 cycles
Used 5685671 cycles
Used 5659003 cycles
Used 5710373 cycles
Used 5754017 cycles
Used 5677565 cycles
Used 5699307 cycles
Used 5734777 cycles
Used 5647465 cycles
Used 5630120 cycles
Used 5688174 cycles
Used 5697787 cycles
Used 5735130 cycles
Used 5795555 cycles
Used 5657136 cycles
Used 5705851 cycles
Used 5708684 cycles
Used 5680934 cycles
Used 5666883 cycles
Used 5650389 cycles
Used 5702600 cycles
Used 5692186 cycles
Used 5667843 cycles
Used 5612066 cycles
Used 5675461 cycles
Used 5663601 cycles
Used 5667161 cycles
Used 5736776 cycles
Used 5727070 cycles
Used 5720203 cycles
Used 5824526 cycles
Used 5694799 cycles
Used 5600060 cycles
Used 5767003 cycles
Used 5691184 cycles
Used 5705613 cycles
Used 5670786 cycles
Used 5728827 cycles
Used 5685249 cycles
Used 5742188 cycles
Used 5699514 cycles
Used 5670884 cycles
Used 5758295 cycles
Used 5712180 cycles
Used 5697514 cycles
Used 5757201 cycles
Used 5694345 cycles
Used 5669453 cycles
Used 5674303 cycles
Used 5647565 cycles
Used 5663152 cycles
Used 5683005 cycles
Used 5666470 cycles
Used 5714193 cycles
Used 5689820 cycles
Used 5679402 cycles
Used 5672894 cycles
Used 5682461 cycles
Used 5701143 cycles
Used 5683074 cycles
Used 5760015 cycles
Used 5663922 cycles
Used 5677554 cycles
Used 5690482 cycles
[-- Attachment #3: oldkernel.txt --]
[-- Type: text/plain, Size: 1780 bytes --]
Used 5882164 cycles
Used 5850099 cycles
Used 5930877 cycles
Used 5841572 cycles
Used 5809251 cycles
Used 5845593 cycles
Used 5832703 cycles
Used 5819283 cycles
Used 5885083 cycles
Used 5888057 cycles
Used 5857240 cycles
Used 5838354 cycles
Used 5829058 cycles
Used 5826108 cycles
Used 5892050 cycles
Used 5907373 cycles
Used 5837317 cycles
Used 5885804 cycles
Used 5944564 cycles
Used 5837752 cycles
Used 5832153 cycles
Used 5883830 cycles
Used 5883603 cycles
Used 5804154 cycles
Used 5852603 cycles
Used 5826546 cycles
Used 5843635 cycles
Used 5797480 cycles
Used 5846276 cycles
Used 5891924 cycles
Used 5849252 cycles
Used 5857151 cycles
Used 5881152 cycles
Used 5924924 cycles
Used 5872509 cycles
Used 5805744 cycles
Used 5831126 cycles
Used 5844736 cycles
Used 5827185 cycles
Used 5848652 cycles
Used 5863982 cycles
Used 5873140 cycles
Used 5937342 cycles
Used 6000375 cycles
Used 5840141 cycles
Used 5906836 cycles
Used 5974467 cycles
Used 5811534 cycles
Used 5866358 cycles
Used 5850431 cycles
Used 5822444 cycles
Used 5817241 cycles
Used 5836811 cycles
Used 5912106 cycles
Used 5859462 cycles
Used 5861770 cycles
Used 5897209 cycles
Used 5779781 cycles
Used 5844075 cycles
Used 5801599 cycles
Used 5852515 cycles
Used 6151891 cycles
Used 5809307 cycles
Used 5817957 cycles
Used 5842894 cycles
Used 5878106 cycles
Used 5867384 cycles
Used 5905804 cycles
Used 5856291 cycles
Used 5916764 cycles
Used 5851960 cycles
Used 5846597 cycles
Used 5833760 cycles
Used 5806083 cycles
Used 5838144 cycles
Used 6102020 cycles
Used 5883813 cycles
Used 5853801 cycles
Used 5883441 cycles
Used 5827994 cycles
Used 5918981 cycles
Used 5788855 cycles
Used 5824117 cycles
Used 5890999 cycles
Used 5828463 cycles
Used 5870945 cycles
Used 5876589 cycles
Used 5789181 cycles
Used 5843746 cycles
[-- Attachment #4: syscalltest.S --]
[-- Type: text/plain, Size: 413 bytes --]
.globl main
main:
subi 1,1,12
stw 14,0(1)
stw 15,4(1)
stw 16,8(1)
li 14, 10000
mftb 15
1: li 0, 24
sc
li 0, 24
sc
li 0, 24
sc
li 0, 24
sc
li 0, 24
sc
li 0, 24
sc
li 0, 24
sc
li 0, 24
sc
li 0, 24
sc
li 0, 24
sc
addic. 14,14,-1
bne 1b
mftb 16
sub 4,16,15
lwz 14,0(1)
lwz 15,4(1)
lwz 16,8(1)
addi 1,1,12
lis 3,msg@ha
la 3,msg@l(3)
b printf
msg: .string "Used %d cycles\n"
^ permalink raw reply
* Re: asm-ppc/page.h vs asm-powerpc/page.h
From: Michael Ellerman @ 2005-11-14 23:47 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, linuxppc64
In-Reply-To: <Pine.LNX.4.44.0511141655560.8331-100000@gate.crashing.org>
[-- Attachment #1: Type: text/plain, Size: 807 bytes --]
My original patch removed it, so Paulus must have kept if for some good
reason.
asm-powerpc/page.h probably should have page_to_virt, I'm not sure why I took
it out :?
cheers
On Tue, 15 Nov 2005 10:01, Kumar Gala wrote:
> Guys, what's going on here.
>
> Why haven't we removed asm-ppc/page.h?
>
> When I build ARCH=powerpc I get asm-powerpc/page.h, which doesn't build on
> 85xx since page_to_virt is missing.
>
> Any reason we are keeping around asm-ppc/page.h and causing this
> confusion?
>
> - kumar
--
Michael Ellerman
IBM OzLabs
email: michael:ellerman.id.au
inmsg: mpe:jabber.org
wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)
We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: BDI2000 and Linux 2.6 kernel
From: Guillaume Autran @ 2005-11-14 23:42 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: support, linux-ppc-embedded
In-Reply-To: <20051107121101.GI15522@logos.cnet>
Hi Marcelo,
Despite your patch, I'm still having trouble getting my BDI2000 to translate
kernel virtual address to physical address on a 2.6.13 kernel.
What should I look for to make sure I set it up properly ?
Regards,
Guillaume.
Marcelo Tosatti wrote:
> Hi,
>
> Currently gdb over BDI (and I've seen other reports on this list) fails to
> translate virtual->physical addresses on PPC 8xx:
>
> *** MMU: address translation for 0xC000C66C failed
> *** MMU: address translation for 0xC000C66C failed
>
> Thats because the v2.6 kernel was changed to use physical addresses on the
> first level page.
>
> Dan informed me there might be a firmware update available to address
> this problem. Is this true?
>
> With the following the kernel stores the virtual address on the PMD
> getting the BDI "to work".
>
> A newer firmware would be much better though.
>
> --- linux-2.6.14-rc4.orig/arch/ppc/kernel/head_8xx.S 2005-10-18 16:59:34.000000000 -0500
> +++ linux-2.6.14-rc4/arch/ppc/kernel/head_8xx.S 2005-11-01 05:45:00.000000000 -0600
> @@ -320,11 +320,12 @@ InstructionTLBMiss:
> lwz r11, 0(r10) /* Get the level 1 entry */
> rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
> beq 2f /* If zero, don't try to find a pte */
> + tophys(r11,r11)
>
> /* We have a pte table, so load the MI_TWC with the attributes
> * for this "segment."
> */
> - ori r11,r11,1 /* Set valid bit */
> + /*ori r11,r11,1 Set valid bit */
> DO_8xx_CPU6(0x2b80, r3)
> mtspr SPRN_MI_TWC, r11 /* Set segment attributes */
> DO_8xx_CPU6(0x3b80, r3)
> @@ -379,6 +380,7 @@ DataStoreTLBMiss:
> lwz r11, 0(r10) /* Get the level 1 entry */
> rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
> beq 2f /* If zero, don't try to find a pte */
> + tophys(r11,r11)
>
> /* We have a pte table, so load fetch the pte from the table.
> */
> @@ -493,6 +495,7 @@ DataTLBError:
> lwz r11, 0(r10) /* Get the level 1 entry */
> rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
> beq 2f /* If zero, bail */
> + tophys(r11,r11)
>
> /* We have a pte table, so fetch the pte from the table.
> */
> diff -Nur -p --exclude-from=linux-2.6.14-rc4/Documentation/dontdiff linux-2.6.14-rc4.orig/include/asm-ppc/pgalloc.h linux-2.6.14-rc4/include/asm-ppc/pgalloc.h
> --- linux-2.6.14-rc4.orig/include/asm-ppc/pgalloc.h 2005-10-18 17:00:09.000000000 -0500
> +++ linux-2.6.14-rc4/include/asm-ppc/pgalloc.h 2005-11-01 08:02:08.000000000 -0600
> @@ -19,16 +19,16 @@ extern void pgd_free(pgd_t *pgd);
> #define __pmd_free_tlb(tlb,x) do { } while (0)
> #define pgd_populate(mm, pmd, pte) BUG()
>
> -#ifndef CONFIG_BOOKE
> +#if defined(CONFIG_BOOKE) || defined(CONFIG_8xx)
> #define pmd_populate_kernel(mm, pmd, pte) \
> - (pmd_val(*(pmd)) = __pa(pte) | _PMD_PRESENT)
> + (pmd_val(*(pmd)) = (unsigned long)pte | _PMD_PRESENT)
> #define pmd_populate(mm, pmd, pte) \
> - (pmd_val(*(pmd)) = (page_to_pfn(pte) << PAGE_SHIFT) | _PMD_PRESENT)
> + (pmd_val(*(pmd)) = (unsigned long)page_to_virt(pte) | _PMD_PRESENT)
> #else
> #define pmd_populate_kernel(mm, pmd, pte) \
> - (pmd_val(*(pmd)) = (unsigned long)pte | _PMD_PRESENT)
> + (pmd_val(*(pmd)) = __pa(pte) | _PMD_PRESENT)
> #define pmd_populate(mm, pmd, pte) \
> - (pmd_val(*(pmd)) = (unsigned long)page_to_virt(pte) | _PMD_PRESENT)
> + (pmd_val(*(pmd)) = (page_to_pfn(pte) << PAGE_SHIFT) | _PMD_PRESENT)
> #endif
>
> extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
> diff -Nur -p --exclude-from=linux-2.6.14-rc4/Documentation/dontdiff linux-2.6.14-rc4.orig/include/asm-ppc/pgtable.h linux-2.6.14-rc4/include/asm-ppc/pgtable.h
> --- linux-2.6.14-rc4.orig/include/asm-ppc/pgtable.h 2005-10-18 17:00:09.000000000 -0500
> +++ linux-2.6.14-rc4/include/asm-ppc/pgtable.h 2005-11-01 08:01:34.000000000 -0600
> @@ -719,16 +719,16 @@ extern pgprot_t phys_mem_access_prot(str
> * handler). On everything else the pmd contains the physical address
> * of the pte page. -- paulus
> */
> -#ifndef CONFIG_BOOKE
> +#if defined (CONFIG_BOOKE) || defined CONFIG_8xx
> #define pmd_page_kernel(pmd) \
> - ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
> + ((unsigned long) (pmd_val(pmd) & PAGE_MASK))
> #define pmd_page(pmd) \
> - (mem_map + (pmd_val(pmd) >> PAGE_SHIFT))
> + (mem_map + (__pa(pmd_val(pmd)) >> PAGE_SHIFT))
> #else
> #define pmd_page_kernel(pmd) \
> - ((unsigned long) (pmd_val(pmd) & PAGE_MASK))
> + ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
> #define pmd_page(pmd) \
> - (mem_map + (__pa(pmd_val(pmd)) >> PAGE_SHIFT))
> + (mem_map + (pmd_val(pmd) >> PAGE_SHIFT))
> #endif
>
> /* to find an entry in a kernel page-table-directory */
>
>
>
>
>
>
>
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
--
=======================================
Guillaume Autran
Senior Software Engineer
MRV Communications, Inc.
Tel: (978) 952-4932 office
=======================================
^ permalink raw reply
* [PATCH] powerpc: put page page_to_virt for Book-e processors
From: Kumar Gala @ 2005-11-14 23:21 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, linuxppc64-dev
Book-E processors use page_to_virt since we have to always translate.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
commit 62ac3a10f41d7d300cf82846348f65eab0dbfd40
tree 039f1c393bd77fb8c6daf1c8ebd883c9a72be6e2
parent ed24c128ba54329d142c4d4c7c5e05cec6065b08
author Kumar Gala <galak@kernel.crashing.org> Mon, 14 Nov 2005 17:22:35 -0600
committer Kumar Gala <galak@kernel.crashing.org> Mon, 14 Nov 2005 17:22:35 -0600
include/asm-powerpc/page.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/include/asm-powerpc/page.h b/include/asm-powerpc/page.h
index 18c1e5e..e34a2ba 100644
--- a/include/asm-powerpc/page.h
+++ b/include/asm-powerpc/page.h
@@ -53,6 +53,7 @@
#endif
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define page_to_virt(page) __va(page_to_pfn(page) << PAGE_SHIFT)
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
^ permalink raw reply related
* asm-ppc/page.h vs asm-powerpc/page.h
From: Kumar Gala @ 2005-11-14 23:01 UTC (permalink / raw)
To: Paul Mackerras; +Cc: michael, linuxppc-dev, linuxppc64
Guys, what's going on here.
Why haven't we removed asm-ppc/page.h?
When I build ARCH=powerpc I get asm-powerpc/page.h, which doesn't build on
85xx since page_to_virt is missing.
Any reason we are keeping around asm-ppc/page.h and causing this
confusion?
- kumar
^ permalink raw reply
* Re: [Edson.Seabra@cyclades.com: Re: BDI and 85xx]
From: Kumar Gala @ 2005-11-14 22:50 UTC (permalink / raw)
To: Dan Malek; +Cc: linux-ppc-embedded
In-Reply-To: <608ff4f57a546901e9193ebbbe368053@embeddededge.com>
On Nov 14, 2005, at 4:43 PM, Dan Malek wrote:
>
> On Nov 14, 2005, at 10:53 AM, Marcelo Tosatti wrote:
>
>> Doh my bad. Attached it is.
>>
>>
>> <8xx_gdb.diff>
>
> Well, this probably works for you but have you
> considered how it affects others?
>
> I'm not going to get into the -ggdb flags discussion,
> since I know we've had that in the past. Why is
> this needed and should it be done for everyone?
>
> Your update of MSR_KERNEL will work for you,
> but won't work on anything that isn't a Book E processor.
> You can't make this a generic update to all processors.
> It will fail on everything that really wants to use the
> BDI_SWITCH configuration option as it was intended.
> The DE in Book E conflicts with BE in traditional PPC.
We should but this in asm-ppc/reg_booke.h since book-e has its own
MSR_* defines.
> This also doesn't do anything to address my real concern,
> we shouldn't have to create a special kernel configuration
> just to attach a debugger .........
I'm not 100% sure this is even possible on some of the book-e variants.
- kumar
^ permalink raw reply
* Re: [Edson.Seabra@cyclades.com: Re: BDI and 85xx]
From: Dan Malek @ 2005-11-14 22:43 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: linux-ppc-embedded
In-Reply-To: <20051114155313.GA29411@logos.cnet>
On Nov 14, 2005, at 10:53 AM, Marcelo Tosatti wrote:
> Doh my bad. Attached it is.
>
>
> <8xx_gdb.diff>
Well, this probably works for you but have you
considered how it affects others?
I'm not going to get into the -ggdb flags discussion,
since I know we've had that in the past. Why is
this needed and should it be done for everyone?
Your update of MSR_KERNEL will work for you,
but won't work on anything that isn't a Book E processor.
You can't make this a generic update to all processors.
It will fail on everything that really wants to use the
BDI_SWITCH configuration option as it was intended.
The DE in Book E conflicts with BE in traditional PPC.
This also doesn't do anything to address my real concern,
we shouldn't have to create a special kernel configuration
just to attach a debugger .........
Thanks.
-- Dan
^ permalink raw reply
* Re: [PATCH] m8xx_wdt: software watchdog reset/interrupt select\
From: Kumar Gala @ 2005-11-14 21:14 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: Florian Schirmer, obi, carjay, linux-ppc-embedded
In-Reply-To: <20051114160302.GC29411@logos.cnet>
On Nov 14, 2005, at 10:03 AM, Marcelo Tosatti wrote:
> On Mon, Nov 14, 2005 at 01:57:37PM -0200, Marcelo Tosatti wrote:
>> Hi Kumar,
>>
>> On Mon, Nov 14, 2005 at 02:55:24PM -0600, Kumar Gala wrote:
>>> Can we put the WDT for 8xx in drivers/char/watchdog/?
>>
>> The userspace interface is already there at
>> drivers/char/watchdog/mpc8xx_wdt.c. I don't any reason for having two
>> files, will try to merge them into drivers/.
>
> Actually, drivers/char/watchdog/mpc8xx_wdt.c is a module, while
> some of the initialization code must reside in the kernel image.
>
> Thats the reason for the split - not sure if merging the two
> files is worth?
Fair enough.
- kumar
^ permalink raw reply
* Re: [PATCH] m8xx_wdt: software watchdog reset/interrupt select\
From: Marcelo Tosatti @ 2005-11-14 16:03 UTC (permalink / raw)
To: Kumar Gala; +Cc: Florian Schirmer, obi, carjay, linux-ppc-embedded
In-Reply-To: <20051114155736.GB29411@logos.cnet>
On Mon, Nov 14, 2005 at 01:57:37PM -0200, Marcelo Tosatti wrote:
> Hi Kumar,
>
> On Mon, Nov 14, 2005 at 02:55:24PM -0600, Kumar Gala wrote:
> > Can we put the WDT for 8xx in drivers/char/watchdog/?
>
> The userspace interface is already there at
> drivers/char/watchdog/mpc8xx_wdt.c. I don't any reason for having two
> files, will try to merge them into drivers/.
Actually, drivers/char/watchdog/mpc8xx_wdt.c is a module, while
some of the initialization code must reside in the kernel image.
Thats the reason for the split - not sure if merging the two
files is worth?
^ permalink raw reply
* Re: [PATCH] m8xx_wdt: software watchdog reset/interrupt select\
From: Marcelo Tosatti @ 2005-11-14 15:57 UTC (permalink / raw)
To: Kumar Gala; +Cc: Florian Schirmer, obi, carjay, linux-ppc-embedded
In-Reply-To: <9E7D3814-47AB-4601-A565-2530C3A4BEE0@kernel.crashing.org>
Hi Kumar,
On Mon, Nov 14, 2005 at 02:55:24PM -0600, Kumar Gala wrote:
> Can we put the WDT for 8xx in drivers/char/watchdog/?
The userspace interface is already there at
drivers/char/watchdog/mpc8xx_wdt.c. I don't any reason for having two
files, will try to merge them into drivers/.
Thanks.
^ permalink raw reply
* Re: [Edson.Seabra@cyclades.com: Re: BDI and 85xx]
From: Kumar Gala @ 2005-11-14 20:45 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: linux-ppc-embedded
In-Reply-To: <20051114152024.GA29314@logos.cnet>
It doesn't look very good since nothing appears to be attached :)
- kumar
On Nov 14, 2005, at 9:20 AM, Marcelo Tosatti wrote:
> FYI - how does it look now?
>
>
> ----- Forwarded message from Edson Seabra
> <Edson.Seabra@cyclades.com> -----
>
> From: Edson Seabra <Edson.Seabra@cyclades.com>
> Date: Mon, 14 Nov 2005 12:11:19 -0800
> To: "marcelo.tosatti" <Marcelo.Tosatti@cyclades.com>
> Subject: Re: BDI and 85xx
>
>
> Hi, Marcelo.
>
> I re-make the changes following the Dan suggestion.
>
> Can you check if he will accept them this time ?
>
> Thanks,
> -Edson.
>
>
>
>
> (See attached file: 8xx_gdb.diff)
>
> Dan Malek <dan@embeddededge.com> wrote on 11/07/2005 09:17:46 AM:
>
>>
>> On Nov 7, 2005, at 6:24 AM, Marcelo Tosatti wrote:
>>
>>> Edson had to patch this in to get BDI to work on 85xx with 2.6.14.
>>
>> How about we just change MSR_KERNEL and MSR_USER
>> in the include file #define instead of all of this run-time code?
>> Or, change the code so it preserves DE in general, so we don't
>> need a special kernel configuration just for the BDI?
>>
>> The original reason I did the BDI_SWITCH was due to the
>> overhead of tracking user PTE switches in the context switch
>> code. I don't like the way this has been overloaded to mean
>> "BDI general operation." We should be able to attach a BDI2000
>> to any kernel configuration and always get kernel debugging
>> capability. The BDI_SWITCH was to enable the extra feature
>> (with some overhead) of debugging into user applications,
>> it never should have affected any kernel debug operation.
>>
>> It's unfortunate that Book-E is such a PITA for debuggers,
>> but let's please find a better way of using these features.
>> Separate kernel configurations to enable hardware
>> debugging isn't acceptable.
>>
>> Thanks.
>>
>> -- Dan
>>
>
>
> ----- End forwarded message -----
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
^ permalink raw reply
* Re: 2.6.15-rc1 fails to boot on eMac
From: Benjamin Herrenschmidt @ 2005-11-14 21:03 UTC (permalink / raw)
To: Mikael Pettersson; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <17272.46529.847423.310952@alkaid.it.uu.se>
On Mon, 2005-11-14 at 17:05 +0100, Mikael Pettersson wrote:
> Linux kernel 2.6.15-rc1 (vanilla, not patched, compiled with
> gcc-3.4.4) refuses to boot on my Apple eMac (1.25GHz G4). After
> yaboot has loaded the kernel the output on the console is:
Yup, there is something wrong, I'm still investigating.
Ben.
^ permalink raw reply
* Re: [Edson.Seabra@cyclades.com: Re: BDI and 85xx]
From: Marcelo Tosatti @ 2005-11-14 15:53 UTC (permalink / raw)
To: Kumar Gala; +Cc: linux-ppc-embedded
In-Reply-To: <5F8A6977-E33A-4E84-B029-D1B49716DC82@kernel.crashing.org>
[-- Attachment #1: Type: text/plain, Size: 159 bytes --]
On Mon, Nov 14, 2005 at 02:45:46PM -0600, Kumar Gala wrote:
> It doesn't look very good since nothing appears to be attached :)
Doh my bad. Attached it is.
[-- Attachment #2: 8xx_gdb.diff --]
[-- Type: text/plain, Size: 705 bytes --]
--- /opt/montavista/pro/devkit/lsp/linux-2.6.14/Makefile 2005-10-27 17:02:08.000000000 -0700
+++ Makefile 2005-11-10 11:32:10.000000000 -0800
@@ -524,7 +524,7 @@
endif
ifdef CONFIG_DEBUG_INFO
-CFLAGS += -g
+CFLAGS += -g -ggdb
endif
include $(srctree)/arch/$(ARCH)/Makefile
--- /opt/montavista/pro/devkit/lsp/linux-2.6.14/include/asm-ppc/reg.h 2005-10-27 17:02:08.000000000 -0700
+++ include/asm-ppc/reg.h 2005-11-10 11:32:10.000000000 -0800
@@ -49,8 +49,12 @@
#endif
#ifndef MSR_KERNEL
+#ifdef CONFIG_BDI_SWITCH
+#define MSR_KERNEL (MSR_DE|MSR_ME|MSR_RI|MSR_IR|MSR_DR)
+#else
#define MSR_KERNEL (MSR_ME|MSR_RI|MSR_IR|MSR_DR)
#endif
+#endif
#define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE)
^ permalink raw reply
* Re: [PATCH] powerpc: Merge align.c
From: Benjamin Herrenschmidt @ 2005-11-14 20:55 UTC (permalink / raw)
To: Becky Bruce; +Cc: linuxppc64-dev, linuxppc-dev list
In-Reply-To: <daaff9f9782443f3d943c2853fb9a476@freescale.com>
On Mon, 2005-11-14 at 13:53 -0600, Becky Bruce wrote:
> Ben,
>
> I talked to Kumar about this a little bit (I had started a merge of
> this file, but got distracted!) and he doesn't have any test cases.
> I'll put something together and test this out on some of the 32-bit
> systems I have here in my lab. It won't be complete, but it will be
> something.......
Thanks,
Ben.
^ permalink raw reply
* Re: [PATCH] m8xx_wdt: software watchdog reset/interrupt select
From: Kumar Gala @ 2005-11-14 20:55 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: Florian Schirmer, obi, carjay, linux-ppc-embedded
In-Reply-To: <20051114143821.GA28852@logos.cnet>
Can we put the WDT for 8xx in drivers/char/watchdog/?
- kumar
On Nov 14, 2005, at 8:38 AM, Marcelo Tosatti wrote:
> Hi,
>
> Currently the mpc8xx_wdt driver installs an IRQ handler for
> PIT_INTERRUPT (SIU_LEVEL0, irq 1) to service the WDT until a userspace
> watchdog daemon takes over after boot.
>
> However, if the "software watchdog reset/interrupt select" (SWRI)
> bit of
> SYPCR register is set, no interrupt is generated. In that
> configuration
> (the default) HRESET signal is generated if the WDT timeout expires,
> without kernel notification.
>
> The following patch creates a kernel timer to service the WDT and
> rearm
> itself in case this configuration is detected, making it possible to
> boot the system with the watchdog turned on. The timer is shutdown
> once the userspace daemon open's the device.
>
> Note: From my reading of the documentation, even if the SWRI bit is
> unset (interrupt select mode), an NMI at IRQ0 should cause the
> system to
> jump to exception vector 0x100, resetting the system.
>
> So I'm wondering if the interrupt mode ever worked?
>
>
> --- ../git/linux-2.6/arch/ppc/syslib/m8xx_wdt.c 2005-11-08
> 11:38:39.000000000 -0600
> +++ linux-2.6-git-wednov02/arch/ppc/syslib/m8xx_wdt.c 2005-11-14
> 10:36:53.000000000 -0600
> @@ -45,35 +45,18 @@
> return IRQ_HANDLED;
> }
>
> -void __init m8xx_wdt_handler_install(bd_t * binfo)
> +#define SYPCR_SWP 0x1
> +#define SYPCR_SWRI 0x2
> +#define SYPCR_SWE 0x4
> +
> +/* software watchdog reset/interrupt select */
> +int m8xx_wdt_keepalive_mode = 0;
> +
> +void __init m8xx_wdt_install_irq(volatile immap_t *imap, bd_t *binfo)
> {
> - volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
> u32 pitc;
> - u32 sypcr;
> u32 pitrtclk;
>
> - sypcr = in_be32(&imap->im_siu_conf.sc_sypcr);
> -
> - if (!(sypcr & 0x04)) {
> - printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n",
> - sypcr);
> - return;
> - }
> -
> - m8xx_wdt_reset();
> -
> - printk(KERN_NOTICE
> - "m8xx_wdt: active wdt found (SWTC: 0x%04X, SWP: 0x%01X)\n",
> - (sypcr >> 16), sypcr & 0x01);
> -
> - wdt_timeout = (sypcr >> 16) & 0xFFFF;
> -
> - if (!wdt_timeout)
> - wdt_timeout = 0xFFFF;
> -
> - if (sypcr & 0x01)
> - wdt_timeout *= 2048;
> -
> /*
> * Fire trigger if half of the wdt ticked down
> */
> @@ -98,6 +81,66 @@
> printk(KERN_NOTICE
> "m8xx_wdt: keep-alive trigger installed (PITC: 0x%04X)\n",
> pitc);
>
> +}
> +
> +static void m8xx_wdt_timer_func(unsigned long data);
> +
> +static struct timer_list m8xx_wdt_timer =
> + TIMER_INITIALIZER(m8xx_wdt_timer_func, 0, 0);
> +
> +void m8xx_wdt_stop_timer(void)
> +{
> + del_timer(&m8xx_wdt_timer);
> +}
> +
> +static void m8xx_wdt_timer_func(unsigned long data)
> +{
> + m8xx_wdt_reset();
> + m8xx_wdt_timer.expires = jiffies + 25;
> + add_timer(&m8xx_wdt_timer);
> +}
> +
> +void m8xx_wdt_install_timer(volatile immap_t *imap)
> +{
> + m8xx_wdt_timer.expires = jiffies + 25;
> + add_timer(&m8xx_wdt_timer);
> +}
> +
> +void __init m8xx_wdt_handler_install(bd_t * binfo)
> +{
> + volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
> + u32 sypcr;
> +
> + sypcr = in_be32(&imap->im_siu_conf.sc_sypcr);
> +
> + printk(KERN_NOTICE "m8xx_wdt SYPCR: 0x%08X)\n", sypcr);
> +
> + if (!(sypcr & SYPCR_SWE)) {
> + printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n",
> + sypcr);
> + return;
> + }
> +
> + m8xx_wdt_reset();
> +
> + printk(KERN_NOTICE
> + "m8xx_wdt: active wdt found (SWTC: 0x%04X, SWP: 0x%01X)\n",
> + (sypcr >> 16), sypcr & SYPCR_SWP);
> +
> + wdt_timeout = (sypcr >> 16) & 0xFFFF;
> +
> + if (!wdt_timeout)
> + wdt_timeout = 0xFFFF;
> +
> + if (sypcr & SYPCR_SWP)
> + wdt_timeout *= 2048;
> +
> + m8xx_wdt_keepalive_mode = sypcr & SYPCR_SWRI;
> + if (m8xx_wdt_keepalive_mode)
> + m8xx_wdt_install_timer(imap);
> + else
> + m8xx_wdt_install_irq(imap, binfo);
> +
> wdt_timeout /= binfo->bi_intfreq;
> }
>
> --- ../git/linux-2.6/arch/ppc/syslib/m8xx_wdt.h 2005-10-10
> 18:06:12.000000000 -0500
> +++ linux-2.6-git-wednov02/arch/ppc/syslib/m8xx_wdt.h 2005-11-14
> 10:37:39.000000000 -0600
> @@ -9,8 +9,12 @@
> #ifndef _PPC_SYSLIB_M8XX_WDT_H
> #define _PPC_SYSLIB_M8XX_WDT_H
>
> +extern int m8xx_wdt_keepalive_mode;
> +
> extern void m8xx_wdt_handler_install(bd_t * binfo);
> extern int m8xx_wdt_get_timeout(void);
> extern void m8xx_wdt_reset(void);
> +extern void m8xx_wdt_install_timer(volatile immap_t *imap);
> +extern void m8xx_wdt_stop_timer(void);
>
> #endif /* _PPC_SYSLIB_M8XX_WDT_H */
> --- ../git/linux-2.6/drivers/char/watchdog/mpc8xx_wdt.c 2005-10-10
> 18:06:15.000000000 -0500
> +++ linux-2.6-git-wednov02/drivers/char/watchdog/mpc8xx_wdt.c
> 2005-11-14 10:37:15.000000000 -0600
> @@ -27,7 +27,10 @@
> {
> volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
>
> - imap->im_sit.sit_piscr &= ~(PISCR_PIE | PISCR_PTE);
> + if (m8xx_wdt_keepalive_mode)
> + m8xx_wdt_stop_timer();
> + else
> + imap->im_sit.sit_piscr &= ~(PISCR_PIE | PISCR_PTE);
>
> printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler deactivated\n");
> }
> @@ -36,7 +39,10 @@
> {
> volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
>
> - imap->im_sit.sit_piscr |= PISCR_PIE | PISCR_PTE;
> + if (m8xx_wdt_keepalive_mode)
> + m8xx_wdt_install_timer(imap);
> + else
> + imap->im_sit.sit_piscr |= PISCR_PIE | PISCR_PTE;
>
> printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler activated\n");
> }
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
^ permalink raw reply
* [Edson.Seabra@cyclades.com: Re: BDI and 85xx]
From: Marcelo Tosatti @ 2005-11-14 15:20 UTC (permalink / raw)
To: dan, linux-ppc-embedded
FYI - how does it look now?
----- Forwarded message from Edson Seabra <Edson.Seabra@cyclades.com> -----
From: Edson Seabra <Edson.Seabra@cyclades.com>
Date: Mon, 14 Nov 2005 12:11:19 -0800
To: "marcelo.tosatti" <Marcelo.Tosatti@cyclades.com>
Subject: Re: BDI and 85xx
Hi, Marcelo.
I re-make the changes following the Dan suggestion.
Can you check if he will accept them this time ?
Thanks,
-Edson.
(See attached file: 8xx_gdb.diff)
Dan Malek <dan@embeddededge.com> wrote on 11/07/2005 09:17:46 AM:
>
> On Nov 7, 2005, at 6:24 AM, Marcelo Tosatti wrote:
>
> > Edson had to patch this in to get BDI to work on 85xx with 2.6.14.
>
> How about we just change MSR_KERNEL and MSR_USER
> in the include file #define instead of all of this run-time code?
> Or, change the code so it preserves DE in general, so we don't
> need a special kernel configuration just for the BDI?
>
> The original reason I did the BDI_SWITCH was due to the
> overhead of tracking user PTE switches in the context switch
> code. I don't like the way this has been overloaded to mean
> "BDI general operation." We should be able to attach a BDI2000
> to any kernel configuration and always get kernel debugging
> capability. The BDI_SWITCH was to enable the extra feature
> (with some overhead) of debugging into user applications,
> it never should have affected any kernel debug operation.
>
> It's unfortunate that Book-E is such a PITA for debuggers,
> but let's please find a better way of using these features.
> Separate kernel configurations to enable hardware
> debugging isn't acceptable.
>
> Thanks.
>
> -- Dan
>
----- End forwarded message -----
^ permalink raw reply
* Re: MPC8260 fcc_enet transmit timed out
From: Ricardo Scop @ 2005-11-14 19:53 UTC (permalink / raw)
To: hubert loewenguth, linuxppc-embedded
In-Reply-To: <4378CAA8.5080808@thales-bm.com>
Hi, Hubert
On Monday 14 November 2005 15:34, hubert loewenguth wrote:
> Hello to the community
>
> After having searched more than a week to correct my problem, I have
> finally decided to try to find some help :
>
> - I have a board with a MPC8260 (HIP 3 C.2), with three PHY chipset :
> LXT971A from intel
> - The MII lines MDC and MDIO are present, but I have no PHY interrupt =
line
> =3D> so I have to configure my PHY and the fcc_enet.c drivers to be in
> half-duplex mode
> - I use the 2.4.20 linux kernel
^^
You could try a newer version, maybe the problem is alr=
eady=20
gone.
HTH,
--=20
Ricardo Scop.
\|/
___ -*-
(@ @)/|\
/ V \| R SCOP Consult.
/( )\ Linux-based communications
--^^---^^+------------------------------
rscop@matrix.com.br
+55 51 999-36-777
Porto Alegre, RS - BRazil
--
P. S.: "If you don't have time to do it right, when will you have time
to do it over?" -- Penny Hines =20
^ permalink raw reply
* Re: [RFC] Attempt to clean up sigsuspend et al
From: David Woodhouse @ 2005-11-14 20:05 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <17272.5610.562107.359574@cargo.ozlabs.ibm.com>
On Mon, 2005-11-14 at 15:43 +1100, Paul Mackerras wrote:
> Ah ok, I see now, that sounds all right.
I've also changed force_successful_syscall_return() to use a TIF flag,
so we don't have to clear ti->syscall_noerror in the syscall entry path
and that can shrink too.
The syscall exit path now checks ti->flags only once in the fast path,
instead of checking it twice as it did before. All the interesting stuff
is done in the slow path.
We lose the assembly wrappers for the signal-related functions, and
clean up the syscall table to call them directly.
It looks a bit like this... I still need to test it a little harder than
"Yes, it boots", and I need to sync up the 32-bit version. Then we can
have syscall entry/exit paths that actually look similar to each other.
What do you think?
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index b757572..e3e6081 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -92,9 +92,9 @@ int main(void)
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
- DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror));
-#ifdef CONFIG_PPC32
+ DEFINE(TI_SIGFRAME, offsetof(struct thread_info, nvgprs_frame));
DEFINE(TI_TASK, offsetof(struct thread_info, task));
+#ifdef CONFIG_PPC32
DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
#endif /* CONFIG_PPC32 */
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 2d22bf0..564452b 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -113,9 +113,7 @@ system_call_common:
addi r9,r1,STACK_FRAME_OVERHEAD
#endif
clrrdi r11,r1,THREAD_SHIFT
- li r12,0
ld r10,TI_FLAGS(r11)
- stb r12,TI_SC_NOERR(r11)
andi. r11,r10,_TIF_SYSCALL_T_OR_A
bne- syscall_dotrace
syscall_dotrace_cont:
@@ -145,23 +143,11 @@ system_call: /* label this so stack tr
syscall_exit:
#ifdef SHOW_SYSCALLS
- std r3,GPR3(r1)
+ std r3,RESULT(r1)
bl .do_show_syscall_exit
- ld r3,GPR3(r1)
+ ld r3,RESULT(r1)
#endif
- std r3,RESULT(r1)
- ld r5,_CCR(r1)
- li r10,-_LAST_ERRNO
- cmpld r3,r10
clrrdi r12,r1,THREAD_SHIFT
- bge- syscall_error
-syscall_error_cont:
-
- /* check for syscall tracing or audit */
- ld r9,TI_FLAGS(r12)
- andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
- bne- syscall_exit_trace
-syscall_exit_trace_cont:
/* disable interrupts so current_thread_info()->flags can't change,
and so that we don't get interrupted after loading SRR0/1. */
@@ -173,8 +159,14 @@ syscall_exit_trace_cont:
rotldi r10,r10,16
mtmsrd r10,1
ld r9,TI_FLAGS(r12)
- andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
+ li r11,-_LAST_ERRNO
+ andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_SAVE_NVGPRS|_TIF_NOERROR)
bne- syscall_exit_work
+ std r3,RESULT(r1)
+ cmpld r3,r11
+ ld r5,_CCR(r1)
+ bge- syscall_error
+syscall_error_cont:
ld r7,_NIP(r1)
stdcx. r0,0,r1 /* to clear the reservation */
andi. r6,r8,MSR_PR
@@ -193,21 +185,13 @@ syscall_exit_trace_cont:
rfid
b . /* prevent speculative execution */
-syscall_enosys:
- li r3,-ENOSYS
- std r3,RESULT(r1)
- clrrdi r12,r1,THREAD_SHIFT
- ld r5,_CCR(r1)
-
-syscall_error:
- lbz r11,TI_SC_NOERR(r12)
- cmpwi 0,r11,0
- bne- syscall_error_cont
+syscall_error:
neg r3,r3
oris r5,r5,0x1000 /* Set SO bit in CR */
+ std r3,RESULT(r1)
std r5,_CCR(r1)
b syscall_error_cont
-
+
/* Traced system call support */
syscall_dotrace:
bl .save_nvgprs
@@ -225,21 +209,72 @@ syscall_dotrace:
ld r10,TI_FLAGS(r10)
b syscall_dotrace_cont
-syscall_exit_trace:
+syscall_enosys:
+ li r3,-ENOSYS
+ b syscall_exit
+
+syscall_exit_work:
+ /* If TIF_RESTOREALL is set, don't scribble on either r3 or ccr.
+ If TIF_NOERROR is set, just save r3 as it is. */
+
+ andi. r0,r9,_TIF_RESTOREALL
+ bne- 2f
+ cmpld r3,r11 /* r10 is -LAST_ERRNO */
+ blt- 1f
+ andi. r0,r9,_TIF_NOERROR
+ bne- 1f
+ ld r5,_CCR(r1)
+ neg r3,r3
+ oris r5,r5,0x1000 /* Set SO bit in CR */
+ std r5,_CCR(r1)
+1:
+ std r3,RESULT(r1)
std r3,GPR3(r1)
- bl .save_nvgprs
+
+2: andi. r0,r9,(_TIF_PERSYSCALL_MASK)
+ beq 4f
+
+ /* Clear per-syscall TIF flags if any are set, but _leave_
+ _TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that
+ yet. */
+
+ li r11,_TIF_PERSYSCALL_MASK
+ addi r12,r12,TI_FLAGS
+3: ldarx r10,0,r12
+ andc r10,r10,r11
+ stdcx. r10,0,r12
+ bne- 3b
+ subi r12,r12,TI_FLAGS
+
+4: bl save_nvgprs
+ /* Anything else left to do? */
+ andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS)
+ beq .ret_from_except_lite
+
+ /* Re-enable interrupts */
+ mfmsr r10
+ ori r10,r10,MSR_EE
+ mtmsrd r10,1
+
+ andi. r0,r9,_TIF_SAVE_NVGPRS
+ bne save_user_nvgprs
+
+ /* If tracing, re-enable interrupts and do it */
+save_user_nvgprs_cont:
+ andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
+ beq 5f
+
addi r3,r1,STACK_FRAME_OVERHEAD
bl .do_syscall_trace_leave
REST_NVGPRS(r1)
- ld r3,GPR3(r1)
- ld r5,_CCR(r1)
clrrdi r12,r1,THREAD_SHIFT
- b syscall_exit_trace_cont
-/* Stuff to do on exit from a system call. */
-syscall_exit_work:
- std r3,GPR3(r1)
- std r5,_CCR(r1)
+ /* Disable interrupts again and handle other work if any */
+5: mfmsr r10
+ rldicl r10,r10,48,1
+ rotldi r10,r10,16
+ mtmsrd r10,1
+
b .ret_from_except_lite
/* Save non-volatile GPRs, if not already saved. */
@@ -252,6 +288,109 @@ _GLOBAL(save_nvgprs)
std r0,_TRAP(r1)
blr
+
+save_user_nvgprs:
+ /* Re-enable interrupts before copying to user */
+ mfmsr r10
+ ori r10,r10,MSR_EE
+ mtmsrd r10,1
+
+ ld r10,TI_SIGFRAME(r9)
+ andi. r0,r9,_TIF_32BIT
+ beq- save_user_nvgprs_64
+
+ /* 32-bit save to userspace */
+101: stw r14,56(r10)
+102: stw r15,60(r10)
+103: stw r16,64(r10)
+104: stw r17,68(r10)
+105: stw r18,72(r10)
+106: stw r19,76(r10)
+107: stw r20,80(r10)
+108: stw r21,84(r10)
+109: stw r22,88(r10)
+110: stw r23,92(r10)
+111: stw r24,96(r10)
+112: stw r25,100(r10)
+113: stw r26,104(r10)
+114: stw r27,108(r10)
+115: stw r28,112(r10)
+116: stw r29,116(r10)
+117: stw r30,120(r10)
+118: stw r31,124(r10)
+ b save_user_nvgprs_cont
+
+save_user_nvgprs_64:
+ /* 64-bit save to userspace */
+119: std r14,112(r10)
+120: std r15,120(r10)
+121: std r16,128(r10)
+122: std r17,136(r10)
+123: std r18,144(r10)
+124: std r19,152(r10)
+125: std r20,160(r10)
+126: std r21,168(r10)
+127: std r22,176(r10)
+128: std r23,184(r10)
+129: std r24,192(r10)
+130: std r25,200(r10)
+131: std r26,208(r10)
+132: std r27,216(r10)
+133: std r28,224(r10)
+134: std r28,232(r10)
+135: std r28,240(r10)
+136: std r28,248(r10)
+ b save_user_nvgprs_cont
+
+ .section __ex_table,"a"
+ .align 3
+ .llong 101b,save_user_nvgprs_fault
+ .llong 102b,save_user_nvgprs_fault
+ .llong 103b,save_user_nvgprs_fault
+ .llong 104b,save_user_nvgprs_fault
+ .llong 105b,save_user_nvgprs_fault
+ .llong 106b,save_user_nvgprs_fault
+ .llong 107b,save_user_nvgprs_fault
+ .llong 108b,save_user_nvgprs_fault
+ .llong 109b,save_user_nvgprs_fault
+ .llong 110b,save_user_nvgprs_fault
+ .llong 111b,save_user_nvgprs_fault
+ .llong 112b,save_user_nvgprs_fault
+ .llong 113b,save_user_nvgprs_fault
+ .llong 114b,save_user_nvgprs_fault
+ .llong 115b,save_user_nvgprs_fault
+ .llong 116b,save_user_nvgprs_fault
+ .llong 117b,save_user_nvgprs_fault
+ .llong 118b,save_user_nvgprs_fault
+ .llong 119b,save_user_nvgprs_fault
+ .llong 120b,save_user_nvgprs_fault
+ .llong 121b,save_user_nvgprs_fault
+ .llong 122b,save_user_nvgprs_fault
+ .llong 123b,save_user_nvgprs_fault
+ .llong 124b,save_user_nvgprs_fault
+ .llong 125b,save_user_nvgprs_fault
+ .llong 126b,save_user_nvgprs_fault
+ .llong 127b,save_user_nvgprs_fault
+ .llong 128b,save_user_nvgprs_fault
+ .llong 129b,save_user_nvgprs_fault
+ .llong 130b,save_user_nvgprs_fault
+ .llong 131b,save_user_nvgprs_fault
+ .llong 132b,save_user_nvgprs_fault
+ .llong 133b,save_user_nvgprs_fault
+ .llong 134b,save_user_nvgprs_fault
+ .llong 135b,save_user_nvgprs_fault
+ .llong 136b,save_user_nvgprs_fault
+ .previous
+
+save_user_nvgprs_fault:
+ li r3,9 // SIGSEGV
+ ld r4,TI_TASK(r9)
+ bl .force_sigsegv
+
+ clrrdi r12,r1,THREAD_SHIFT
+ ld r9,TI_FLAGS(r12)
+ b save_user_nvgprs_cont
+
/*
* The sigsuspend and rt_sigsuspend system calls can call do_signal
* and thus put the process into the stopped state where we might
@@ -260,35 +399,6 @@ _GLOBAL(save_nvgprs)
* the C code. Similarly, fork, vfork and clone need the full
* register state on the stack so that it can be copied to the child.
*/
-_GLOBAL(ppc32_sigsuspend)
- bl .save_nvgprs
- bl .compat_sys_sigsuspend
- b 70f
-
-_GLOBAL(ppc64_rt_sigsuspend)
- bl .save_nvgprs
- bl .sys_rt_sigsuspend
- b 70f
-
-_GLOBAL(ppc32_rt_sigsuspend)
- bl .save_nvgprs
- bl .compat_sys_rt_sigsuspend
-70: cmpdi 0,r3,0
- /* If it returned an error, we need to return via syscall_exit to set
- the SO bit in cr0 and potentially stop for ptrace. */
- bne syscall_exit
- /* If sigsuspend() returns zero, we are going into a signal handler. We
- may need to call audit_syscall_exit() to mark the exit from sigsuspend() */
-#ifdef CONFIG_AUDITSYSCALL
- ld r3,PACACURRENT(r13)
- ld r4,AUDITCONTEXT(r3)
- cmpdi 0,r4,0
- beq .ret_from_except /* No audit_context: Leave immediately. */
- li r4, 2 /* AUDITSC_FAILURE */
- li r5,-4 /* It's always -EINTR */
- bl .audit_syscall_exit
-#endif
- b .ret_from_except
_GLOBAL(ppc_fork)
bl .save_nvgprs
@@ -305,37 +415,6 @@ _GLOBAL(ppc_clone)
bl .sys_clone
b syscall_exit
-_GLOBAL(ppc32_swapcontext)
- bl .save_nvgprs
- bl .compat_sys_swapcontext
- b 80f
-
-_GLOBAL(ppc64_swapcontext)
- bl .save_nvgprs
- bl .sys_swapcontext
- b 80f
-
-_GLOBAL(ppc32_sigreturn)
- bl .compat_sys_sigreturn
- b 80f
-
-_GLOBAL(ppc32_rt_sigreturn)
- bl .compat_sys_rt_sigreturn
- b 80f
-
-_GLOBAL(ppc64_rt_sigreturn)
- bl .sys_rt_sigreturn
-
-80: cmpdi 0,r3,0
- blt syscall_exit
- clrrdi r4,r1,THREAD_SHIFT
- ld r4,TI_FLAGS(r4)
- andi. r4,r4,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
- beq+ 81f
- addi r3,r1,STACK_FRAME_OVERHEAD
- bl .do_syscall_trace_leave
-81: b .ret_from_except
-
_GLOBAL(ret_from_fork)
bl .schedule_tail
REST_NVGPRS(r1)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 081d931..88b86ac 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -75,7 +75,6 @@
* registers from *regs. This is what we need
* to do when a signal has been delivered.
*/
-#define sigreturn_exit(regs) return 0
#define GP_REGS_SIZE min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32))
#undef __SIGNAL_FRAMESIZE
@@ -155,9 +154,18 @@ static inline int save_general_regs(stru
elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
int i;
- for (i = 0; i <= PT_RESULT; i ++)
+ if (!FULL_REGS(regs)) {
+ printk("Save NVGPRS at %lx\n", (unsigned long)frame->mc_gregs);
+ set_thread_flag(TIF_SAVE_NVGPRS);
+ current_thread_info()->nvgprs_frame = frame->mc_gregs;
+ }
+
+ for (i = 0; i <= PT_RESULT; i ++) {
+ if (i == 14 && !FULL_REGS(regs))
+ i = 32;
if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i]))
return -EFAULT;
+ }
return 0;
}
@@ -178,8 +186,6 @@ static inline int restore_general_regs(s
#else /* CONFIG_PPC64 */
-extern void sigreturn_exit(struct pt_regs *);
-
#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set)
@@ -255,8 +261,10 @@ long sys_sigsuspend(old_sigset_t mask, i
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
- if (do_signal(&saveset, regs))
- sigreturn_exit(regs);
+ if (do_signal(&saveset, regs)) {
+ set_thread_flag(TIF_RESTOREALL);
+ return 0;
+ }
}
}
@@ -291,8 +299,10 @@ long sys_rt_sigsuspend(
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
- if (do_signal(&saveset, regs))
- sigreturn_exit(regs);
+ if (do_signal(&saveset, regs)) {
+ set_thread_flag(TIF_RESTOREALL);
+ return 0;
+ }
}
}
@@ -829,12 +839,6 @@ static int handle_rt_signal(unsigned lon
regs->gpr[6] = (unsigned long) rt_sf;
regs->nip = (unsigned long) ka->sa.sa_handler;
regs->trap = 0;
-#ifdef CONFIG_PPC64
- regs->result = 0;
-
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
-#endif
return 1;
badframe:
@@ -912,8 +916,8 @@ long sys_swapcontext(struct ucontext __u
*/
if (do_setcontext(new_ctx, regs, 0))
do_exit(SIGSEGV);
- sigreturn_exit(regs);
- /* doesn't actually return back to here */
+
+ set_thread_flag(TIF_RESTOREALL);
return 0;
}
@@ -946,12 +950,11 @@ long sys_rt_sigreturn(int r3, int r4, in
* nobody does any...
*/
compat_sys_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs);
- return (int)regs->result;
#else
do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]);
- sigreturn_exit(regs); /* doesn't return here */
- return 0;
#endif
+ set_thread_flag(TIF_RESTOREALL);
+ return 0;
bad:
force_sig(SIGSEGV, current);
@@ -1042,9 +1045,7 @@ int sys_debug_setcontext(struct ucontext
*/
do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]);
- sigreturn_exit(regs);
- /* doesn't actually return back to here */
-
+ set_thread_flag(TIF_RESTOREALL);
out:
return 0;
}
@@ -1109,12 +1110,6 @@ static int handle_signal(unsigned long s
regs->gpr[4] = (unsigned long) sc;
regs->nip = (unsigned long) ka->sa.sa_handler;
regs->trap = 0;
-#ifdef CONFIG_PPC64
- regs->result = 0;
-
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
-#endif
return 1;
@@ -1162,12 +1157,8 @@ long sys_sigreturn(int r3, int r4, int r
|| restore_user_regs(regs, sr, 1))
goto badframe;
-#ifdef CONFIG_PPC64
- return (int)regs->result;
-#else
- sigreturn_exit(regs); /* doesn't return */
+ set_thread_flag(TIF_RESTOREALL);
return 0;
-#endif
badframe:
force_sig(SIGSEGV, current);
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 58194e1..e071e95 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -96,8 +96,10 @@ long sys_rt_sigsuspend(sigset_t __user *
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
- if (do_signal(&saveset, regs))
+ if (do_signal(&saveset, regs)) {
+ set_thread_flag(TIF_RESTOREALL);
return 0;
+ }
}
}
@@ -155,6 +157,14 @@ static long setup_sigcontext(struct sigc
err |= __put_user(0, &sc->v_regs);
#endif /* CONFIG_ALTIVEC */
err |= __put_user(&sc->gp_regs, &sc->regs);
+ if (!FULL_REGS(regs)) {
+ /* Zero out the unsaved GPRs to avoid information
+ leak, and set TIF_SAVE_NVGPRS to ensure that the
+ registers do actually get saved later. */
+ memset(®s->gpr[14], 0, 18 * sizeof(unsigned long));
+ set_thread_flag(TIF_SAVE_NVGPRS);
+ current_thread_info()->nvgprs_frame = &sc->gp_regs;
+ }
err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE);
err |= __copy_to_user(&sc->fp_regs, ¤t->thread.fpr, FP_REGS_SIZE);
err |= __put_user(signr, &sc->signal);
@@ -343,6 +353,7 @@ int sys_swapcontext(struct ucontext __us
do_exit(SIGSEGV);
/* This returns like rt_sigreturn */
+ set_thread_flag(TIF_RESTOREALL);
return 0;
}
@@ -375,7 +386,8 @@ int sys_rt_sigreturn(unsigned long r3, u
*/
do_sigaltstack(&uc->uc_stack, NULL, regs->gpr[1]);
- return regs->result;
+ set_thread_flag(TIF_RESTOREALL);
+ return 0;
badframe:
#if DEBUG_SIG
@@ -454,9 +466,6 @@ static int setup_rt_frame(int signr, str
if (err)
goto badframe;
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
-
return 1;
badframe:
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
index 65eaea9..4bb3650 100644
--- a/arch/powerpc/kernel/systbl.S
+++ b/arch/powerpc/kernel/systbl.S
@@ -113,7 +113,7 @@ SYSCALL(sgetmask)
COMPAT_SYS(ssetmask)
SYSCALL(setreuid)
SYSCALL(setregid)
-SYSX(sys_ni_syscall,ppc32_sigsuspend,ppc_sigsuspend)
+SYS32ONLY(sigsuspend)
COMPAT_SYS(sigpending)
COMPAT_SYS(sethostname)
COMPAT_SYS(setrlimit)
@@ -160,7 +160,7 @@ SYSCALL(swapoff)
COMPAT_SYS(sysinfo)
COMPAT_SYS(ipc)
SYSCALL(fsync)
-SYSX(sys_ni_syscall,ppc32_sigreturn,sys_sigreturn)
+SYS32ONLY(sigreturn)
PPC_SYS(clone)
COMPAT_SYS(setdomainname)
PPC_SYS(newuname)
@@ -213,13 +213,13 @@ COMPAT_SYS(nfsservctl)
SYSCALL(setresgid)
SYSCALL(getresgid)
COMPAT_SYS(prctl)
-SYSX(ppc64_rt_sigreturn,ppc32_rt_sigreturn,sys_rt_sigreturn)
+COMPAT_SYS(rt_sigreturn)
COMPAT_SYS(rt_sigaction)
COMPAT_SYS(rt_sigprocmask)
COMPAT_SYS(rt_sigpending)
COMPAT_SYS(rt_sigtimedwait)
COMPAT_SYS(rt_sigqueueinfo)
-SYSX(ppc64_rt_sigsuspend,ppc32_rt_sigsuspend,ppc_rt_sigsuspend)
+COMPAT_SYS(rt_sigsuspend)
COMPAT_SYS(pread64)
COMPAT_SYS(pwrite64)
SYSCALL(chown)
@@ -290,7 +290,7 @@ COMPAT_SYS(clock_settime)
COMPAT_SYS(clock_gettime)
COMPAT_SYS(clock_getres)
COMPAT_SYS(clock_nanosleep)
-SYSX(ppc64_swapcontext,ppc32_swapcontext,ppc_swapcontext)
+COMPAT_SYS(swapcontext)
COMPAT_SYS(tgkill)
COMPAT_SYS(utimes)
COMPAT_SYS(statfs64)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 32f2158..2010d35 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -205,8 +205,8 @@ void _exception(int signr, struct pt_reg
if (handler == SIG_DFL) {
/* init has generated a synchronous exception
and it doesn't have a handler for the signal */
- printk(KERN_CRIT "init has generated signal %d "
- "but has no handler for it\n", signr);
+ die("init has generated signal %d "
+ "but has no handler for it\n", regs, signr);
do_exit(signr);
}
}
diff --git a/include/asm-powerpc/ptrace.h b/include/asm-powerpc/ptrace.h
index 1f7ecdb..9c550b3 100644
--- a/include/asm-powerpc/ptrace.h
+++ b/include/asm-powerpc/ptrace.h
@@ -87,7 +87,7 @@ extern unsigned long profile_pc(struct p
#define force_successful_syscall_return() \
do { \
- current_thread_info()->syscall_noerror = 1; \
+ set_thread_flag(TIF_NOERROR); \
} while(0)
/*
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
index e525f49..ac1e80e 100644
--- a/include/asm-powerpc/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -37,8 +37,7 @@ struct thread_info {
int preempt_count; /* 0 => preemptable,
<0 => BUG */
struct restart_block restart_block;
- /* set by force_successful_syscall_return */
- unsigned char syscall_noerror;
+ void *nvgprs_frame;
/* low level flags - has atomic operations done on it */
unsigned long flags ____cacheline_aligned_in_smp;
};
@@ -123,6 +122,9 @@ static inline struct thread_info *curren
#define TIF_SINGLESTEP 9 /* singlestepping active */
#define TIF_MEMDIE 10
#define TIF_SECCOMP 11 /* secure computing */
+#define TIF_RESTOREALL 12 /* Restore all regs (implies NOERROR) */
+#define TIF_SAVE_NVGPRS 13 /* Save r14-r31 in signal frame */
+#define TIF_NOERROR 14 /* Force successful syscall return */
/* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -136,10 +138,14 @@ static inline struct thread_info *curren
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
#define _TIF_SECCOMP (1<<TIF_SECCOMP)
+#define _TIF_RESTOREALL (1<<TIF_RESTOREALL)
+#define _TIF_SAVE_NVGPRS (1<<TIF_SAVE_NVGPRS)
+#define _TIF_NOERROR (1<<TIF_NOERROR)
#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
#define _TIF_USER_WORK_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
- _TIF_NEED_RESCHED)
+ _TIF_NEED_RESCHED | _TIF_RESTOREALL)
+#define _TIF_PERSYSCALL_MASK (_TIF_RESTOREALL|_TIF_NOERROR|_TIF_SAVE_NVGPRS)
#endif /* __KERNEL__ */
--
dwmw2
^ permalink raw reply related
* Re: Linuv 2.6.15-rc1
From: Tom Rini @ 2005-11-14 19:56 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Linux Kernel Mailing List, Adrian Bunk, linuxppc-dev,
Linus Torvalds, Michael Buesch
In-Reply-To: <1131834667.7406.49.camel@gaston>
On Sun, Nov 13, 2005 at 09:31:06AM +1100, Benjamin Herrenschmidt wrote:
>
> > ucSystemType is a variable that is EXPORT_SYMBOL'ed but never used in
> > any way.
> >
> > _prep_type is a variable that is needlessly EXPORT_SYMBOL'ed.
>
> Therse are old PREP stuffs
>
> > But prep_init points to the real problem:
> >
> > CONFIG_PPC_PREP requires code from arch/ppc/platforms/, but this
> > directory is never visited.
> >
> > What is the correct fix?
> > Migrate the code from arch/ppc/platforms/ to arch/powerpc/platforms/ ?
>
> Yes, PREP need to be migrated, but that includes adding some minimum
> device-tree support for it among others. And few people still have PREP
> machines, I'm not even sure we have access to one here in ozlabs... I
> think for 2.6.15, we'd better just disable it in .config for
> ARCH=powerpc.
I think we really should just drop _prep_type from being exported. the
uc* stuff doesn't look to be used, but we can clean that up as its
converted to arch/powerpc. But I don't think anything out of tree uses
_prep_type (it's used at a very low level, it really couldn't be used at
the modular level).
As an occasional PReP monkey,
Acked-by: Tom Rini <trini@kernel.crashing.org>
--
Tom Rini
http://gate.crashing.org/~trini/
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox