--- /dev/null
+/*
+
+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__ */