kdebugserver.c 2.35 KB
#include "os.h"
#include "os_internal.h"
#include "rdb.h"
#include "R4300.h"

#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif

OSThread      __osThreadSave;
extern OSThread      *__osRunningThread;

#ifndef _FINALROM

static u8     buffer[12];
static u32    numChars = 0;

extern u32    __osRdb_IP6_Empty;

static u32 string_to_u32(u8 *s)
{
	u32 k;

	k = (((u32) s[0]) & 0xff) << 24;
	k |= (((u32) s[1]) & 0xff) << 16;
	k |= (((u32) s[2]) & 0xff) << 8;
	k |= ((u32) s[3]) & 0xff;
	return k;
}

static void send_packet(u8 *s, u32 n)
{	/* 1 <= n <= 3 */
	rdbPacket packet;
	u32 i;

	packet.type = RDB_TYPE_GtoH_KDEBUG;
	packet.length = n;
	for (i = 0; i < n; i++)
		packet.buf[i] = s[i];
	/* send out packet */
	*((vu32 *) RDB_BASE_REG) = *((vu32 *) &packet);
}

static void clear_IP6(void)
{
    while ((__osGetCause() & CAUSE_IP6) == 0);
    *((vu32 *) RDB_READ_INTR_REG) = 0;
    while ((__osGetCause() & CAUSE_IP6) != 0);
}

/*
 * This send takes place within the exception handler, so you can't use the 
 * regular osSendRdb(). If exceptasm is waiting for an IP6, __osRdb_IP6_Empty
 * will be FALSE. In this case, clear the IP6, send your data clearing all but
 * the last IP6, which you want to leave around to replace the one you cleared
 * at the start. If osRdb_IP6_Empty is TRUE, don't block for an IP6 at the start,
 * go ahead sending your data, clearing each one, and also clear the last IP6
 */
static void send(u8 *s, u32 n)
{
    u32   ct, i = 0;
    u32   getLastIP6;
    
    if (!__osRdb_IP6_Empty) 
    {
	clear_IP6();
	getLastIP6 = FALSE;
    }
    else
	getLastIP6 = TRUE;

    while(n > 0)
    {
	ct = MIN(n,3);
	send_packet(&s[i], ct);
	n -= ct;
	i += ct;
	if (n > 0) /* won't clear the last IP6 */
	    clear_IP6();
    }
    if(getLastIP6) /* should you get the last IP6 ? */
	clear_IP6();

}


void kdebugserver(rdbPacket packet)
{
    u32  i,length;
    u8   *addr;

    for (i = 0; i < 3; i++)
	buffer[numChars++] = packet.buf[i];

    if(buffer[0] == DEBUG_COMMAND_REGISTER)
    {
	/* send((u8*)&(__osThreadSave.context), sizeof(__OSThreadContext)); */
	send((u8*)&(__osRunningThread->context), sizeof(__OSThreadContext));
	numChars = 0;
    }

    else if((numChars >= 9) && buffer[0] == DEBUG_COMMAND_MEMORY)
    {
	addr = (u8*)string_to_u32(&buffer[1]);
	length = string_to_u32(&buffer[5]);
	send(addr,length);
	numChars = 0;
    }
}

#endif /*#ifndef _FINALROM */