Patch from Eric Valette <valette@crf.canon.fr> and Emmanuel Raguet

<raguet@crf.canon.fr>:

    - the dec21140 driver code has been hardened (various bug fixed) Emmanuel,
    - bug in the mcp750 init code have been fixed (interrupt stack/initial
      stack initialization), BSS correctly cleared (Eric V)
    - remote debugging over TCP/IP is nearly complete (berakpoints,
      backtrace, variables,...) (Eric V),
    - exception handling code has also been improved in order to fully
      support RDBG requirements (Eric V),
This commit is contained in:
Joel Sherrill
1999-08-10 16:41:44 +00:00
parent 908436c1ec
commit 981b99faf2
89 changed files with 2464 additions and 780 deletions

View File

@@ -24,7 +24,7 @@ INSTALL_CHANGE = @INSTALL_CHANGE@
SHARED_LIB = shared SHARED_LIB = shared
ifeq ($(RTEMS_CPU_MODEL),mpc750) ifeq ($(RTEMS_CPU_MODEL),mpc750)
CPUDIR = other_cpu CPUDIR = mpc750
else else
CPUDIR = other_cpu CPUDIR = other_cpu
endif endif

View File

@@ -58,8 +58,6 @@ void _CPU_Initialize(
* _CPU_Context_Initialize * _CPU_Context_Initialize
*/ */
#define CPU_MINIMUM_STACK_FRAME_SIZE 8
void _CPU_Context_Initialize( void _CPU_Context_Initialize(
Context_Control *the_context, Context_Control *the_context,
unsigned32 *stack_base, unsigned32 *stack_base,

View File

@@ -344,6 +344,8 @@ extern "C" {
* a debugger such as gdb. But that is another problem. * a debugger such as gdb. But that is another problem.
*/ */
#ifndef ASM
typedef struct { typedef struct {
unsigned32 gpr1; /* Stack pointer for all */ unsigned32 gpr1; /* Stack pointer for all */
unsigned32 gpr2; /* TOC in PowerOpen, reserved SVR4, section ptr EABI + */ unsigned32 gpr2; /* TOC in PowerOpen, reserved SVR4, section ptr EABI + */
@@ -465,6 +467,8 @@ typedef struct {
SCORE_EXTERN void *_CPU_Interrupt_stack_low; SCORE_EXTERN void *_CPU_Interrupt_stack_low;
SCORE_EXTERN void *_CPU_Interrupt_stack_high; SCORE_EXTERN void *_CPU_Interrupt_stack_high;
#endif /* ndef ASM */
/* /*
* This defines the number of levels and the mask used to pick those * This defines the number of levels and the mask used to pick those
* bits out of a thread mode. * bits out of a thread mode.
@@ -489,6 +493,7 @@ SCORE_EXTERN void *_CPU_Interrupt_stack_high;
* Nothing prevents the porter from declaring more CPU specific variables. * Nothing prevents the porter from declaring more CPU specific variables.
*/ */
#ifndef ASM
SCORE_EXTERN struct { SCORE_EXTERN struct {
unsigned32 *Disable_level; unsigned32 *Disable_level;
@@ -498,6 +503,8 @@ SCORE_EXTERN struct {
} _CPU_IRQ_info CPU_STRUCTURE_ALIGNMENT; } _CPU_IRQ_info CPU_STRUCTURE_ALIGNMENT;
#endif /* ndef ASM */
/* /*
* The size of the floating point context area. On some CPUs this * The size of the floating point context area. On some CPUs this
* will not be a "sizeof" because the format of the floating point * will not be a "sizeof" because the format of the floating point
@@ -584,6 +591,12 @@ SCORE_EXTERN struct {
#define CPU_STACK_ALIGNMENT (PPC_STACK_ALIGNMENT) #define CPU_STACK_ALIGNMENT (PPC_STACK_ALIGNMENT)
/*
* Needed for Interrupt stack
*/
#define CPU_MINIMUM_STACK_FRAME_SIZE 8
/* ISR handler macros */ /* ISR handler macros */
/* /*
@@ -593,6 +606,7 @@ SCORE_EXTERN struct {
#define loc_string(a,b) a " (" #b ")\n" #define loc_string(a,b) a " (" #b ")\n"
#ifndef ASM
static inline unsigned32 _CPU_ISR_Get_level( void ) static inline unsigned32 _CPU_ISR_Get_level( void )
{ {
@@ -941,6 +955,8 @@ static inline unsigned64 PPC_Get_timebase_register( void )
return tbr; return tbr;
} }
#endif /* ndef ASM */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -6,6 +6,8 @@
* *
* Synopsis = Machine-dependent header file * Synopsis = Machine-dependent header file
* *
* $Id$
*
************************************************************************** **************************************************************************
*/ */
@@ -17,35 +19,21 @@
#define EFLAGS_TF 0x00100 #define EFLAGS_TF 0x00100
typedef struct Exception_context_struct { static inline int isRdbgException(Exception_context *ctx)
struct Exception_context_struct *next; {
struct Exception_context_struct *previous; if (
Objects_Id id; ctx->ctx->idtIndex != I386_EXCEPTION_DEBUG &&
Objects_Id semaphoreId; ctx->ctx->idtIndex != I386_EXCEPTION_BREAKPOINT &&
CPU_Exception_frame *ctx; ctx->ctx->idtIndex != I386_EXCEPTION_ENTER_RDBG
} Exception_context; ) return 0;
else return 1;
extern int PushExceptCtx (Objects_Id Id, }
Objects_Id semId, static inline int getExcNum(Exception_context *ctx)
CPU_Exception_frame *ctx); {
extern int PopExceptCtx (Objects_Id Id); return ctx->ctx->idtIndex;
extern Exception_context *GetExceptCtx (Objects_Id Id); }
extern int Single_Step (CPU_Exception_frame* ctx);
extern int CheckForSingleStep (CPU_Exception_frame* ctx);
extern void BreakPointExcHdl (CPU_Exception_frame *ctx);
extern void CtxToRegs (const CPU_Exception_frame*,xdr_regs*);
extern void RegsToCtx (const xdr_regs*,CPU_Exception_frame*);
extern void enterRdbg ();
extern void get_ctx_thread (Thread_Control *thread,
CPU_Exception_frame* ctx);
extern void set_ctx_thread (Thread_Control *thread,
CPU_Exception_frame* ctx);
void copyback_data_cache_and_invalidate_instr_cache();
extern int ExitForSingleStep;
extern void connect_rdbg_exception();
#endif #endif

View File

@@ -1,4 +1,8 @@
/*
* Registers Offset in frame definition
*
* $Id$
*/
#define NBREGS 19 #define NBREGS 19

View File

@@ -0,0 +1,38 @@
/*
**************************************************************************
*
* Component = RDBG
* Module = rdbg_f.h
*
* Synopsis = Machine-dependent header file
*
* $Id$
*
**************************************************************************
*/
#ifndef RDBG_F_H
#define RDBG_F_H
#include <rtems.h>
#include <rdbg/remdeb.h>
static inline int isRdbgException(Exception_context *ctx)
{
if (
ctx->ctx->_EXC_number != ASM_SYS_VECTOR &&
ctx->ctx->_EXC_number != ASM_TRACE_VECTOR
) return 0;
else return 1;
}
static inline int getExcNum(Exception_context *ctx)
{
return ctx->ctx->_EXC_number;
}
extern void connect_rdbg_exception();
#endif

View File

@@ -0,0 +1,16 @@
/*
* Registers frame offset definition
*
* $Id$
*/
#define NBREGS 43
typedef unsigned int regs[NBREGS];
/* To be used in common code */
typedef regs REGS;

View File

@@ -5,6 +5,8 @@
* *
* Synopsis = rdbg.h * Synopsis = rdbg.h
* *
* $Id$
*
************************************************************************** **************************************************************************
*/ */
@@ -14,9 +16,9 @@
#include <rpc/rpc.h> #include <rpc/rpc.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <rdbg/rdbg_f.h>
#include <stdlib.h> /* For malloc() and free() prototypes */ #include <stdlib.h> /* For malloc() and free() prototypes */
#include <bsp.h> #include <bsp.h>
#include <rtems.h>
#define Malloc(size) malloc (size) #define Malloc(size) malloc (size)
#define Free(block) free (block) #define Free(block) free (block)
@@ -49,5 +51,45 @@ void svc_processrequest (SVCXPRT* xprt,
void (*dispatch)()); void (*dispatch)());
int svcudp_enablecache (SVCXPRT *transp, u_long size); int svcudp_enablecache (SVCXPRT *transp, u_long size);
typedef struct Exception_context_struct {
struct Exception_context_struct *next;
struct Exception_context_struct *previous;
Objects_Id id;
Objects_Id semaphoreId;
CPU_Exception_frame *ctx;
} Exception_context;
struct xdr_regs;
extern int PushExceptCtx (Objects_Id Id,
Objects_Id semId,
CPU_Exception_frame *ctx);
extern int PopExceptCtx (Objects_Id Id);
extern Exception_context *GetExceptCtx (Objects_Id Id);
extern int Single_Step (CPU_Exception_frame* ctx);
extern int CheckForSingleStep (CPU_Exception_frame* ctx);
extern void BreakPointExcHdl (CPU_Exception_frame *ctx);
extern void CtxToRegs (const CPU_Exception_frame*,struct xdr_regs*);
extern void RegsToCtx (const struct xdr_regs*,CPU_Exception_frame*);
extern void enterRdbg ();
extern void get_ctx_thread (Thread_Control *thread,
CPU_Exception_frame* ctx);
extern void set_ctx_thread (Thread_Control *thread,
CPU_Exception_frame* ctx);
extern int PushSavedExceptCtx ( Objects_Id Id,
CPU_Exception_frame *ctx );
extern int ExcepToSig (Exception_context *ctx);
extern int ExitForSingleStep;
extern rtems_id serializeSemId;
extern rtems_id wakeupEventSemId;
extern volatile unsigned int NbSerializedCtx;
void copyback_data_cache_and_invalidate_instr_cache(unsigned char* addr, int size);
#include <rdbg/rdbg_f.h>
#endif /* !RDBG_H */ #endif /* !RDBG_H */

View File

@@ -1,3 +1,6 @@
/*
* $Id$
*/
#ifndef SERVRPC_H #ifndef SERVRPC_H
#define SERVRPC_H #define SERVRPC_H
@@ -30,6 +33,15 @@ extern const char* PtraceNames[]; /* list of ptrace requests for debug out */
extern const char* BmsgNames[]; /* list of BMSG_xxx names */ extern const char* BmsgNames[]; /* list of BMSG_xxx names */
extern const char* PtraceName(int req); extern const char* PtraceName(int req);
#ifdef i386 /* low-high machine such as 386 */
#define HL_W(w) (((UINT16)(w)>>8)+((((w)&0xFF)<<8)))
#define HL_D(d) (((UINT32)(d)>>24)+(((d)&0x00FF0000)>>8) \
+(((d)&0xFF00)<<8)+(((d)&0xFF)<<24))
#else
#define HL_W(w) w
#define HL_D(d) d
#endif
# define DPRINTF(a) (rdb_debug ? printk ("%d >>> ", getId()), printk a : 0) # define DPRINTF(a) (rdb_debug ? printk ("%d >>> ", getId()), printk a : 0)
#else #else
# define DPRINTF(a) /* suppress */ # define DPRINTF(a) /* suppress */

View File

@@ -117,7 +117,7 @@ struct MD {
/* /*
* Receive buffer size -- Allow for a full ethernet packet including CRC * Receive buffer size -- Allow for a full ethernet packet including CRC
*/ */
#define RBUF_SIZE 1520 #define RBUF_SIZE 1536
#define ET_MINLEN 60 /* minimum message length */ #define ET_MINLEN 60 /* minimum message length */
@@ -419,7 +419,8 @@ dec21140Enet_initialize_hardware (struct dec21140_softc *sc)
sc->rxBdCount = 0; sc->rxBdCount = 0;
cp = (char *)malloc((NRXBUFS+NTXBUFS)*(sizeof(struct MD)+ RBUF_SIZE) + PPC_CACHE_ALIGNMENT); cp = (char *)malloc((NRXBUFS+NTXBUFS)*(sizeof(struct MD)+ RBUF_SIZE) + PPC_CACHE_ALIGNMENT);
sc->bufferBase = cp; sc->bufferBase = cp;
cp += (PPC_CACHE_ALIGNMENT - (int)cp) & MASK_OFFSET; if ((unsigned int)cp & (PPC_CACHE_ALIGNMENT-1))
cp = ((unsigned int)cp + PPC_CACHE_ALIGNMENT) & ~(PPC_CACHE_ALIGNMENT-1);
#ifdef PCI_BRIDGE_DOES_NOT_ENSURE_CACHE_COHERENCY_FOR_DMA #ifdef PCI_BRIDGE_DOES_NOT_ENSURE_CACHE_COHERENCY_FOR_DMA
if (_CPU_is_paging_enabled()) if (_CPU_is_paging_enabled())
_CPU_change_memory_mapping_attribute _CPU_change_memory_mapping_attribute

View File

@@ -16,6 +16,7 @@
#include <console.h> #include <console.h>
#include <libcpu/io.h> #include <libcpu/io.h>
#include <clockdrv.h> #include <clockdrv.h>
#include <bsp/vectors.h>
#ifndef ASM #ifndef ASM
#define outport_byte(port,value) outb(value,port) #define outport_byte(port,value) outb(value,port)

View File

@@ -21,9 +21,8 @@
/* /*
* lower byte is interrupt mask on the master PIC. * lower byte is interrupt mask on the master PIC.
* while upper bits are interrupt on the slave PIC. * while upper bits are interrupt on the slave PIC.
* This cache is initialized in ldseg.s
*/ */
volatile rtems_i8259_masks i8259s_cache; volatile rtems_i8259_masks i8259s_cache = 0xfffb;
/*-------------------------------------------------------------------------+ /*-------------------------------------------------------------------------+
| Function: BSP_irq_disable_at_i8259s | Function: BSP_irq_disable_at_i8259s
@@ -53,7 +52,7 @@ int BSP_irq_disable_at_i8259s (const rtems_irq_symbolic_name irqLine)
} }
else else
{ {
outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) > 8)); outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
} }
_CPU_ISR_Enable (level); _CPU_ISR_Enable (level);
@@ -88,7 +87,7 @@ int BSP_irq_enable_at_i8259s (const rtems_irq_symbolic_name irqLine)
} }
else else
{ {
outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) > 8)); outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
} }
_CPU_ISR_Enable (level); _CPU_ISR_Enable (level);
@@ -119,9 +118,12 @@ int BSP_irq_enabled_at_i8259s (const rtems_irq_symbolic_name irqLine)
int BSP_irq_ack_at_i8259s (const rtems_irq_symbolic_name irqLine) int BSP_irq_ack_at_i8259s (const rtems_irq_symbolic_name irqLine)
{ {
if (irqLine >= 8) { if (irqLine >= 8) {
outport_byte(PIC_SLAVE_COMMAND_IO_PORT, PIC_EOI); outport_byte(PIC_MASTER_COMMAND_IO_PORT, SLAVE_PIC_EOSI);
outport_byte(PIC_SLAVE_COMMAND_IO_PORT, (PIC_EOSI | (irqLine - 8)));
}
else {
outport_byte(PIC_MASTER_COMMAND_IO_PORT, (PIC_EOSI | irqLine));
} }
outport_byte(PIC_MASTER_COMMAND_IO_PORT, PIC_EOI);
return 0; return 0;
@@ -146,6 +148,5 @@ void BSP_i8259s_init(void)
outport_byte(PIC_SLAVE_IMR_IO_PORT, 0x01); /* Select 8086 mode */ outport_byte(PIC_SLAVE_IMR_IO_PORT, 0x01); /* Select 8086 mode */
outport_byte(PIC_SLAVE_IMR_IO_PORT, 0xFF); /* Mask all */ outport_byte(PIC_SLAVE_IMR_IO_PORT, 0xFF); /* Mask all */
i8259s_cache = 0xFFFB;
} }

View File

@@ -378,7 +378,7 @@ void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
void _ThreadProcessSignalsFromIrq (exception_frame* ctx) void _ThreadProcessSignalsFromIrq (BSP_Exception_frame* ctx)
{ {
/* /*
* Process pending signals that have not already been * Process pending signals that have not already been

View File

@@ -54,6 +54,7 @@
/* Command for specific EOI (End Of Interrupt): Interrupt acknowledge */ /* Command for specific EOI (End Of Interrupt): Interrupt acknowledge */
#define PIC_EOSI 0x60 /* End of Specific Interrupt (EOSI) */ #define PIC_EOSI 0x60 /* End of Specific Interrupt (EOSI) */
#define SLAVE_PIC_EOSI 0x62 /* End of Specific Interrupt (EOSI) for cascade */
#define PIC_EOI 0x20 /* Generic End of Interrupt (EOI) */ #define PIC_EOI 0x20 /* Generic End of Interrupt (EOI) */
#ifndef ASM #ifndef ASM

View File

@@ -212,6 +212,13 @@ nested:
*/ */
stmw r16, GPR16_OFFSET(r1) stmw r16, GPR16_OFFSET(r1)
addi r3, r1, 0x8 addi r3, r1, 0x8
/*
* compute SP at exception entry
*/
addi r2, r1, EXCEPTION_FRAME_END
/*
* store it at the right place
*/
bl _ISR_Signals_to_thread_executing bl _ISR_Signals_to_thread_executing
/* /*
* start restoring exception like frame * start restoring exception like frame

View File

@@ -1,33 +1,20 @@
/* /*
* arch/ppc/kernel/head.S * start.S : RTEMS entry point
*
* Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
* *
* $Id$ * $Id$
* *
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
* Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
* Adapted for Power Macintosh by Paul Mackerras.
* Low-level exception handlers and MMU support
* rewritten by Paul Mackerras.
* Copyright (C) 1996 Paul Mackerras.
* MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
* Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
*
* This file contains the low-level support and setup for the
* PowerPC platform, including trap and interrupt dispatch.
* Also included here is low-level thread/task switch 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 <libcpu/cpu.h> #include <libcpu/cpu.h>
#include <libcpu/io.h> #include <libcpu/io.h>
#include <rtems/score/targopts.h> #include <rtems/score/targopts.h>
#include <rtems/score/cpu.h>
#include "asm.h" #include "asm.h"
#define SYNC \ #define SYNC \
@@ -91,8 +78,8 @@ enter_C_code:
/* /*
* stack = &__rtems_end + 4096 * stack = &__rtems_end + 4096
*/ */
addis r9,r0, __rtems_end+4096@ha addis r9,r0, __rtems_end+(4096-CPU_MINIMUM_STACK_FRAME_SIZE)@ha
addi r9,r9, __rtems_end+4096@l addi r9,r9, __rtems_end+(4096-CPU_MINIMUM_STACK_FRAME_SIZE)@l
mr r1, r9 mr r1, r9
bl zero_bss bl zero_bss
/* /*
@@ -142,8 +129,3 @@ _return_to_ppcbug:
bl MMUon bl MMUon
mtctr r30 mtctr r30
bctr bctr

View File

@@ -131,7 +131,9 @@ void bsp_pretasking_hook(void)
heap_size = (BSP_mem_size - heap_start) - BSP_Configuration.work_space_size; heap_size = (BSP_mem_size - heap_start) - BSP_Configuration.work_space_size;
#ifdef SHOW_MORE_INIT_SETTINGS
printk(" HEAP start %x size %x\n", heap_start, heap_size); printk(" HEAP start %x size %x\n", heap_start, heap_size);
#endif
bsp_libc_init((void *) heap_start, heap_size, 0); bsp_libc_init((void *) heap_start, heap_size, 0);
#ifdef RTEMS_DEBUG #ifdef RTEMS_DEBUG
@@ -141,7 +143,7 @@ void bsp_pretasking_hook(void)
void zero_bss() void zero_bss()
{ {
memset(&__bss_start, 0, &__rtems_end - &__bss_start); memset(&__bss_start, 0, ((unsigned) (&__rtems_end)) - ((unsigned) &__bss_start));
} }
void save_boot_params(RESIDUAL* r3, void *r4, void* r5, char *additional_boot_options) void save_boot_params(RESIDUAL* r3, void *r4, void* r5, char *additional_boot_options)
@@ -184,7 +186,7 @@ void bsp_start( void )
* the initial stack has aready been set to this value in start.S * the initial stack has aready been set to this value in start.S
* so there is no need to set it in r1 again... * so there is no need to set it in r1 again...
*/ */
stack = ((unsigned char*) &__rtems_end) + INIT_STACK_SIZE; stack = ((unsigned char*) &__rtems_end) + INIT_STACK_SIZE - CPU_MINIMUM_STACK_FRAME_SIZE;
/* /*
* Initialize the interrupt related settings * Initialize the interrupt related settings
* SPRG0 = interrupt nesting level count * SPRG0 = interrupt nesting level count
@@ -193,7 +195,7 @@ void bsp_start( void )
* This could be done latter (e.g in IRQ_INIT) but it helps to understand * This could be done latter (e.g in IRQ_INIT) but it helps to understand
* some settings below... * some settings below...
*/ */
intrStack = ((unsigned char*) &__rtems_end) + INIT_STACK_SIZE + INTR_STACK_SIZE; intrStack = ((unsigned char*) &__rtems_end) + INIT_STACK_SIZE + INTR_STACK_SIZE - CPU_MINIMUM_STACK_FRAME_SIZE;
asm volatile ("mtspr 273, %0" : "=r" (intrStack) : "0" (intrStack)); asm volatile ("mtspr 273, %0" : "=r" (intrStack) : "0" (intrStack));
asm volatile ("mtspr 272, %0" : "=r" (intrNestingLevel) : "0" (intrNestingLevel)); asm volatile ("mtspr 272, %0" : "=r" (intrNestingLevel) : "0" (intrNestingLevel));
/* /*
@@ -286,7 +288,9 @@ void bsp_start( void )
Cpu_table.clicks_per_usec = BSP_processor_frequency/(BSP_time_base_divisor * 1000); Cpu_table.clicks_per_usec = BSP_processor_frequency/(BSP_time_base_divisor * 1000);
Cpu_table.exceptions_in_RAM = TRUE; Cpu_table.exceptions_in_RAM = TRUE;
#ifdef SHOW_MORE_INIT_SETTINGS
printk("BSP_Configuration.work_space_size = %x\n", BSP_Configuration.work_space_size); printk("BSP_Configuration.work_space_size = %x\n", BSP_Configuration.work_space_size);
#endif
work_space_start = work_space_start =
(unsigned char *)BSP_mem_size - BSP_Configuration.work_space_size; (unsigned char *)BSP_mem_size - BSP_Configuration.work_space_size;
@@ -306,5 +310,7 @@ void bsp_start( void )
* Initalize RTEMS IRQ system * Initalize RTEMS IRQ system
*/ */
BSP_rtems_irq_mng_init(0); BSP_rtems_irq_mng_init(0);
#ifdef SHOW_MORE_INIT_SETTINGS
printk("Exit from bspstart\n"); printk("Exit from bspstart\n");
#endif
} }

View File

@@ -86,6 +86,14 @@ SYM (push_normalized_frame):
stw r30, EXC_CTR_OFFSET(r1) stw r30, EXC_CTR_OFFSET(r1)
mfxer r28 mfxer r28
stw r28, EXC_XER_OFFSET(r1) stw r28, EXC_XER_OFFSET(r1)
/*
* compute SP at exception entry
*/
addi r2, r1, EXCEPTION_FRAME_END
/*
* store it at the right place
*/
stw r2, GPR1_OFFSET(r1)
/* /*
* Enable data and instruction address translation, exception nesting * Enable data and instruction address translation, exception nesting
*/ */
@@ -97,8 +105,17 @@ SYM (push_normalized_frame):
/* /*
* Call C exception handler * Call C exception handler
*/ */
/*
* store the execption frame address in r3 (first param)
*/
addi r3, r1, 0x8 addi r3, r1, 0x8
bl C_exception_handler /*
* globalExceptHdl(r3)
*/
addis r4, 0, globalExceptHdl@ha
lwz r5, globalExceptHdl@l(r4)
mtlr r5
blrl
/* /*
* Restore registers status * Restore registers status
*/ */
@@ -135,8 +152,3 @@ SYM (push_normalized_frame):
addi r1,r1, EXCEPTION_FRAME_END addi r1,r1, EXCEPTION_FRAME_END
SYNC SYNC
rfi rfi

View File

@@ -128,9 +128,16 @@ typedef struct {
unsigned EXC_LR; unsigned EXC_LR;
unsigned EXC_MSR; unsigned EXC_MSR;
unsigned EXC_DAR; unsigned EXC_DAR;
} exception_frame; }BSP_Exception_frame;
extern void C_exception_handler(exception_frame* excPtr);
typedef void (*exception_handler_t) (BSP_Exception_frame* excPtr);
extern exception_handler_t globalExceptHdl;
/*
* Compatibility with pc386
*/
typedef BSP_Exception_frame CPU_Exception_frame;
typedef exception_handler_t cpuExcHandlerType;
#endif /* ASM */ #endif /* ASM */

View File

@@ -19,7 +19,9 @@
static rtems_raw_except_global_settings exception_config; static rtems_raw_except_global_settings exception_config;
static rtems_raw_except_connect_data exception_table[LAST_VALID_EXC + 1]; static rtems_raw_except_connect_data exception_table[LAST_VALID_EXC + 1];
void C_exception_handler(exception_frame* excPtr) exception_handler_t globalExceptHdl;
void C_exception_handler(BSP_Exception_frame* excPtr)
{ {
int recoverable = 0; int recoverable = 0;
@@ -82,6 +84,14 @@ void initialize_exceptions()
{ {
int i; int i;
/*
* Initialize pointer used by low level execption handling
*/
globalExceptHdl = C_exception_handler;
/*
* Put default_exception_vector_code_prolog at relevant exception
* code entry addresses
*/
exception_config.exceptSize = LAST_VALID_EXC + 1; exception_config.exceptSize = LAST_VALID_EXC + 1;
exception_config.rawExceptHdlTbl = &exception_table[0]; exception_config.rawExceptHdlTbl = &exception_table[0];
exception_config.defaultRawEntry.exceptIndex = 0; exception_config.defaultRawEntry.exceptIndex = 0;

View File

@@ -117,7 +117,7 @@ struct MD {
/* /*
* Receive buffer size -- Allow for a full ethernet packet including CRC * Receive buffer size -- Allow for a full ethernet packet including CRC
*/ */
#define RBUF_SIZE 1520 #define RBUF_SIZE 1536
#define ET_MINLEN 60 /* minimum message length */ #define ET_MINLEN 60 /* minimum message length */
@@ -419,7 +419,8 @@ dec21140Enet_initialize_hardware (struct dec21140_softc *sc)
sc->rxBdCount = 0; sc->rxBdCount = 0;
cp = (char *)malloc((NRXBUFS+NTXBUFS)*(sizeof(struct MD)+ RBUF_SIZE) + PPC_CACHE_ALIGNMENT); cp = (char *)malloc((NRXBUFS+NTXBUFS)*(sizeof(struct MD)+ RBUF_SIZE) + PPC_CACHE_ALIGNMENT);
sc->bufferBase = cp; sc->bufferBase = cp;
cp += (PPC_CACHE_ALIGNMENT - (int)cp) & MASK_OFFSET; if ((unsigned int)cp & (PPC_CACHE_ALIGNMENT-1))
cp = ((unsigned int)cp + PPC_CACHE_ALIGNMENT) & ~(PPC_CACHE_ALIGNMENT-1);
#ifdef PCI_BRIDGE_DOES_NOT_ENSURE_CACHE_COHERENCY_FOR_DMA #ifdef PCI_BRIDGE_DOES_NOT_ENSURE_CACHE_COHERENCY_FOR_DMA
if (_CPU_is_paging_enabled()) if (_CPU_is_paging_enabled())
_CPU_change_memory_mapping_attribute _CPU_change_memory_mapping_attribute

View File

@@ -16,6 +16,7 @@
#include <console.h> #include <console.h>
#include <libcpu/io.h> #include <libcpu/io.h>
#include <clockdrv.h> #include <clockdrv.h>
#include <bsp/vectors.h>
#ifndef ASM #ifndef ASM
#define outport_byte(port,value) outb(value,port) #define outport_byte(port,value) outb(value,port)

View File

@@ -21,9 +21,8 @@
/* /*
* lower byte is interrupt mask on the master PIC. * lower byte is interrupt mask on the master PIC.
* while upper bits are interrupt on the slave PIC. * while upper bits are interrupt on the slave PIC.
* This cache is initialized in ldseg.s
*/ */
volatile rtems_i8259_masks i8259s_cache; volatile rtems_i8259_masks i8259s_cache = 0xfffb;
/*-------------------------------------------------------------------------+ /*-------------------------------------------------------------------------+
| Function: BSP_irq_disable_at_i8259s | Function: BSP_irq_disable_at_i8259s
@@ -53,7 +52,7 @@ int BSP_irq_disable_at_i8259s (const rtems_irq_symbolic_name irqLine)
} }
else else
{ {
outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) > 8)); outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
} }
_CPU_ISR_Enable (level); _CPU_ISR_Enable (level);
@@ -88,7 +87,7 @@ int BSP_irq_enable_at_i8259s (const rtems_irq_symbolic_name irqLine)
} }
else else
{ {
outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) > 8)); outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
} }
_CPU_ISR_Enable (level); _CPU_ISR_Enable (level);
@@ -119,9 +118,12 @@ int BSP_irq_enabled_at_i8259s (const rtems_irq_symbolic_name irqLine)
int BSP_irq_ack_at_i8259s (const rtems_irq_symbolic_name irqLine) int BSP_irq_ack_at_i8259s (const rtems_irq_symbolic_name irqLine)
{ {
if (irqLine >= 8) { if (irqLine >= 8) {
outport_byte(PIC_SLAVE_COMMAND_IO_PORT, PIC_EOI); outport_byte(PIC_MASTER_COMMAND_IO_PORT, SLAVE_PIC_EOSI);
outport_byte(PIC_SLAVE_COMMAND_IO_PORT, (PIC_EOSI | (irqLine - 8)));
}
else {
outport_byte(PIC_MASTER_COMMAND_IO_PORT, (PIC_EOSI | irqLine));
} }
outport_byte(PIC_MASTER_COMMAND_IO_PORT, PIC_EOI);
return 0; return 0;
@@ -146,6 +148,5 @@ void BSP_i8259s_init(void)
outport_byte(PIC_SLAVE_IMR_IO_PORT, 0x01); /* Select 8086 mode */ outport_byte(PIC_SLAVE_IMR_IO_PORT, 0x01); /* Select 8086 mode */
outport_byte(PIC_SLAVE_IMR_IO_PORT, 0xFF); /* Mask all */ outport_byte(PIC_SLAVE_IMR_IO_PORT, 0xFF); /* Mask all */
i8259s_cache = 0xFFFB;
} }

View File

@@ -378,7 +378,7 @@ void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
void _ThreadProcessSignalsFromIrq (exception_frame* ctx) void _ThreadProcessSignalsFromIrq (BSP_Exception_frame* ctx)
{ {
/* /*
* Process pending signals that have not already been * Process pending signals that have not already been

View File

@@ -54,6 +54,7 @@
/* Command for specific EOI (End Of Interrupt): Interrupt acknowledge */ /* Command for specific EOI (End Of Interrupt): Interrupt acknowledge */
#define PIC_EOSI 0x60 /* End of Specific Interrupt (EOSI) */ #define PIC_EOSI 0x60 /* End of Specific Interrupt (EOSI) */
#define SLAVE_PIC_EOSI 0x62 /* End of Specific Interrupt (EOSI) for cascade */
#define PIC_EOI 0x20 /* Generic End of Interrupt (EOI) */ #define PIC_EOI 0x20 /* Generic End of Interrupt (EOI) */
#ifndef ASM #ifndef ASM

View File

@@ -212,6 +212,13 @@ nested:
*/ */
stmw r16, GPR16_OFFSET(r1) stmw r16, GPR16_OFFSET(r1)
addi r3, r1, 0x8 addi r3, r1, 0x8
/*
* compute SP at exception entry
*/
addi r2, r1, EXCEPTION_FRAME_END
/*
* store it at the right place
*/
bl _ISR_Signals_to_thread_executing bl _ISR_Signals_to_thread_executing
/* /*
* start restoring exception like frame * start restoring exception like frame

View File

@@ -1,33 +1,20 @@
/* /*
* arch/ppc/kernel/head.S * start.S : RTEMS entry point
*
* Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
* *
* $Id$ * $Id$
* *
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
* Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
* Adapted for Power Macintosh by Paul Mackerras.
* Low-level exception handlers and MMU support
* rewritten by Paul Mackerras.
* Copyright (C) 1996 Paul Mackerras.
* MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
* Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
*
* This file contains the low-level support and setup for the
* PowerPC platform, including trap and interrupt dispatch.
* Also included here is low-level thread/task switch 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 <libcpu/cpu.h> #include <libcpu/cpu.h>
#include <libcpu/io.h> #include <libcpu/io.h>
#include <rtems/score/targopts.h> #include <rtems/score/targopts.h>
#include <rtems/score/cpu.h>
#include "asm.h" #include "asm.h"
#define SYNC \ #define SYNC \
@@ -91,8 +78,8 @@ enter_C_code:
/* /*
* stack = &__rtems_end + 4096 * stack = &__rtems_end + 4096
*/ */
addis r9,r0, __rtems_end+4096@ha addis r9,r0, __rtems_end+(4096-CPU_MINIMUM_STACK_FRAME_SIZE)@ha
addi r9,r9, __rtems_end+4096@l addi r9,r9, __rtems_end+(4096-CPU_MINIMUM_STACK_FRAME_SIZE)@l
mr r1, r9 mr r1, r9
bl zero_bss bl zero_bss
/* /*
@@ -142,8 +129,3 @@ _return_to_ppcbug:
bl MMUon bl MMUon
mtctr r30 mtctr r30
bctr bctr

View File

@@ -131,7 +131,9 @@ void bsp_pretasking_hook(void)
heap_size = (BSP_mem_size - heap_start) - BSP_Configuration.work_space_size; heap_size = (BSP_mem_size - heap_start) - BSP_Configuration.work_space_size;
#ifdef SHOW_MORE_INIT_SETTINGS
printk(" HEAP start %x size %x\n", heap_start, heap_size); printk(" HEAP start %x size %x\n", heap_start, heap_size);
#endif
bsp_libc_init((void *) heap_start, heap_size, 0); bsp_libc_init((void *) heap_start, heap_size, 0);
#ifdef RTEMS_DEBUG #ifdef RTEMS_DEBUG
@@ -141,7 +143,7 @@ void bsp_pretasking_hook(void)
void zero_bss() void zero_bss()
{ {
memset(&__bss_start, 0, &__rtems_end - &__bss_start); memset(&__bss_start, 0, ((unsigned) (&__rtems_end)) - ((unsigned) &__bss_start));
} }
void save_boot_params(RESIDUAL* r3, void *r4, void* r5, char *additional_boot_options) void save_boot_params(RESIDUAL* r3, void *r4, void* r5, char *additional_boot_options)
@@ -184,7 +186,7 @@ void bsp_start( void )
* the initial stack has aready been set to this value in start.S * the initial stack has aready been set to this value in start.S
* so there is no need to set it in r1 again... * so there is no need to set it in r1 again...
*/ */
stack = ((unsigned char*) &__rtems_end) + INIT_STACK_SIZE; stack = ((unsigned char*) &__rtems_end) + INIT_STACK_SIZE - CPU_MINIMUM_STACK_FRAME_SIZE;
/* /*
* Initialize the interrupt related settings * Initialize the interrupt related settings
* SPRG0 = interrupt nesting level count * SPRG0 = interrupt nesting level count
@@ -193,7 +195,7 @@ void bsp_start( void )
* This could be done latter (e.g in IRQ_INIT) but it helps to understand * This could be done latter (e.g in IRQ_INIT) but it helps to understand
* some settings below... * some settings below...
*/ */
intrStack = ((unsigned char*) &__rtems_end) + INIT_STACK_SIZE + INTR_STACK_SIZE; intrStack = ((unsigned char*) &__rtems_end) + INIT_STACK_SIZE + INTR_STACK_SIZE - CPU_MINIMUM_STACK_FRAME_SIZE;
asm volatile ("mtspr 273, %0" : "=r" (intrStack) : "0" (intrStack)); asm volatile ("mtspr 273, %0" : "=r" (intrStack) : "0" (intrStack));
asm volatile ("mtspr 272, %0" : "=r" (intrNestingLevel) : "0" (intrNestingLevel)); asm volatile ("mtspr 272, %0" : "=r" (intrNestingLevel) : "0" (intrNestingLevel));
/* /*
@@ -286,7 +288,9 @@ void bsp_start( void )
Cpu_table.clicks_per_usec = BSP_processor_frequency/(BSP_time_base_divisor * 1000); Cpu_table.clicks_per_usec = BSP_processor_frequency/(BSP_time_base_divisor * 1000);
Cpu_table.exceptions_in_RAM = TRUE; Cpu_table.exceptions_in_RAM = TRUE;
#ifdef SHOW_MORE_INIT_SETTINGS
printk("BSP_Configuration.work_space_size = %x\n", BSP_Configuration.work_space_size); printk("BSP_Configuration.work_space_size = %x\n", BSP_Configuration.work_space_size);
#endif
work_space_start = work_space_start =
(unsigned char *)BSP_mem_size - BSP_Configuration.work_space_size; (unsigned char *)BSP_mem_size - BSP_Configuration.work_space_size;
@@ -306,5 +310,7 @@ void bsp_start( void )
* Initalize RTEMS IRQ system * Initalize RTEMS IRQ system
*/ */
BSP_rtems_irq_mng_init(0); BSP_rtems_irq_mng_init(0);
#ifdef SHOW_MORE_INIT_SETTINGS
printk("Exit from bspstart\n"); printk("Exit from bspstart\n");
#endif
} }

View File

@@ -86,6 +86,14 @@ SYM (push_normalized_frame):
stw r30, EXC_CTR_OFFSET(r1) stw r30, EXC_CTR_OFFSET(r1)
mfxer r28 mfxer r28
stw r28, EXC_XER_OFFSET(r1) stw r28, EXC_XER_OFFSET(r1)
/*
* compute SP at exception entry
*/
addi r2, r1, EXCEPTION_FRAME_END
/*
* store it at the right place
*/
stw r2, GPR1_OFFSET(r1)
/* /*
* Enable data and instruction address translation, exception nesting * Enable data and instruction address translation, exception nesting
*/ */
@@ -97,8 +105,17 @@ SYM (push_normalized_frame):
/* /*
* Call C exception handler * Call C exception handler
*/ */
/*
* store the execption frame address in r3 (first param)
*/
addi r3, r1, 0x8 addi r3, r1, 0x8
bl C_exception_handler /*
* globalExceptHdl(r3)
*/
addis r4, 0, globalExceptHdl@ha
lwz r5, globalExceptHdl@l(r4)
mtlr r5
blrl
/* /*
* Restore registers status * Restore registers status
*/ */
@@ -135,8 +152,3 @@ SYM (push_normalized_frame):
addi r1,r1, EXCEPTION_FRAME_END addi r1,r1, EXCEPTION_FRAME_END
SYNC SYNC
rfi rfi

View File

@@ -128,9 +128,16 @@ typedef struct {
unsigned EXC_LR; unsigned EXC_LR;
unsigned EXC_MSR; unsigned EXC_MSR;
unsigned EXC_DAR; unsigned EXC_DAR;
} exception_frame; }BSP_Exception_frame;
extern void C_exception_handler(exception_frame* excPtr);
typedef void (*exception_handler_t) (BSP_Exception_frame* excPtr);
extern exception_handler_t globalExceptHdl;
/*
* Compatibility with pc386
*/
typedef BSP_Exception_frame CPU_Exception_frame;
typedef exception_handler_t cpuExcHandlerType;
#endif /* ASM */ #endif /* ASM */

View File

@@ -19,7 +19,9 @@
static rtems_raw_except_global_settings exception_config; static rtems_raw_except_global_settings exception_config;
static rtems_raw_except_connect_data exception_table[LAST_VALID_EXC + 1]; static rtems_raw_except_connect_data exception_table[LAST_VALID_EXC + 1];
void C_exception_handler(exception_frame* excPtr) exception_handler_t globalExceptHdl;
void C_exception_handler(BSP_Exception_frame* excPtr)
{ {
int recoverable = 0; int recoverable = 0;
@@ -82,6 +84,14 @@ void initialize_exceptions()
{ {
int i; int i;
/*
* Initialize pointer used by low level execption handling
*/
globalExceptHdl = C_exception_handler;
/*
* Put default_exception_vector_code_prolog at relevant exception
* code entry addresses
*/
exception_config.exceptSize = LAST_VALID_EXC + 1; exception_config.exceptSize = LAST_VALID_EXC + 1;
exception_config.rawExceptHdlTbl = &exception_table[0]; exception_config.rawExceptHdlTbl = &exception_table[0];
exception_config.defaultRawEntry.exceptIndex = 0; exception_config.defaultRawEntry.exceptIndex = 0;

View File

@@ -1,6 +1,7 @@
/* /*
============================================================================ ============================================================================
_SERVTGT _SERVTGT
$Id$
============================================================================ ============================================================================
*/ */
@@ -17,9 +18,6 @@
#include <assert.h> #include <assert.h>
#include <rtems/score/cpu.h> #include <rtems/score/cpu.h>
extern void rtems_exception_prologue_50();
#ifdef DDEBUG #ifdef DDEBUG
#define Ptrace TgtDbgPtrace #define Ptrace TgtDbgPtrace
#else #else
@@ -34,8 +32,6 @@ rtems_id wakeupEventSemId;
CPU_Exception_frame Idle_frame; CPU_Exception_frame Idle_frame;
cpuExcHandlerType old_currentExcHandler;
/* ----------------------------------------------------------------- /* -----------------------------------------------------------------
TgtRealPtrace - lowest level ptrace() wrapper TgtRealPtrace - lowest level ptrace() wrapper
----------------------------------------------------------------- */ ----------------------------------------------------------------- */
@@ -47,43 +43,6 @@ TgtRealPtrace(int req, PID aid, char* addr, int d, void* addr2)
} }
/* -----------------------------------------------------------------
Maping of hardware exceptions into Unix-like signal numbers.
It is identical to the one used by the PM and the AM.
----------------------------------------------------------------- */
int
ExcepToSig (int excep)
{
switch (excep) {
case I386_EXCEPTION_MATH_COPROC_UNAVAIL:
case I386_EXCEPTION_I386_COPROC_SEG_ERR:
case I386_EXCEPTION_FLOAT_ERROR:
case I386_EXCEPTION_BOUND:
return SIGFPE;
case I386_EXCEPTION_DEBUG:
case I386_EXCEPTION_BREAKPOINT:
case I386_EXCEPTION_ENTER_RDBG:
return SIGTRAP;
case I386_EXCEPTION_OVERFLOW:
case I386_EXCEPTION_DIVIDE_BY_ZERO:
case I386_EXCEPTION_ILLEGAL_INSTR:
return SIGILL;
case I386_EXCEPTION_SEGMENT_NOT_PRESENT:
case I386_EXCEPTION_STACK_SEGMENT_FAULT:
case I386_EXCEPTION_GENERAL_PROT_ERR:
case I386_EXCEPTION_PAGE_FAULT:
return SIGSEGV;
default:
break;
}
return SIGKILL;
}
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
TgtChange() is called when the system stops. TgtChange() is called when the system stops.
@@ -128,7 +87,7 @@ rtems_task eventTask( rtems_task_argument pid)
CheckForSingleStep(ctx->ctx); CheckForSingleStep(ctx->ctx);
TgtChange(pid, ctx->ctx,STS_MAKESIG(ExcepToSig(ctx->ctx->idtIndex))); TgtChange(pid, ctx->ctx,STS_MAKESIG(ExcepToSig(ctx)));
} }
} }
@@ -162,9 +121,6 @@ Boolean TgtAttach(
rtems_name task_name; rtems_name task_name;
rtems_status_code status; rtems_status_code status;
rtems_id debugId; rtems_id debugId;
interrupt_gate_descriptor *currentIdtEntry;
unsigned limit;
unsigned level;
errno = 0; errno = 0;
@@ -177,18 +133,7 @@ Boolean TgtAttach(
TgtCreateNew(pid, conn_idx, 0, NULL, False); TgtCreateNew(pid, conn_idx, 0, NULL, False);
/* connect_rdbg_exception();
* Connect the Exception used to debug
*/
i386_get_info_from_IDTR (&currentIdtEntry, &limit);
_CPU_ISR_Disable(level);
create_interrupt_gate_descriptor (&currentIdtEntry[50], rtems_exception_prologue_50);
_CPU_ISR_Enable(level);
old_currentExcHandler = _currentExcHandler;
_currentExcHandler = BreakPointExcHdl ;
/* /*
* Create the attach debuger task * Create the attach debuger task

View File

@@ -7,7 +7,9 @@
# by rpcgen(1) into something suitable for RDB servers. # by rpcgen(1) into something suitable for RDB servers.
# #
######################################################################### #########################################################################
#
# $Id$
#
BEGIN { BEGIN {
headerstarted = 0 headerstarted = 0
withinproc = 0 withinproc = 0

136
c/src/lib/librdbg/excep.c Normal file
View File

@@ -0,0 +1,136 @@
/*
**************************************************************************
*
* Component =
*
* Synopsis = rdbgexcep.c
*
* $Id$
*
**************************************************************************
*/
#include <rtems.h>
#include <rtems/error.h>
#include <assert.h>
#include <errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
unsigned int NbExceptCtx;
volatile unsigned int NbSerializedCtx;
Exception_context *FirstCtx = NULL;
Exception_context *LastCtx = NULL;
CPU_Exception_frame SavedContext;
/********* Save an exception context at the end of a list *****/
int PushExceptCtx ( Objects_Id Id, Objects_Id semId, CPU_Exception_frame *ctx ) {
Exception_context *SaveCtx;
SaveCtx = (Exception_context *)malloc(sizeof(Exception_context));
if (SaveCtx == NULL)
rtems_panic("Can't allocate memory to save Exception context");
SaveCtx->id = Id;
SaveCtx->ctx = ctx;
SaveCtx->semaphoreId = semId;
SaveCtx->previous = NULL;
SaveCtx->next = NULL;
if (FirstCtx == NULL){ /* initialization */
FirstCtx = SaveCtx;
LastCtx = SaveCtx;
NbExceptCtx = 1;
}
else {
NbExceptCtx ++;
LastCtx->next = SaveCtx;
SaveCtx->previous = LastCtx;
LastCtx = SaveCtx;
}
return 0;
}
/********* Save an temporary exception context in a ******/
/********* global variable ******/
int PushSavedExceptCtx ( Objects_Id Id, CPU_Exception_frame *ctx ) {
memcpy (&(SavedContext), ctx, sizeof(CPU_Exception_frame));
return 0;
}
/****** Remove the context of the specified Id thread *********/
/****** If Id = -1, then return the first context *********/
int PopExceptCtx ( Objects_Id Id ) {
Exception_context *ExtractCtx;
if (FirstCtx == NULL) return -1;
if (Id == -1) {
ExtractCtx = LastCtx;
LastCtx = LastCtx->previous;
free(ExtractCtx);
NbExceptCtx --;
return 0;
}
ExtractCtx = LastCtx;
while (ExtractCtx->id != Id && ExtractCtx != NULL) {
ExtractCtx = ExtractCtx->previous;
}
if (ExtractCtx == NULL)
return -1;
if ( ExtractCtx->previous != NULL)
(ExtractCtx->previous)->next = ExtractCtx->next;
if ( ExtractCtx->next != NULL)
(ExtractCtx->next)->previous = ExtractCtx->previous;
if (ExtractCtx == FirstCtx)
FirstCtx = FirstCtx->next;
else
if (ExtractCtx == LastCtx)
LastCtx = LastCtx->previous;
free(ExtractCtx);
NbExceptCtx --;
return 0;
}
/****** Return the context of the specified Id thread *********/
/****** If Id = -1, then return the first context *********/
Exception_context *GetExceptCtx ( Objects_Id Id ) {
Exception_context *ExtractCtx;
if (FirstCtx == NULL) return NULL;
if (Id == -1) {
return LastCtx;
}
ExtractCtx = LastCtx;
while (ExtractCtx->id != Id && ExtractCtx != NULL) {
ExtractCtx = ExtractCtx->previous;
}
if (ExtractCtx == NULL)
return NULL;
return ExtractCtx;
}

View File

@@ -1,233 +0,0 @@
/*
**************************************************************************
*
* Component =
*
* Synopsis = rdbg/i386/excep.c
*
**************************************************************************
*/
#include <rtems.h>
#include <rtems/error.h>
#include <rdbg/rdbg_f.h>
#include <assert.h>
#include <errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
extern rtems_id serializeSemId;
extern rtems_id wakeupEventSemId;
unsigned int NbExceptCtx;
volatile unsigned int NbSerializedCtx;
Exception_context *FirstCtx = NULL;
Exception_context *LastCtx = NULL;
CPU_Exception_frame SavedContext;
/********* Save an exception context at the end of a list *****/
int PushExceptCtx ( Objects_Id Id, Objects_Id semId, CPU_Exception_frame *ctx ) {
Exception_context *SaveCtx;
SaveCtx = (Exception_context *)malloc(sizeof(Exception_context));
if (SaveCtx == NULL)
rtems_panic("Can't allocate memory to save Exception context");
SaveCtx->id = Id;
SaveCtx->ctx = ctx;
SaveCtx->semaphoreId = semId;
SaveCtx->previous = NULL;
SaveCtx->next = NULL;
if (FirstCtx == NULL){ /* initialization */
FirstCtx = SaveCtx;
LastCtx = SaveCtx;
NbExceptCtx = 1;
}
else {
NbExceptCtx ++;
LastCtx->next = SaveCtx;
SaveCtx->previous = LastCtx;
LastCtx = SaveCtx;
}
return 0;
}
/********* Save an temporary exception context in a ******/
/********* global variable ******/
int PushSavedExceptCtx ( Objects_Id Id, CPU_Exception_frame *ctx ) {
memcpy (&(SavedContext), ctx, sizeof(CPU_Exception_frame));
return 0;
}
/****** Remove the context of the specified Id thread *********/
/****** If Id = -1, then return the first context *********/
int PopExceptCtx ( Objects_Id Id ) {
Exception_context *ExtractCtx;
if (FirstCtx == NULL) return -1;
if (Id == -1) {
ExtractCtx = LastCtx;
LastCtx = LastCtx->previous;
free(ExtractCtx);
NbExceptCtx --;
return 0;
}
ExtractCtx = LastCtx;
while (ExtractCtx->id != Id && ExtractCtx != NULL) {
ExtractCtx = ExtractCtx->previous;
}
if (ExtractCtx == NULL)
return -1;
if ( ExtractCtx->previous != NULL)
(ExtractCtx->previous)->next = ExtractCtx->next;
if ( ExtractCtx->next != NULL)
(ExtractCtx->next)->previous = ExtractCtx->previous;
if (ExtractCtx == FirstCtx)
FirstCtx = FirstCtx->next;
else
if (ExtractCtx == LastCtx)
LastCtx = LastCtx->previous;
free(ExtractCtx);
NbExceptCtx --;
return 0;
}
/****** Return the context of the specified Id thread *********/
/****** If Id = -1, then return the first context *********/
Exception_context *GetExceptCtx ( Objects_Id Id ) {
Exception_context *ExtractCtx;
if (FirstCtx == NULL) return NULL;
if (Id == -1) {
return LastCtx;
}
ExtractCtx = LastCtx;
while (ExtractCtx->id != Id && ExtractCtx != NULL) {
ExtractCtx = ExtractCtx->previous;
}
if (ExtractCtx == NULL)
return NULL;
return ExtractCtx;
}
/*----- Breakpoint Exception management -----*/
/*
* Handler for Breakpoint Exceptions :
* software breakpoints.
*/
void
BreakPointExcHdl(CPU_Exception_frame *ctx)
{
rtems_status_code status;
rtems_id continueSemId;
if ( (justSaveContext) && (ctx->idtIndex == I386_EXCEPTION_ENTER_RDBG) ) {
PushSavedExceptCtx (_Thread_Executing->Object.id, ctx);
justSaveContext = 0;
}
else {
if (ctx->idtIndex != I386_EXCEPTION_DEBUG){
NbSerializedCtx++;
rtems_semaphore_obtain(serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
NbSerializedCtx--;
}
currentTargetThread = _Thread_Executing->Object.id;
#ifdef DDEBUG
printk("----------------------------------------------------------\n");
printk("Exception %d caught at PC %x by thread %d\n",
ctx->idtIndex,
ctx->eip,
_Thread_Executing->Object.id);
printk("----------------------------------------------------------\n");
printk("Processor execution context at time of the fault was :\n");
printk("----------------------------------------------------------\n");
printk(" EAX = %x EBX = %x ECX = %x EDX = %x\n",
ctx->eax, ctx->ebx, ctx->ecx, ctx->edx);
printk(" ESI = %x EDI = %x EBP = %x ESP = %x\n",
ctx->esi, ctx->edi, ctx->ebp, ctx->esp0);
printk("----------------------------------------------------------\n");
printk("Error code pushed by processor itself (if not 0) = %x\n",
ctx->faultCode);
printk("----------------------------------------------------------\n\n");
#endif
status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 'c'),
0,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL,
0,
&continueSemId);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't create continue semaphore: `%s'\n",rtems_status_text(status));
PushExceptCtx (_Thread_Executing->Object.id, continueSemId, ctx);
switch (ctx->idtIndex){
case I386_EXCEPTION_DEBUG:
DPRINTF((" DEBUG EXCEPTION !!!\n"));
ctx->eflags &= ~EFLAGS_TF;
ExitForSingleStep-- ;
rtems_semaphore_release( wakeupEventSemId );
break;
case I386_EXCEPTION_BREAKPOINT:
DPRINTF((" BREAKPOINT EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
case I386_EXCEPTION_ENTER_RDBG:
DPRINTF((" ENTER RDBG !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
default:
DPRINTF((" OTHER EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
}
rtems_semaphore_obtain(continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
PopExceptCtx (_Thread_Executing->Object.id);
rtems_semaphore_delete(continueSemId);
}
}

View File

@@ -0,0 +1,153 @@
/*
**************************************************************************
*
* Component =
*
* Synopsis = rdbg/i386/excep.c
*
* $Id$
*
**************************************************************************
*/
#include <rtems.h>
#include <rtems/error.h>
#include <assert.h>
#include <errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
/* -----------------------------------------------------------------
Maping of hardware exceptions into Unix-like signal numbers.
It is identical to the one used by the PM and the AM.
----------------------------------------------------------------- */
int
ExcepToSig (Exception_context *ctx)
{
int excep = getExcNum (ctx);
switch (excep) {
case I386_EXCEPTION_MATH_COPROC_UNAVAIL:
case I386_EXCEPTION_I386_COPROC_SEG_ERR:
case I386_EXCEPTION_FLOAT_ERROR:
case I386_EXCEPTION_BOUND:
return SIGFPE;
case I386_EXCEPTION_DEBUG:
case I386_EXCEPTION_BREAKPOINT:
case I386_EXCEPTION_ENTER_RDBG:
return SIGTRAP;
case I386_EXCEPTION_OVERFLOW:
case I386_EXCEPTION_DIVIDE_BY_ZERO:
case I386_EXCEPTION_ILLEGAL_INSTR:
return SIGILL;
case I386_EXCEPTION_SEGMENT_NOT_PRESENT:
case I386_EXCEPTION_STACK_SEGMENT_FAULT:
case I386_EXCEPTION_GENERAL_PROT_ERR:
case I386_EXCEPTION_PAGE_FAULT:
return SIGSEGV;
default:
break;
}
return SIGKILL;
}
/*----- Breakpoint Exception management -----*/
/*
* Handler for Breakpoint Exceptions :
* software breakpoints.
*/
void
BreakPointExcHdl(CPU_Exception_frame *ctx)
{
rtems_status_code status;
rtems_id continueSemId;
if ( (justSaveContext) && (ctx->idtIndex == I386_EXCEPTION_ENTER_RDBG) ) {
PushSavedExceptCtx (_Thread_Executing->Object.id, ctx);
justSaveContext = 0;
}
else {
if (ctx->idtIndex != I386_EXCEPTION_DEBUG){
NbSerializedCtx++;
rtems_semaphore_obtain(serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
NbSerializedCtx--;
}
currentTargetThread = _Thread_Executing->Object.id;
#ifdef DDEBUG
printk("----------------------------------------------------------\n");
printk("Exception %d caught at PC %x by thread %d\n",
ctx->idtIndex,
ctx->eip,
_Thread_Executing->Object.id);
printk("----------------------------------------------------------\n");
printk("Processor execution context at time of the fault was :\n");
printk("----------------------------------------------------------\n");
printk(" EAX = %x EBX = %x ECX = %x EDX = %x\n",
ctx->eax, ctx->ebx, ctx->ecx, ctx->edx);
printk(" ESI = %x EDI = %x EBP = %x ESP = %x\n",
ctx->esi, ctx->edi, ctx->ebp, ctx->esp0);
printk("----------------------------------------------------------\n");
printk("Error code pushed by processor itself (if not 0) = %x\n",
ctx->faultCode);
printk("----------------------------------------------------------\n\n");
#endif
status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 'c'),
0,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL,
0,
&continueSemId);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't create continue semaphore: `%s'\n",rtems_status_text(status));
PushExceptCtx (_Thread_Executing->Object.id, continueSemId, ctx);
switch (ctx->idtIndex){
case I386_EXCEPTION_DEBUG:
DPRINTF((" DEBUG EXCEPTION !!!\n"));
ctx->eflags &= ~EFLAGS_TF;
ExitForSingleStep-- ;
rtems_semaphore_release( wakeupEventSemId );
break;
case I386_EXCEPTION_BREAKPOINT:
DPRINTF((" BREAKPOINT EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
case I386_EXCEPTION_ENTER_RDBG:
DPRINTF((" ENTER RDBG !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
default:
DPRINTF((" OTHER EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
}
rtems_semaphore_obtain(continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
PopExceptCtx (_Thread_Executing->Object.id);
rtems_semaphore_delete(continueSemId);
}
}

View File

@@ -17,8 +17,10 @@ LIBNAME = librdbg.a
LIB = ${ARCH}/${LIBNAME} LIB = ${ARCH}/${LIBNAME}
# C and C++ source names, if any, go here -- minus the .c or .cc # C and C++ source names, if any, go here -- minus the .c or .cc
C_PIECES = rdbg servcon servbkpt servrpc excep servtgt servtsp servutil \ C_PIECES = rdbg servcon servbkpt servrpc excep excep_f \
_servtgt rdbg_f ptrace servtgt servtsp servutil _servtgt rdbg_f \
ptrace
C_FILES = $(C_PIECES:%=%.c) C_FILES = $(C_PIECES:%=%.c)
C_O_FILES = $(C_PIECES:%=${ARCH}/%.o) C_O_FILES = $(C_PIECES:%=${ARCH}/%.o)

View File

@@ -5,6 +5,7 @@
* *
* Synopsis = remdeb_f.x * Synopsis = remdeb_f.x
* *
* $Id$
* *
************************************************************************** **************************************************************************
*/ */

View File

@@ -3,6 +3,8 @@
* This file contains all assembly code for the Intel i386 implementation * This file contains all assembly code for the Intel i386 implementation
* of RDBG. * of RDBG.
* *
* $Id$
*
*/ */
#include <asm.h> #include <asm.h>
@@ -10,7 +12,7 @@
BEGIN_CODE BEGIN_CODE
/* /*
* void copyback_data_cache_and_invalidate_instr_cache() * void copyback_data_cache_and_invalidate_instr_cache(addr, size)
* *
* This routine performs a copy of the data cache * This routine performs a copy of the data cache
* and invalidate the instruction cache * and invalidate the instruction cache

View File

@@ -5,6 +5,8 @@
* *
* Synopsis = rdbg/i386/rdbg_f.c * Synopsis = rdbg/i386/rdbg_f.c
* *
* $Id$
*
************************************************************************** **************************************************************************
*/ */
@@ -128,3 +130,26 @@ CancelSingleStep (CPU_Exception_frame* ctx)
ctx->eflags &= ~EFLAGS_TF; ctx->eflags &= ~EFLAGS_TF;
ExitForSingleStep-- ; ExitForSingleStep-- ;
} }
cpuExcHandlerType old_currentExcHandler;
extern void rtems_exception_prologue_50();
void connect_rdbg_exception()
{
interrupt_gate_descriptor *currentIdtEntry;
unsigned limit;
unsigned level;
/*
* Connect the Exception used to debug
*/
i386_get_info_from_IDTR (&currentIdtEntry, &limit);
_CPU_ISR_Disable(level);
create_interrupt_gate_descriptor (&currentIdtEntry[50], rtems_exception_prologue_50);
_CPU_ISR_Enable(level);
old_currentExcHandler = _currentExcHandler;
_currentExcHandler = BreakPointExcHdl ;
}

View File

@@ -0,0 +1,25 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ../..
subdir = librdbg/powerpc
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
include $(RTEMS_ROOT)/make/custom/${RTEMS_BSP}.cfg
include $(RTEMS_ROOT)/make/directory.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
SUB_DIRS = @RTEMS_BSP@
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -0,0 +1,167 @@
/*
**************************************************************************
*
* Component =
*
* Synopsis = rdbg/powerpc/excep_f.c
*
* $Id$
*
**************************************************************************
*/
#include <rtems.h>
#include <rtems/error.h>
#include <assert.h>
#include <errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
int
ExcepToSig (Exception_context *ctx)
{
int excep = getExcNum (ctx);
switch (excep) {
case ASM_FLOAT_VECTOR : return SIGFPE;
case ASM_TRACE_VECTOR :
case ASM_SYS_VECTOR : return SIGTRAP;
case ASM_ISI_VECTOR : return SIGSEGV;
case ASM_PROG_VECTOR :
case ASM_RESET_VECTOR :
case ASM_MACH_VECTOR :
case ASM_EXT_VECTOR :
case ASM_ALIGN_VECTOR : return SIGILL;
default:
break;
}
return SIGKILL;
}
/*----- Breakpoint Exception management -----*/
/*
* Handler for Breakpoint Exceptions :
* software breakpoints.
*/
void
BreakPointExcHdl(CPU_Exception_frame *ctx)
{
rtems_status_code status;
rtems_id continueSemId;
if ( (justSaveContext) && (ctx->_EXC_number == ASM_SYS_VECTOR) ) {
PushSavedExceptCtx (_Thread_Executing->Object.id, ctx);
justSaveContext = 0;
}
else {
if (ctx->_EXC_number != ASM_TRACE_VECTOR){
NbSerializedCtx++;
rtems_semaphore_obtain(serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
NbSerializedCtx--;
}
currentTargetThread = _Thread_Executing->Object.id;
#ifdef DDEBUG
printk("----------------------------------------------------------\n");
printk("Exception %d caught at PC %x by thread %d\n",
ctx->_EXC_number,
ctx->EXC_SRR0,
_Thread_Executing->Object.id);
printk("----------------------------------------------------------\n");
printk("Processor execution context at time of the fault was :\n");
printk("----------------------------------------------------------\n");
printk("\t R0 = %x\n", ctx->GPR0);
printk("\t R1 = %x\n", ctx->GPR1);
printk("\t R2 = %x\n", ctx->GPR2);
printk("\t R3 = %x\n", ctx->GPR3);
printk("\t R4 = %x\n", ctx->GPR4);
printk("\t R5 = %x\n", ctx->GPR5);
printk("\t R6 = %x\n", ctx->GPR6);
printk("\t R7 = %x\n", ctx->GPR7);
printk("\t R8 = %x\n", ctx->GPR8);
printk("\t R9 = %x\n", ctx->GPR9);
printk("\t R10 = %x\n", ctx->GPR10);
printk("\t R11 = %x\n", ctx->GPR11);
printk("\t R12 = %x\n", ctx->GPR12);
printk("\t R13 = %x\n", ctx->GPR13);
printk("\t R14 = %x\n", ctx->GPR14);
printk("\t R15 = %x\n", ctx->GPR15);
printk("\t R16 = %x\n", ctx->GPR16);
printk("\t R17 = %x\n", ctx->GPR17);
printk("\t R18 = %x\n", ctx->GPR18);
printk("\t R19 = %x\n", ctx->GPR19);
printk("\t R20 = %x\n", ctx->GPR20);
printk("\t R21 = %x\n", ctx->GPR21);
printk("\t R22 = %x\n", ctx->GPR22);
printk("\t R23 = %x\n", ctx->GPR23);
printk("\t R24 = %x\n", ctx->GPR24);
printk("\t R25 = %x\n", ctx->GPR25);
printk("\t R26 = %x\n", ctx->GPR26);
printk("\t R27 = %x\n", ctx->GPR27);
printk("\t R28 = %x\n", ctx->GPR28);
printk("\t R29 = %x\n", ctx->GPR29);
printk("\t R30 = %x\n", ctx->GPR30);
printk("\t R31 = %x\n", ctx->GPR31);
printk("\t CR = %x\n", ctx->EXC_CR);
printk("\t CTR = %x\n", ctx->EXC_CTR);
printk("\t XER = %x\n", ctx->EXC_XER);
printk("\t LR = %x\n", ctx->EXC_LR);
printk("\t MSR = %x\n", ctx->EXC_MSR);
#endif
status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 'c'),
0,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL,
0,
&continueSemId);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't create continue semaphore: `%s'\n",rtems_status_text(status));
PushExceptCtx (_Thread_Executing->Object.id, continueSemId, ctx);
switch (ctx->_EXC_number){
case ASM_TRACE_VECTOR :
DPRINTF((" TRACE EXCEPTION !!!\n"));
ctx->EXC_SRR1 &= ~MSR_SE;
ExitForSingleStep-- ;
rtems_semaphore_release( wakeupEventSemId );
break;
case ASM_PROG_VECTOR :
DPRINTF((" BREAKPOINT EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
case ASM_SYS_VECTOR :
DPRINTF((" ENTER RDBG !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
default:
DPRINTF((" OTHER EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
}
rtems_semaphore_obtain(continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
PopExceptCtx (_Thread_Executing->Object.id);
rtems_semaphore_delete(continueSemId);
}
}

View File

@@ -0,0 +1,114 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ../../..
subdir = librdbg/powerpc/mcp750
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@:@srcdir@/..:@srcdir@/../..
LIBNAME = librdbg.a
LIB = ${ARCH}/${LIBNAME}
# C and C++ source names, if any, go here -- minus the .c or .cc
C_PIECES = rdbg servcon servbkpt servrpc excep excep_f \
servtgt servtsp servutil _servtgt rdbg_f \
ptrace
C_FILES = $(C_PIECES:%=%.c)
C_O_FILES = $(C_PIECES:%=${ARCH}/%.o)
# Asm source names, if any, go here -- minus the .s
S_PIECES = rdbg_cpu_asm
S_FILES = $(ASM_PIECES:%=%.S)
S_O_FILES = $(ASM_PIECES:%=${ARCH}/%.o)
# Generated C source names, if any, go here -- minus the .c
GEN_C_PIECES= remdeb_xdr remdeb_svc
GEN_C_FILES = $(GEN_C_PIECES:%=%.c)
GEN_C_O_FILES = $(GEN_C_PIECES:%=${ARCH}/%.o)
# H source names, if any, go here -- minus the .h
H_PIECES = remdeb
H_FILES = $(H_PIECES:%=%.h)
# X source names
X_FILES = remdeb.x remdeb_f.x
SRCS= $(C_FILES) $(S_FILES) $(GEN_C_FILES) $(H_FILES)
OBJS = $(GEN_C_O_FILES) $(C_O_FILES) $(S_O_FILES)
RPCGEN = @RPCGEN@
AWK = @AWK@
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/lib.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
mkinstalldirs = $(SHELL) $(top_srcdir)/@RTEMS_TOPdir@/mkinstalldirs
INSTALLDIRS = $(PROJECT_INCLUDE)/rdbg
$(INSTALLDIRS):
@$(mkinstalldirs) $(INSTALLDIRS)
#
# Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
#
# Enable traces in RDBG
#
#CFLAGS += -DDDEBUG
#
CFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS += $(LIB) $(H_FILES) $(GEN_C_FILES)
CLOBBER_ADDITIONS +=
FRONTEND = \"$(RTEMS_CPU)/@RTEMS_BSP@/remdeb_f.x\"
all: ${ARCH} $(LIB)
@$(INSTALL_VARIANT) -m 644 $(LIB) $(PROJECT_RELEASE)/lib
$(LIB): $(SRCS) ${OBJS}
$(make-library)
remdeb.h: $(X_FILES)
@rm -f $@
( pwd=`pwd`; cd $(srcdir)/../..; \
$(RPCGEN) -h -DFRONTEND=$(FRONTEND) \
-o $$pwd/$@ remdeb.x )
@$(INSTALL_CHANGE) -m 755 $@ $(PROJECT_INCLUDE)/rdbg
remdeb_xdr.c: $(X_FILES)
@rm -f $@
( pwd=`pwd`; cd $(srcdir)/../..; \
$(RPCGEN) -c -DFRONTEND=$(FRONTEND) \
-o $$pwd/$@ remdeb.x )
remdeb_svc.c: $(X_FILES)
@rm -f $@ tmpSvc.c
( pwd=`pwd`; cd $(srcdir)/../..; \
$(RPCGEN) -s udp -DFRONTEND=$(FRONTEND) \
-o $$pwd/tmpSvc.c remdeb.x )
$(AWK) -f $(srcdir)/../../awk.svc THEPROG="remdeb.h" tmpSvc.c >$@
@rm -f tmpSvc.c
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -0,0 +1,76 @@
/*
**************************************************************************
*
* Component = rdblib
* Synopsis = remdeb_f.x
*
**************************************************************************
* $Id$
**************************************************************************
*/
struct xdr_regs
{
unsigned int tabreg[40];
};
#ifdef RPC_HDR
%/* now define register macros to apply to xdr_regs struct */
%
%#define R_PC 0
%#define R_MSR 1
%#define R_EXCEPNB 2
%#define R_R0 3
%#define R_R1 (R_R0 + 1)
%#define R_R2 (R_R0 + 2)
%#define R_R3 (R_R0 + 3)
%#define R_R4 (R_R0 + 4)
%#define R_R5 (R_R0 + 5)
%#define R_R6 (R_R0 + 6)
%#define R_R7 (R_R0 + 7)
%#define R_R8 (R_R0 + 8)
%#define R_R9 (R_R0 + 9)
%#define R_R10 (R_R0 + 10)
%#define R_R11 (R_R0 + 11)
%#define R_R12 (R_R0 + 12)
%#define R_R13 (R_R0 + 13)
%#define R_R14 (R_R0 + 14)
%#define R_R15 (R_R0 + 15)
%#define R_R16 (R_R0 + 16)
%#define R_R17 (R_R0 + 17)
%#define R_R18 (R_R0 + 18)
%#define R_R19 (R_R0 + 19)
%#define R_R20 (R_R0 + 20)
%#define R_R21 (R_R0 + 21)
%#define R_R22 (R_R0 + 22)
%#define R_R23 (R_R0 + 23)
%#define R_R24 (R_R0 + 24)
%#define R_R25 (R_R0 + 25)
%#define R_R26 (R_R0 + 26)
%#define R_R27 (R_R0 + 27)
%#define R_R28 (R_R0 + 28)
%#define R_R29 (R_R0 + 29)
%#define R_R30 (R_R0 + 30)
%#define R_R31 (R_R0 + 31)
%#define R_CR 35
%#define R_CTR 36
%#define R_XER 37
%#define R_LR 38
%#define R_MQ 39
%
%#include <libcpu/raw_exception.h>
%
%#define REG_PC tabreg[R_PC] /* PC register offset */
%#define REG_SP tabreg[R_R1] /* SP register offset */
%#define REG_FP tabreg[R_R1] /* SP register offset (no FP on PPC) */
%#define BREAK_SIZE 4 /* Breakpoint occupies 4 bytes */
%#define BREAK_ADJ 0 /* Nothing to subtract from address after bp */
%#define IS_BREAK(l) ((l) == 0x7d8d6808)
%#define SET_BREAK(l) (0x7d8d6808)
%#define ORG_BREAK(c,p) (p)
%#define IS_STEP(regs) (regs.tabreg[R_EXCEPNB] == ASM_TRACE_VECTOR) /* Was step and not break */
%#define TARGET_PROC_TYPE 3
#endif

View File

@@ -0,0 +1,82 @@
/* cpu_asm.s
*
* This file contains all assembly code for the Intel i386 implementation
* of RDBG.
*
* $Id$
*
*/
#include <libcpu/cpu.h>
#include <libcpu/io.h>
#include <rtems/score/targopts.h>
#include <asm.h>
BEGIN_CODE
/*
* void copyback_data_cache_and_invalidate_instr_cache(addr, size)
*
* This routine performs a copy of the data cache
* and invalidate the instruction cache
*/
.p2align 5
PUBLIC_VAR (copyback_data_cache_and_invalidate_instr_cache)
SYM (copyback_data_cache_and_invalidate_instr_cache):
/* r3 address to handle, r4 length in bytes */
addi r6, r0, PPC_CACHE_ALIGNMENT
/* r5 = last address to handle */
add r5,r3,r4
/* r3 = cache_align(r3, PPC_CACHE_ALIGNMENT)
subi r0,r6,1
andc r3,r3,r0
/* R4 = R3 = copy of first address */
mr r4,r3
/*
* Copyback data cache
*/
1: cmplw r4,r5 /* r4 >= r5 then done */
dcbst 0,r4 /* flush (data cache bloc store) */
add r4,r4,r6 /* r4 = next cache line addr */
blt 1b /* end r4 >= r5 then done */
sync /* Wait for all dcbst to complete on bus */
/*
* invalidate instruction cache
*/
/* R4 = fisrt address */
mr r4,r3
2: cmplw r4,r5 /* r4 >= r5 then done */
icbi 0,r4 /* invalidate (instruction cache bloc invalidate) */
add r4,r4,r6 /* r4 = next cache line addr */
blt 2b /* end r4 >= r5 then done */
sync /* Wait for all icbi to complete on bus */
isync
blr
/*
* void enterRdbg(void)
*
* This function perform a call to the exception SYSTEM call
* It is used :
* 1 - in the user code, to simulate a Breakpoint.
* (with justSaveContext = 0)
* 2 - in the RDBG code, to push a ctx in the list.
* (with justSaveContext = 1)
*
* In most of case, it will be use as described in 1.
* The 2nd possibility will be used by RDBG to obtain
* its own ctx
*/
PUBLIC_VAR (enterRdbg)
SYM (enterRdbg):
sc
blr
END_CODE
END

View File

@@ -0,0 +1,156 @@
/*
**************************************************************************
*
* Component =
*
* Synopsis = rdbg/powerpc/rdbg_f.c
*
* $Id$
*
**************************************************************************
*/
#include <assert.h>
#include <errno.h>
#include <rdbg/reg.h>
#include <rdbg/remdeb.h>
#include <rdbg/rdbg.h>
#include <rtems/score/cpu.h>
#include <rtems/score/thread.h>
#include <libcpu/cpu.h>
void
CtxToRegs (const CPU_Exception_frame* ctx, xdr_regs* regs)
{
* ((CPU_Exception_frame*) regs) = *ctx;
}
void
RegsToCtx (const xdr_regs* regs, CPU_Exception_frame* ctx)
{
*ctx = * ((CPU_Exception_frame*) regs);
}
void
get_ctx_thread( Thread_Control *thread, CPU_Exception_frame* ctx)
{
unsigned int *ptr;
unsigned int i;
ctx->EXC_SRR0 = thread->Registers.pc;
ctx->EXC_SRR1 = thread->Registers.msr;
ctx->_EXC_number = 0xdeadbeef;
ctx->GPR1 = thread->Registers.gpr1;
ctx->GPR2 = thread->Registers.gpr2;
/*
* Fill with dummy values...
*/
ptr = &ctx->GPR3;
for (i = 0; i < 10; i++)
ptr [i] = 0xdeadbeef;
ctx->GPR13 = thread->Registers.gpr13;
ctx->GPR14 = thread->Registers.gpr14;
ctx->GPR15 = thread->Registers.gpr15;
ctx->GPR16 = thread->Registers.gpr16;
ctx->GPR17 = thread->Registers.gpr17;
ctx->GPR18 = thread->Registers.gpr18;
ctx->GPR19 = thread->Registers.gpr19;
ctx->GPR20 = thread->Registers.gpr20;
ctx->GPR21 = thread->Registers.gpr21;
ctx->GPR22 = thread->Registers.gpr22;
ctx->GPR23 = thread->Registers.gpr23;
ctx->GPR24 = thread->Registers.gpr24;
ctx->GPR25 = thread->Registers.gpr25;
ctx->GPR26 = thread->Registers.gpr26;
ctx->GPR27 = thread->Registers.gpr27;
ctx->GPR28 = thread->Registers.gpr28;
ctx->GPR29 = thread->Registers.gpr29;
ctx->GPR30 = thread->Registers.gpr30;
ctx->GPR31 = thread->Registers.gpr31;
ctx->EXC_CR = thread->Registers.cr;
ctx->EXC_CTR = 0xdeadbeef;
ctx->EXC_XER = 0xdeadbeef;
ctx->EXC_LR = 0xdeadbeef;
ctx->EXC_MSR = 0xdeadbeef;
ctx->EXC_DAR = 0xdeadbeef;
}
void
set_ctx_thread( Thread_Control *thread, CPU_Exception_frame* ctx)
{
thread->Registers.gpr1 = ctx->GPR1;
thread->Registers.gpr2 = ctx->GPR2;
thread->Registers.gpr13 = ctx->GPR13;
thread->Registers.gpr14 = ctx->GPR14;
thread->Registers.gpr15 = ctx->GPR15;
thread->Registers.gpr16 = ctx->GPR16;
thread->Registers.gpr17 = ctx->GPR17;
thread->Registers.gpr18 = ctx->GPR18;
thread->Registers.gpr19 = ctx->GPR19;
thread->Registers.gpr20 = ctx->GPR20;
thread->Registers.gpr21 = ctx->GPR21;
thread->Registers.gpr22 = ctx->GPR22;
thread->Registers.gpr23 = ctx->GPR23;
thread->Registers.gpr24 = ctx->GPR24;
thread->Registers.gpr25 = ctx->GPR25;
thread->Registers.gpr26 = ctx->GPR26;
thread->Registers.gpr27 = ctx->GPR27;
thread->Registers.gpr28 = ctx->GPR28;
thread->Registers.gpr29 = ctx->GPR29;
thread->Registers.gpr30 = ctx->GPR30;
thread->Registers.gpr31 = ctx->GPR31;
thread->Registers.cr = ctx->EXC_CR;
thread->Registers.pc = ctx->EXC_SRR0;
thread->Registers.msr = ctx->EXC_SRR1;
}
int
Single_Step(CPU_Exception_frame* ctx)
{
if ((ctx->EXC_SRR1 & MSR_SE) != 0 || ExitForSingleStep != 0) {
/* Check coherency */
assert ((ctx->EXC_SRR1 & MSR_SE) != 0);
assert (ExitForSingleStep != 0);
return 0;
}
ctx->EXC_SRR1 |= MSR_SE;
++ExitForSingleStep;
return 0;
}
int
CheckForSingleStep (CPU_Exception_frame* ctx)
{
if (ExitForSingleStep) {
/*
* This functions can be called both from
* INT1 and INT3 handlers. In case it is
* called from INT3, need to clear TF.
*/
ctx->EXC_SRR1 &= ~MSR_SE;
ExitForSingleStep = 0;
return 1;
}
return 0;
}
void
CancelSingleStep (CPU_Exception_frame* ctx)
{
/* Cancel scheduled SS */
ctx->EXC_SRR1 &= ~MSR_SE;
ExitForSingleStep-- ;
}
cpuExcHandlerType oldExcHandler;
void connect_rdbg_exception()
{
oldExcHandler = globalExceptHdl;
globalExceptHdl = BreakPointExcHdl ;
}

View File

@@ -5,6 +5,8 @@
* *
* Synopsis = rkdb/rkdb.c * Synopsis = rkdb/rkdb.c
* *
* $Id$
*
************************************************************************** **************************************************************************
*/ */
@@ -142,7 +144,7 @@ ptrace (int request, int pid, char* addr, int data, char* addr2)
*/ */
if (diag == 0) { if (diag == 0) {
copyback_data_cache_and_invalidate_instr_cache(); copyback_data_cache_and_invalidate_instr_cache(addr, sizeof data);
return 0; return 0;
} }
goto mem_error; goto mem_error;
@@ -162,11 +164,7 @@ ptrace (int request, int pid, char* addr, int data, char* addr2)
ctx = GetExceptCtx (currentTargetThread); ctx = GetExceptCtx (currentTargetThread);
if ( if (!isRdbgException(ctx)) {
ctx->ctx->idtIndex != I386_EXCEPTION_DEBUG &&
ctx->ctx->idtIndex != I386_EXCEPTION_BREAKPOINT &&
ctx->ctx->idtIndex != I386_EXCEPTION_ENTER_RDBG
) {
CannotRestart = 1; CannotRestart = 1;
setErrno (EIO); setErrno (EIO);
return -1; return -1;

View File

@@ -5,6 +5,8 @@
* *
* Synopsis = rkdb/rkdb.c * Synopsis = rkdb/rkdb.c
* *
* $Id$
*
************************************************************************** **************************************************************************
*/ */

View File

@@ -7,6 +7,8 @@
* Synopsis: XDR definitions for remote debug server RPC calls. * Synopsis: XDR definitions for remote debug server RPC calls.
* XDR definitions for RPCGEN to build remote debug server. * XDR definitions for RPCGEN to build remote debug server.
* *
* $Id$
*
********************************************************************** **********************************************************************
*/ */

View File

@@ -6,6 +6,8 @@
* *
* Synopsis: Management of breakpoints * Synopsis: Management of breakpoints
* *
* $Id$
*
********************************************************************** **********************************************************************
*/ */

View File

@@ -6,6 +6,8 @@
* *
* Synopsis: Management of RPC client connections. * Synopsis: Management of RPC client connections.
* *
* $Id$
*
************************************************************************** **************************************************************************
*/ */

View File

@@ -7,6 +7,8 @@
* Synopsis: support routines for RPC dispatch for remote debug server. * Synopsis: support routines for RPC dispatch for remote debug server.
* Main server dispatch routines from RPC to support remote debug. * Main server dispatch routines from RPC to support remote debug.
* *
* $Id$
*
********************************************************************** **********************************************************************
*/ */

View File

@@ -4,6 +4,8 @@
* Component: RDB servers * Component: RDB servers
* Module: servtgt.c * Module: servtgt.c
* *
* $Id$
*
************************************************************************** **************************************************************************
*/ */

View File

@@ -6,6 +6,8 @@
* *
* Synopsis: Transport management for remote debug server. * Synopsis: Transport management for remote debug server.
* *
* $Id$
*
************************************************************************** **************************************************************************
*/ */

View File

@@ -6,6 +6,8 @@
* *
* Synopsis: Various utility routines * Synopsis: Various utility routines
* *
* $Id$
*
********************************************************************** **********************************************************************
*/ */

View File

@@ -6,6 +6,8 @@
* *
* Synopsis = Machine-dependent header file * Synopsis = Machine-dependent header file
* *
* $Id$
*
************************************************************************** **************************************************************************
*/ */
@@ -17,35 +19,21 @@
#define EFLAGS_TF 0x00100 #define EFLAGS_TF 0x00100
typedef struct Exception_context_struct { static inline int isRdbgException(Exception_context *ctx)
struct Exception_context_struct *next; {
struct Exception_context_struct *previous; if (
Objects_Id id; ctx->ctx->idtIndex != I386_EXCEPTION_DEBUG &&
Objects_Id semaphoreId; ctx->ctx->idtIndex != I386_EXCEPTION_BREAKPOINT &&
CPU_Exception_frame *ctx; ctx->ctx->idtIndex != I386_EXCEPTION_ENTER_RDBG
} Exception_context; ) return 0;
else return 1;
extern int PushExceptCtx (Objects_Id Id, }
Objects_Id semId, static inline int getExcNum(Exception_context *ctx)
CPU_Exception_frame *ctx); {
extern int PopExceptCtx (Objects_Id Id); return ctx->ctx->idtIndex;
extern Exception_context *GetExceptCtx (Objects_Id Id); }
extern int Single_Step (CPU_Exception_frame* ctx);
extern int CheckForSingleStep (CPU_Exception_frame* ctx);
extern void BreakPointExcHdl (CPU_Exception_frame *ctx);
extern void CtxToRegs (const CPU_Exception_frame*,xdr_regs*);
extern void RegsToCtx (const xdr_regs*,CPU_Exception_frame*);
extern void enterRdbg ();
extern void get_ctx_thread (Thread_Control *thread,
CPU_Exception_frame* ctx);
extern void set_ctx_thread (Thread_Control *thread,
CPU_Exception_frame* ctx);
void copyback_data_cache_and_invalidate_instr_cache();
extern int ExitForSingleStep;
extern void connect_rdbg_exception();
#endif #endif

View File

@@ -1,4 +1,8 @@
/*
* Registers Offset in frame definition
*
* $Id$
*/
#define NBREGS 19 #define NBREGS 19

View File

@@ -0,0 +1,38 @@
/*
**************************************************************************
*
* Component = RDBG
* Module = rdbg_f.h
*
* Synopsis = Machine-dependent header file
*
* $Id$
*
**************************************************************************
*/
#ifndef RDBG_F_H
#define RDBG_F_H
#include <rtems.h>
#include <rdbg/remdeb.h>
static inline int isRdbgException(Exception_context *ctx)
{
if (
ctx->ctx->_EXC_number != ASM_SYS_VECTOR &&
ctx->ctx->_EXC_number != ASM_TRACE_VECTOR
) return 0;
else return 1;
}
static inline int getExcNum(Exception_context *ctx)
{
return ctx->ctx->_EXC_number;
}
extern void connect_rdbg_exception();
#endif

View File

@@ -0,0 +1,16 @@
/*
* Registers frame offset definition
*
* $Id$
*/
#define NBREGS 43
typedef unsigned int regs[NBREGS];
/* To be used in common code */
typedef regs REGS;

View File

@@ -5,6 +5,8 @@
* *
* Synopsis = rdbg.h * Synopsis = rdbg.h
* *
* $Id$
*
************************************************************************** **************************************************************************
*/ */
@@ -14,9 +16,9 @@
#include <rpc/rpc.h> #include <rpc/rpc.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <rdbg/rdbg_f.h>
#include <stdlib.h> /* For malloc() and free() prototypes */ #include <stdlib.h> /* For malloc() and free() prototypes */
#include <bsp.h> #include <bsp.h>
#include <rtems.h>
#define Malloc(size) malloc (size) #define Malloc(size) malloc (size)
#define Free(block) free (block) #define Free(block) free (block)
@@ -49,5 +51,45 @@ void svc_processrequest (SVCXPRT* xprt,
void (*dispatch)()); void (*dispatch)());
int svcudp_enablecache (SVCXPRT *transp, u_long size); int svcudp_enablecache (SVCXPRT *transp, u_long size);
typedef struct Exception_context_struct {
struct Exception_context_struct *next;
struct Exception_context_struct *previous;
Objects_Id id;
Objects_Id semaphoreId;
CPU_Exception_frame *ctx;
} Exception_context;
struct xdr_regs;
extern int PushExceptCtx (Objects_Id Id,
Objects_Id semId,
CPU_Exception_frame *ctx);
extern int PopExceptCtx (Objects_Id Id);
extern Exception_context *GetExceptCtx (Objects_Id Id);
extern int Single_Step (CPU_Exception_frame* ctx);
extern int CheckForSingleStep (CPU_Exception_frame* ctx);
extern void BreakPointExcHdl (CPU_Exception_frame *ctx);
extern void CtxToRegs (const CPU_Exception_frame*,struct xdr_regs*);
extern void RegsToCtx (const struct xdr_regs*,CPU_Exception_frame*);
extern void enterRdbg ();
extern void get_ctx_thread (Thread_Control *thread,
CPU_Exception_frame* ctx);
extern void set_ctx_thread (Thread_Control *thread,
CPU_Exception_frame* ctx);
extern int PushSavedExceptCtx ( Objects_Id Id,
CPU_Exception_frame *ctx );
extern int ExcepToSig (Exception_context *ctx);
extern int ExitForSingleStep;
extern rtems_id serializeSemId;
extern rtems_id wakeupEventSemId;
extern volatile unsigned int NbSerializedCtx;
void copyback_data_cache_and_invalidate_instr_cache(unsigned char* addr, int size);
#include <rdbg/rdbg_f.h>
#endif /* !RDBG_H */ #endif /* !RDBG_H */

View File

@@ -1,3 +1,6 @@
/*
* $Id$
*/
#ifndef SERVRPC_H #ifndef SERVRPC_H
#define SERVRPC_H #define SERVRPC_H
@@ -30,6 +33,15 @@ extern const char* PtraceNames[]; /* list of ptrace requests for debug out */
extern const char* BmsgNames[]; /* list of BMSG_xxx names */ extern const char* BmsgNames[]; /* list of BMSG_xxx names */
extern const char* PtraceName(int req); extern const char* PtraceName(int req);
#ifdef i386 /* low-high machine such as 386 */
#define HL_W(w) (((UINT16)(w)>>8)+((((w)&0xFF)<<8)))
#define HL_D(d) (((UINT32)(d)>>24)+(((d)&0x00FF0000)>>8) \
+(((d)&0xFF00)<<8)+(((d)&0xFF)<<24))
#else
#define HL_W(w) w
#define HL_D(d) d
#endif
# define DPRINTF(a) (rdb_debug ? printk ("%d >>> ", getId()), printk a : 0) # define DPRINTF(a) (rdb_debug ? printk ("%d >>> ", getId()), printk a : 0)
#else #else
# define DPRINTF(a) /* suppress */ # define DPRINTF(a) /* suppress */

View File

@@ -1,6 +1,7 @@
/* /*
============================================================================ ============================================================================
_SERVTGT _SERVTGT
$Id$
============================================================================ ============================================================================
*/ */
@@ -17,9 +18,6 @@
#include <assert.h> #include <assert.h>
#include <rtems/score/cpu.h> #include <rtems/score/cpu.h>
extern void rtems_exception_prologue_50();
#ifdef DDEBUG #ifdef DDEBUG
#define Ptrace TgtDbgPtrace #define Ptrace TgtDbgPtrace
#else #else
@@ -34,8 +32,6 @@ rtems_id wakeupEventSemId;
CPU_Exception_frame Idle_frame; CPU_Exception_frame Idle_frame;
cpuExcHandlerType old_currentExcHandler;
/* ----------------------------------------------------------------- /* -----------------------------------------------------------------
TgtRealPtrace - lowest level ptrace() wrapper TgtRealPtrace - lowest level ptrace() wrapper
----------------------------------------------------------------- */ ----------------------------------------------------------------- */
@@ -47,43 +43,6 @@ TgtRealPtrace(int req, PID aid, char* addr, int d, void* addr2)
} }
/* -----------------------------------------------------------------
Maping of hardware exceptions into Unix-like signal numbers.
It is identical to the one used by the PM and the AM.
----------------------------------------------------------------- */
int
ExcepToSig (int excep)
{
switch (excep) {
case I386_EXCEPTION_MATH_COPROC_UNAVAIL:
case I386_EXCEPTION_I386_COPROC_SEG_ERR:
case I386_EXCEPTION_FLOAT_ERROR:
case I386_EXCEPTION_BOUND:
return SIGFPE;
case I386_EXCEPTION_DEBUG:
case I386_EXCEPTION_BREAKPOINT:
case I386_EXCEPTION_ENTER_RDBG:
return SIGTRAP;
case I386_EXCEPTION_OVERFLOW:
case I386_EXCEPTION_DIVIDE_BY_ZERO:
case I386_EXCEPTION_ILLEGAL_INSTR:
return SIGILL;
case I386_EXCEPTION_SEGMENT_NOT_PRESENT:
case I386_EXCEPTION_STACK_SEGMENT_FAULT:
case I386_EXCEPTION_GENERAL_PROT_ERR:
case I386_EXCEPTION_PAGE_FAULT:
return SIGSEGV;
default:
break;
}
return SIGKILL;
}
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
TgtChange() is called when the system stops. TgtChange() is called when the system stops.
@@ -128,7 +87,7 @@ rtems_task eventTask( rtems_task_argument pid)
CheckForSingleStep(ctx->ctx); CheckForSingleStep(ctx->ctx);
TgtChange(pid, ctx->ctx,STS_MAKESIG(ExcepToSig(ctx->ctx->idtIndex))); TgtChange(pid, ctx->ctx,STS_MAKESIG(ExcepToSig(ctx)));
} }
} }
@@ -162,9 +121,6 @@ Boolean TgtAttach(
rtems_name task_name; rtems_name task_name;
rtems_status_code status; rtems_status_code status;
rtems_id debugId; rtems_id debugId;
interrupt_gate_descriptor *currentIdtEntry;
unsigned limit;
unsigned level;
errno = 0; errno = 0;
@@ -177,18 +133,7 @@ Boolean TgtAttach(
TgtCreateNew(pid, conn_idx, 0, NULL, False); TgtCreateNew(pid, conn_idx, 0, NULL, False);
/* connect_rdbg_exception();
* Connect the Exception used to debug
*/
i386_get_info_from_IDTR (&currentIdtEntry, &limit);
_CPU_ISR_Disable(level);
create_interrupt_gate_descriptor (&currentIdtEntry[50], rtems_exception_prologue_50);
_CPU_ISR_Enable(level);
old_currentExcHandler = _currentExcHandler;
_currentExcHandler = BreakPointExcHdl ;
/* /*
* Create the attach debuger task * Create the attach debuger task

View File

@@ -7,7 +7,9 @@
# by rpcgen(1) into something suitable for RDB servers. # by rpcgen(1) into something suitable for RDB servers.
# #
######################################################################### #########################################################################
#
# $Id$
#
BEGIN { BEGIN {
headerstarted = 0 headerstarted = 0
withinproc = 0 withinproc = 0

136
c/src/librdbg/src/excep.c Normal file
View File

@@ -0,0 +1,136 @@
/*
**************************************************************************
*
* Component =
*
* Synopsis = rdbgexcep.c
*
* $Id$
*
**************************************************************************
*/
#include <rtems.h>
#include <rtems/error.h>
#include <assert.h>
#include <errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
unsigned int NbExceptCtx;
volatile unsigned int NbSerializedCtx;
Exception_context *FirstCtx = NULL;
Exception_context *LastCtx = NULL;
CPU_Exception_frame SavedContext;
/********* Save an exception context at the end of a list *****/
int PushExceptCtx ( Objects_Id Id, Objects_Id semId, CPU_Exception_frame *ctx ) {
Exception_context *SaveCtx;
SaveCtx = (Exception_context *)malloc(sizeof(Exception_context));
if (SaveCtx == NULL)
rtems_panic("Can't allocate memory to save Exception context");
SaveCtx->id = Id;
SaveCtx->ctx = ctx;
SaveCtx->semaphoreId = semId;
SaveCtx->previous = NULL;
SaveCtx->next = NULL;
if (FirstCtx == NULL){ /* initialization */
FirstCtx = SaveCtx;
LastCtx = SaveCtx;
NbExceptCtx = 1;
}
else {
NbExceptCtx ++;
LastCtx->next = SaveCtx;
SaveCtx->previous = LastCtx;
LastCtx = SaveCtx;
}
return 0;
}
/********* Save an temporary exception context in a ******/
/********* global variable ******/
int PushSavedExceptCtx ( Objects_Id Id, CPU_Exception_frame *ctx ) {
memcpy (&(SavedContext), ctx, sizeof(CPU_Exception_frame));
return 0;
}
/****** Remove the context of the specified Id thread *********/
/****** If Id = -1, then return the first context *********/
int PopExceptCtx ( Objects_Id Id ) {
Exception_context *ExtractCtx;
if (FirstCtx == NULL) return -1;
if (Id == -1) {
ExtractCtx = LastCtx;
LastCtx = LastCtx->previous;
free(ExtractCtx);
NbExceptCtx --;
return 0;
}
ExtractCtx = LastCtx;
while (ExtractCtx->id != Id && ExtractCtx != NULL) {
ExtractCtx = ExtractCtx->previous;
}
if (ExtractCtx == NULL)
return -1;
if ( ExtractCtx->previous != NULL)
(ExtractCtx->previous)->next = ExtractCtx->next;
if ( ExtractCtx->next != NULL)
(ExtractCtx->next)->previous = ExtractCtx->previous;
if (ExtractCtx == FirstCtx)
FirstCtx = FirstCtx->next;
else
if (ExtractCtx == LastCtx)
LastCtx = LastCtx->previous;
free(ExtractCtx);
NbExceptCtx --;
return 0;
}
/****** Return the context of the specified Id thread *********/
/****** If Id = -1, then return the first context *********/
Exception_context *GetExceptCtx ( Objects_Id Id ) {
Exception_context *ExtractCtx;
if (FirstCtx == NULL) return NULL;
if (Id == -1) {
return LastCtx;
}
ExtractCtx = LastCtx;
while (ExtractCtx->id != Id && ExtractCtx != NULL) {
ExtractCtx = ExtractCtx->previous;
}
if (ExtractCtx == NULL)
return NULL;
return ExtractCtx;
}

View File

@@ -17,8 +17,10 @@ LIBNAME = librdbg.a
LIB = ${ARCH}/${LIBNAME} LIB = ${ARCH}/${LIBNAME}
# C and C++ source names, if any, go here -- minus the .c or .cc # C and C++ source names, if any, go here -- minus the .c or .cc
C_PIECES = rdbg servcon servbkpt servrpc excep servtgt servtsp servutil \ C_PIECES = rdbg servcon servbkpt servrpc excep excep_f \
_servtgt rdbg_f ptrace servtgt servtsp servutil _servtgt rdbg_f \
ptrace
C_FILES = $(C_PIECES:%=%.c) C_FILES = $(C_PIECES:%=%.c)
C_O_FILES = $(C_PIECES:%=${ARCH}/%.o) C_O_FILES = $(C_PIECES:%=${ARCH}/%.o)

View File

@@ -5,6 +5,7 @@
* *
* Synopsis = remdeb_f.x * Synopsis = remdeb_f.x
* *
* $Id$
* *
************************************************************************** **************************************************************************
*/ */

View File

@@ -1,233 +0,0 @@
/*
**************************************************************************
*
* Component =
*
* Synopsis = rdbg/i386/excep.c
*
**************************************************************************
*/
#include <rtems.h>
#include <rtems/error.h>
#include <rdbg/rdbg_f.h>
#include <assert.h>
#include <errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
extern rtems_id serializeSemId;
extern rtems_id wakeupEventSemId;
unsigned int NbExceptCtx;
volatile unsigned int NbSerializedCtx;
Exception_context *FirstCtx = NULL;
Exception_context *LastCtx = NULL;
CPU_Exception_frame SavedContext;
/********* Save an exception context at the end of a list *****/
int PushExceptCtx ( Objects_Id Id, Objects_Id semId, CPU_Exception_frame *ctx ) {
Exception_context *SaveCtx;
SaveCtx = (Exception_context *)malloc(sizeof(Exception_context));
if (SaveCtx == NULL)
rtems_panic("Can't allocate memory to save Exception context");
SaveCtx->id = Id;
SaveCtx->ctx = ctx;
SaveCtx->semaphoreId = semId;
SaveCtx->previous = NULL;
SaveCtx->next = NULL;
if (FirstCtx == NULL){ /* initialization */
FirstCtx = SaveCtx;
LastCtx = SaveCtx;
NbExceptCtx = 1;
}
else {
NbExceptCtx ++;
LastCtx->next = SaveCtx;
SaveCtx->previous = LastCtx;
LastCtx = SaveCtx;
}
return 0;
}
/********* Save an temporary exception context in a ******/
/********* global variable ******/
int PushSavedExceptCtx ( Objects_Id Id, CPU_Exception_frame *ctx ) {
memcpy (&(SavedContext), ctx, sizeof(CPU_Exception_frame));
return 0;
}
/****** Remove the context of the specified Id thread *********/
/****** If Id = -1, then return the first context *********/
int PopExceptCtx ( Objects_Id Id ) {
Exception_context *ExtractCtx;
if (FirstCtx == NULL) return -1;
if (Id == -1) {
ExtractCtx = LastCtx;
LastCtx = LastCtx->previous;
free(ExtractCtx);
NbExceptCtx --;
return 0;
}
ExtractCtx = LastCtx;
while (ExtractCtx->id != Id && ExtractCtx != NULL) {
ExtractCtx = ExtractCtx->previous;
}
if (ExtractCtx == NULL)
return -1;
if ( ExtractCtx->previous != NULL)
(ExtractCtx->previous)->next = ExtractCtx->next;
if ( ExtractCtx->next != NULL)
(ExtractCtx->next)->previous = ExtractCtx->previous;
if (ExtractCtx == FirstCtx)
FirstCtx = FirstCtx->next;
else
if (ExtractCtx == LastCtx)
LastCtx = LastCtx->previous;
free(ExtractCtx);
NbExceptCtx --;
return 0;
}
/****** Return the context of the specified Id thread *********/
/****** If Id = -1, then return the first context *********/
Exception_context *GetExceptCtx ( Objects_Id Id ) {
Exception_context *ExtractCtx;
if (FirstCtx == NULL) return NULL;
if (Id == -1) {
return LastCtx;
}
ExtractCtx = LastCtx;
while (ExtractCtx->id != Id && ExtractCtx != NULL) {
ExtractCtx = ExtractCtx->previous;
}
if (ExtractCtx == NULL)
return NULL;
return ExtractCtx;
}
/*----- Breakpoint Exception management -----*/
/*
* Handler for Breakpoint Exceptions :
* software breakpoints.
*/
void
BreakPointExcHdl(CPU_Exception_frame *ctx)
{
rtems_status_code status;
rtems_id continueSemId;
if ( (justSaveContext) && (ctx->idtIndex == I386_EXCEPTION_ENTER_RDBG) ) {
PushSavedExceptCtx (_Thread_Executing->Object.id, ctx);
justSaveContext = 0;
}
else {
if (ctx->idtIndex != I386_EXCEPTION_DEBUG){
NbSerializedCtx++;
rtems_semaphore_obtain(serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
NbSerializedCtx--;
}
currentTargetThread = _Thread_Executing->Object.id;
#ifdef DDEBUG
printk("----------------------------------------------------------\n");
printk("Exception %d caught at PC %x by thread %d\n",
ctx->idtIndex,
ctx->eip,
_Thread_Executing->Object.id);
printk("----------------------------------------------------------\n");
printk("Processor execution context at time of the fault was :\n");
printk("----------------------------------------------------------\n");
printk(" EAX = %x EBX = %x ECX = %x EDX = %x\n",
ctx->eax, ctx->ebx, ctx->ecx, ctx->edx);
printk(" ESI = %x EDI = %x EBP = %x ESP = %x\n",
ctx->esi, ctx->edi, ctx->ebp, ctx->esp0);
printk("----------------------------------------------------------\n");
printk("Error code pushed by processor itself (if not 0) = %x\n",
ctx->faultCode);
printk("----------------------------------------------------------\n\n");
#endif
status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 'c'),
0,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL,
0,
&continueSemId);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't create continue semaphore: `%s'\n",rtems_status_text(status));
PushExceptCtx (_Thread_Executing->Object.id, continueSemId, ctx);
switch (ctx->idtIndex){
case I386_EXCEPTION_DEBUG:
DPRINTF((" DEBUG EXCEPTION !!!\n"));
ctx->eflags &= ~EFLAGS_TF;
ExitForSingleStep-- ;
rtems_semaphore_release( wakeupEventSemId );
break;
case I386_EXCEPTION_BREAKPOINT:
DPRINTF((" BREAKPOINT EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
case I386_EXCEPTION_ENTER_RDBG:
DPRINTF((" ENTER RDBG !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
default:
DPRINTF((" OTHER EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
}
rtems_semaphore_obtain(continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
PopExceptCtx (_Thread_Executing->Object.id);
rtems_semaphore_delete(continueSemId);
}
}

View File

@@ -0,0 +1,153 @@
/*
**************************************************************************
*
* Component =
*
* Synopsis = rdbg/i386/excep.c
*
* $Id$
*
**************************************************************************
*/
#include <rtems.h>
#include <rtems/error.h>
#include <assert.h>
#include <errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
/* -----------------------------------------------------------------
Maping of hardware exceptions into Unix-like signal numbers.
It is identical to the one used by the PM and the AM.
----------------------------------------------------------------- */
int
ExcepToSig (Exception_context *ctx)
{
int excep = getExcNum (ctx);
switch (excep) {
case I386_EXCEPTION_MATH_COPROC_UNAVAIL:
case I386_EXCEPTION_I386_COPROC_SEG_ERR:
case I386_EXCEPTION_FLOAT_ERROR:
case I386_EXCEPTION_BOUND:
return SIGFPE;
case I386_EXCEPTION_DEBUG:
case I386_EXCEPTION_BREAKPOINT:
case I386_EXCEPTION_ENTER_RDBG:
return SIGTRAP;
case I386_EXCEPTION_OVERFLOW:
case I386_EXCEPTION_DIVIDE_BY_ZERO:
case I386_EXCEPTION_ILLEGAL_INSTR:
return SIGILL;
case I386_EXCEPTION_SEGMENT_NOT_PRESENT:
case I386_EXCEPTION_STACK_SEGMENT_FAULT:
case I386_EXCEPTION_GENERAL_PROT_ERR:
case I386_EXCEPTION_PAGE_FAULT:
return SIGSEGV;
default:
break;
}
return SIGKILL;
}
/*----- Breakpoint Exception management -----*/
/*
* Handler for Breakpoint Exceptions :
* software breakpoints.
*/
void
BreakPointExcHdl(CPU_Exception_frame *ctx)
{
rtems_status_code status;
rtems_id continueSemId;
if ( (justSaveContext) && (ctx->idtIndex == I386_EXCEPTION_ENTER_RDBG) ) {
PushSavedExceptCtx (_Thread_Executing->Object.id, ctx);
justSaveContext = 0;
}
else {
if (ctx->idtIndex != I386_EXCEPTION_DEBUG){
NbSerializedCtx++;
rtems_semaphore_obtain(serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
NbSerializedCtx--;
}
currentTargetThread = _Thread_Executing->Object.id;
#ifdef DDEBUG
printk("----------------------------------------------------------\n");
printk("Exception %d caught at PC %x by thread %d\n",
ctx->idtIndex,
ctx->eip,
_Thread_Executing->Object.id);
printk("----------------------------------------------------------\n");
printk("Processor execution context at time of the fault was :\n");
printk("----------------------------------------------------------\n");
printk(" EAX = %x EBX = %x ECX = %x EDX = %x\n",
ctx->eax, ctx->ebx, ctx->ecx, ctx->edx);
printk(" ESI = %x EDI = %x EBP = %x ESP = %x\n",
ctx->esi, ctx->edi, ctx->ebp, ctx->esp0);
printk("----------------------------------------------------------\n");
printk("Error code pushed by processor itself (if not 0) = %x\n",
ctx->faultCode);
printk("----------------------------------------------------------\n\n");
#endif
status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 'c'),
0,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL,
0,
&continueSemId);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't create continue semaphore: `%s'\n",rtems_status_text(status));
PushExceptCtx (_Thread_Executing->Object.id, continueSemId, ctx);
switch (ctx->idtIndex){
case I386_EXCEPTION_DEBUG:
DPRINTF((" DEBUG EXCEPTION !!!\n"));
ctx->eflags &= ~EFLAGS_TF;
ExitForSingleStep-- ;
rtems_semaphore_release( wakeupEventSemId );
break;
case I386_EXCEPTION_BREAKPOINT:
DPRINTF((" BREAKPOINT EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
case I386_EXCEPTION_ENTER_RDBG:
DPRINTF((" ENTER RDBG !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
default:
DPRINTF((" OTHER EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
}
rtems_semaphore_obtain(continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
PopExceptCtx (_Thread_Executing->Object.id);
rtems_semaphore_delete(continueSemId);
}
}

View File

@@ -17,8 +17,10 @@ LIBNAME = librdbg.a
LIB = ${ARCH}/${LIBNAME} LIB = ${ARCH}/${LIBNAME}
# C and C++ source names, if any, go here -- minus the .c or .cc # C and C++ source names, if any, go here -- minus the .c or .cc
C_PIECES = rdbg servcon servbkpt servrpc excep servtgt servtsp servutil \ C_PIECES = rdbg servcon servbkpt servrpc excep excep_f \
_servtgt rdbg_f ptrace servtgt servtsp servutil _servtgt rdbg_f \
ptrace
C_FILES = $(C_PIECES:%=%.c) C_FILES = $(C_PIECES:%=%.c)
C_O_FILES = $(C_PIECES:%=${ARCH}/%.o) C_O_FILES = $(C_PIECES:%=${ARCH}/%.o)

View File

@@ -5,6 +5,7 @@
* *
* Synopsis = remdeb_f.x * Synopsis = remdeb_f.x
* *
* $Id$
* *
************************************************************************** **************************************************************************
*/ */

View File

@@ -3,6 +3,8 @@
* This file contains all assembly code for the Intel i386 implementation * This file contains all assembly code for the Intel i386 implementation
* of RDBG. * of RDBG.
* *
* $Id$
*
*/ */
#include <asm.h> #include <asm.h>
@@ -10,7 +12,7 @@
BEGIN_CODE BEGIN_CODE
/* /*
* void copyback_data_cache_and_invalidate_instr_cache() * void copyback_data_cache_and_invalidate_instr_cache(addr, size)
* *
* This routine performs a copy of the data cache * This routine performs a copy of the data cache
* and invalidate the instruction cache * and invalidate the instruction cache

View File

@@ -5,6 +5,8 @@
* *
* Synopsis = rdbg/i386/rdbg_f.c * Synopsis = rdbg/i386/rdbg_f.c
* *
* $Id$
*
************************************************************************** **************************************************************************
*/ */
@@ -128,3 +130,26 @@ CancelSingleStep (CPU_Exception_frame* ctx)
ctx->eflags &= ~EFLAGS_TF; ctx->eflags &= ~EFLAGS_TF;
ExitForSingleStep-- ; ExitForSingleStep-- ;
} }
cpuExcHandlerType old_currentExcHandler;
extern void rtems_exception_prologue_50();
void connect_rdbg_exception()
{
interrupt_gate_descriptor *currentIdtEntry;
unsigned limit;
unsigned level;
/*
* Connect the Exception used to debug
*/
i386_get_info_from_IDTR (&currentIdtEntry, &limit);
_CPU_ISR_Disable(level);
create_interrupt_gate_descriptor (&currentIdtEntry[50], rtems_exception_prologue_50);
_CPU_ISR_Enable(level);
old_currentExcHandler = _currentExcHandler;
_currentExcHandler = BreakPointExcHdl ;
}

View File

@@ -0,0 +1,25 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ../..
subdir = librdbg/powerpc
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
include $(RTEMS_ROOT)/make/custom/${RTEMS_BSP}.cfg
include $(RTEMS_ROOT)/make/directory.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
SUB_DIRS = @RTEMS_BSP@
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -0,0 +1,167 @@
/*
**************************************************************************
*
* Component =
*
* Synopsis = rdbg/powerpc/excep_f.c
*
* $Id$
*
**************************************************************************
*/
#include <rtems.h>
#include <rtems/error.h>
#include <assert.h>
#include <errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>
int
ExcepToSig (Exception_context *ctx)
{
int excep = getExcNum (ctx);
switch (excep) {
case ASM_FLOAT_VECTOR : return SIGFPE;
case ASM_TRACE_VECTOR :
case ASM_SYS_VECTOR : return SIGTRAP;
case ASM_ISI_VECTOR : return SIGSEGV;
case ASM_PROG_VECTOR :
case ASM_RESET_VECTOR :
case ASM_MACH_VECTOR :
case ASM_EXT_VECTOR :
case ASM_ALIGN_VECTOR : return SIGILL;
default:
break;
}
return SIGKILL;
}
/*----- Breakpoint Exception management -----*/
/*
* Handler for Breakpoint Exceptions :
* software breakpoints.
*/
void
BreakPointExcHdl(CPU_Exception_frame *ctx)
{
rtems_status_code status;
rtems_id continueSemId;
if ( (justSaveContext) && (ctx->_EXC_number == ASM_SYS_VECTOR) ) {
PushSavedExceptCtx (_Thread_Executing->Object.id, ctx);
justSaveContext = 0;
}
else {
if (ctx->_EXC_number != ASM_TRACE_VECTOR){
NbSerializedCtx++;
rtems_semaphore_obtain(serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
NbSerializedCtx--;
}
currentTargetThread = _Thread_Executing->Object.id;
#ifdef DDEBUG
printk("----------------------------------------------------------\n");
printk("Exception %d caught at PC %x by thread %d\n",
ctx->_EXC_number,
ctx->EXC_SRR0,
_Thread_Executing->Object.id);
printk("----------------------------------------------------------\n");
printk("Processor execution context at time of the fault was :\n");
printk("----------------------------------------------------------\n");
printk("\t R0 = %x\n", ctx->GPR0);
printk("\t R1 = %x\n", ctx->GPR1);
printk("\t R2 = %x\n", ctx->GPR2);
printk("\t R3 = %x\n", ctx->GPR3);
printk("\t R4 = %x\n", ctx->GPR4);
printk("\t R5 = %x\n", ctx->GPR5);
printk("\t R6 = %x\n", ctx->GPR6);
printk("\t R7 = %x\n", ctx->GPR7);
printk("\t R8 = %x\n", ctx->GPR8);
printk("\t R9 = %x\n", ctx->GPR9);
printk("\t R10 = %x\n", ctx->GPR10);
printk("\t R11 = %x\n", ctx->GPR11);
printk("\t R12 = %x\n", ctx->GPR12);
printk("\t R13 = %x\n", ctx->GPR13);
printk("\t R14 = %x\n", ctx->GPR14);
printk("\t R15 = %x\n", ctx->GPR15);
printk("\t R16 = %x\n", ctx->GPR16);
printk("\t R17 = %x\n", ctx->GPR17);
printk("\t R18 = %x\n", ctx->GPR18);
printk("\t R19 = %x\n", ctx->GPR19);
printk("\t R20 = %x\n", ctx->GPR20);
printk("\t R21 = %x\n", ctx->GPR21);
printk("\t R22 = %x\n", ctx->GPR22);
printk("\t R23 = %x\n", ctx->GPR23);
printk("\t R24 = %x\n", ctx->GPR24);
printk("\t R25 = %x\n", ctx->GPR25);
printk("\t R26 = %x\n", ctx->GPR26);
printk("\t R27 = %x\n", ctx->GPR27);
printk("\t R28 = %x\n", ctx->GPR28);
printk("\t R29 = %x\n", ctx->GPR29);
printk("\t R30 = %x\n", ctx->GPR30);
printk("\t R31 = %x\n", ctx->GPR31);
printk("\t CR = %x\n", ctx->EXC_CR);
printk("\t CTR = %x\n", ctx->EXC_CTR);
printk("\t XER = %x\n", ctx->EXC_XER);
printk("\t LR = %x\n", ctx->EXC_LR);
printk("\t MSR = %x\n", ctx->EXC_MSR);
#endif
status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 'c'),
0,
RTEMS_FIFO |
RTEMS_COUNTING_SEMAPHORE |
RTEMS_NO_INHERIT_PRIORITY |
RTEMS_NO_PRIORITY_CEILING |
RTEMS_LOCAL,
0,
&continueSemId);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't create continue semaphore: `%s'\n",rtems_status_text(status));
PushExceptCtx (_Thread_Executing->Object.id, continueSemId, ctx);
switch (ctx->_EXC_number){
case ASM_TRACE_VECTOR :
DPRINTF((" TRACE EXCEPTION !!!\n"));
ctx->EXC_SRR1 &= ~MSR_SE;
ExitForSingleStep-- ;
rtems_semaphore_release( wakeupEventSemId );
break;
case ASM_PROG_VECTOR :
DPRINTF((" BREAKPOINT EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
case ASM_SYS_VECTOR :
DPRINTF((" ENTER RDBG !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
default:
DPRINTF((" OTHER EXCEPTION !!!\n"));
rtems_semaphore_release( wakeupEventSemId );
break;
}
rtems_semaphore_obtain(continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
PopExceptCtx (_Thread_Executing->Object.id);
rtems_semaphore_delete(continueSemId);
}
}

View File

@@ -0,0 +1,114 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ../../..
subdir = librdbg/powerpc/mcp750
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@:@srcdir@/..:@srcdir@/../..
LIBNAME = librdbg.a
LIB = ${ARCH}/${LIBNAME}
# C and C++ source names, if any, go here -- minus the .c or .cc
C_PIECES = rdbg servcon servbkpt servrpc excep excep_f \
servtgt servtsp servutil _servtgt rdbg_f \
ptrace
C_FILES = $(C_PIECES:%=%.c)
C_O_FILES = $(C_PIECES:%=${ARCH}/%.o)
# Asm source names, if any, go here -- minus the .s
S_PIECES = rdbg_cpu_asm
S_FILES = $(ASM_PIECES:%=%.S)
S_O_FILES = $(ASM_PIECES:%=${ARCH}/%.o)
# Generated C source names, if any, go here -- minus the .c
GEN_C_PIECES= remdeb_xdr remdeb_svc
GEN_C_FILES = $(GEN_C_PIECES:%=%.c)
GEN_C_O_FILES = $(GEN_C_PIECES:%=${ARCH}/%.o)
# H source names, if any, go here -- minus the .h
H_PIECES = remdeb
H_FILES = $(H_PIECES:%=%.h)
# X source names
X_FILES = remdeb.x remdeb_f.x
SRCS= $(C_FILES) $(S_FILES) $(GEN_C_FILES) $(H_FILES)
OBJS = $(GEN_C_O_FILES) $(C_O_FILES) $(S_O_FILES)
RPCGEN = @RPCGEN@
AWK = @AWK@
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/lib.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
mkinstalldirs = $(SHELL) $(top_srcdir)/@RTEMS_TOPdir@/mkinstalldirs
INSTALLDIRS = $(PROJECT_INCLUDE)/rdbg
$(INSTALLDIRS):
@$(mkinstalldirs) $(INSTALLDIRS)
#
# Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
#
# Enable traces in RDBG
#
#CFLAGS += -DDDEBUG
#
CFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS += $(LIB) $(H_FILES) $(GEN_C_FILES)
CLOBBER_ADDITIONS +=
FRONTEND = \"$(RTEMS_CPU)/@RTEMS_BSP@/remdeb_f.x\"
all: ${ARCH} $(LIB)
@$(INSTALL_VARIANT) -m 644 $(LIB) $(PROJECT_RELEASE)/lib
$(LIB): $(SRCS) ${OBJS}
$(make-library)
remdeb.h: $(X_FILES)
@rm -f $@
( pwd=`pwd`; cd $(srcdir)/../..; \
$(RPCGEN) -h -DFRONTEND=$(FRONTEND) \
-o $$pwd/$@ remdeb.x )
@$(INSTALL_CHANGE) -m 755 $@ $(PROJECT_INCLUDE)/rdbg
remdeb_xdr.c: $(X_FILES)
@rm -f $@
( pwd=`pwd`; cd $(srcdir)/../..; \
$(RPCGEN) -c -DFRONTEND=$(FRONTEND) \
-o $$pwd/$@ remdeb.x )
remdeb_svc.c: $(X_FILES)
@rm -f $@ tmpSvc.c
( pwd=`pwd`; cd $(srcdir)/../..; \
$(RPCGEN) -s udp -DFRONTEND=$(FRONTEND) \
-o $$pwd/tmpSvc.c remdeb.x )
$(AWK) -f $(srcdir)/../../awk.svc THEPROG="remdeb.h" tmpSvc.c >$@
@rm -f tmpSvc.c
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -0,0 +1,76 @@
/*
**************************************************************************
*
* Component = rdblib
* Synopsis = remdeb_f.x
*
**************************************************************************
* $Id$
**************************************************************************
*/
struct xdr_regs
{
unsigned int tabreg[40];
};
#ifdef RPC_HDR
%/* now define register macros to apply to xdr_regs struct */
%
%#define R_PC 0
%#define R_MSR 1
%#define R_EXCEPNB 2
%#define R_R0 3
%#define R_R1 (R_R0 + 1)
%#define R_R2 (R_R0 + 2)
%#define R_R3 (R_R0 + 3)
%#define R_R4 (R_R0 + 4)
%#define R_R5 (R_R0 + 5)
%#define R_R6 (R_R0 + 6)
%#define R_R7 (R_R0 + 7)
%#define R_R8 (R_R0 + 8)
%#define R_R9 (R_R0 + 9)
%#define R_R10 (R_R0 + 10)
%#define R_R11 (R_R0 + 11)
%#define R_R12 (R_R0 + 12)
%#define R_R13 (R_R0 + 13)
%#define R_R14 (R_R0 + 14)
%#define R_R15 (R_R0 + 15)
%#define R_R16 (R_R0 + 16)
%#define R_R17 (R_R0 + 17)
%#define R_R18 (R_R0 + 18)
%#define R_R19 (R_R0 + 19)
%#define R_R20 (R_R0 + 20)
%#define R_R21 (R_R0 + 21)
%#define R_R22 (R_R0 + 22)
%#define R_R23 (R_R0 + 23)
%#define R_R24 (R_R0 + 24)
%#define R_R25 (R_R0 + 25)
%#define R_R26 (R_R0 + 26)
%#define R_R27 (R_R0 + 27)
%#define R_R28 (R_R0 + 28)
%#define R_R29 (R_R0 + 29)
%#define R_R30 (R_R0 + 30)
%#define R_R31 (R_R0 + 31)
%#define R_CR 35
%#define R_CTR 36
%#define R_XER 37
%#define R_LR 38
%#define R_MQ 39
%
%#include <libcpu/raw_exception.h>
%
%#define REG_PC tabreg[R_PC] /* PC register offset */
%#define REG_SP tabreg[R_R1] /* SP register offset */
%#define REG_FP tabreg[R_R1] /* SP register offset (no FP on PPC) */
%#define BREAK_SIZE 4 /* Breakpoint occupies 4 bytes */
%#define BREAK_ADJ 0 /* Nothing to subtract from address after bp */
%#define IS_BREAK(l) ((l) == 0x7d8d6808)
%#define SET_BREAK(l) (0x7d8d6808)
%#define ORG_BREAK(c,p) (p)
%#define IS_STEP(regs) (regs.tabreg[R_EXCEPNB] == ASM_TRACE_VECTOR) /* Was step and not break */
%#define TARGET_PROC_TYPE 3
#endif

View File

@@ -0,0 +1,76 @@
/*
**************************************************************************
*
* Component = rdblib
* Synopsis = remdeb_f.x
*
**************************************************************************
* $Id$
**************************************************************************
*/
struct xdr_regs
{
unsigned int tabreg[40];
};
#ifdef RPC_HDR
%/* now define register macros to apply to xdr_regs struct */
%
%#define R_PC 0
%#define R_MSR 1
%#define R_EXCEPNB 2
%#define R_R0 3
%#define R_R1 (R_R0 + 1)
%#define R_R2 (R_R0 + 2)
%#define R_R3 (R_R0 + 3)
%#define R_R4 (R_R0 + 4)
%#define R_R5 (R_R0 + 5)
%#define R_R6 (R_R0 + 6)
%#define R_R7 (R_R0 + 7)
%#define R_R8 (R_R0 + 8)
%#define R_R9 (R_R0 + 9)
%#define R_R10 (R_R0 + 10)
%#define R_R11 (R_R0 + 11)
%#define R_R12 (R_R0 + 12)
%#define R_R13 (R_R0 + 13)
%#define R_R14 (R_R0 + 14)
%#define R_R15 (R_R0 + 15)
%#define R_R16 (R_R0 + 16)
%#define R_R17 (R_R0 + 17)
%#define R_R18 (R_R0 + 18)
%#define R_R19 (R_R0 + 19)
%#define R_R20 (R_R0 + 20)
%#define R_R21 (R_R0 + 21)
%#define R_R22 (R_R0 + 22)
%#define R_R23 (R_R0 + 23)
%#define R_R24 (R_R0 + 24)
%#define R_R25 (R_R0 + 25)
%#define R_R26 (R_R0 + 26)
%#define R_R27 (R_R0 + 27)
%#define R_R28 (R_R0 + 28)
%#define R_R29 (R_R0 + 29)
%#define R_R30 (R_R0 + 30)
%#define R_R31 (R_R0 + 31)
%#define R_CR 35
%#define R_CTR 36
%#define R_XER 37
%#define R_LR 38
%#define R_MQ 39
%
%#include <libcpu/raw_exception.h>
%
%#define REG_PC tabreg[R_PC] /* PC register offset */
%#define REG_SP tabreg[R_R1] /* SP register offset */
%#define REG_FP tabreg[R_R1] /* SP register offset (no FP on PPC) */
%#define BREAK_SIZE 4 /* Breakpoint occupies 4 bytes */
%#define BREAK_ADJ 0 /* Nothing to subtract from address after bp */
%#define IS_BREAK(l) ((l) == 0x7d8d6808)
%#define SET_BREAK(l) (0x7d8d6808)
%#define ORG_BREAK(c,p) (p)
%#define IS_STEP(regs) (regs.tabreg[R_EXCEPNB] == ASM_TRACE_VECTOR) /* Was step and not break */
%#define TARGET_PROC_TYPE 3
#endif

View File

@@ -0,0 +1,82 @@
/* cpu_asm.s
*
* This file contains all assembly code for the Intel i386 implementation
* of RDBG.
*
* $Id$
*
*/
#include <libcpu/cpu.h>
#include <libcpu/io.h>
#include <rtems/score/targopts.h>
#include <asm.h>
BEGIN_CODE
/*
* void copyback_data_cache_and_invalidate_instr_cache(addr, size)
*
* This routine performs a copy of the data cache
* and invalidate the instruction cache
*/
.p2align 5
PUBLIC_VAR (copyback_data_cache_and_invalidate_instr_cache)
SYM (copyback_data_cache_and_invalidate_instr_cache):
/* r3 address to handle, r4 length in bytes */
addi r6, r0, PPC_CACHE_ALIGNMENT
/* r5 = last address to handle */
add r5,r3,r4
/* r3 = cache_align(r3, PPC_CACHE_ALIGNMENT)
subi r0,r6,1
andc r3,r3,r0
/* R4 = R3 = copy of first address */
mr r4,r3
/*
* Copyback data cache
*/
1: cmplw r4,r5 /* r4 >= r5 then done */
dcbst 0,r4 /* flush (data cache bloc store) */
add r4,r4,r6 /* r4 = next cache line addr */
blt 1b /* end r4 >= r5 then done */
sync /* Wait for all dcbst to complete on bus */
/*
* invalidate instruction cache
*/
/* R4 = fisrt address */
mr r4,r3
2: cmplw r4,r5 /* r4 >= r5 then done */
icbi 0,r4 /* invalidate (instruction cache bloc invalidate) */
add r4,r4,r6 /* r4 = next cache line addr */
blt 2b /* end r4 >= r5 then done */
sync /* Wait for all icbi to complete on bus */
isync
blr
/*
* void enterRdbg(void)
*
* This function perform a call to the exception SYSTEM call
* It is used :
* 1 - in the user code, to simulate a Breakpoint.
* (with justSaveContext = 0)
* 2 - in the RDBG code, to push a ctx in the list.
* (with justSaveContext = 1)
*
* In most of case, it will be use as described in 1.
* The 2nd possibility will be used by RDBG to obtain
* its own ctx
*/
PUBLIC_VAR (enterRdbg)
SYM (enterRdbg):
sc
blr
END_CODE
END

View File

@@ -0,0 +1,156 @@
/*
**************************************************************************
*
* Component =
*
* Synopsis = rdbg/powerpc/rdbg_f.c
*
* $Id$
*
**************************************************************************
*/
#include <assert.h>
#include <errno.h>
#include <rdbg/reg.h>
#include <rdbg/remdeb.h>
#include <rdbg/rdbg.h>
#include <rtems/score/cpu.h>
#include <rtems/score/thread.h>
#include <libcpu/cpu.h>
void
CtxToRegs (const CPU_Exception_frame* ctx, xdr_regs* regs)
{
* ((CPU_Exception_frame*) regs) = *ctx;
}
void
RegsToCtx (const xdr_regs* regs, CPU_Exception_frame* ctx)
{
*ctx = * ((CPU_Exception_frame*) regs);
}
void
get_ctx_thread( Thread_Control *thread, CPU_Exception_frame* ctx)
{
unsigned int *ptr;
unsigned int i;
ctx->EXC_SRR0 = thread->Registers.pc;
ctx->EXC_SRR1 = thread->Registers.msr;
ctx->_EXC_number = 0xdeadbeef;
ctx->GPR1 = thread->Registers.gpr1;
ctx->GPR2 = thread->Registers.gpr2;
/*
* Fill with dummy values...
*/
ptr = &ctx->GPR3;
for (i = 0; i < 10; i++)
ptr [i] = 0xdeadbeef;
ctx->GPR13 = thread->Registers.gpr13;
ctx->GPR14 = thread->Registers.gpr14;
ctx->GPR15 = thread->Registers.gpr15;
ctx->GPR16 = thread->Registers.gpr16;
ctx->GPR17 = thread->Registers.gpr17;
ctx->GPR18 = thread->Registers.gpr18;
ctx->GPR19 = thread->Registers.gpr19;
ctx->GPR20 = thread->Registers.gpr20;
ctx->GPR21 = thread->Registers.gpr21;
ctx->GPR22 = thread->Registers.gpr22;
ctx->GPR23 = thread->Registers.gpr23;
ctx->GPR24 = thread->Registers.gpr24;
ctx->GPR25 = thread->Registers.gpr25;
ctx->GPR26 = thread->Registers.gpr26;
ctx->GPR27 = thread->Registers.gpr27;
ctx->GPR28 = thread->Registers.gpr28;
ctx->GPR29 = thread->Registers.gpr29;
ctx->GPR30 = thread->Registers.gpr30;
ctx->GPR31 = thread->Registers.gpr31;
ctx->EXC_CR = thread->Registers.cr;
ctx->EXC_CTR = 0xdeadbeef;
ctx->EXC_XER = 0xdeadbeef;
ctx->EXC_LR = 0xdeadbeef;
ctx->EXC_MSR = 0xdeadbeef;
ctx->EXC_DAR = 0xdeadbeef;
}
void
set_ctx_thread( Thread_Control *thread, CPU_Exception_frame* ctx)
{
thread->Registers.gpr1 = ctx->GPR1;
thread->Registers.gpr2 = ctx->GPR2;
thread->Registers.gpr13 = ctx->GPR13;
thread->Registers.gpr14 = ctx->GPR14;
thread->Registers.gpr15 = ctx->GPR15;
thread->Registers.gpr16 = ctx->GPR16;
thread->Registers.gpr17 = ctx->GPR17;
thread->Registers.gpr18 = ctx->GPR18;
thread->Registers.gpr19 = ctx->GPR19;
thread->Registers.gpr20 = ctx->GPR20;
thread->Registers.gpr21 = ctx->GPR21;
thread->Registers.gpr22 = ctx->GPR22;
thread->Registers.gpr23 = ctx->GPR23;
thread->Registers.gpr24 = ctx->GPR24;
thread->Registers.gpr25 = ctx->GPR25;
thread->Registers.gpr26 = ctx->GPR26;
thread->Registers.gpr27 = ctx->GPR27;
thread->Registers.gpr28 = ctx->GPR28;
thread->Registers.gpr29 = ctx->GPR29;
thread->Registers.gpr30 = ctx->GPR30;
thread->Registers.gpr31 = ctx->GPR31;
thread->Registers.cr = ctx->EXC_CR;
thread->Registers.pc = ctx->EXC_SRR0;
thread->Registers.msr = ctx->EXC_SRR1;
}
int
Single_Step(CPU_Exception_frame* ctx)
{
if ((ctx->EXC_SRR1 & MSR_SE) != 0 || ExitForSingleStep != 0) {
/* Check coherency */
assert ((ctx->EXC_SRR1 & MSR_SE) != 0);
assert (ExitForSingleStep != 0);
return 0;
}
ctx->EXC_SRR1 |= MSR_SE;
++ExitForSingleStep;
return 0;
}
int
CheckForSingleStep (CPU_Exception_frame* ctx)
{
if (ExitForSingleStep) {
/*
* This functions can be called both from
* INT1 and INT3 handlers. In case it is
* called from INT3, need to clear TF.
*/
ctx->EXC_SRR1 &= ~MSR_SE;
ExitForSingleStep = 0;
return 1;
}
return 0;
}
void
CancelSingleStep (CPU_Exception_frame* ctx)
{
/* Cancel scheduled SS */
ctx->EXC_SRR1 &= ~MSR_SE;
ExitForSingleStep-- ;
}
cpuExcHandlerType oldExcHandler;
void connect_rdbg_exception()
{
oldExcHandler = globalExceptHdl;
globalExceptHdl = BreakPointExcHdl ;
}

View File

@@ -5,6 +5,8 @@
* *
* Synopsis = rkdb/rkdb.c * Synopsis = rkdb/rkdb.c
* *
* $Id$
*
************************************************************************** **************************************************************************
*/ */
@@ -142,7 +144,7 @@ ptrace (int request, int pid, char* addr, int data, char* addr2)
*/ */
if (diag == 0) { if (diag == 0) {
copyback_data_cache_and_invalidate_instr_cache(); copyback_data_cache_and_invalidate_instr_cache(addr, sizeof data);
return 0; return 0;
} }
goto mem_error; goto mem_error;
@@ -162,11 +164,7 @@ ptrace (int request, int pid, char* addr, int data, char* addr2)
ctx = GetExceptCtx (currentTargetThread); ctx = GetExceptCtx (currentTargetThread);
if ( if (!isRdbgException(ctx)) {
ctx->ctx->idtIndex != I386_EXCEPTION_DEBUG &&
ctx->ctx->idtIndex != I386_EXCEPTION_BREAKPOINT &&
ctx->ctx->idtIndex != I386_EXCEPTION_ENTER_RDBG
) {
CannotRestart = 1; CannotRestart = 1;
setErrno (EIO); setErrno (EIO);
return -1; return -1;

View File

@@ -5,6 +5,8 @@
* *
* Synopsis = rkdb/rkdb.c * Synopsis = rkdb/rkdb.c
* *
* $Id$
*
************************************************************************** **************************************************************************
*/ */

View File

@@ -7,6 +7,8 @@
* Synopsis: XDR definitions for remote debug server RPC calls. * Synopsis: XDR definitions for remote debug server RPC calls.
* XDR definitions for RPCGEN to build remote debug server. * XDR definitions for RPCGEN to build remote debug server.
* *
* $Id$
*
********************************************************************** **********************************************************************
*/ */

View File

@@ -6,6 +6,8 @@
* *
* Synopsis: Management of breakpoints * Synopsis: Management of breakpoints
* *
* $Id$
*
********************************************************************** **********************************************************************
*/ */

View File

@@ -6,6 +6,8 @@
* *
* Synopsis: Management of RPC client connections. * Synopsis: Management of RPC client connections.
* *
* $Id$
*
************************************************************************** **************************************************************************
*/ */

View File

@@ -7,6 +7,8 @@
* Synopsis: support routines for RPC dispatch for remote debug server. * Synopsis: support routines for RPC dispatch for remote debug server.
* Main server dispatch routines from RPC to support remote debug. * Main server dispatch routines from RPC to support remote debug.
* *
* $Id$
*
********************************************************************** **********************************************************************
*/ */

View File

@@ -4,6 +4,8 @@
* Component: RDB servers * Component: RDB servers
* Module: servtgt.c * Module: servtgt.c
* *
* $Id$
*
************************************************************************** **************************************************************************
*/ */

View File

@@ -6,6 +6,8 @@
* *
* Synopsis: Transport management for remote debug server. * Synopsis: Transport management for remote debug server.
* *
* $Id$
*
************************************************************************** **************************************************************************
*/ */

View File

@@ -6,6 +6,8 @@
* *
* Synopsis: Various utility routines * Synopsis: Various utility routines
* *
* $Id$
*
********************************************************************** **********************************************************************
*/ */

View File

@@ -104,13 +104,14 @@ define make-exe
$(CC) $(CFLAGS) -o $(basename $@).exe $(LINK_OBJS) $(CC) $(CFLAGS) -o $(basename $@).exe $(LINK_OBJS)
$(NM) -g -n $(basename $@).exe > $(basename $@).num $(NM) -g -n $(basename $@).exe > $(basename $@).num
$(SIZE) $(basename $@).exe $(SIZE) $(basename $@).exe
$(CP) $(basename $@).exe $(PROJECT_ROOT)/c/src/lib/libbsp/powerpc/mcp750/bootloader/$(ARCH); \ $(CP) $(basename $@).exe $(PROJECT_ROOT)/powerpc-rtems/c/mcp750/lib/libbsp/powerpc/mcp750/bootloader/$(ARCH); \
cd $(PROJECT_ROOT)/c/src/lib/libbsp/powerpc/mcp750/bootloader; \ cd $(PROJECT_ROOT)/powerpc-rtems/c/mcp750/lib/libbsp/powerpc/mcp750/bootloader; \
make bootloader BINARY_LOADED=$(basename $@).exe; \ make bootloader BINARY_LOADED=$(basename $@).exe; \
COMPLETE_FILE_NAME=$(basename $@).exe ;\ COMPLETE_FILE_NAME=$(basename $@).exe ;\
echo $${COMPLETE_FILE_NAME} ;\ echo $${COMPLETE_FILE_NAME} ;\
FILE_NAME=`basename $${COMPLETE_FILE_NAME}` ;\ FILE_NAME=`basename $${COMPLETE_FILE_NAME}` ;\
echo $${FILE_NAME} ;\ echo $${FILE_NAME} ;\
mkdir -p $(PROJECT_ROOT)/$(RTEMS_BSP)/bin ;\
$(CP) bootloader $(PROJECT_ROOT)/$(RTEMS_BSP)/bin/$${FILE_NAME} $(CP) bootloader $(PROJECT_ROOT)/$(RTEMS_BSP)/bin/$${FILE_NAME}
endef endef