rmonmain.c
7.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/*
* ==========================================================================
* Copyright (c) 1994, Silicon Graphics, Inc. All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied
* or duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished
* rights reserved under the Copyright Laws of the United States.
* ==========================================================================
*/
/************************************************************************
Program: rmon (reality monitor) in-circuit target monitor
File: main.c
Contents: This file is the main entry point and communication functions
for HERMON execution environments.
Author: Kenneth F. Greenberg
Revision history:
94.10.21 Original
************************************************************************/
#include "rmonint.h"
#include "rcp.h"
#include <rdb.h>
#ifndef _FINALROM
#define BDBIT 0x80000000
#define PAUSE 15000
int __rmonActive = 0; /* flag so others can know if rmon is alive */
static vu32 somethingToDo;
static u32 inbuffer[MAXENCODED/4];
static u8 cmdinptr, cmdoutptr;
static int state; /* current state of the command parser */
static char * inPointer; /* current read location in input buffer */
/************************************************************************
Function: __rmonSendHeader
Args:
KKHeader * block - address of the standard protocol structure for
packet headers - or maybe more... At least, the address
of what is to be sent.
u32 blockSize - how many bytes to send
u32 type - what type of message this is (reply, exception, ...)
Type: void
Purpose: This function sends a header (or perhaps a whole packet) to
the host debugger. Normally, it is called by SendReply and
implements the entire reply transmission. (Note that it does
not look at what it is sending to see if it is ONLY a header.)
For very large (unbuffered) packets, we send the header separately
and then send the data later. Thus, this function may really
send only the header in some cases. This has been isolated to
a separate function to avoid duplication of code.
************************************************************************/
void __rmonSendHeader( KKHeader * const block, u32 blockSize, u32 type )
{
int sent;
unsigned char *cPtr = (unsigned char *)block;
/* set the version number */
block->rev = VERSION;
block->type = type;
sent = 0;
while(sent < blockSize)
sent += __osRdbSend(cPtr + sent, blockSize - sent, RDB_TYPE_GtoH_DEBUG);
}
/************************************************************************
Function: __rmonSendReply
Args:
KKHeader * block - address of the standard protocol structure for
a header and associated data.
u32 blockSize - number of bytes to send
Type: void
Purpose: This function sends a buffered reply packet to the host
debugger. It is passed the beginning of the reply buffer and
the number of bytes to transmit. It assumes the size of the block
is the number of bytes to be sent, and so fills it in for the
caller. It then invokes SendHeader to do the transmission.
Some functions (e.g., read mem) do not use this mechanism,
since they do not buffer the packet. Note also that declaring
a large packet counts as buffering, since the entire reply
packet exists at consecutive memory locations.
************************************************************************/
void __rmonSendReply( KKHeader * const block, u32 blockSize, u32 replyType )
{
unsigned char *cPtr;
int sent = 0;
block->length = blockSize;
cPtr = (unsigned char*)&blockSize;
/* send the size of the transfer */
while(sent < 4)
sent += __osRdbSend(&cPtr[sent],4-sent,RDB_TYPE_GtoH_DEBUG);
__rmonSendHeader( block, blockSize, replyType );
__rmonIOflush();
}
/************************************************************************
Function: __rmonSendData
Args:
const char * block - address of data to be sent
unsigned int blockSize - number of bytes to send
Type: void
Purpose: This function sends a block of memory from the target to the
host debugger. In all cases, it is safe to assume that SendHeader
has already been called to prepare the host to receive this info.
The primary purpose of this function is to implement the ReadMem
command, which is unbuffered.
************************************************************************/
void __rmonSendData( const char * block, unsigned int blockSize )
{
int * blockPointer = (int *) block;
unsigned int wordCount;
u32 data;
union {
char bufBytes[4];
u32 bufWord;
} buffer;
wordCount = (blockSize + 3) >> 2;
/*
Look for the easy case first - even number of words starting on
a word boundary. For the real hardware or the emulator, do a
range check on RCP memory, which must be done specially.
*/
if ( ((u32) block & 3) == 0 )
{
while ( wordCount-- )
{
if ( (u32) blockPointer >= RCPMEM_START &&
(u32) blockPointer <= RCPMEM_END )
{
__osSpRawReadIo( (u32) blockPointer++, &data );
__rmonIOputw( data );
}
else
__rmonIOputw( *blockPointer++ );
}
}
else while ( wordCount-- )
{
__rmonMemcpy( (u8 *) &buffer.bufBytes, (u8 *) blockPointer, 4 );
__rmonIOputw( buffer.bufWord );
++blockPointer;
}
__rmonIOflush();
}
/************************************************************************
Function: rmonMain
Args: none
Type: void
Purpose: This is the main loop of the rmon debugger. It is mostly a protocol
parser/dispatcher.
************************************************************************/
void rmonMain( void )
{
register int newChars;
somethingToDo = 0;
cmdinptr = cmdoutptr = 0;
__rmonInit();
__rmonActive = 1;
/*
* Loop forever acquiring commands
*/
for ( state = 0, newChars = 0, inPointer = (char *) inbuffer; ; )
{
OSMesg work;
osRecvMesg( &__rmonMQ, &work, OS_MESG_BLOCK );
somethingToDo |= (u32) work;
if ( somethingToDo & MSG_BREAKPOINT )
{
somethingToDo &= ~MSG_BREAKPOINT;
__rmonHitBreak();
}
if ( somethingToDo & MSG_SPBREAKPOINT )
{
somethingToDo &= ~MSG_SPBREAKPOINT;
__rmonHitSpBreak();
}
if ( somethingToDo & MSG_CPUFAULT )
{
somethingToDo &= ~MSG_CPUFAULT;
__rmonHitCpuFault();
}
if ( somethingToDo & MSG_THREADCREATE )
{
Debug( "rmon: Thread %d created\n", somethingToDo >> 8 );
somethingToDo &= ~(MSG_THREADCREATE | 0xffffff00);
}
if ( somethingToDo & MSG_THREADDESTROY )
{
Debug( "rmon: Thread %d destroyed\n", somethingToDo >> 8 );
somethingToDo &= ~(MSG_THREADDESTROY | 0xffffff00);
}
}
}
#endif /* #ifndef _FINALROM */