forked from Imagelibrary/rtems
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:
@@ -24,7 +24,7 @@ INSTALL_CHANGE = @INSTALL_CHANGE@
|
||||
SHARED_LIB = shared
|
||||
|
||||
ifeq ($(RTEMS_CPU_MODEL),mpc750)
|
||||
CPUDIR = other_cpu
|
||||
CPUDIR = mpc750
|
||||
else
|
||||
CPUDIR = other_cpu
|
||||
endif
|
||||
|
||||
@@ -58,8 +58,6 @@ void _CPU_Initialize(
|
||||
* _CPU_Context_Initialize
|
||||
*/
|
||||
|
||||
#define CPU_MINIMUM_STACK_FRAME_SIZE 8
|
||||
|
||||
void _CPU_Context_Initialize(
|
||||
Context_Control *the_context,
|
||||
unsigned32 *stack_base,
|
||||
|
||||
@@ -344,6 +344,8 @@ extern "C" {
|
||||
* a debugger such as gdb. But that is another problem.
|
||||
*/
|
||||
|
||||
#ifndef ASM
|
||||
|
||||
typedef struct {
|
||||
unsigned32 gpr1; /* Stack pointer for all */
|
||||
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_high;
|
||||
|
||||
#endif /* ndef ASM */
|
||||
|
||||
/*
|
||||
* This defines the number of levels and the mask used to pick those
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef ASM
|
||||
|
||||
SCORE_EXTERN struct {
|
||||
unsigned32 *Disable_level;
|
||||
@@ -498,6 +503,8 @@ SCORE_EXTERN struct {
|
||||
|
||||
} _CPU_IRQ_info CPU_STRUCTURE_ALIGNMENT;
|
||||
|
||||
#endif /* ndef ASM */
|
||||
|
||||
/*
|
||||
* The size of the floating point context area. On some CPUs this
|
||||
* 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)
|
||||
|
||||
/*
|
||||
* Needed for Interrupt stack
|
||||
*/
|
||||
#define CPU_MINIMUM_STACK_FRAME_SIZE 8
|
||||
|
||||
|
||||
/* ISR handler macros */
|
||||
|
||||
/*
|
||||
@@ -593,6 +606,7 @@ SCORE_EXTERN struct {
|
||||
|
||||
#define loc_string(a,b) a " (" #b ")\n"
|
||||
|
||||
#ifndef ASM
|
||||
|
||||
static inline unsigned32 _CPU_ISR_Get_level( void )
|
||||
{
|
||||
@@ -941,6 +955,8 @@ static inline unsigned64 PPC_Get_timebase_register( void )
|
||||
return tbr;
|
||||
}
|
||||
|
||||
#endif /* ndef ASM */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
*
|
||||
* Synopsis = Machine-dependent header file
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
@@ -17,35 +19,21 @@
|
||||
|
||||
#define EFLAGS_TF 0x00100
|
||||
|
||||
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;
|
||||
|
||||
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*,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;
|
||||
static inline int isRdbgException(Exception_context *ctx)
|
||||
{
|
||||
if (
|
||||
ctx->ctx->idtIndex != I386_EXCEPTION_DEBUG &&
|
||||
ctx->ctx->idtIndex != I386_EXCEPTION_BREAKPOINT &&
|
||||
ctx->ctx->idtIndex != I386_EXCEPTION_ENTER_RDBG
|
||||
) return 0;
|
||||
else return 1;
|
||||
}
|
||||
static inline int getExcNum(Exception_context *ctx)
|
||||
{
|
||||
return ctx->ctx->idtIndex;
|
||||
}
|
||||
|
||||
extern void connect_rdbg_exception();
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
|
||||
/*
|
||||
* Registers Offset in frame definition
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#define NBREGS 19
|
||||
|
||||
|
||||
38
c/src/lib/include/rdbg/powerpc/rdbg_f.h
Normal file
38
c/src/lib/include/rdbg/powerpc/rdbg_f.h
Normal 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
|
||||
|
||||
|
||||
|
||||
16
c/src/lib/include/rdbg/powerpc/reg.h
Normal file
16
c/src/lib/include/rdbg/powerpc/reg.h
Normal 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;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
*
|
||||
* Synopsis = rdbg.h
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
@@ -14,9 +16,9 @@
|
||||
#include <rpc/rpc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <rdbg/rdbg_f.h>
|
||||
#include <stdlib.h> /* For malloc() and free() prototypes */
|
||||
#include <bsp.h>
|
||||
#include <rtems.h>
|
||||
|
||||
#define Malloc(size) malloc (size)
|
||||
#define Free(block) free (block)
|
||||
@@ -49,5 +51,45 @@ void svc_processrequest (SVCXPRT* xprt,
|
||||
void (*dispatch)());
|
||||
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 */
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef 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* 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)
|
||||
#else
|
||||
# define DPRINTF(a) /* suppress */
|
||||
|
||||
@@ -117,7 +117,7 @@ struct MD {
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
@@ -419,7 +419,8 @@ dec21140Enet_initialize_hardware (struct dec21140_softc *sc)
|
||||
sc->rxBdCount = 0;
|
||||
cp = (char *)malloc((NRXBUFS+NTXBUFS)*(sizeof(struct MD)+ RBUF_SIZE) + PPC_CACHE_ALIGNMENT);
|
||||
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
|
||||
if (_CPU_is_paging_enabled())
|
||||
_CPU_change_memory_mapping_attribute
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <console.h>
|
||||
#include <libcpu/io.h>
|
||||
#include <clockdrv.h>
|
||||
#include <bsp/vectors.h>
|
||||
|
||||
#ifndef ASM
|
||||
#define outport_byte(port,value) outb(value,port)
|
||||
|
||||
@@ -21,9 +21,8 @@
|
||||
/*
|
||||
* lower byte is interrupt mask on the master 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
|
||||
@@ -53,7 +52,7 @@ int BSP_irq_disable_at_i8259s (const rtems_irq_symbolic_name irqLine)
|
||||
}
|
||||
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);
|
||||
|
||||
@@ -88,7 +87,7 @@ int BSP_irq_enable_at_i8259s (const rtems_irq_symbolic_name irqLine)
|
||||
}
|
||||
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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -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, 0xFF); /* Mask all */
|
||||
|
||||
i8259s_cache = 0xFFFB;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
|
||||
/* Command for specific EOI (End Of Interrupt): Interrupt acknowledge */
|
||||
#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) */
|
||||
|
||||
#ifndef ASM
|
||||
|
||||
@@ -212,6 +212,13 @@ nested:
|
||||
*/
|
||||
stmw r16, GPR16_OFFSET(r1)
|
||||
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
|
||||
/*
|
||||
* start restoring exception like frame
|
||||
|
||||
@@ -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$
|
||||
*
|
||||
* 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/io.h>
|
||||
#include <rtems/score/targopts.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
#include "asm.h"
|
||||
|
||||
#define SYNC \
|
||||
@@ -91,8 +78,8 @@ enter_C_code:
|
||||
/*
|
||||
* stack = &__rtems_end + 4096
|
||||
*/
|
||||
addis r9,r0, __rtems_end+4096@ha
|
||||
addi r9,r9, __rtems_end+4096@l
|
||||
addis r9,r0, __rtems_end+(4096-CPU_MINIMUM_STACK_FRAME_SIZE)@ha
|
||||
addi r9,r9, __rtems_end+(4096-CPU_MINIMUM_STACK_FRAME_SIZE)@l
|
||||
mr r1, r9
|
||||
bl zero_bss
|
||||
/*
|
||||
@@ -142,8 +129,3 @@ _return_to_ppcbug:
|
||||
bl MMUon
|
||||
mtctr r30
|
||||
bctr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -131,7 +131,9 @@ void bsp_pretasking_hook(void)
|
||||
|
||||
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);
|
||||
#endif
|
||||
bsp_libc_init((void *) heap_start, heap_size, 0);
|
||||
|
||||
#ifdef RTEMS_DEBUG
|
||||
@@ -141,7 +143,7 @@ void bsp_pretasking_hook(void)
|
||||
|
||||
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)
|
||||
@@ -184,7 +186,7 @@ void bsp_start( void )
|
||||
* the initial stack has aready been set to this value in start.S
|
||||
* 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
|
||||
* 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
|
||||
* 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 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.exceptions_in_RAM = TRUE;
|
||||
|
||||
#ifdef SHOW_MORE_INIT_SETTINGS
|
||||
printk("BSP_Configuration.work_space_size = %x\n", BSP_Configuration.work_space_size);
|
||||
#endif
|
||||
work_space_start =
|
||||
(unsigned char *)BSP_mem_size - BSP_Configuration.work_space_size;
|
||||
|
||||
@@ -306,5 +310,7 @@ void bsp_start( void )
|
||||
* Initalize RTEMS IRQ system
|
||||
*/
|
||||
BSP_rtems_irq_mng_init(0);
|
||||
#ifdef SHOW_MORE_INIT_SETTINGS
|
||||
printk("Exit from bspstart\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -86,6 +86,14 @@ SYM (push_normalized_frame):
|
||||
stw r30, EXC_CTR_OFFSET(r1)
|
||||
mfxer r28
|
||||
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
|
||||
*/
|
||||
@@ -97,8 +105,17 @@ SYM (push_normalized_frame):
|
||||
/*
|
||||
* Call C exception handler
|
||||
*/
|
||||
/*
|
||||
* store the execption frame address in r3 (first param)
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@@ -135,8 +152,3 @@ SYM (push_normalized_frame):
|
||||
addi r1,r1, EXCEPTION_FRAME_END
|
||||
SYNC
|
||||
rfi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -128,9 +128,16 @@ typedef struct {
|
||||
unsigned EXC_LR;
|
||||
unsigned EXC_MSR;
|
||||
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 */
|
||||
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
static rtems_raw_except_global_settings exception_config;
|
||||
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;
|
||||
|
||||
@@ -82,6 +84,14 @@ void initialize_exceptions()
|
||||
{
|
||||
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.rawExceptHdlTbl = &exception_table[0];
|
||||
exception_config.defaultRawEntry.exceptIndex = 0;
|
||||
|
||||
@@ -117,7 +117,7 @@ struct MD {
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
@@ -419,7 +419,8 @@ dec21140Enet_initialize_hardware (struct dec21140_softc *sc)
|
||||
sc->rxBdCount = 0;
|
||||
cp = (char *)malloc((NRXBUFS+NTXBUFS)*(sizeof(struct MD)+ RBUF_SIZE) + PPC_CACHE_ALIGNMENT);
|
||||
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
|
||||
if (_CPU_is_paging_enabled())
|
||||
_CPU_change_memory_mapping_attribute
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <console.h>
|
||||
#include <libcpu/io.h>
|
||||
#include <clockdrv.h>
|
||||
#include <bsp/vectors.h>
|
||||
|
||||
#ifndef ASM
|
||||
#define outport_byte(port,value) outb(value,port)
|
||||
|
||||
@@ -21,9 +21,8 @@
|
||||
/*
|
||||
* lower byte is interrupt mask on the master 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
|
||||
@@ -53,7 +52,7 @@ int BSP_irq_disable_at_i8259s (const rtems_irq_symbolic_name irqLine)
|
||||
}
|
||||
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);
|
||||
|
||||
@@ -88,7 +87,7 @@ int BSP_irq_enable_at_i8259s (const rtems_irq_symbolic_name irqLine)
|
||||
}
|
||||
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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -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, 0xFF); /* Mask all */
|
||||
|
||||
i8259s_cache = 0xFFFB;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
|
||||
/* Command for specific EOI (End Of Interrupt): Interrupt acknowledge */
|
||||
#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) */
|
||||
|
||||
#ifndef ASM
|
||||
|
||||
@@ -212,6 +212,13 @@ nested:
|
||||
*/
|
||||
stmw r16, GPR16_OFFSET(r1)
|
||||
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
|
||||
/*
|
||||
* start restoring exception like frame
|
||||
|
||||
@@ -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$
|
||||
*
|
||||
* 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/io.h>
|
||||
#include <rtems/score/targopts.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
#include "asm.h"
|
||||
|
||||
#define SYNC \
|
||||
@@ -91,8 +78,8 @@ enter_C_code:
|
||||
/*
|
||||
* stack = &__rtems_end + 4096
|
||||
*/
|
||||
addis r9,r0, __rtems_end+4096@ha
|
||||
addi r9,r9, __rtems_end+4096@l
|
||||
addis r9,r0, __rtems_end+(4096-CPU_MINIMUM_STACK_FRAME_SIZE)@ha
|
||||
addi r9,r9, __rtems_end+(4096-CPU_MINIMUM_STACK_FRAME_SIZE)@l
|
||||
mr r1, r9
|
||||
bl zero_bss
|
||||
/*
|
||||
@@ -142,8 +129,3 @@ _return_to_ppcbug:
|
||||
bl MMUon
|
||||
mtctr r30
|
||||
bctr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -131,7 +131,9 @@ void bsp_pretasking_hook(void)
|
||||
|
||||
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);
|
||||
#endif
|
||||
bsp_libc_init((void *) heap_start, heap_size, 0);
|
||||
|
||||
#ifdef RTEMS_DEBUG
|
||||
@@ -141,7 +143,7 @@ void bsp_pretasking_hook(void)
|
||||
|
||||
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)
|
||||
@@ -184,7 +186,7 @@ void bsp_start( void )
|
||||
* the initial stack has aready been set to this value in start.S
|
||||
* 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
|
||||
* 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
|
||||
* 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 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.exceptions_in_RAM = TRUE;
|
||||
|
||||
#ifdef SHOW_MORE_INIT_SETTINGS
|
||||
printk("BSP_Configuration.work_space_size = %x\n", BSP_Configuration.work_space_size);
|
||||
#endif
|
||||
work_space_start =
|
||||
(unsigned char *)BSP_mem_size - BSP_Configuration.work_space_size;
|
||||
|
||||
@@ -306,5 +310,7 @@ void bsp_start( void )
|
||||
* Initalize RTEMS IRQ system
|
||||
*/
|
||||
BSP_rtems_irq_mng_init(0);
|
||||
#ifdef SHOW_MORE_INIT_SETTINGS
|
||||
printk("Exit from bspstart\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -86,6 +86,14 @@ SYM (push_normalized_frame):
|
||||
stw r30, EXC_CTR_OFFSET(r1)
|
||||
mfxer r28
|
||||
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
|
||||
*/
|
||||
@@ -97,8 +105,17 @@ SYM (push_normalized_frame):
|
||||
/*
|
||||
* Call C exception handler
|
||||
*/
|
||||
/*
|
||||
* store the execption frame address in r3 (first param)
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@@ -135,8 +152,3 @@ SYM (push_normalized_frame):
|
||||
addi r1,r1, EXCEPTION_FRAME_END
|
||||
SYNC
|
||||
rfi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -128,9 +128,16 @@ typedef struct {
|
||||
unsigned EXC_LR;
|
||||
unsigned EXC_MSR;
|
||||
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 */
|
||||
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
static rtems_raw_except_global_settings exception_config;
|
||||
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;
|
||||
|
||||
@@ -82,6 +84,14 @@ void initialize_exceptions()
|
||||
{
|
||||
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.rawExceptHdlTbl = &exception_table[0];
|
||||
exception_config.defaultRawEntry.exceptIndex = 0;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
============================================================================
|
||||
_SERVTGT
|
||||
$Id$
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
@@ -17,9 +18,6 @@
|
||||
#include <assert.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
|
||||
extern void rtems_exception_prologue_50();
|
||||
|
||||
|
||||
#ifdef DDEBUG
|
||||
#define Ptrace TgtDbgPtrace
|
||||
#else
|
||||
@@ -34,8 +32,6 @@ rtems_id wakeupEventSemId;
|
||||
|
||||
CPU_Exception_frame Idle_frame;
|
||||
|
||||
cpuExcHandlerType old_currentExcHandler;
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
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.
|
||||
@@ -128,7 +87,7 @@ rtems_task eventTask( rtems_task_argument pid)
|
||||
|
||||
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_status_code status;
|
||||
rtems_id debugId;
|
||||
interrupt_gate_descriptor *currentIdtEntry;
|
||||
unsigned limit;
|
||||
unsigned level;
|
||||
|
||||
errno = 0;
|
||||
|
||||
@@ -177,18 +133,7 @@ Boolean TgtAttach(
|
||||
TgtCreateNew(pid, conn_idx, 0, NULL, False);
|
||||
|
||||
|
||||
/*
|
||||
* Connect the Exception used to debug
|
||||
*/
|
||||
i386_get_info_from_IDTR (¤tIdtEntry, &limit);
|
||||
|
||||
_CPU_ISR_Disable(level);
|
||||
create_interrupt_gate_descriptor (¤tIdtEntry[50], rtems_exception_prologue_50);
|
||||
_CPU_ISR_Enable(level);
|
||||
|
||||
old_currentExcHandler = _currentExcHandler;
|
||||
_currentExcHandler = BreakPointExcHdl ;
|
||||
|
||||
connect_rdbg_exception();
|
||||
|
||||
/*
|
||||
* Create the attach debuger task
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
# by rpcgen(1) into something suitable for RDB servers.
|
||||
#
|
||||
#########################################################################
|
||||
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
BEGIN {
|
||||
headerstarted = 0
|
||||
withinproc = 0
|
||||
|
||||
136
c/src/lib/librdbg/excep.c
Normal file
136
c/src/lib/librdbg/excep.c
Normal 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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
153
c/src/lib/librdbg/i386/excep_f.c
Normal file
153
c/src/lib/librdbg/i386/excep_f.c
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,8 +17,10 @@ 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 servtgt servtsp servutil \
|
||||
_servtgt rdbg_f ptrace
|
||||
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)
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*
|
||||
* Synopsis = remdeb_f.x
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* This file contains all assembly code for the Intel i386 implementation
|
||||
* of RDBG.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#include <asm.h>
|
||||
@@ -10,7 +12,7 @@
|
||||
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
|
||||
* and invalidate the instruction cache
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
*
|
||||
* Synopsis = rdbg/i386/rdbg_f.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
@@ -128,3 +130,26 @@ CancelSingleStep (CPU_Exception_frame* ctx)
|
||||
ctx->eflags &= ~EFLAGS_TF;
|
||||
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 (¤tIdtEntry, &limit);
|
||||
|
||||
_CPU_ISR_Disable(level);
|
||||
create_interrupt_gate_descriptor (¤tIdtEntry[50], rtems_exception_prologue_50);
|
||||
_CPU_ISR_Enable(level);
|
||||
|
||||
old_currentExcHandler = _currentExcHandler;
|
||||
_currentExcHandler = BreakPointExcHdl ;
|
||||
|
||||
}
|
||||
|
||||
25
c/src/lib/librdbg/powerpc/Makefile.in
Normal file
25
c/src/lib/librdbg/powerpc/Makefile.in
Normal 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
|
||||
167
c/src/lib/librdbg/powerpc/excep_f.c
Normal file
167
c/src/lib/librdbg/powerpc/excep_f.c
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
114
c/src/lib/librdbg/powerpc/mcp750/Makefile.in
Normal file
114
c/src/lib/librdbg/powerpc/mcp750/Makefile.in
Normal 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
|
||||
76
c/src/lib/librdbg/powerpc/mcp750/remdeb_f.x
Normal file
76
c/src/lib/librdbg/powerpc/mcp750/remdeb_f.x
Normal 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
|
||||
|
||||
82
c/src/lib/librdbg/powerpc/rdbg_cpu_asm.S
Normal file
82
c/src/lib/librdbg/powerpc/rdbg_cpu_asm.S
Normal 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
|
||||
156
c/src/lib/librdbg/powerpc/rdbg_f.c
Normal file
156
c/src/lib/librdbg/powerpc/rdbg_f.c
Normal 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 ;
|
||||
}
|
||||
@@ -5,6 +5,8 @@
|
||||
*
|
||||
* Synopsis = rkdb/rkdb.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
@@ -142,7 +144,7 @@ ptrace (int request, int pid, char* addr, int data, char* addr2)
|
||||
*/
|
||||
|
||||
if (diag == 0) {
|
||||
copyback_data_cache_and_invalidate_instr_cache();
|
||||
copyback_data_cache_and_invalidate_instr_cache(addr, sizeof data);
|
||||
return 0;
|
||||
}
|
||||
goto mem_error;
|
||||
@@ -162,11 +164,7 @@ ptrace (int request, int pid, char* addr, int data, char* addr2)
|
||||
|
||||
ctx = GetExceptCtx (currentTargetThread);
|
||||
|
||||
if (
|
||||
ctx->ctx->idtIndex != I386_EXCEPTION_DEBUG &&
|
||||
ctx->ctx->idtIndex != I386_EXCEPTION_BREAKPOINT &&
|
||||
ctx->ctx->idtIndex != I386_EXCEPTION_ENTER_RDBG
|
||||
) {
|
||||
if (!isRdbgException(ctx)) {
|
||||
CannotRestart = 1;
|
||||
setErrno (EIO);
|
||||
return -1;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
*
|
||||
* Synopsis = rkdb/rkdb.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
* Synopsis: XDR definitions for remote debug server RPC calls.
|
||||
* XDR definitions for RPCGEN to build remote debug server.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
*
|
||||
* Synopsis: Management of breakpoints
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
*
|
||||
* Synopsis: Management of RPC client connections.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
* Synopsis: support routines for RPC dispatch for remote debug server.
|
||||
* Main server dispatch routines from RPC to support remote debug.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
* Component: RDB servers
|
||||
* Module: servtgt.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
*
|
||||
* Synopsis: Transport management for remote debug server.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
*
|
||||
* Synopsis: Various utility routines
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
*
|
||||
* Synopsis = Machine-dependent header file
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
@@ -17,35 +19,21 @@
|
||||
|
||||
#define EFLAGS_TF 0x00100
|
||||
|
||||
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;
|
||||
|
||||
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*,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;
|
||||
static inline int isRdbgException(Exception_context *ctx)
|
||||
{
|
||||
if (
|
||||
ctx->ctx->idtIndex != I386_EXCEPTION_DEBUG &&
|
||||
ctx->ctx->idtIndex != I386_EXCEPTION_BREAKPOINT &&
|
||||
ctx->ctx->idtIndex != I386_EXCEPTION_ENTER_RDBG
|
||||
) return 0;
|
||||
else return 1;
|
||||
}
|
||||
static inline int getExcNum(Exception_context *ctx)
|
||||
{
|
||||
return ctx->ctx->idtIndex;
|
||||
}
|
||||
|
||||
extern void connect_rdbg_exception();
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
|
||||
/*
|
||||
* Registers Offset in frame definition
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#define NBREGS 19
|
||||
|
||||
|
||||
38
c/src/librdbg/include/rdbg/powerpc/rdbg_f.h
Normal file
38
c/src/librdbg/include/rdbg/powerpc/rdbg_f.h
Normal 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
|
||||
|
||||
|
||||
|
||||
16
c/src/librdbg/include/rdbg/powerpc/reg.h
Normal file
16
c/src/librdbg/include/rdbg/powerpc/reg.h
Normal 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;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
*
|
||||
* Synopsis = rdbg.h
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
@@ -14,9 +16,9 @@
|
||||
#include <rpc/rpc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <rdbg/rdbg_f.h>
|
||||
#include <stdlib.h> /* For malloc() and free() prototypes */
|
||||
#include <bsp.h>
|
||||
#include <rtems.h>
|
||||
|
||||
#define Malloc(size) malloc (size)
|
||||
#define Free(block) free (block)
|
||||
@@ -49,5 +51,45 @@ void svc_processrequest (SVCXPRT* xprt,
|
||||
void (*dispatch)());
|
||||
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 */
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef 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* 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)
|
||||
#else
|
||||
# define DPRINTF(a) /* suppress */
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
============================================================================
|
||||
_SERVTGT
|
||||
$Id$
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
@@ -17,9 +18,6 @@
|
||||
#include <assert.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
|
||||
extern void rtems_exception_prologue_50();
|
||||
|
||||
|
||||
#ifdef DDEBUG
|
||||
#define Ptrace TgtDbgPtrace
|
||||
#else
|
||||
@@ -34,8 +32,6 @@ rtems_id wakeupEventSemId;
|
||||
|
||||
CPU_Exception_frame Idle_frame;
|
||||
|
||||
cpuExcHandlerType old_currentExcHandler;
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
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.
|
||||
@@ -128,7 +87,7 @@ rtems_task eventTask( rtems_task_argument pid)
|
||||
|
||||
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_status_code status;
|
||||
rtems_id debugId;
|
||||
interrupt_gate_descriptor *currentIdtEntry;
|
||||
unsigned limit;
|
||||
unsigned level;
|
||||
|
||||
errno = 0;
|
||||
|
||||
@@ -177,18 +133,7 @@ Boolean TgtAttach(
|
||||
TgtCreateNew(pid, conn_idx, 0, NULL, False);
|
||||
|
||||
|
||||
/*
|
||||
* Connect the Exception used to debug
|
||||
*/
|
||||
i386_get_info_from_IDTR (¤tIdtEntry, &limit);
|
||||
|
||||
_CPU_ISR_Disable(level);
|
||||
create_interrupt_gate_descriptor (¤tIdtEntry[50], rtems_exception_prologue_50);
|
||||
_CPU_ISR_Enable(level);
|
||||
|
||||
old_currentExcHandler = _currentExcHandler;
|
||||
_currentExcHandler = BreakPointExcHdl ;
|
||||
|
||||
connect_rdbg_exception();
|
||||
|
||||
/*
|
||||
* Create the attach debuger task
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
# by rpcgen(1) into something suitable for RDB servers.
|
||||
#
|
||||
#########################################################################
|
||||
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
BEGIN {
|
||||
headerstarted = 0
|
||||
withinproc = 0
|
||||
|
||||
136
c/src/librdbg/src/excep.c
Normal file
136
c/src/librdbg/src/excep.c
Normal 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;
|
||||
}
|
||||
@@ -17,8 +17,10 @@ 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 servtgt servtsp servutil \
|
||||
_servtgt rdbg_f ptrace
|
||||
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)
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*
|
||||
* Synopsis = remdeb_f.x
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
153
c/src/librdbg/src/i386/excep_f.c
Normal file
153
c/src/librdbg/src/i386/excep_f.c
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,8 +17,10 @@ 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 servtgt servtsp servutil \
|
||||
_servtgt rdbg_f ptrace
|
||||
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)
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*
|
||||
* Synopsis = remdeb_f.x
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* This file contains all assembly code for the Intel i386 implementation
|
||||
* of RDBG.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#include <asm.h>
|
||||
@@ -10,7 +12,7 @@
|
||||
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
|
||||
* and invalidate the instruction cache
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
*
|
||||
* Synopsis = rdbg/i386/rdbg_f.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
@@ -128,3 +130,26 @@ CancelSingleStep (CPU_Exception_frame* ctx)
|
||||
ctx->eflags &= ~EFLAGS_TF;
|
||||
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 (¤tIdtEntry, &limit);
|
||||
|
||||
_CPU_ISR_Disable(level);
|
||||
create_interrupt_gate_descriptor (¤tIdtEntry[50], rtems_exception_prologue_50);
|
||||
_CPU_ISR_Enable(level);
|
||||
|
||||
old_currentExcHandler = _currentExcHandler;
|
||||
_currentExcHandler = BreakPointExcHdl ;
|
||||
|
||||
}
|
||||
|
||||
25
c/src/librdbg/src/powerpc/Makefile.in
Normal file
25
c/src/librdbg/src/powerpc/Makefile.in
Normal 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
|
||||
167
c/src/librdbg/src/powerpc/excep_f.c
Normal file
167
c/src/librdbg/src/powerpc/excep_f.c
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
114
c/src/librdbg/src/powerpc/mcp750/Makefile.in
Normal file
114
c/src/librdbg/src/powerpc/mcp750/Makefile.in
Normal 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
|
||||
76
c/src/librdbg/src/powerpc/mcp750/remdeb_f.x
Normal file
76
c/src/librdbg/src/powerpc/mcp750/remdeb_f.x
Normal 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
|
||||
|
||||
@@ -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
|
||||
|
||||
82
c/src/librdbg/src/powerpc/rdbg_cpu_asm.S
Normal file
82
c/src/librdbg/src/powerpc/rdbg_cpu_asm.S
Normal 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
|
||||
156
c/src/librdbg/src/powerpc/rdbg_f.c
Normal file
156
c/src/librdbg/src/powerpc/rdbg_f.c
Normal 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 ;
|
||||
}
|
||||
@@ -5,6 +5,8 @@
|
||||
*
|
||||
* Synopsis = rkdb/rkdb.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
@@ -142,7 +144,7 @@ ptrace (int request, int pid, char* addr, int data, char* addr2)
|
||||
*/
|
||||
|
||||
if (diag == 0) {
|
||||
copyback_data_cache_and_invalidate_instr_cache();
|
||||
copyback_data_cache_and_invalidate_instr_cache(addr, sizeof data);
|
||||
return 0;
|
||||
}
|
||||
goto mem_error;
|
||||
@@ -162,11 +164,7 @@ ptrace (int request, int pid, char* addr, int data, char* addr2)
|
||||
|
||||
ctx = GetExceptCtx (currentTargetThread);
|
||||
|
||||
if (
|
||||
ctx->ctx->idtIndex != I386_EXCEPTION_DEBUG &&
|
||||
ctx->ctx->idtIndex != I386_EXCEPTION_BREAKPOINT &&
|
||||
ctx->ctx->idtIndex != I386_EXCEPTION_ENTER_RDBG
|
||||
) {
|
||||
if (!isRdbgException(ctx)) {
|
||||
CannotRestart = 1;
|
||||
setErrno (EIO);
|
||||
return -1;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
*
|
||||
* Synopsis = rkdb/rkdb.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
* Synopsis: XDR definitions for remote debug server RPC calls.
|
||||
* XDR definitions for RPCGEN to build remote debug server.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
*
|
||||
* Synopsis: Management of breakpoints
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
*
|
||||
* Synopsis: Management of RPC client connections.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
* Synopsis: support routines for RPC dispatch for remote debug server.
|
||||
* Main server dispatch routines from RPC to support remote debug.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
* Component: RDB servers
|
||||
* Module: servtgt.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
*
|
||||
* Synopsis: Transport management for remote debug server.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
*
|
||||
* Synopsis: Various utility routines
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -104,13 +104,14 @@ define make-exe
|
||||
$(CC) $(CFLAGS) -o $(basename $@).exe $(LINK_OBJS)
|
||||
$(NM) -g -n $(basename $@).exe > $(basename $@).num
|
||||
$(SIZE) $(basename $@).exe
|
||||
$(CP) $(basename $@).exe $(PROJECT_ROOT)/c/src/lib/libbsp/powerpc/mcp750/bootloader/$(ARCH); \
|
||||
cd $(PROJECT_ROOT)/c/src/lib/libbsp/powerpc/mcp750/bootloader; \
|
||||
$(CP) $(basename $@).exe $(PROJECT_ROOT)/powerpc-rtems/c/mcp750/lib/libbsp/powerpc/mcp750/bootloader/$(ARCH); \
|
||||
cd $(PROJECT_ROOT)/powerpc-rtems/c/mcp750/lib/libbsp/powerpc/mcp750/bootloader; \
|
||||
make bootloader BINARY_LOADED=$(basename $@).exe; \
|
||||
COMPLETE_FILE_NAME=$(basename $@).exe ;\
|
||||
echo $${COMPLETE_FILE_NAME} ;\
|
||||
FILE_NAME=`basename $${COMPLETE_FILE_NAME}` ;\
|
||||
echo $${FILE_NAME} ;\
|
||||
mkdir -p $(PROJECT_ROOT)/$(RTEMS_BSP)/bin ;\
|
||||
$(CP) bootloader $(PROJECT_ROOT)/$(RTEMS_BSP)/bin/$${FILE_NAME}
|
||||
endef
|
||||
|
||||
|
||||
Reference in New Issue
Block a user