608 lines
12 KiB
C
608 lines
12 KiB
C
/*
|
|
|
|
Interface from UDI calls in 32-bit mode to go32 in 16-bit mode.
|
|
Communication is done through a single interrupt vector, which passes
|
|
data through two linear buffers.
|
|
|
|
Call:
|
|
AH = 0xfe
|
|
AL = UDI function number
|
|
ECX = IN length
|
|
ESI = pointer to IN buffer
|
|
EDI = pointer to OUT buffer
|
|
|
|
Return:
|
|
EAX = return value of UDI function
|
|
|
|
Vector:
|
|
0x21
|
|
|
|
*/
|
|
#ifdef __GO32__
|
|
|
|
#include <stdlib.h>
|
|
#include "udiproc.h"
|
|
#include "udisoc.h"
|
|
|
|
char dfe_errmsg[500];
|
|
|
|
static char in_buffer[4096];
|
|
static char out_buffer[4096];
|
|
static char *in_ptr;
|
|
static char *out_ptr;
|
|
|
|
#define IN_INIT() in_ptr = in_buffer
|
|
#define IN_VAL(t,v) *((t *)in_ptr)++ = v
|
|
#define IN_DATA(ptr, cnt) memcpy(in_ptr, ptr, cnt), in_ptr += cnt
|
|
|
|
#define OUT_INIT() out_ptr = out_buffer
|
|
#define OUT_VAL(t) (*((t *)out_ptr)++)
|
|
#define OUT_DATA(ptr, cnt) memcpy(ptr, out_ptr, cnt), out_ptr += cnt
|
|
|
|
static int DO_CALL(int function)
|
|
{
|
|
asm("pushl %esi");
|
|
asm("pushl %edi");
|
|
asm("movb %0, %%al" : : "g" (function));
|
|
asm("movl _in_ptr, %ecx");
|
|
asm("movl $_in_buffer, %esi");
|
|
asm("subl %esi, %ecx");
|
|
asm("movl $_out_buffer, %edi");
|
|
asm("movb $0xfe, %ah");
|
|
asm("int $0x21");
|
|
asm("popl %edi");
|
|
asm("popl %esi");
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
#ifdef TEST_UDI
|
|
int main()
|
|
{
|
|
int r;
|
|
long p2;
|
|
short p1;
|
|
IN_INIT();
|
|
IN_VAL(long, 11111111);
|
|
IN_VAL(short, 2222);
|
|
IN_DATA("Hello, world\n", 17);
|
|
|
|
r = DO_CALL(42);
|
|
|
|
OUT_INIT();
|
|
p1 = OUT_VAL(short);
|
|
p2 = OUT_VAL(long);
|
|
printf("main: p1=%d p2=%d rv=%d\n", p1, p2, r);
|
|
return r;
|
|
}
|
|
#endif
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
unsupported(char *s)
|
|
{
|
|
printf("unsupported UDI host call %s\n", s);
|
|
abort();
|
|
}
|
|
|
|
UDIError UDIConnect (
|
|
char *Configuration, /* In */
|
|
UDISessionId *Session /* Out */
|
|
)
|
|
{
|
|
int r;
|
|
out_buffer[0] = 0; /* DJ - test */
|
|
IN_INIT();
|
|
IN_DATA(Configuration, strlen(Configuration)+1);
|
|
|
|
r = DO_CALL(UDIConnect_c);
|
|
|
|
OUT_INIT();
|
|
*Session = OUT_VAL(UDISessionId);
|
|
return r;
|
|
}
|
|
|
|
UDIError UDIDisconnect (
|
|
UDISessionId Session, /* In */
|
|
UDIBool Terminate /* In */
|
|
)
|
|
{
|
|
int r;
|
|
IN_INIT();
|
|
IN_VAL(UDISessionId, Session);
|
|
IN_VAL(UDIBool, Terminate);
|
|
|
|
return DO_CALL(UDIDisconnect_c);
|
|
}
|
|
|
|
UDIError UDISetCurrentConnection (
|
|
UDISessionId Session /* In */
|
|
)
|
|
{
|
|
IN_INIT();
|
|
IN_VAL(UDISessionId, Session);
|
|
|
|
return DO_CALL(UDISetCurrentConnection_c);
|
|
}
|
|
|
|
UDIError UDICapabilities (
|
|
UDIUInt32 *TIPId, /* Out */
|
|
UDIUInt32 *TargetId, /* Out */
|
|
UDIUInt32 DFEId, /* In */
|
|
UDIUInt32 DFE, /* In */
|
|
UDIUInt32 *TIP, /* Out */
|
|
UDIUInt32 *DFEIPCId, /* Out */
|
|
UDIUInt32 *TIPIPCId, /* Out */
|
|
char *TIPString /* Out */
|
|
)
|
|
{
|
|
int r;
|
|
IN_INIT();
|
|
IN_VAL(UDIUInt32, DFEId);
|
|
IN_VAL(UDIUInt32, DFE);
|
|
r = DO_CALL(UDICapabilities_c);
|
|
OUT_INIT();
|
|
*TIPId = OUT_VAL(UDIUInt32);
|
|
*TargetId = OUT_VAL(UDIUInt32);
|
|
*TIP = OUT_VAL(UDIUInt32);
|
|
*DFEIPCId = OUT_VAL(UDIUInt32);
|
|
*TIPIPCId = OUT_VAL(UDIUInt32);
|
|
strcpy(TIPString, out_ptr);
|
|
return r;
|
|
}
|
|
|
|
UDIError UDIEnumerateTIPs (
|
|
UDIInt (*UDIETCallback) /* In */
|
|
( char *Configuration ) /* In to callback() */
|
|
)
|
|
{
|
|
UDIETCallback("montip.exe");
|
|
}
|
|
|
|
UDIError UDIGetErrorMsg (
|
|
UDIError ErrorCode, /* In */
|
|
UDISizeT MsgSize, /* In */
|
|
char *Msg, /* Out */
|
|
UDISizeT *CountDone /* Out */
|
|
)
|
|
{
|
|
int r;
|
|
if (MsgSize > 4000)
|
|
MsgSize = 4000;
|
|
IN_INIT();
|
|
IN_VAL(UDIError, ErrorCode);
|
|
IN_VAL(UDISizeT, MsgSize);
|
|
|
|
r = DO_CALL(UDIGetErrorMsg_c);
|
|
|
|
OUT_INIT();
|
|
*CountDone = OUT_VAL(UDISizeT);
|
|
OUT_DATA(Msg, *CountDone);
|
|
return r;
|
|
}
|
|
|
|
UDIError UDIGetTargetConfig (
|
|
UDIMemoryRange KnownMemory[], /* Out */
|
|
UDIInt *NumberOfRanges, /* In/Out */
|
|
UDIUInt32 ChipVersions[], /* Out */
|
|
UDIInt *NumberOfChips /* In/Out */
|
|
)
|
|
{
|
|
int r, i;
|
|
int nr = *NumberOfRanges;
|
|
int nc = *NumberOfChips;
|
|
IN_INIT();
|
|
IN_VAL(UDIInt, *NumberOfRanges);
|
|
IN_VAL(UDIInt, *NumberOfChips);
|
|
r = DO_CALL(UDIGetTargetConfig_c);
|
|
if (r == UDIErrorIncomplete)
|
|
return r;
|
|
OUT_INIT();
|
|
*NumberOfRanges = OUT_VAL(UDIInt);
|
|
*NumberOfChips = OUT_VAL(UDIInt);
|
|
for (i=0; i<nr; i++)
|
|
{
|
|
KnownMemory[i].Space = OUT_VAL(short);
|
|
KnownMemory[i].Offset = OUT_VAL(CPUOffset);
|
|
KnownMemory[i].Size = OUT_VAL(CPUSizeT);
|
|
}
|
|
for (i=0; i<nc; i++)
|
|
{
|
|
ChipVersions[i] = OUT_VAL(UDIUInt32);
|
|
}
|
|
return r;
|
|
}
|
|
|
|
UDIError UDICreateProcess (
|
|
UDIPId *PId /* Out */
|
|
)
|
|
{
|
|
int r = DO_CALL(UDICreateProcess_c);
|
|
|
|
OUT_INIT();
|
|
*PId = OUT_VAL(UDIPId);
|
|
|
|
return r;
|
|
}
|
|
|
|
UDIError UDISetCurrentProcess (
|
|
UDIPId PId /* In */
|
|
)
|
|
{
|
|
IN_INIT();
|
|
IN_VAL(UDIPId, PId);
|
|
|
|
return DO_CALL(UDISetCurrentProcess_c);
|
|
}
|
|
|
|
UDIError UDIDestroyProcess (
|
|
UDIPId PId /* In */
|
|
)
|
|
{
|
|
IN_INIT();
|
|
IN_VAL(UDIPId, PId);
|
|
|
|
return DO_CALL(UDIDestroyProcess_c);
|
|
}
|
|
|
|
UDIError UDIInitializeProcess (
|
|
UDIMemoryRange ProcessMemory[], /* In */
|
|
UDIInt NumberOfRanges, /* In */
|
|
UDIResource EntryPoint, /* In */
|
|
CPUSizeT StackSizes[], /* In */
|
|
UDIInt NumberOfStacks, /* In */
|
|
char *ArgString /* In */
|
|
)
|
|
{
|
|
int i, r;
|
|
IN_INIT();
|
|
IN_VAL(UDIInt, NumberOfRanges);
|
|
for (i=0; i<NumberOfRanges; i++)
|
|
{
|
|
IN_VAL(short, ProcessMemory[i].Space);
|
|
IN_VAL(CPUOffset, ProcessMemory[i].Offset);
|
|
IN_VAL(CPUSizeT, ProcessMemory[i].Size);
|
|
}
|
|
IN_VAL(short, EntryPoint.Space);
|
|
IN_VAL(CPUOffset, EntryPoint.Offset);
|
|
IN_VAL(UDIInt, NumberOfStacks);
|
|
for (i=0; i<NumberOfStacks; i++)
|
|
IN_VAL(CPUSizeT, StackSizes[i]);
|
|
IN_DATA(ArgString, strlen(ArgString)+1);
|
|
|
|
return DO_CALL(UDIInitializeProcess_c);
|
|
}
|
|
|
|
UDIError UDIRead (
|
|
UDIResource From, /* In */
|
|
UDIHostMemPtr To, /* Out */
|
|
UDICount Count, /* In */
|
|
UDISizeT Size, /* In */
|
|
UDICount *CountDone, /* Out */
|
|
UDIBool HostEndian /* In */
|
|
)
|
|
{
|
|
int cleft = Count, cthis, dthis;
|
|
int cdone = 0, r, bsize=2048/Size;
|
|
|
|
while (cleft)
|
|
{
|
|
cthis = (cleft<bsize) ? cleft : bsize;
|
|
IN_INIT();
|
|
IN_VAL(short, From.Space);
|
|
IN_VAL(CPUOffset, From.Offset);
|
|
IN_VAL(UDICount, cthis);
|
|
IN_VAL(UDISizeT, Size);
|
|
IN_VAL(UDIBool, HostEndian);
|
|
|
|
r = DO_CALL(UDIRead_c);
|
|
|
|
OUT_INIT();
|
|
dthis = OUT_VAL(UDICount);
|
|
OUT_DATA(To, dthis*Size);
|
|
cdone += dthis;
|
|
To += dthis*Size;
|
|
|
|
if (r != UDINoError)
|
|
{
|
|
*CountDone = cdone;
|
|
return r;
|
|
}
|
|
cleft -= cthis;
|
|
}
|
|
*CountDone = cdone;
|
|
return UDINoError;
|
|
}
|
|
|
|
UDIError UDIWrite (
|
|
UDIHostMemPtr From, /* In */
|
|
UDIResource To, /* In */
|
|
UDICount Count, /* In */
|
|
UDISizeT Size, /* In */
|
|
UDICount *CountDone, /* Out */
|
|
UDIBool HostEndian /* In */
|
|
)
|
|
{
|
|
int cleft = Count, cthis, dthis;
|
|
int cdone = 0, r, bsize=2048/Size;
|
|
|
|
while (cleft)
|
|
{
|
|
cthis = (cleft<bsize) ? cleft : bsize;
|
|
IN_INIT();
|
|
IN_VAL(short, To.Space);
|
|
IN_VAL(CPUOffset, To.Offset);
|
|
IN_VAL(UDICount, cthis);
|
|
IN_VAL(UDISizeT, Size);
|
|
IN_VAL(UDIBool, HostEndian);
|
|
IN_DATA(From, cthis*Size);
|
|
From += cthis*Size;
|
|
|
|
r = DO_CALL(UDIWrite_c);
|
|
|
|
OUT_INIT();
|
|
cdone += OUT_VAL(UDICount);
|
|
|
|
if (r != UDINoError)
|
|
{
|
|
*CountDone = cdone;
|
|
return r;
|
|
}
|
|
cleft -= cthis;
|
|
}
|
|
*CountDone = cdone;
|
|
return UDINoError;
|
|
}
|
|
|
|
UDIError UDICopy (
|
|
UDIResource From, /* In */
|
|
UDIResource To, /* In */
|
|
UDICount Count, /* In */
|
|
UDISizeT Size, /* In */
|
|
UDICount *CountDone, /* Out */
|
|
UDIBool Direction /* In */
|
|
)
|
|
{
|
|
int r;
|
|
IN_INIT();
|
|
IN_VAL(short, From.Space);
|
|
IN_VAL(CPUOffset, From.Offset);
|
|
IN_VAL(short, To.Space);
|
|
IN_VAL(CPUOffset, To.Offset);
|
|
IN_VAL(UDICount, Count);
|
|
IN_VAL(UDISizeT, Size);
|
|
IN_VAL(UDIBool, Direction);
|
|
|
|
r = DO_CALL(UDICopy_c);
|
|
|
|
OUT_INIT();
|
|
*CountDone = OUT_VAL(UDICount);
|
|
|
|
return r;
|
|
}
|
|
|
|
UDIError UDIExecute (
|
|
void
|
|
)
|
|
{
|
|
return DO_CALL(UDIExecute_c);
|
|
}
|
|
|
|
UDIError UDIStep (
|
|
UDIUInt32 Steps, /* In */
|
|
UDIStepType StepType, /* In */
|
|
UDIRange Range /* In */
|
|
)
|
|
{
|
|
IN_INIT();
|
|
IN_VAL(UDIUInt32, Steps);
|
|
IN_VAL(UDIStepType, StepType);
|
|
IN_VAL(UDIRange, Range);
|
|
|
|
return DO_CALL(UDIStep_c);
|
|
}
|
|
|
|
UDIVoid UDIStop (
|
|
void
|
|
)
|
|
{
|
|
DO_CALL(UDIStop_c);
|
|
}
|
|
|
|
UDIError UDIWait (
|
|
UDIInt32 MaxTime, /* In */
|
|
UDIPId *PId, /* Out */
|
|
UDIUInt32 *StopReason /* Out */
|
|
)
|
|
{
|
|
int r;
|
|
IN_INIT();
|
|
IN_VAL(UDIInt32, MaxTime);
|
|
r = DO_CALL(UDIWait_c);
|
|
OUT_INIT();
|
|
*PId = OUT_VAL(UDIPId);
|
|
*StopReason = OUT_VAL(UDIUInt32);
|
|
return r;
|
|
}
|
|
|
|
UDIError UDISetBreakpoint (
|
|
UDIResource Addr, /* In */
|
|
UDIInt32 PassCount, /* In */
|
|
UDIBreakType Type, /* In */
|
|
UDIBreakId *BreakId /* Out */
|
|
)
|
|
{
|
|
int r;
|
|
IN_INIT();
|
|
IN_VAL(short, Addr.Space);
|
|
IN_VAL(CPUOffset, Addr.Offset);
|
|
IN_VAL(UDIInt32, PassCount);
|
|
IN_VAL(UDIBreakType, Type);
|
|
|
|
r = DO_CALL(UDISetBreakpoint_c);
|
|
|
|
OUT_INIT();
|
|
*BreakId = OUT_VAL(UDIBreakId);
|
|
return r;
|
|
}
|
|
|
|
UDIError UDIQueryBreakpoint (
|
|
UDIBreakId BreakId, /* In */
|
|
UDIResource *Addr, /* Out */
|
|
UDIInt32 *PassCount, /* Out */
|
|
UDIBreakType *Type, /* Out */
|
|
UDIInt32 *CurrentCount /* Out */
|
|
)
|
|
{
|
|
int r;
|
|
IN_INIT();
|
|
IN_VAL(UDIBreakId, BreakId);
|
|
|
|
r = DO_CALL(UDIQueryBreakpoint_c);
|
|
|
|
OUT_INIT();
|
|
Addr->Space = OUT_VAL(short);
|
|
Addr->Offset = OUT_VAL(CPUOffset);
|
|
*PassCount = OUT_VAL(UDIInt32);
|
|
*Type = OUT_VAL(UDIBreakType);
|
|
*CurrentCount = OUT_VAL(UDIInt32);
|
|
|
|
return r;
|
|
}
|
|
|
|
UDIError UDIClearBreakpoint (
|
|
UDIBreakId BreakId /* In */
|
|
)
|
|
{
|
|
IN_INIT();
|
|
IN_VAL(UDIBreakId, BreakId);
|
|
|
|
return DO_CALL(UDIClearBreakpoint_c);
|
|
}
|
|
|
|
UDIError UDIGetStdout (
|
|
UDIHostMemPtr Buf, /* Out */
|
|
UDISizeT BufSize, /* In */
|
|
UDISizeT *CountDone /* Out */
|
|
)
|
|
{
|
|
int r;
|
|
IN_INIT();
|
|
if (BufSize > 4000)
|
|
BufSize = 4000;
|
|
IN_VAL(UDISizeT,BufSize);
|
|
r = DO_CALL(UDIGetStdout_c);
|
|
OUT_INIT();
|
|
*CountDone = OUT_VAL(UDISizeT);
|
|
if (*CountDone <= BufSize)
|
|
OUT_DATA(Buf, *CountDone);
|
|
return r;
|
|
}
|
|
|
|
UDIError UDIGetStderr (
|
|
UDIHostMemPtr Buf, /* Out */
|
|
UDISizeT BufSize, /* In */
|
|
UDISizeT *CountDone /* Out */
|
|
)
|
|
{
|
|
int r;
|
|
IN_INIT();
|
|
if (BufSize > 4000)
|
|
BufSize = 4000;
|
|
IN_VAL(UDISizeT,BufSize);
|
|
r = DO_CALL(UDIGetStderr_c);
|
|
OUT_INIT();
|
|
*CountDone = OUT_VAL(UDISizeT);
|
|
OUT_DATA(Buf, *CountDone);
|
|
return r;
|
|
}
|
|
|
|
UDIError UDIPutStdin (
|
|
UDIHostMemPtr Buf, /* In */
|
|
UDISizeT Count, /* In */
|
|
UDISizeT *CountDone /* Out */
|
|
)
|
|
{
|
|
int r;
|
|
IN_INIT();
|
|
if (Count > 4000)
|
|
Count = 4000;
|
|
IN_VAL(UDISizeT,Count);
|
|
IN_DATA(Buf, Count);
|
|
r = DO_CALL(UDIPutStdin_c);
|
|
OUT_INIT();
|
|
*CountDone = OUT_VAL(UDISizeT);
|
|
return r;
|
|
}
|
|
|
|
UDIError UDIStdinMode (
|
|
UDIMode *Mode /* Out */
|
|
)
|
|
{
|
|
int r;
|
|
IN_INIT();
|
|
r = DO_CALL(UDIStdinMode_c);
|
|
OUT_INIT();
|
|
*Mode = OUT_VAL(UDIMode);
|
|
return r;
|
|
}
|
|
|
|
UDIError UDIPutTrans (
|
|
UDIHostMemPtr Buf, /* In */
|
|
UDISizeT Count, /* In */
|
|
UDISizeT *CountDone /* Out */
|
|
)
|
|
{
|
|
int r;
|
|
IN_INIT();
|
|
if (Count > 4000)
|
|
Count = 4000;
|
|
IN_VAL(UDISizeT,Count);
|
|
IN_DATA(Buf, Count);
|
|
r = DO_CALL(UDIPutTrans_c);
|
|
OUT_INIT();
|
|
*CountDone = OUT_VAL(UDISizeT);
|
|
return r;
|
|
}
|
|
|
|
UDIError UDIGetTrans (
|
|
UDIHostMemPtr Buf, /* Out */
|
|
UDISizeT BufSize, /* In */
|
|
UDISizeT *CountDone /* Out */
|
|
)
|
|
{
|
|
int r;
|
|
IN_INIT();
|
|
if (BufSize > 4000)
|
|
BufSize = 4000;
|
|
IN_VAL(UDISizeT,BufSize);
|
|
r = DO_CALL(UDIGetTrans_c);
|
|
OUT_INIT();
|
|
*CountDone = OUT_VAL(UDISizeT);
|
|
OUT_DATA(Buf, *CountDone);
|
|
return r;
|
|
}
|
|
|
|
UDIError UDITransMode (
|
|
UDIMode *Mode /* Out */
|
|
)
|
|
{
|
|
int r;
|
|
IN_INIT();
|
|
r = DO_CALL(UDITransMode_c);
|
|
OUT_INIT();
|
|
*Mode = OUT_VAL(UDIMode);
|
|
return r;
|
|
}
|
|
|
|
#define DFEIPCIdCompany 0x0001 /* Company ID AMD */
|
|
#define DFEIPCIdProduct 0x1 /* Product ID 0 */
|
|
#define DFEIPCIdVersion 0x125 /* 1.2.5 */
|
|
|
|
unsigned UDIGetDFEIPCId ()
|
|
{
|
|
return((((UDIUInt32)DFEIPCIdCompany) << 16) |(DFEIPCIdProduct << 12) | DFEIPCIdVersion);
|
|
}
|
|
|
|
#endif /* __GO32__ */
|