forked from Imagelibrary/rtems
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
This commit is contained in:
@@ -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>
|
2003-02-14 Greg Menke <gregory.menke@gsfc.nasa.gov>
|
||||||
|
|
||||||
PR 348/bsps
|
PR 348/bsps
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ int mpc60x_vector_is_valid(rtems_vector vector)
|
|||||||
break;
|
break;
|
||||||
case PPC_604:
|
case PPC_604:
|
||||||
case PPC_604e:
|
case PPC_604e:
|
||||||
/* case PPC_604r: -- same value as PPC_750 */
|
case PPC_604r:
|
||||||
if (!mpc604_vector_is_valid(vector)) {
|
if (!mpc604_vector_is_valid(vector)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,7 @@ int mpc60x_vector_is_valid(rtems_vector vector)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
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);
|
printk("current_ppc_cpu = %x\n", current_ppc_cpu);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ void setdbat(int bat_index, unsigned long virt, unsigned long phys,
|
|||||||
int wimgxpp;
|
int wimgxpp;
|
||||||
ubat bat;
|
ubat bat;
|
||||||
|
|
||||||
bl = (size >> 17) - 1;
|
bl = (size >= (1<<17)) ? (size >> 17) - 1 : 0;
|
||||||
/* 603, 604, etc. */
|
/* 603, 604, etc. */
|
||||||
wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
|
wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
|
||||||
| _PAGE_COHERENT | _PAGE_GUARDED);
|
| _PAGE_COHERENT | _PAGE_GUARDED);
|
||||||
@@ -53,8 +53,13 @@ void setdbat(int bat_index, unsigned long virt, unsigned long phys,
|
|||||||
if (flags & _PAGE_USER)
|
if (flags & _PAGE_USER)
|
||||||
bat.bat.batu.vp = 1;
|
bat.bat.batu.vp = 1;
|
||||||
bat_addrs[bat_index].start = virt;
|
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;
|
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) {
|
switch (bat_index) {
|
||||||
case 0 : asm_setdbat0(bat.word[0], bat.word[1]); break;
|
case 0 : asm_setdbat0(bat.word[0], bat.word[1]); break;
|
||||||
case 1 : asm_setdbat1(bat.word[0], bat.word[1]); break;
|
case 1 : asm_setdbat1(bat.word[0], bat.word[1]); break;
|
||||||
|
|||||||
@@ -22,8 +22,8 @@
|
|||||||
#include <rtems.h>
|
#include <rtems.h>
|
||||||
#include <rtems/bspIo.h>
|
#include <rtems/bspIo.h>
|
||||||
#include <libcpu/cpuIdent.h>
|
#include <libcpu/cpuIdent.h>
|
||||||
#include <bsp.h>
|
|
||||||
#ifdef DEBUG_EXC
|
#ifdef DEBUG_EXC
|
||||||
|
#include <bsp.h>
|
||||||
#include <bsp/vectors.h>
|
#include <bsp/vectors.h>
|
||||||
#include <libcpu/raw_exception.h>
|
#include <libcpu/raw_exception.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -125,7 +125,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Horrible Macros */
|
/* Horrible Macros */
|
||||||
#ifdef __rtems
|
#ifdef __rtems__
|
||||||
/* must not use printf until multitasking is up */
|
/* must not use printf until multitasking is up */
|
||||||
typedef void (*PrintF)(char *,...);
|
typedef void (*PrintF)(char *,...);
|
||||||
static PrintF whatPrintf(void)
|
static PrintF whatPrintf(void)
|
||||||
@@ -363,8 +363,8 @@ triv121PgTblInit(unsigned long base, unsigned ldSize)
|
|||||||
if (base & ((1<<ldSize)-1))
|
if (base & ((1<<ldSize)-1))
|
||||||
return 0; /* misaligned */
|
return 0; /* misaligned */
|
||||||
|
|
||||||
/* This should work on a 604, but I couldn't test (I did
|
/* This was tested on 604r, 750 and 7400.
|
||||||
* on 750 and 7400). Verify that the TLB invalidation works
|
* On other CPUs, verify that the TLB invalidation works
|
||||||
* for a new CPU variant and that it has hardware PTE lookup/
|
* for a new CPU variant and that it has hardware PTE lookup/
|
||||||
* TLB replacement before adding it to this list.
|
* 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;
|
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;
|
int err=0;
|
||||||
char buf[500];
|
char buf[500];
|
||||||
unsigned long *lp=(unsigned long*)pte;
|
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)) {
|
if ( (*lp & (0xfffff0<<7)) || *(lp+1) & 0xe00 || (pte->v && pte->marked)) {
|
||||||
/* check for vsid (without segment bits) == 0, unused bits == 0, valid && marked */
|
/* check for vsid (without segment bits) == 0, unused bits == 0, valid && marked */
|
||||||
sprintf(buf,"invalid VSID , unused bits or v && m");
|
sprintf(buf,"invalid VSID , unused bits or v && m");
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ char *get_ppc_cpu_type_name(ppc_cpu_id_t cpu)
|
|||||||
case PPC_603: return "MPC603";
|
case PPC_603: return "MPC603";
|
||||||
case PPC_603ev: return "MPC603ev";
|
case PPC_603ev: return "MPC603ev";
|
||||||
case PPC_604: return "MPC604";
|
case PPC_604: return "MPC604";
|
||||||
/* case PPC_604r: return "MPC604r"; same value as 750 */
|
|
||||||
case PPC_750: return "MPC750";
|
case PPC_750: return "MPC750";
|
||||||
case PPC_7400: return "MPC7400";
|
case PPC_7400: return "MPC7400";
|
||||||
case PPC_604e: return "MPC604e";
|
case PPC_604e: return "MPC604e";
|
||||||
|
case PPC_604r: return "MPC604r";
|
||||||
case PPC_620: return "MPC620";
|
case PPC_620: return "MPC620";
|
||||||
case PPC_860: return "MPC860";
|
case PPC_860: return "MPC860";
|
||||||
case PPC_8260: return "MPC8260";
|
case PPC_8260: return "MPC8260";
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ typedef enum
|
|||||||
PPC_750 = 0x8,
|
PPC_750 = 0x8,
|
||||||
PPC_604e = 0x9,
|
PPC_604e = 0x9,
|
||||||
PPC_604r = 0xA,
|
PPC_604r = 0xA,
|
||||||
PPC_7400 = 0xA,
|
PPC_7400 = 0xC,
|
||||||
PPC_620 = 0x16,
|
PPC_620 = 0x16,
|
||||||
PPC_860 = 0x50,
|
PPC_860 = 0x50,
|
||||||
PPC_821 = PPC_860,
|
PPC_821 = PPC_860,
|
||||||
|
|||||||
@@ -5,12 +5,12 @@
|
|||||||
|
|
||||||
VPATH = @srcdir@:@srcdir@/../../../shared/src
|
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))
|
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
|
||||||
|
|
||||||
include_libcpudir = $(includedir)/libcpu
|
include_libcpudir = $(includedir)/libcpu
|
||||||
|
|
||||||
include_libcpu_HEADERS = cache_.h cache.h
|
include_libcpu_HEADERS = cache_.h cache.h stackTrace.h
|
||||||
|
|
||||||
OBJS = $(C_O_FILES)
|
OBJS = $(C_O_FILES)
|
||||||
|
|
||||||
|
|||||||
42
c/src/lib/libcpu/powerpc/shared/src/stack.c
Normal file
42
c/src/lib/libcpu/powerpc/shared/src/stack.c
Normal file
@@ -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");
|
||||||
|
}
|
||||||
8
c/src/lib/libcpu/powerpc/shared/src/stackTrace.h
Normal file
8
c/src/lib/libcpu/powerpc/shared/src/stackTrace.h
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user