summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2003-02-20 22:07:22 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2003-02-20 22:07:22 +0000
commitd49389adb995168842d8f5b967945f6bbb281244 (patch)
tree7035607055dbc6c107416c594e7baefb89e69332
parentf3ceb2bf62c3583534a4a47fdba4b372899cdd99 (diff)
downloadrtems-d49389adb995168842d8f5b967945f6bbb281244.tar.bz2
2003-02-20 Till Straumann <strauman@slac.stanford.edu>
PR 349/bsps * mpc6xx/exceptions/raw_exception.c, mpc6xx/mmu/bat.c, mpc6xx/mmu/pte121.c, shared/include/cpuIdent.c, shared/include/cpuIdent.h, shared/src/Makefile.am, shared/src/stack.c, shared/src/stackTrace.h, powerpc/registers.h: - undo improper 'fix' who broke mpc604r identification - fix: 7400 identification PVR value was wrong - enhance 'setdbat()' to switch OFF a given BAT if called with 0 size - fix: page table support bugfix - enhancement: provide routines to take and print stack trace snapshots - add definitions for HID1 and DABR SPRs
-rw-r--r--c/src/lib/libcpu/powerpc/ChangeLog15
-rw-r--r--c/src/lib/libcpu/powerpc/mpc6xx/exceptions/raw_exception.c4
-rw-r--r--c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.c9
-rw-r--r--c/src/lib/libcpu/powerpc/mpc6xx/mmu/pte121.c34
-rw-r--r--c/src/lib/libcpu/powerpc/shared/include/cpuIdent.c2
-rw-r--r--c/src/lib/libcpu/powerpc/shared/include/cpuIdent.h2
-rw-r--r--c/src/lib/libcpu/powerpc/shared/src/Makefile.am4
-rw-r--r--c/src/lib/libcpu/powerpc/shared/src/stack.c42
-rw-r--r--c/src/lib/libcpu/powerpc/shared/src/stackTrace.h8
9 files changed, 107 insertions, 13 deletions
diff --git a/c/src/lib/libcpu/powerpc/ChangeLog b/c/src/lib/libcpu/powerpc/ChangeLog
index 408d44b691..dc007ce489 100644
--- a/c/src/lib/libcpu/powerpc/ChangeLog
+++ b/c/src/lib/libcpu/powerpc/ChangeLog
@@ -1,3 +1,18 @@
+2003-02-20 Till Straumann <strauman@slac.stanford.edu>
+
+ PR 349/bsps
+ * mpc6xx/exceptions/raw_exception.c, mpc6xx/mmu/bat.c,
+ mpc6xx/mmu/pte121.c, shared/include/cpuIdent.c,
+ shared/include/cpuIdent.h, shared/src/Makefile.am, shared/src/stack.c,
+ shared/src/stackTrace.h, powerpc/registers.h:
+ - undo improper 'fix' who broke mpc604r identification
+ - fix: 7400 identification PVR value was wrong
+ - enhance 'setdbat()' to switch OFF a given BAT if called with 0 size
+ - fix: page table support bugfix
+ - enhancement: provide routines to take and print stack trace
+ snapshots
+ - add definitions for HID1 and DABR SPRs
+
2003-02-14 Greg Menke <gregory.menke@gsfc.nasa.gov>
PR 348/bsps
diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/exceptions/raw_exception.c b/c/src/lib/libcpu/powerpc/mpc6xx/exceptions/raw_exception.c
index 7b6c6a573c..e2fca933a2 100644
--- a/c/src/lib/libcpu/powerpc/mpc6xx/exceptions/raw_exception.c
+++ b/c/src/lib/libcpu/powerpc/mpc6xx/exceptions/raw_exception.c
@@ -125,7 +125,7 @@ int mpc60x_vector_is_valid(rtems_vector vector)
break;
case PPC_604:
case PPC_604e:
- /* case PPC_604r: -- same value as PPC_750 */
+ case PPC_604r:
if (!mpc604_vector_is_valid(vector)) {
return 0;
}
@@ -138,7 +138,7 @@ int mpc60x_vector_is_valid(rtems_vector vector)
}
break;
default:
- printk("Please complete libcpu/powerpc/mpc6xx/raw_exception.c\n");
+ printk("Please complete libcpu/powerpc/mpc6xx/exceptions/raw_exception.c\n");
printk("current_ppc_cpu = %x\n", current_ppc_cpu);
return 0;
}
diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.c b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.c
index 4e49bcc07e..9c2df3f03f 100644
--- a/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.c
+++ b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.c
@@ -43,7 +43,7 @@ void setdbat(int bat_index, unsigned long virt, unsigned long phys,
int wimgxpp;
ubat bat;
- bl = (size >> 17) - 1;
+ bl = (size >= (1<<17)) ? (size >> 17) - 1 : 0;
/* 603, 604, etc. */
wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
| _PAGE_COHERENT | _PAGE_GUARDED);
@@ -53,8 +53,13 @@ void setdbat(int bat_index, unsigned long virt, unsigned long phys,
if (flags & _PAGE_USER)
bat.bat.batu.vp = 1;
bat_addrs[bat_index].start = virt;
- bat_addrs[bat_index].limit = virt + ((bl + 1) << 17) - 1;
+ bat_addrs[bat_index].limit = virt + (bl ? ((bl + 1) << 17) - 1 : 0);
bat_addrs[bat_index].phys = phys;
+ if ( 0 == bl ) {
+ /* size of 0 tells us to switch it off */
+ bat.bat.batu.vp = 0;
+ bat.bat.batu.vs = 0;
+ }
switch (bat_index) {
case 0 : asm_setdbat0(bat.word[0], bat.word[1]); break;
case 1 : asm_setdbat1(bat.word[0], bat.word[1]); break;
diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/mmu/pte121.c b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/pte121.c
index d0676833f7..5d25a1ac17 100644
--- a/c/src/lib/libcpu/powerpc/mpc6xx/mmu/pte121.c
+++ b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/pte121.c
@@ -22,8 +22,8 @@
#include <rtems.h>
#include <rtems/bspIo.h>
#include <libcpu/cpuIdent.h>
-#include <bsp.h>
#ifdef DEBUG_EXC
+#include <bsp.h>
#include <bsp/vectors.h>
#include <libcpu/raw_exception.h>
#endif
@@ -125,7 +125,7 @@
/* Horrible Macros */
-#ifdef __rtems
+#ifdef __rtems__
/* must not use printf until multitasking is up */
typedef void (*PrintF)(char *,...);
static PrintF whatPrintf(void)
@@ -363,8 +363,8 @@ triv121PgTblInit(unsigned long base, unsigned ldSize)
if (base & ((1<<ldSize)-1))
return 0; /* misaligned */
- /* This should work on a 604, but I couldn't test (I did
- * on 750 and 7400). Verify that the TLB invalidation works
+ /* This was tested on 604r, 750 and 7400.
+ * On other CPUs, verify that the TLB invalidation works
* for a new CPU variant and that it has hardware PTE lookup/
* TLB replacement before adding it to this list.
*
@@ -678,10 +678,34 @@ static int maxw=20; /* mute after detecting this many errors */
}
v=m=0;
- for (i=0, pte=pt->base; i<pt->size/sizeof(PTERec); i++,pte++) {
+#if 1
+ /* 10/9/2002: I had machine checks crashing after this loop
+ * terminated. Maybe caused by speculative loads
+ * from beyond the valid memory area (since the
+ * page hash table sits at the top of physical
+ * memory).
+ * Very bizarre - the other loops in this file
+ * seem to be fine. Maybe there is a compiler bug??
+ * For the moment, I let the loop run backwards...
+ *
+ * Also see the comment a couple of lines down.
+ */
+ for (i=pt->size/sizeof(PTERec)-1, pte=pt->base + i; i>=0; i--,pte--)
+#else
+ for (i=0, pte=pt->base; i<pt->size/sizeof(PTERec); i++,pte++)
+#endif
+ {
int err=0;
char buf[500];
unsigned long *lp=(unsigned long*)pte;
+#if 0
+ /* If I put this bogus while statement here (the body is
+ * never reached), the original loop works OK
+ */
+ while (pte >= pt->base + pt->size/sizeof(PTERec))
+ /* never reached */;
+#endif
+
if ( (*lp & (0xfffff0<<7)) || *(lp+1) & 0xe00 || (pte->v && pte->marked)) {
/* check for vsid (without segment bits) == 0, unused bits == 0, valid && marked */
sprintf(buf,"invalid VSID , unused bits or v && m");
diff --git a/c/src/lib/libcpu/powerpc/shared/include/cpuIdent.c b/c/src/lib/libcpu/powerpc/shared/include/cpuIdent.c
index 7144b1864f..bf2df226a9 100644
--- a/c/src/lib/libcpu/powerpc/shared/include/cpuIdent.c
+++ b/c/src/lib/libcpu/powerpc/shared/include/cpuIdent.c
@@ -33,10 +33,10 @@ char *get_ppc_cpu_type_name(ppc_cpu_id_t cpu)
case PPC_603: return "MPC603";
case PPC_603ev: return "MPC603ev";
case PPC_604: return "MPC604";
- /* case PPC_604r: return "MPC604r"; same value as 750 */
case PPC_750: return "MPC750";
case PPC_7400: return "MPC7400";
case PPC_604e: return "MPC604e";
+ case PPC_604r: return "MPC604r";
case PPC_620: return "MPC620";
case PPC_860: return "MPC860";
case PPC_8260: return "MPC8260";
diff --git a/c/src/lib/libcpu/powerpc/shared/include/cpuIdent.h b/c/src/lib/libcpu/powerpc/shared/include/cpuIdent.h
index e61749067e..f7b9a88399 100644
--- a/c/src/lib/libcpu/powerpc/shared/include/cpuIdent.h
+++ b/c/src/lib/libcpu/powerpc/shared/include/cpuIdent.h
@@ -27,7 +27,7 @@ typedef enum
PPC_750 = 0x8,
PPC_604e = 0x9,
PPC_604r = 0xA,
- PPC_7400 = 0xA,
+ PPC_7400 = 0xC,
PPC_620 = 0x16,
PPC_860 = 0x50,
PPC_821 = PPC_860,
diff --git a/c/src/lib/libcpu/powerpc/shared/src/Makefile.am b/c/src/lib/libcpu/powerpc/shared/src/Makefile.am
index 784cedd4a9..623a6fad80 100644
--- a/c/src/lib/libcpu/powerpc/shared/src/Makefile.am
+++ b/c/src/lib/libcpu/powerpc/shared/src/Makefile.am
@@ -5,12 +5,12 @@
VPATH = @srcdir@:@srcdir@/../../../shared/src
-C_FILES = cache.c cache_aligned_malloc.c cache_manager.c
+C_FILES = cache.c cache_aligned_malloc.c cache_manager.c stack.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
include_libcpudir = $(includedir)/libcpu
-include_libcpu_HEADERS = cache_.h cache.h
+include_libcpu_HEADERS = cache_.h cache.h stackTrace.h
OBJS = $(C_O_FILES)
diff --git a/c/src/lib/libcpu/powerpc/shared/src/stack.c b/c/src/lib/libcpu/powerpc/shared/src/stack.c
new file mode 100644
index 0000000000..bf97cb53db
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/shared/src/stack.c
@@ -0,0 +1,42 @@
+#include "stackTrace.h"
+#include <rtems/bspIo.h>
+#include <libcpu/spr.h>
+
+SPR_RO(LR)
+
+typedef struct FrameRec_ {
+ struct FrameRec_ *up;
+ void *lr;
+} FrameRec, *Frame;
+
+#define CPU_STACK_TRACE_DEPTH 40
+
+void CPU_stack_take_snapshot(void **stack, int size, void *pc, void *lr, void *r1)
+{
+register Frame p = (Frame)lr;
+register int i=0;
+ if (pc) stack[i++]=pc;
+ if (!p)
+ p = (Frame)_read_LR();
+ stack[i++]=p;
+ p = r1;
+ if (!p) /* no macro for reading user regs */
+ __asm__ __volatile__("mr %0, %%r1":"=r"(p));
+ for (; i<size-1 && p->up; p=p->up, i++) {
+ stack[i]=p->up->lr;
+ }
+ stack[i]=0;
+}
+
+void CPU_print_stack(void)
+{
+ void *stck[CPU_STACK_TRACE_DEPTH];
+ int i;
+ CPU_stack_take_snapshot(stck,CPU_STACK_TRACE_DEPTH,0,0,0);
+ for (i=0; stck[i]; i++) {
+ if (i%5) printk("--> ");
+ else printk("\n");
+ printk("0x%08x",stck[i]);
+ }
+ printk("\n");
+}
diff --git a/c/src/lib/libcpu/powerpc/shared/src/stackTrace.h b/c/src/lib/libcpu/powerpc/shared/src/stackTrace.h
new file mode 100644
index 0000000000..b85b333876
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/shared/src/stackTrace.h
@@ -0,0 +1,8 @@
+#ifndef CPU_STACK_UTIL_H
+#define CPU_STACK_UTIL_H
+
+void CPU_stack_take_snapshot(void **stack, int size, void *pc, void *lr, void *r1);
+
+void CPU_print_stack(void);
+
+#endif