blob: 63d98ae401775aec90c2bd04e3ecc3fc9955d1f6 [file] [log] [blame]
/*
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__ */