diff options
Diffstat (limited to 'gdb/29k-share/udi/udip2soc.c')
-rw-r--r-- | gdb/29k-share/udi/udip2soc.c | 1250 |
1 files changed, 1250 insertions, 0 deletions
diff --git a/gdb/29k-share/udi/udip2soc.c b/gdb/29k-share/udi/udip2soc.c new file mode 100644 index 00000000000..969e8502eb4 --- /dev/null +++ b/gdb/29k-share/udi/udip2soc.c @@ -0,0 +1,1250 @@ +/* Copyright 1993 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +static char udip2soc_c[]="@(#)udip2soc.c 2.11 Daniel Mann"; +static char udip2soc_c_AMD[]="@(#)udip2soc.c 2.8, AMD"; +/* +* This module converts UDI Procedural calls into +* UDI socket messages for UNIX. +* It is used by DFE client processes +********************************************************************** HISTORY +*/ +/* This is all unneeded on DOS machines. */ +#ifndef __GO32__ + +#include <stdio.h> +#include <string.h> + +/* Before sys/file.h for Unixware. */ +#include <sys/types.h> + +#include <sys/file.h> + +/* This used to say sys/fcntl.h, but the only systems I know of that + require that are old (pre-4.3, at least) BSD systems, which we + probably don't need to worry about. */ +#include <fcntl.h> + +#include <sys/wait.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <signal.h> +#include <sys/errno.h> +#include "udiproc.h" +#include "udisoc.h" + +extern int errno; +extern int sys_nerr; +extern int udr_errno; +extern char* getenv(); + +/* local type decs. and macro defs. not in a .h file ************* MACRO/TYPE +*/ +#define version_c 0x121 /* DFE-IPC version id */ +#define TRUE -1 +#define FALSE 0 +#define PORT_NUM 7000 +#define MAX_SESSIONS 5 /* maximum DFE-TIP connections */ +#define SOC_BUF_SIZE 4* 1024 /* size of socket comms buffer */ +#define SBUF_SIZE 500 /* size of string buffer */ +#define ERRMSG_SIZE 500 /* size of error message buffer */ + +typedef struct connection_str /* record of connect session */ +{ + int in_use; + char connect_id[20]; /* connection identifier */ + char domain_string[20]; /* dommaing for conection */ + char tip_string[30]; /* TIP host name for AF_INET */ + char tip_exe[80]; /* TIP exe name */ + int dfe_sd; /* associated DFE socket */ + int tip_pid; /* pid of TIP process */ + struct sockaddr_in dfe_sockaddr; + struct sockaddr_in tip_sockaddr_in; + struct sockaddr tip_sockaddr; +} connection_t; + +typedef struct session_str +{ + int in_use; + connection_t* soc_con_p; /* associated connection */ + UDISessionId tip_id; /* associated TIP session ID */ +} session_t; + +/* global dec/defs. which are not in a .h file ************* EXPORT DEC/DEFS +*/ +UDIError dfe_errno; +char dfe_errmsg[ERRMSG_SIZE];/* error string */ + +/* local dec/defs. which are not in a .h file *************** LOCAL DEC/DEFS +*/ +LOCAL connection_t soc_con[MAX_SESSIONS]; +LOCAL session_t session[MAX_SESSIONS]; +LOCAL UDR udr; +LOCAL UDR* udrs = &udr; /* UDR for current session */ +LOCAL int current; /* int-id for current session */ +LOCAL char sbuf[SBUF_SIZE]; /* String handler buffer */ +LOCAL char config_file[80]; /* path/name for config file */ + +/***************************************************************** UDI_CONNECT +* Establish a new FDE to TIP conection. The file "./udi_soc" or +* "/etc/udi_soc" may be examined to obtain the conection information +* if the "Config" parameter is not a completd "line entry". +* +* NOTE: the Session string must not start whith white-space characters. +* Format of string is: +* <session> <domain> <soc_name|host_name> <tip_exe|port> <pass to UDIconnect> +* soc2cayman AF_INET cayman 7000 <not supported> +* soc2tip AF_UNIX astring tip.exe ... +*/ +UDIError +UDIConnect(Config, Session) + char *Config; /* in -- identification string */ + UDISessionId *Session; /* out -- session ID */ +{ + UDIInt32 service_id = UDIConnect_c; + int domain; + int cnt=0; + int rcnt, pos, params_pos=0; + char *tip_main_string; + char *env_p; + struct hostent *tip_info_p; + FILE *fd; +#if 0 + FILE *f_p; +#endif + UDIUInt32 TIPIPCId; + UDIUInt32 DFEIPCId; + +#if 0 /* This is crap. It assumes that udi_soc is executable! */ + sprintf(sbuf, "which udi_soc"); + f_p = popen(sbuf, "r"); + if(f_p) + { while( (sbuf[cnt++]=getc(f_p)) != EOF); + sbuf[cnt-2]=0; + } + pclose(f_p); +#endif + + for (rcnt=0; + rcnt < MAX_SESSIONS && session[rcnt].in_use; + rcnt++); + + if (rcnt >= MAX_SESSIONS) + { + sprintf(dfe_errmsg, "DFE-ipc ERROR: Too many sessions already open"); + return UDIErrorIPCLimitation; + } + + /* One connection can be multiplexed between several sessions. */ + + for (cnt=0; + cnt < MAX_SESSIONS && soc_con[cnt].in_use; + cnt++); + + if (cnt >= MAX_SESSIONS) + { + sprintf(dfe_errmsg, + "DFE-ipc ERROR: Too many connections already open"); + return UDIErrorIPCLimitation; + } + + *Session = rcnt; + session[rcnt].soc_con_p = &soc_con[cnt]; + + if (strchr(Config, ' ')) /* test if file entry given */ + { + soc_con[cnt].in_use = TRUE; + sscanf(Config, "%s %s %s %s %n", + soc_con[cnt].connect_id, + soc_con[cnt].domain_string, + soc_con[cnt].tip_string, + soc_con[cnt].tip_exe, + ¶ms_pos); + tip_main_string = Config + params_pos; + } + else /* here if need to read udi_soc file */ + { + strcpy(config_file, "udi_soc"); + env_p = getenv("UDICONF"); + if (env_p) + strcpy(config_file, env_p); + + fd = fopen(config_file, "r"); + + if (!fd) + { + sprintf(dfe_errmsg, "UDIConnect, can't open udi_soc file:\n%s ", + strerror(errno)); + dfe_errno = UDIErrorCantOpenConfigFile; + goto tip_failure; + } + + while (1) + { + if (fscanf(fd, "%s %s %s %s %[^\n]\n", + soc_con[cnt].connect_id, + soc_con[cnt].domain_string, + soc_con[cnt].tip_string, + soc_con[cnt].tip_exe, + sbuf) == EOF) + break; + + if (strcmp(Config, soc_con[cnt].connect_id) != 0) + continue; + + soc_con[cnt].in_use = TRUE; /* here if entry found */ + + tip_main_string = sbuf; + break; + } + + fclose(fd); + if (!soc_con[cnt].in_use) + { + sprintf(dfe_errmsg, + "UDIConnect, can't find `%s' entry in udi_soc file", + Config); + dfe_errno = UDIErrorNoSuchConfiguration; + goto tip_failure; + } + } +/*----------------------------------------------------------- SELECT DOMAIN */ + if (strcmp(soc_con[cnt].domain_string, "AF_UNIX") == 0) + domain = AF_UNIX; + else if (strcmp(soc_con[cnt].domain_string, "AF_INET") == 0) + domain = AF_INET; + else + { + sprintf(dfe_errmsg, "DFE-ipc ERROR: socket address family not known"); + dfe_errno = UDIErrorBadConfigFileEntry; + goto tip_failure; + } + +/*---------------------------------------------------- MULTIPLEXED SOCKET ? */ +/* If the requested session requires communication with + a TIP which already has a socket connection established, + then we do not create a new socket but multiplex the + existing one. A TIP is said to use the same socket if + socket-name/host-name and the domain are the same. + */ + for (rcnt=0; rcnt < MAX_SESSIONS; rcnt++) + { + if (soc_con[rcnt].in_use + && rcnt != cnt + && strcmp(soc_con[cnt].domain_string, + soc_con[rcnt].domain_string) == 0 + && strcmp(soc_con[cnt].tip_string, + soc_con[rcnt].tip_string) == 0) + { + session[*Session].soc_con_p = &soc_con[rcnt]; + soc_con[cnt].in_use = FALSE; /* don't need new connect */ + goto tip_connect; + } + } +/*------------------------------------------------------------------ SOCKET */ + soc_con[cnt].dfe_sd = socket(domain, SOCK_STREAM, 0); + if (soc_con[cnt].dfe_sd == -1) + { + sprintf(dfe_errmsg, "DFE-ipc ERROR, socket() call failed %s ", + strerror (errno)); + dfe_errno = UDIErrorUnknownError; + goto tip_failure; + } + +/*--------------------------------------------------------- AF_UNIX CONNECT */ + if (domain == AF_UNIX) + { + if (strcmp(soc_con[cnt].tip_string, "*") == 0) + { + for (pos = 0; pos < 20; pos++) + { + int f; + + sprintf(soc_con[cnt].tip_string,"/tmp/U%d", getpid() + pos); + f = open(soc_con[cnt].tip_string, O_CREAT); + if (f == -1) + continue; + + close(f); + unlink(soc_con[cnt].tip_string); + break; + } + + if (pos >= 20) + { + sprintf(dfe_errmsg, + "DFE-ipc ERROR, can't create random socket name"); + dfe_errno = UDIErrorCantConnect; + goto tip_failure; + } + } + + soc_con[cnt].tip_sockaddr.sa_family = domain; + memcpy(soc_con[cnt].tip_sockaddr.sa_data, + soc_con[cnt].tip_string, + sizeof(soc_con[cnt].tip_sockaddr.sa_data)); + if (connect(soc_con[cnt].dfe_sd, + &soc_con[cnt].tip_sockaddr, + sizeof(soc_con[cnt].tip_sockaddr))) + { /* if connect() fails assume TIP not yet started */ +/*------------------------------------------------------------ AF_UNIX EXEC */ + int pid; + int statusp; + char *arg0; + + arg0 = strrchr(soc_con[cnt].tip_exe,'/'); + + if (arg0) + arg0++; + else + arg0 = soc_con[cnt].tip_exe; + + pid = vfork(); + + if (pid == 0) /* Child */ + { + execlp(soc_con[cnt].tip_exe, + arg0, + soc_con[cnt].domain_string, + soc_con[cnt].tip_string, + NULL); + _exit(1); + } + + if (waitpid(pid, &statusp, WNOHANG)) + { + sprintf(dfe_errmsg, "DFE-ipc ERROR: can't exec the TIP"); + dfe_errno = UDIErrorCantStartTIP; + goto tip_failure; + } + + pos = 3; + for (pos = 3; pos > 0; pos--) + { + if (!connect(soc_con[cnt].dfe_sd, + &soc_con[cnt].tip_sockaddr, + sizeof(soc_con[cnt].tip_sockaddr))) + break; + sleep(1); + } + + if (pos == 0) + { + sprintf(dfe_errmsg, "DFE-ipc ERROR, connect() call failed: %s", + strerror (errno)); + dfe_errno = UDIErrorCantConnect; + goto tip_failure; + } + } + } +/*--------------------------------------------------------- AF_INET CONNECT */ + else if (domain == AF_INET) + { + fprintf(stderr, + "DFE-ipc WARNING, need to have first started remote TIP"); + + soc_con[cnt].tip_sockaddr_in.sin_family = domain; + soc_con[cnt].tip_sockaddr_in.sin_addr.s_addr = + inet_addr(soc_con[cnt].tip_string); + if (soc_con[cnt].tip_sockaddr_in.sin_addr.s_addr == -1) + { + tip_info_p = gethostbyname(soc_con[cnt].tip_string); + if (tip_info_p == NULL) + { + sprintf(dfe_errmsg,"DFE-ipc ERROR, No such host %s", + soc_con[cnt].tip_string); + dfe_errno = UDIErrorNoSuchConnection; + goto tip_failure; + } + memcpy((char *)&soc_con[cnt].tip_sockaddr_in.sin_addr, + tip_info_p->h_addr, + tip_info_p->h_length); + } + soc_con[cnt].tip_sockaddr_in.sin_port + = htons(atoi(soc_con[cnt].tip_exe)); + + if (connect(soc_con[cnt].dfe_sd, + (struct sockaddr *) &soc_con[cnt].tip_sockaddr_in, + sizeof(soc_con[cnt].tip_sockaddr_in))) + { + sprintf(dfe_errmsg, "DFE-ipc ERROR, connect() call failed %s ", + strerror (errno)); + dfe_errno = UDIErrorCantConnect; + goto tip_failure; + } + } +/*------------------------------------------------------------- TIP CONNECT */ + if (cnt == 0) udr_create(udrs, soc_con[cnt].dfe_sd, SOC_BUF_SIZE); + +tip_connect: + current = cnt; + session[*Session].in_use = TRUE; /* session id is now in use */ + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + + DFEIPCId = (company_c << 16) + (product_c << 12) + version_c; + udr_UDIUInt32(udrs, &DFEIPCId); + + udr_string(udrs, tip_main_string); + + udr_sendnow(udrs); + + udrs->udr_op = UDR_DECODE; /* recv all "out" parameters */ + udr_UDIUInt32(udrs, &TIPIPCId); + if ((TIPIPCId & 0xfff) < version_c) + sprintf(dfe_errmsg, "DFE-ipc: Obsolete TIP Specified"); + + udr_UDIInt32(udrs, &soc_con[cnt].tip_pid); + + udr_UDISessionId(udrs, &session[*Session].tip_id); + + udr_UDIError(udrs, &dfe_errno); + if (dfe_errno > 0) UDIKill(*Session, 0); + + return dfe_errno; + +tip_failure: + + soc_con[cnt].in_use = FALSE; + session[*Session].in_use = FALSE; +/* XXX - Should also close dfe_sd, but not sure what to do if muxed */ + return dfe_errno; +} + +/************************************************************** UDI_Disconnect +* UDIDisconnect() should be called before exiting the +* DFE to ensure proper shut down of the TIP. +*/ +UDIError UDIDisconnect(Session, Terminate) +UDISessionId Session; +UDIBool Terminate; +{ + int cnt; + UDIInt32 service_id = UDIDisconnect_c; + if(Session < 0 || Session > MAX_SESSIONS) + { + sprintf(dfe_errmsg," SessionId not valid (%d)", Session); + return UDIErrorNoSuchConfiguration; + } + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDISessionId(udrs, &session[Session].tip_id); + udr_UDIBool(udrs, &Terminate); + udr_sendnow(udrs); + + session[Session].in_use = FALSE; /* session id is now free */ + for (cnt=0; cnt < MAX_SESSIONS; cnt++) + if(session[cnt].in_use + && session[cnt].soc_con_p == session[Session].soc_con_p + ) break; + if(cnt >= MAX_SESSIONS) /* test if socket not multiplexed */ + if(shutdown(session[Session].soc_con_p->dfe_sd, 2)) + { + sprintf(dfe_errmsg, "DFE-ipc WARNING: socket shutdown failed"); + return UDIErrorIPCInternal; + } + else + session[Session].soc_con_p->in_use = 0; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/******************************************************************** UDI_KILL +* UDIKill() is used to send a signal to the TIP. +* This is a private IPC call. +*/ +UDIError UDIKill(Session, Signal) +UDISessionId Session; +UDIInt32 Signal; +{ + int cnt; + UDIInt32 service_id = UDIKill_c; + if(Session < 0 || Session > MAX_SESSIONS) + { + sprintf(dfe_errmsg," SessionId not valid (%d)", Session); + return UDIErrorNoSuchConfiguration; + } + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDISessionId(udrs, &session[Session].tip_id); + udr_UDIInt32(udrs, &Signal); + udr_sendnow(udrs); + + session[Session].in_use = FALSE; /* session id is now free */ + for (cnt=0; cnt < MAX_SESSIONS; cnt++) + if(session[cnt].in_use + && session[cnt].soc_con_p == session[Session].soc_con_p + ) break; + if(cnt < MAX_SESSIONS) /* test if socket not multiplexed */ + if(shutdown(session[Session].soc_con_p->dfe_sd, 2)) + { + sprintf(dfe_errmsg, "DFE-ipc WARNING: socket shutdown failed"); + return UDIErrorIPCInternal; + } + else + session[Session].soc_con_p->in_use = 0; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/************************************************** UDI_Set_Current_Connection +* If you are connected to multiple TIPs, you can change +* TIPs using UDISetCurrentConnection(). +*/ +UDIError UDISetCurrentConnection(Session) +UDISessionId Session; +{ + UDIInt32 service_id = UDISetCurrentConnection_c; + + if(Session < 0 || Session > MAX_SESSIONS) + return UDIErrorNoSuchConfiguration; + if(!session[Session].in_use) /* test if not in use yet */ + return UDIErrorNoSuchConnection; + + current = Session; + /* change socket or multiplex the same socket */ + udrs->sd = session[Session].soc_con_p->dfe_sd; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDISessionId(udrs, &session[Session].tip_id); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/************************************************************ UDI_Capabilities +* The DFE uses UDICapabilities() to both inform the TIP +* of what services the DFE offers and to inquire of the +* TIP what services the TIP offers. +*/ +UDIError UDICapabilities(TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, + TIPIPCId, TIPString) +UDIUInt32 *TIPId; /* out */ +UDIUInt32 *TargetId; /* out */ +UDIUInt32 DFEId; /* in */ +UDIUInt32 DFE; /* in */ +UDIUInt32 *TIP; /* out */ +UDIUInt32 *DFEIPCId; /* out */ +UDIUInt32 *TIPIPCId; /* out */ +char *TIPString; /* out */ +{ + UDIInt32 service_id = UDICapabilities_c; + int size; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDIInt32(udrs, &DFEId); + udr_UDIInt32(udrs, &DFE); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" paramters */ + udr_UDIInt32(udrs, TIPId); + udr_UDIInt32(udrs, TargetId); + udr_UDIInt32(udrs, TIP); + udr_UDIInt32(udrs, DFEIPCId); + *DFEIPCId = (company_c << 16) + (product_c << 12) + version_c; + udr_UDIInt32(udrs, TIPIPCId); + udr_string(udrs, sbuf); + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + size = strlen(sbuf); + if(size +1 > 80) return -1; /* test if sufficient space */ + strcpy(TIPString, sbuf); + return dfe_errno; +} + +/********************************************************** UDI_Enumerate_TIPs +* Used by the DFE to enquire about available TIP +* connections. +*/ +UDIError UDIEnumerateTIPs(UDIETCallback) + int (*UDIETCallback)(); /* In -- function to callback */ +{ + FILE *fp; + + fp = fopen(config_file, "r"); + if(fp == NULL) + return UDIErrorCantOpenConfigFile; + while(fgets( sbuf, SBUF_SIZE, fp)) + if(UDIETCallback( sbuf) == UDITerminateEnumeration) + break; + fclose( fp); + return UDINoError; /* return success */ +} + +/*********************************************************** UDI_GET_ERROR_MSG +* Some errors are target specific. They are indicated +* by a negative error return value. The DFE uses +* UDIGetErrorMsg() to get the descriptive text for +* the error message which can then be displayed to +* the user. +*/ +UDIError UDIGetErrorMsg(error_code, msg_len, msg, CountDone) +UDIError error_code; /* In */ +UDISizeT msg_len; /* In -- allowed message space */ +char* msg; /* Out -- length of message*/ +UDISizeT *CountDone; /* Out -- number of characters */ +{ + UDIInt32 service_id = UDIGetErrorMsg_c; + int size; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDIError(udrs, &error_code); + udr_UDISizeT(udrs, &msg_len); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_string(udrs, sbuf); + udr_UDISizeT(udrs, CountDone); + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + size = strlen(sbuf); + if(size +1 > msg_len) return -1; /* test if sufficient space */ + strcpy(msg, sbuf); + return dfe_errno; +} + +/******************************************************* UDI_GET_TARGET_CONFIG +* UDIGetTargetConfig() gets information about the target. +*/ +UDIError UDIGetTargetConfig(KnownMemory, NumberOfRanges, ChipVersions, + NumberOfChips) +UDIMemoryRange KnownMemory[]; /* Out */ +UDIInt *NumberOfRanges; /* In and Out */ +UDIUInt32 ChipVersions[]; /* Out */ +UDIInt *NumberOfChips; /* In and Out */ +{ + UDIInt32 service_id = UDIGetTargetConfig_c; + int cnt; + int MaxOfRanges = *NumberOfRanges; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDIInt(udrs, NumberOfRanges); + udr_UDIInt(udrs, NumberOfChips); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" paramters */ + for(cnt=1; cnt <= MaxOfRanges; cnt++) + udr_UDIMemoryRange(udrs, &KnownMemory[cnt-1]); + udr_UDIInt(udrs, NumberOfRanges); + udr_UDIInt(udrs, NumberOfChips); + for(cnt=1; cnt <= *NumberOfChips; cnt++) + udr_UDIUInt32(udrs, &ChipVersions[cnt -1]); + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/********************************************************** UDI_CREATE_PRCOESS +* UDICreateProcess() tells the target OS that a +* process is to be created and gets a PID back unless +* there is some error. +*/ +UDIError UDICreateProcess(pid) +UDIPId *pid; /* out */ +{ + UDIInt32 service_id = UDICreateProcess_c; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDIPId(udrs, pid); + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/***************************************************** UDI_Set_Current_Process +* UDISetCurrentProcess uses a pid supplied by +* UDICreateProcess and sets it as the default for all +* udi calls until a new one is set. A user of a +*/ +UDIError UDISetCurrentProcess (pid) +UDIPId pid; /* In */ +{ + UDIInt32 service_id = UDISetCurrentProcess_c; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDIPId(udrs, &pid); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/****************************************************** UDI_INITIALISE_PROCESS +* UDIInitializeProcess() prepare process for +* execution. (Reset processor if process os processor). +*/ +UDIError UDIInitializeProcess( ProcessMemory, NumberOfRanges, EntryPoint, + StackSizes, NumberOfStacks, ArgString) +UDIMemoryRange ProcessMemory[]; /* In */ +UDIInt NumberOfRanges; /* In */ +UDIResource EntryPoint; /* In */ +CPUSizeT *StackSizes; /* In */ +UDIInt NumberOfStacks; /* In */ +char *ArgString; /* In */ +{ + UDIInt32 service_id = UDIInitializeProcess_c; + int cnt; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDIInt(udrs, &NumberOfRanges); + for(cnt = 0; cnt < NumberOfRanges; cnt++) + udr_UDIMemoryRange(udrs, &ProcessMemory[cnt] ); + udr_UDIResource(udrs, &EntryPoint); + udr_UDIInt(udrs, &NumberOfStacks); + for(cnt = 0; cnt < NumberOfStacks; cnt++) + udr_CPUSizeT(udrs, &StackSizes[cnt]); + udr_string(udrs, ArgString); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/********************************************************* UDI_DESTROY_PROCESS +* UDIDestroyProcess() frees a process resource +* previously created by UDICreateProcess(). +*/ +UDIError UDIDestroyProcess(pid) +UDIPId pid; /* in */ +{ + UDIInt32 service_id = UDIDestroyProcess_c; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDIPId(udrs, &pid); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/****************************************************************** UDI_READ +* UDIRead() reads a block of objects from a target +* address space to host space. +*/ + +UDIError UDIRead (from, to, count, size, count_done, host_endian) +UDIResource from; /* in - source address on target */ +UDIHostMemPtr to; /* out - destination address on host */ +UDICount count; /* in -- count of objects to be transferred */ +UDISizeT size; /* in -- size of each object */ +UDICount *count_done; /* out - count actually transferred */ +UDIBool host_endian; /* in -- flag for endian information */ +{ + UDIInt32 service_id = UDIRead_c; + int byte_count; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDIResource(udrs, &from); + udr_UDICount(udrs, &count); + udr_UDISizeT(udrs, &size); + udr_UDIBool(udrs, &host_endian); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" paramters */ + udr_UDICount(udrs, count_done); + byte_count = (*count_done) * size; + if(*count_done > 0 && *count_done <= count) + udr_bytes(udrs, to, byte_count); + if(udr_errno) return udr_errno; + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/****************************************************************** UDI_WRITE +* UDIWrite() writes a block of objects from host +* space to a target address+space. +*/ +UDIError UDIWrite( from, to, count, size, count_done, host_endian ) +UDIHostMemPtr from; /* in -- source address on host */ +UDIResource to; /* in -- destination address on target */ +UDICount count; /* in -- count of objects to be transferred */ +UDISizeT size; /* in -- size of each object */ +UDICount *count_done; /* out - count actually transferred */ +UDIBool host_endian; /* in -- flag for endian information */ +{ + UDIInt32 service_id = UDIWrite_c; + int byte_count = count * size; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDIResource(udrs, &to); + udr_UDICount(udrs, &count); + udr_UDISizeT(udrs, &size); + udr_UDIBool(udrs, &host_endian); + udr_bytes(udrs, from, byte_count); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" paramters */ + udr_UDICount(udrs, count_done); + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/******************************************************************** UDI_COPY +* UDICopy() copies a block of objects from one target +* get address/space to another target address/space. +*/ +UDIError UDICopy(from, to, count, size, count_done, direction ) +UDIResource from; /* in -- destination address on target */ +UDIResource to; /* in -- source address on target */ +UDICount count; /* in -- count of objects to be transferred */ +UDISizeT size; /* in -- size of each object */ +UDICount *count_done; /* out - count actually transferred */ +UDIBool direction; /* in -- high-to-low or reverse */ +{ + UDIInt32 service_id = UDICopy_c; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDIResource(udrs, &from); + udr_UDIResource(udrs, &to); + udr_UDICount(udrs, &count); + udr_UDISizeT(udrs, &size); + udr_UDIBool(udrs, &direction); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDICount(udrs, count_done); + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/***************************************************************** UDI_EXECUTE +* UDIExecute() continues execution of the default +* process from the current PC. +*/ +UDIError UDIExecute() +{ + UDIInt32 service_id = UDIExecute_c; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/******************************************************************** UDI_STEP +* UDIStep() specifies a number of "instruction" +* steps to make. +*/ +UDIError UDIStep(steps, steptype, range) +UDIUInt32 steps; /* in -- number of steps */ +UDIStepType steptype; /* in -- type of stepping to be done */ +UDIRange range; /* in -- range if StepInRange is TRUE */ +{ + UDIInt32 service_id = UDIStep_c; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDIInt32(udrs, &steps); + udr_UDIStepType(udrs, &steptype); + udr_UDIRange(udrs, &range); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/******************************************************************** UDI_STOP +* UDIStop() stops the default process +*/ +UDIVoid UDIStop() +{ + if (strcmp(session[current].soc_con_p->domain_string, "AF_UNIX") == 0) + kill(session[current].soc_con_p->tip_pid, SIGINT); + else + udr_signal(udrs); + +/* XXX - should clean up session[] and soc_con[] structs here as well... */ + + return; +} + +/******************************************************************** UDI_WAIT +* UDIWait() returns the state of the target procesor. +*/ +UDIError UDIWait(maxtime, pid, stop_reason) +UDIInt32 maxtime; /* in -- maximum time to wait for completion */ +UDIPId *pid; /* out -- pid of process which stopped if any */ +UDIUInt32 *stop_reason; /* out -- PC where process stopped */ +{ + UDIInt32 service_id = UDIWait_c; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDIInt32(udrs, &maxtime); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDIPId(udrs, pid); + udr_UDIUInt32(udrs, stop_reason); + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/********************************************************** UDI_SET_BREAKPOINT +* UDISetBreakpoint() sets a breakpoint at an adress +* and uses the passcount to state how many +* times that instruction should be hit before the +* break occurs. +*/ +UDIError UDISetBreakpoint (addr, passcount, type, break_id) +UDIResource addr; /* in -- where breakpoint gets set */ +UDIInt32 passcount; /* in -- passcount for breakpoint */ +UDIBreakType type; /* in -- breakpoint type */ +UDIBreakId *break_id; /* out - assigned break id */ +{ + UDIInt32 service_id = UDISetBreakpoint_c; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDIResource(udrs, &addr); + udr_UDIInt32(udrs, &passcount); + udr_UDIBreakType(udrs, &type); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDIBreakId(udrs, break_id); + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/******************************************************** UDI_QUERY_BREAKPOINT +*/ +UDIError UDIQueryBreakpoint (break_id, addr, passcount, type, current_count) +UDIBreakId break_id; /* in -- assigned break id */ +UDIResource *addr; /* out - where breakpoint was set */ +UDIInt32 *passcount; /* out - trigger passcount for breakpoint */ +UDIBreakType *type; /* out - breakpoint type */ +UDIInt32 *current_count; /* out - current count for breakpoint */ +{ + UDIInt32 service_id = UDIQueryBreakpoint_c; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDIBreakId(udrs, &break_id); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDIResource(udrs, addr); + udr_UDIInt32(udrs, passcount); + udr_UDIBreakType(udrs, type); + udr_UDIInt32(udrs, current_count); + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/******************************************************** UDI_CLEAR_BREAKPOINT +* UDIClearBreakpoint() is used to clear a breakpoint. +*/ +UDIError UDIClearBreakpoint (break_id) +UDIBreakId break_id; /* in -- assigned break id */ +{ + UDIInt32 service_id = UDIClearBreakpoint_c; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDIBreakId(udrs, &break_id); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/************************************************************** UDI_GET_STDOUT +* UDIGetStdout() is called when a call to +* UDIWait() indicates there is STD output data ready. +*/ +UDIError UDIGetStdout(buf, bufsize, count_done) +UDIHostMemPtr buf; /* out -- buffer to be filled */ +UDISizeT bufsize; /* in -- buffer size in bytes */ +UDISizeT *count_done; /* out -- number of bytes written to buf */ +{ + UDIInt32 service_id = UDIGetStdout_c; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDISizeT(udrs, &bufsize); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDISizeT(udrs, count_done); + udr_bytes(udrs, buf, *count_done); + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/************************************************************** UDI_GET_STDERR +* UDIGetStderr() is called when a call to +* UDIWait() indicates there is STDERR output data ready +*/ +UDIError UDIGetStderr(buf, bufsize, count_done) +UDIHostMemPtr buf; /* out -- buffer to be filled */ +UDISizeT bufsize; /* in -- buffer size in bytes */ +UDISizeT *count_done; /* out -- number of bytes written to buf */ +{ + UDIInt32 service_id = UDIGetStderr_c; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDISizeT(udrs, &bufsize); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDISizeT(udrs, count_done); + udr_bytes(udrs, buf, *count_done); + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/*************************************************************** UDI_PUT_STDIN +* UDIPutStdin() is called whenever the DFE wants to +* deliver an input character to the TIP. +*/ +UDIError UDIPutStdin (buf, count, count_done) +UDIHostMemPtr buf; /* in -- buffer to be filled */ +UDISizeT count; /* in -- buffer size in bytes */ +UDISizeT *count_done; /* out - number of bytes written to buf */ +{ + UDIInt32 service_id = UDIPutStdin_c; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDISizeT(udrs, &count); + udr_bytes(udrs, buf, count); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDISizeT(udrs, count_done); + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/************************************************************** UDI_STDIN_MODE +* UDIStdinMode() is used to change the mode that chazcters +* are fetched from the user. +*/ +UDIError UDIStdinMode(mode) +UDIMode *mode; /* out - */ +{ + UDIInt32 service_id = UDIStdinMode_c; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDIMode(udrs, mode); + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/*************************************************************** UDI_PUT_TRANS +* UDIPutTrans() is used to feed input to the passthru mode. +*/ +UDIError UDIPutTrans (buf, count, count_done) +UDIHostMemPtr buf; /* in -- buffer address containing input data */ +UDISizeT count; /* in -- number of bytes in buf */ +UDISizeT *count_done; /* out-- number of bytes transfered */ +{ + UDIInt32 service_id = UDIPutTrans_c; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDISizeT(udrs, &count); + udr_bytes(udrs, buf, count); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDISizeT(udrs, count_done); + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/*************************************************************** UDI_GET_TRANS +* UDIGetTrans() is used to get output lines from the +* passthru mode. +*/ +UDIError UDIGetTrans (buf, bufsize, count_done) +UDIHostMemPtr buf; /* out -- buffer to be filled */ +UDISizeT bufsize; /* in -- size of buf */ +UDISizeT *count_done; /* out -- number of bytes in buf */ +{ + UDIInt32 service_id = UDIGetTrans_c; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDISizeT(udrs, &bufsize); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDISizeT(udrs, count_done); + udr_bytes(udrs, buf, *count_done); + udr_UDIError(udrs, &dfe_errno); /* get any TIP error */ + return dfe_errno; +} + +/************************************************************** UDI_Trans_Mode +* UDITransMode() is used to change the mode that the +* transparent routines operate in. +*/ +UDIError UDITransMode(mode) +UDIMode *mode; /* out -- selected mode */ +{ + UDIInt32 service_id = UDITransMode_c; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + udr_UDIMode(udrs, mode); + udr_sendnow(udrs); + if(udr_errno) return udr_errno; + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + udr_UDIError(udrs, &dfe_errno); + return dfe_errno; +} + +/******************************************************************** UDI_TEST +*/ +UDIError UDITest( cnt, str_p, array) +UDISizeT cnt; +UDIHostMemPtr str_p; +UDIInt32 array[]; +{ + UDIInt32 service_id = UDITest_c; + UDIInt16 scnt = cnt; + UDISizeT r_cnt; + char buf[256]; + + udr_errno = 0; + udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ + udr_UDIInt32(udrs, &service_id); + + printf("send cnt=%d scnt=%d\n", cnt, scnt); + udr_UDISizeT(udrs, &cnt); + udr_UDIInt16(udrs, &scnt); + printf(" array[0]=0x%x array[1]=0x%x array[2]=0x%x array[3]=0x%x\n", + array[0], array[1], array[2], array[3]); + udr_bytes(udrs, (char*)array, 4*sizeof(UDIInt32)); + printf(" string=%s\n", str_p); + udr_string(udrs, str_p); + udr_sendnow(udrs); + if(udr_errno) + { fprintf(stderr, " DFE-ipc Send ERROR\n"); + return udr_errno; + } + + udrs->udr_op = UDR_DECODE; /* receive all "out" parameters */ + printf("recv "); + udr_UDISizeT(udrs, &r_cnt); + udr_UDIInt16(udrs, &scnt); + printf(" rcnt=%d scnt=%d\n", r_cnt, scnt); + udr_bytes(udrs, (char*)array, 4*sizeof(UDIInt32)); + + printf(" array[0]=0x%x array[1]=0x%x array[2]=0x%x array[3]=0x%x\n", + array[0], array[1], array[2], array[3]); + udr_string(udrs, str_p); + printf(" string=%s\n", str_p); + + udr_UDIError(udrs, &dfe_errno); + return dfe_errno; +} + + + +UDIUInt32 UDIGetDFEIPCId() +{ + return ((company_c << 16) + (product_c << 12) + version_c); +} +#endif /* __GO32__ */ |