📄 ardi.c
字号:
/* * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved. * * This software may be freely used, copied, modified, and distributed * provided that the above copyright notice is preserved in all copies of the * software. *//* * ARDI.c * Angel Remote Debug Interface * * * $Revision: 1.7 $ * $Date: 2000/01/12 17:26:37 $ * * This file is based on /plg/pisd/rdi.c, but instead of using RDP it uses * ADP messages. */#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#define uint HIDE_HPs_uint#include <signal.h>#undef uint#include "angel_endian.h"#include "ardi.h"#include "buffers.h"#include "channels.h"#include "hostchan.h"#include "host.h"#include "angel_bytesex.h"#include "dbg_cp.h"#include "adp.h"#include "hsys.h"#include "logging.h"#include "msgbuild.h"#include "rxtx.h"#include "devsw.h"#include "params.h"#ifdef COMPILING_ON_WINDOWS# define IGNORE(x) (x = x) /* must go after #includes to work on Windows */#endif#define NOT(x) (!(x))#define ADP_INITIAL_TIMEOUT_PERIOD 5static volatile int executing;static int rdi_log = 0 ; /* debugging ? *//* we need a starting point for our first buffers, this is a safe one */int Armsd_BufferSize = ADP_BUFFER_MIN_SIZE;int Armsd_LongBufSize = ADP_BUFFER_MIN_SIZE;#ifdef WIN32 extern int interrupted; extern int swiprocessing;#endifstatic char dummycline = 0;char *ardi_commandline = &dummycline ; /* exported in ardi.h */extern unsigned int heartbeat_enabled;static unsigned char *cpwords[16];typedef struct stoppedProcListElement { struct stoppedProcListElement *next; angel_RDI_TargetStoppedProc *fn; void *arg;} stoppedProcListElement;static stoppedProcListElement *stopped_proc_list=NULL;const struct Dbg_HostosInterface *angel_hostif;static hsys_state *hstate;static void angel_DebugPrint(const char *format, ...){ va_list ap; va_start(ap, format); angel_hostif->dbgprint(angel_hostif->dbgarg, format, ap); va_end(ap);}#ifdef RDI_VERBOSE#define TracePrint(s) \ if (rdi_log & 2) angel_DebugPrint("\n"); \ if (rdi_log & 1) angel_DebugPrint s#else#define TracePrint(s)#endiftypedef struct receive_dbgmsg_state { volatile int received; Packet *packet;} receive_dbgmsg_state;static receive_dbgmsg_state dbgmsg_state;static void receive_debug_packet(Packet *packet, void *stateptr){ receive_dbgmsg_state *state = stateptr; state->packet = packet; state->received = 1;}static int register_debug_message_handler(void){ int err; dbgmsg_state.received = 0; err = Adp_ChannelRegisterRead(CI_HADP, receive_debug_packet, &dbgmsg_state);#ifdef DEBUG if (err!=adp_ok) angel_DebugPrint("register_debug_message_handler failed %i\n", err);#endif return err;}static int wait_for_debug_message(int *rcode, int *debugID, int *OSinfo1, int *OSinfo2, int *status, Packet **packet){ unsigned int reason;#ifdef DEBUG angel_DebugPrint("wait_for_debug_message waiting for %X\n", *rcode);#endif for ( ; dbgmsg_state.received == 0 ; ) Adp_AsynchronousProcessing(async_block_on_read);#ifdef DEBUG angel_DebugPrint("wait_for_debug_message got packet\n");#endif *packet = dbgmsg_state.packet; Adp_ChannelRegisterRead(CI_HADP, NULL, NULL); /* * TODO: * If ADP_Unrecognised return error. * If ADP_Acknowledge - handle appropriately. * If expected message read arguments and return RDIError_NoError. * Note: if RDIError occurs then the data values returned are junk */ unpack_message(BUFFERDATA((*packet)->pk_buffer), "%w%w%w%w%w", &reason, debugID, OSinfo1, OSinfo2, status); if ((reason&0xffffff) == ADP_HADPUnrecognised) return RDIError_UnimplementedMessage; if (reason != (unsigned ) *rcode) { if((reason&0xffffff) == ADP_HADPUnrecognised) return RDIError_UnimplementedMessage; else { angel_DebugPrint("ARDI ERROR: Expected reasoncode %x got reasoncode %x.\n", *rcode, reason); return RDIError_Error; } } else return RDIError_NoError; return RDIError_Error; /* stop a pesky ANSI compiler warning */}/* * Handler and registration for logging messages from target */static void TargetLogCallback( Packet *packet, void *state ){ p_Buffer reply = BUFFERDATA(packet->pk_buffer); unsigned int len = packet->pk_length; IGNORE(state); angel_hostif->write(angel_hostif->hostosarg, (char *)reply, len - CHAN_HEADER_SIZE); DevSW_FreePacket(packet); packet = DevSW_AllocatePacket(4); /* better not ask for 0 */ /* the reply is the ACK - any contents are ignored */ if (packet != NULL) Adp_ChannelWrite( CI_TLOG, packet );}static void TargetLogInit( void ){ AdpErrs err = Adp_ChannelRegisterRead( CI_TLOG, TargetLogCallback, NULL );#ifdef DEBUG if (err != adp_ok) angel_DebugPrint("CI_TLOG RegisterRead failed %d\n", err);#else IGNORE(err);#endif}/*----------------------------------------------------------------------*//*----angel_RDI_open-----------------------------------------------------*//*----------------------------------------------------------------------*/typedef struct NegotiateState { bool negotiate_resp; bool negotiate_ack; bool link_check_resp; ParameterConfig *accepted_config;} NegotiateState;static void receive_negotiate(Packet *packet, void *stateptr){ unsigned reason, debugID, OSinfo1, OSinfo2, status; NegotiateState *n_state = (NegotiateState *)stateptr; p_Buffer reply = BUFFERDATA(packet->pk_buffer); unpack_message( reply, "%w%w%w%w", &reason, &debugID, &OSinfo1, &OSinfo2 ); reply += ADP_DEFAULT_HEADER_SIZE;#ifdef DEBUG angel_DebugPrint( "receive_negotiate: reason %x\n", reason );#endif switch ( reason ) { case ADP_ParamNegotiate | TtoH: { n_state->negotiate_resp = TRUE; status = GET32LE( reply ); reply += sizeof(word);#ifdef DEBUG angel_DebugPrint( "ParamNegotiate status %u\n", status );#endif if ( status == RDIError_NoError ) { if ( Angel_ReadParamConfigMessage( reply, n_state->accepted_config ) ) n_state->negotiate_ack = TRUE; } break; } case ADP_LinkCheck | TtoH: {#ifdef DEBUG angel_DebugPrint( "PONG!\n" );#endif n_state->link_check_resp = TRUE; break; } default: {#ifdef DEBUG angel_DebugPrint( "Unexpected!\n" );#endif break; } } DevSW_FreePacket( packet );}# include <sys/types.h>#ifdef __unix# include <sys/time.h>#else# include <time.h>#endif/* * convert a config into a single-valued options list */static ParameterOptions *config_to_options( const ParameterConfig *config ){ unsigned int num_params; size_t size; ParameterOptions *base_p; num_params = config->num_parameters; size = sizeof(ParameterOptions) + num_params*(sizeof(ParameterList) + sizeof(unsigned int)); base_p = malloc( size ); if ( base_p != NULL ) { unsigned int u; ParameterList *list_p = (ParameterList *)((char *)base_p + sizeof(ParameterOptions)); unsigned int *option_p = (unsigned int *)(list_p + num_params); base_p->num_param_lists = num_params; base_p->param_list = list_p; for ( u = 0; u < num_params; ++u ) { option_p[u] = config->param[u].value; list_p[u].type = config->param[u].type; list_p[u].num_options = 1; list_p[u].option = &option_p[u]; } } return base_p;}static AdpErrs negotiate_params( const ParameterOptions *user_options ){ Packet *packet; unsigned int count; static Parameter params[AP_NUM_PARAMS]; static ParameterConfig accepted_config = { AP_NUM_PARAMS, params }; time_t t; static volatile NegotiateState n_state; n_state.negotiate_resp = FALSE; n_state.negotiate_ack = FALSE; n_state.link_check_resp = FALSE; n_state.accepted_config = &accepted_config; #ifdef DEBUG angel_DebugPrint( "negotiate_params\n" );#endif Adp_ChannelRegisterRead( CI_HBOOT, receive_negotiate, (void *)&n_state ); packet = (Packet *)DevSW_AllocatePacket(Armsd_BufferSize); count = msgbuild( BUFFERDATA(packet->pk_buffer), "%w%w%w%w", ADP_ParamNegotiate | HtoT, 0, ADP_HandleUnknown, ADP_HandleUnknown ); count += Angel_BuildParamOptionsMessage( BUFFERDATA(packet->pk_buffer) + count, user_options ); packet->pk_length = count; Adp_ChannelWriteAsync( CI_HBOOT, packet );#ifdef DEBUG angel_DebugPrint( "sent negotiate packet\n" );#endif t=time(NULL); do { Adp_AsynchronousProcessing(async_block_on_nothing); if ((time(NULL)-t) > ADP_INITIAL_TIMEOUT_PERIOD) { return adp_timeout_on_open; } } while ( ! n_state.negotiate_resp ); if ( n_state.negotiate_ack ) { /* select accepted config */ Adp_Ioctl( DC_SET_PARAMS, (void *)n_state.accepted_config ); /* * 960430 KWelton * * There is a race in the renegotiation protocol: the * target has to have had time to load new config before * we send the link check packet - insert a deliberate * pause (100ms) to give the target some time */ Adp_delay(100000); /* do link check */ msgsend( CI_HBOOT, "%w%w%w%w", ADP_LinkCheck | HtoT, 0, ADP_HandleUnknown, ADP_HandleUnknown );#ifdef DEBUG angel_DebugPrint("sent link check\n");#endif do { Adp_AsynchronousProcessing(async_block_on_read); } while ( ! n_state.link_check_resp ); Adp_initSeq(); } return adp_ok;}static int late_booted = FALSE;static bool ardi_handler_installed = FALSE;#ifdef __unixstatic struct sigaction old_action;#elsestatic void (*old_handler)();#endifstatic bool boot_interrupted = FALSE;static volatile bool interrupt_request = FALSE;static volatile bool stop_request = FALSE;static void ardi_sigint_handler(int sig) {#ifdef DEBUG if (sig != SIGINT) angel_DebugPrint("Expecting SIGINT got %d.\n", sig);#else IGNORE(sig);#endif boot_interrupted = TRUE; interrupt_request = TRUE;#ifndef __unix
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -