Remove gdb-4.17.

This commit is contained in:
thorpej 2002-09-16 17:42:22 +00:00
parent e2ba73e2b5
commit 2a57f8214b
76 changed files with 0 additions and 23312 deletions

View File

@ -1,42 +0,0 @@
description "GDB debugger stub"
version 1,2
debug
module clib
screenname "System Console"
input gdbserve.O
output gdbserve.nlm
start _Prelude
exit _Stop
import
AllocateResourceTag
ConsolePrintf
GetCurrentScreen
GetNLMHandle
GetThreadID
KillMe
LoadModule
ReadByteAltDebugger
RegisterDebuggerRTag
ResumeThread
SuspendThread
UnRegisterDebugger
WriteByteAltDebugger
_GetCLibNLMLibHandle
_NWRegisterNLMLibraryUser
_SetupArgv
_StartNLM
_TerminateNLM
__GetScreenID
__get_errno_ptr
exit
fprintf
getcmd
memcmp
memcpy
memset
sprintf
strcmp
strcpy
strlen
strnicmp
strtol

View File

@ -1,108 +0,0 @@
#include <dfs.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include <conio.h>
#include <advanced.h>
#include <debugapi.h>
#include <process.h>
#include <errno.h>
#include "i386.h"
extern char *mem2hex (void *mem, char *buf, int count, int may_fault);
extern char *hex2mem (char *buf, void *mem, int count, int may_fault);
extern int computeSignal (int exceptionVector);
void
flush_i_cache()
{
}
/* Get the registers out of the frame information. */
void
frame_to_registers (frame, regs)
struct StackFrame *frame;
char *regs;
{
/* Copy EAX -> EDI */
mem2hex (&frame->ExceptionEAX, &regs[0 * 4 * 2], 4 * 8, 0);
/* Copy EIP & PS */
mem2hex (&frame->ExceptionPC, &regs[8 * 4 * 2], 4 * 2, 0);
/* Copy CS, SS, DS */
mem2hex (&frame->ExceptionCS, &regs[10 * 4 * 2], 4 * 3, 0);
/* Copy ES */
mem2hex (&frame->ExceptionES, &regs[13 * 4 * 2], 4 * 1, 0);
/* Copy FS & GS */
mem2hex (&frame->ExceptionFS, &regs[14 * 4 * 2], 4 * 2, 0);
}
/* Put the registers back into the frame information. */
void
registers_to_frame (regs, frame)
char *regs;
struct StackFrame *frame;
{
/* Copy EAX -> EDI */
hex2mem (&regs[0 * 4 * 2], &frame->ExceptionEAX, 4 * 8, 0);
/* Copy EIP & PS */
hex2mem (&regs[8 * 4 * 2], &frame->ExceptionPC, 4 * 2, 0);
/* Copy CS, SS, DS */
hex2mem (&regs[10 * 4 * 2], &frame->ExceptionCS, 4 * 3, 0);
/* Copy ES */
hex2mem (&regs[13 * 4 * 2], &frame->ExceptionES, 4 * 1, 0);
/* Copy FS & GS */
hex2mem (&regs[14 * 4 * 2], &frame->ExceptionFS, 4 * 2, 0);
}
void
set_step_traps (frame)
struct StackFrame *frame;
{
frame->ExceptionSystemFlags |= 0x100;
}
void
clear_step_traps (frame)
struct StackFrame *frame;
{
frame->ExceptionSystemFlags &= ~0x100;
}
void
do_status (ptr, frame)
char *ptr;
struct StackFrame *frame;
{
int sigval;
sigval = computeSignal (frame->ExceptionNumber);
sprintf (ptr, "T%02x", sigval);
ptr += 3;
sprintf (ptr, "%02x:", PC_REGNUM);
ptr = mem2hex (&frame->ExceptionPC, ptr + 3, 4, 0);
*ptr++ = ';';
sprintf (ptr, "%02x:", SP_REGNUM);
ptr = mem2hex (&frame->ExceptionESP, ptr + 3, 4, 0);
*ptr++ = ';';
sprintf (ptr, "%02x:", FP_REGNUM);
ptr = mem2hex (&frame->ExceptionEBP, ptr + 3, 4, 0);
*ptr++ = ';';
*ptr = '\000';
}

View File

@ -1,13 +0,0 @@
/* Register values. All of these values *MUST* agree with tm.h */
#define SP_REGNUM 4 /* Contains address of top of stack */
#define PC_REGNUM 8 /* Contains program counter */
#define FP_REGNUM 5 /* Virtual frame pointer */
#define NUM_REGS 16 /* Number of machine registers */
#define REGISTER_BYTES (NUM_REGS * 4) /* Total size of registers array */
#define ExceptionPC ExceptionEIP
#define DECR_PC_AFTER_BREAK 1 /* int 3 leaves PC pointing after insn */
#define BREAKPOINT {0xcc}
#define BREAKPOINT_SIZE (sizeof breakpoint_insn)
#define StackFrame T_TSS_StackFrame

257
gnu/dist/gdb/nlm/ppc.c vendored
View File

@ -1,257 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <nwtypes.h>
#include <nwdfs.h>
#include <nwconio.h>
#include <nwadv.h>
#include <nwdbgapi.h>
#include <nwthread.h>
#include "ppc.h"
extern char *mem2hex (void *mem, char *buf, int count, int may_fault);
extern char *hex2mem (char *buf, void *mem, int count, int may_fault);
extern int computeSignal (int exceptionVector);
void
flush_i_cache (void)
{
}
/* Get the registers out of the frame information. */
void
frame_to_registers (frame, regs)
struct StackFrame *frame;
char *regs;
{
mem2hex (&frame->ExceptionState.CsavedRegs, &regs[GP0_REGNUM * 4 * 2], 4 * 32, 0);
mem2hex (&frame->ExceptionState.CSavedFPRegs, &regs[FP0_REGNUM * 4 * 2], 4 * 32, 0);
mem2hex (&frame->ExceptionPC, &regs[PC_REGNUM * 4 * 2], 4 * 1, 0);
mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR1, &regs[CR_REGNUM * 4 * 2], 4 * 1, 0);
mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR, &regs[LR_REGNUM * 4 * 2], 4 * 1, 0);
mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR, &regs[CTR_REGNUM * 4 * 2], 4 * 1, 0);
mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedXER, &regs[XER_REGNUM * 4 * 2], 4 * 1, 0);
mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedMQ, &regs[MQ_REGNUM * 4 * 2], 4 * 1, 0);
}
/* Put the registers back into the frame information. */
void
registers_to_frame (regs, frame)
char *regs;
struct StackFrame *frame;
{
hex2mem (&regs[GP0_REGNUM * 4 * 2], &frame->ExceptionState.CsavedRegs, 4 * 32, 0);
hex2mem (&regs[FP0_REGNUM * 4 * 2], &frame->ExceptionState.CSavedFPRegs, 4 * 32, 0);
hex2mem (&regs[PC_REGNUM * 4 * 2], &frame->ExceptionPC, 4 * 1, 0);
hex2mem (&regs[CR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR1, 4 * 1, 0);
hex2mem (&regs[LR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR, 4 * 1, 0);
hex2mem (&regs[CTR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR, 4 * 1, 0);
hex2mem (&regs[XER_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedXER, 4 * 1, 0);
hex2mem (&regs[MQ_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedMQ, 4 * 1, 0);
}
extern volatile int mem_err;
#ifdef ALTERNATE_MEM_FUNCS
extern int ReadByteAltDebugger (char* addr, char *theByte);
extern int WriteByteAltDebugger (char* addr, char theByte);
int
get_char (addr)
char *addr;
{
char c;
if (!ReadByteAltDebugger (addr, &c))
mem_err = 1;
return c;
}
void
set_char (addr, val)
char *addr;
int val;
{
if (!WriteByteAltDebugger (addr, val))
mem_err = 1;
}
#endif
int
mem_write (dst, src, len)
char *dst, *src;
int len;
{
while (len-- && !mem_err)
set_char (dst++, *src++);
return mem_err;
}
union inst
{
LONG l;
struct
{
union
{
struct /* Unconditional branch */
{
unsigned opcode : 6; /* 18 */
signed li : 24;
unsigned aa : 1;
unsigned lk : 1;
} b;
struct /* Conditional branch */
{
unsigned opcode : 6; /* 16 */
unsigned bo : 5;
unsigned bi : 5;
signed bd : 14;
unsigned aa : 1;
unsigned lk : 1;
} bc;
struct /* Conditional branch to ctr or lr reg */
{
unsigned opcode : 6; /* 19 */
unsigned bo : 5;
unsigned bi : 5;
unsigned type : 15; /* 528 = ctr, 16 = lr */
unsigned lk : 1;
} bclr;
} variant;
} inst;
};
static LONG saved_inst;
static LONG *saved_inst_pc = 0;
static LONG saved_target_inst;
static LONG *saved_target_inst_pc = 0;
void
set_step_traps (frame)
struct StackFrame *frame;
{
union inst inst;
LONG *target;
int opcode;
int ra, rb;
LONG *pc = (LONG *)frame->ExceptionPC;
inst.l = *pc++;
opcode = inst.inst.variant.b.opcode;
target = pc;
switch (opcode)
{
case 18: /* Unconditional branch */
if (inst.inst.variant.b.aa) /* Absolute? */
target = 0;
target += inst.inst.variant.b.li;
break;
case 16: /* Conditional branch */
if (!inst.inst.variant.bc.aa) /* Absolute? */
target = 0;
target += inst.inst.variant.bc.bd;
break;
case 19: /* Cond. branch via ctr or lr reg */
switch (inst.inst.variant.bclr.type)
{
case 528: /* ctr */
target = (LONG *)frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR;
break;
case 16: /* lr */
target = (LONG *)frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR;
break;
}
break;
}
saved_inst = *pc;
mem_write (pc, breakpoint_insn, BREAKPOINT_SIZE);
saved_inst_pc = pc;
if (target != pc)
{
saved_target_inst = *target;
mem_write (target, breakpoint_insn, BREAKPOINT_SIZE);
saved_target_inst_pc = target;
}
}
/* Remove step breakpoints. Returns non-zero if pc was at a step breakpoint,
zero otherwise. This routine works even if there were no step breakpoints
set. */
int
clear_step_traps (frame)
struct StackFrame *frame;
{
int retcode;
LONG *pc = (LONG *)frame->ExceptionPC;
if (saved_inst_pc == pc || saved_target_inst_pc == pc)
retcode = 1;
else
retcode = 0;
if (saved_inst_pc)
{
mem_write (saved_inst_pc, saved_inst, BREAKPOINT_SIZE);
saved_inst_pc = 0;
}
if (saved_target_inst_pc)
{
mem_write (saved_target_inst_pc, saved_target_inst, BREAKPOINT_SIZE);
saved_target_inst_pc = 0;
}
return retcode;
}
void
do_status (ptr, frame)
char *ptr;
struct StackFrame *frame;
{
int sigval;
sigval = computeSignal (frame->ExceptionNumber);
sprintf (ptr, "T%02x", sigval);
ptr += 3;
sprintf (ptr, "%02x:", PC_REGNUM);
ptr = mem2hex (&frame->ExceptionPC, ptr + 3, 4, 0);
*ptr++ = ';';
sprintf (ptr, "%02x:", SP_REGNUM);
ptr = mem2hex (&frame->ExceptionState.CsavedRegs[SP_REGNUM], ptr + 3, 4, 0);
*ptr++ = ';';
sprintf (ptr, "%02x:", LR_REGNUM);
ptr = mem2hex (&frame->ExceptionState.CsavedRegs[LR_REGNUM], ptr + 3, 4, 0);
*ptr++ = ';';
*ptr = '\000';
}

165
gnu/dist/gdb/nlm/ppc.h vendored
View File

@ -1,165 +0,0 @@
typedef long Long;
/* The following enum is used to access the special registers in
the saved machine state. */
typedef enum
{
kDc_SavedPC = 0, /* really SRR0 */
kDc_SavedMSR = 1, /* really SRR1 */
kDc_SavedCR = 2,
kDc_SavedLR = 3,
kDc_SavedDSISR = 4,
kDc_SavedDAR = 5,
kDc_SavedXER = 6,
kDc_SavedCTR = 7,
kDc_SavedSDR1 = 8,
kDc_SavedRTCU = 9,
kDc_SavedRTCL = 10,
kDc_SavedDEC = 11,
kDc_SavedSR00 = 12, /* The Segement Registers are consecutive */
kDc_SavedSR01 = 13, /* kDc_SavedSR00 + n is supported */
kDc_SavedSR02 = 14,
kDc_SavedSR03 = 15,
kDc_SavedSR04 = 16,
kDc_SavedSR05 = 17,
kDc_SavedSR06 = 18,
kDc_SavedSR07 = 19,
kDc_SavedSR08 = 20,
kDc_SavedSR09 = 21,
kDc_SavedSR10 = 22,
kDc_SavedSR11 = 23,
kDc_SavedSR12 = 24,
kDc_SavedSR13 = 25,
kDc_SavedSR14 = 26,
kDc_SavedSR15 = 27,
kDc_SavedFPSCR = 29,
kDc_SavedMQ = 30,
kDc_SavedBAT0U = 31,
kDc_SavedBAT0L = 32,
kDc_SavedBAT1U = 33,
kDc_SavedBAT1L = 34,
kDc_SavedBAT2U = 35,
kDc_SavedBAT2L = 36,
kDc_SavedBAT3U = 37,
kDc_SavedBAT3L = 38,
kNumberSpecialRegisters = 39
} Dc_SavedRegisterName;
/* Access to floating points is not very easy. This allows the number to be
accessed both as a floating number and as a pair of Longs. */
typedef union
{
double asfloat; /* access the variable as a floating number */
struct
{
Long high;
Long low;
}
asLONG; /* access the variable as two Longs */
} FloatingPoints;
/* The following is the standard record for Saving a machine state */
struct SavedMachineState
{
FloatingPoints CSavedFPRegs[32]; /* The floating point registers [0->31] */
/* ***32bit assumption*** */
Long CsavedRegs[32]; /* space to save the General Registers */
/* These are saved 0->31 */
Long CexReason;
Long SavedDomainID;
union
{ /* must be 8-byte aligned, so doubleFPSCR is 8-byte aligned */
struct
{
Long CsavedSRR0; /* Index 0 - The saved PC */
Long CsavedSRR1; /* 1 saved MSR */
Long CsavedCR; /* 2 */
Long CsavedLR; /* 3 */
Long CsavedDSISR; /* 4 */
Long CsavedDAR; /* 5 */
Long CsavedXER; /* 6 */
Long CsavedCTR; /* 7 */
Long CsavedSDR1; /* 8 */
Long CsavedRTCU; /* 9 */
Long CsavedRTCL; /* 10 */
Long CsavedDEC; /* 11 */
Long CsavedSR0; /* 12 */
Long CsavedSR1; /* 13 */
Long CsavedSR2; /* 14 */
Long CsavedSR3; /* 15 */
Long CsavedSR4; /* 16 */
Long CsavedSR5; /* 17 */
Long CsavedSR6; /* 18 */
Long CsavedSR7; /* 19 */
Long CsavedSR8; /* 20 */
Long CsavedSR9; /* 21 */
Long CsavedSR10; /* 22 */
Long CsavedSR11; /* 23 */
Long CsavedSR12; /* 24 */
Long CsavedSR13; /* 25 */
Long CsavedSR14; /* 26 */
Long CsavedSR15; /* 27 */
/* CdoubleFPSCR must be double word aligned */
Long CdoubleFPSCR; /* 28 this is the upper part of the store and has
no meaning */
Long CsavedFPSCR; /* 29 */
Long CsavedMQ; /* 30 */
Long CsavedBAT0U; /* 31 */
Long CsavedBAT0L; /* 32 */
Long CsavedBAT1U; /* 33 */
Long CsavedBAT1L; /* 34 */
Long CsavedBAT2U; /* 35 */
Long CsavedBAT2L; /* 36 */
Long CsavedBAT3U; /* 37 */
Long CsavedBAT3L; /* 38 */
}
SpecialRegistersEnumerated;
Long SpecialRegistersIndexed[kNumberSpecialRegisters];
} u;
Long Padding[3]; /* Needed for quad-word alignment */
};
struct StackFrame
{
LONG *ExceptionDomainID;
/*ProcessorStructure*/ int *ExceptionProcessorID;
BYTE *ExceptionDescription;
LONG ExceptionFlags;
LONG ExceptionErrorCode;
LONG ExceptionNumber;
struct SavedMachineState ExceptionState;
};
/* Register values. All of these values *MUST* agree with tm.h */
#define GP0_REGNUM 0 /* GPR register 0 */
#define SP_REGNUM 1 /* Contains address of top of stack */
#define FP0_REGNUM 32 /* FPR (Floating point) register 0 */
#define PC_REGNUM 64 /* Contains program counter */
#define PS_REGNUM 65 /* Processor (or machine) status (%msr) */
#define CR_REGNUM 66 /* Condition register */
#define LR_REGNUM 67 /* Link register */
#define CTR_REGNUM 68 /* Count register */
#define XER_REGNUM 69 /* Fixed point exception registers */
#define MQ_REGNUM 70 /* Multiply/quotient register */
#define NUM_REGS 71 /* Number of machine registers */
#define REGISTER_BYTES (420) /* Total size of registers array */
#define ExceptionPC ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR0
#define DECR_PC_AFTER_BREAK 0 /* PPCs get this right! */
#define BREAKPOINT {0x7d, 0x82, 0x10, 0x08}
extern unsigned char breakpoint_insn[];
#define BREAKPOINT_SIZE 4
#if 0
#define ALTERNATE_MEM_FUNCS /* We need our own get_char/set_char */
#endif
extern int get_char (char *addr);
extern void set_char (char *addr, int val);

View File

@ -1,67 +0,0 @@
/*===========================================================================
= Novell Standard C Library for NetWare Loadable Modules
=
= Unpublished Copyright (C) 1993 by Novell, Inc. All rights reserved.
=
= No part of this file may be duplicated, revised, translated, localized or
= modified in any manner or compiled, linked or uploaded or downloaded to or
= from any computer system without the prior written consent of Novell, Inc.
==============================================================================
= The object produced by compiling this file is for use by the client of this
= library and is not linked in; Prelude.Obj is therefore one of the files to
= be distributed with CLib.NLM and its headers.
==============================================================================
*/
#include <stddef.h>
#if defined(__netware__) && defined(__i386__)
#define TERMINATE_BY_UNLOAD 5
#else
#include <nwpre.h>
#endif
/*#include "libhooks.h"*/
extern int main (int, char **);
static int NLMID;
void _Stop( void )
{
_TerminateNLM(NLMID, NULL, TERMINATE_BY_UNLOAD);
}
int _cstart_( void )
{
return _SetupArgv(main);
}
int _Prelude
(
int NLMHandle,
int initErrorScreenID,
char *commandLine,
char *loadDirectoryPath,
int uninitializedDataLength,
int NLMFileHandle,
int (*readRoutineP)(),
int customDataOffset,
int customDataSize
)
{
int rc;
rc = _StartNLM(NLMHandle,
initErrorScreenID,
commandLine,
loadDirectoryPath,
uninitializedDataLength,
NLMFileHandle,
readRoutineP,
customDataOffset,
customDataSize,
&NLMID,
_cstart_);
return rc;
}

View File

@ -1,457 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
* Header file for thread synchrounous I/O
*/
#ifndef CMA_THREAD_IO
#define CMA_THREAD_IO
/*
* INCLUDE FILES
*/
#include <cma_config.h>
#include <sys/file.h>
#include <cma.h>
#include <sys/types.h>
#include <sys/time.h>
#include <cma_init.h>
#include <cma_errors.h>
/*
* CONSTANTS
*/
/*
* Define symbols which indicate whether to compile code for obsolete
* "non-blocking mode" flags: FNDELAY and FNBLOCK. If the obsolete
* symbols are defined, and if their replacement symbols are defined
* and are different or if they are undefined, then define a symbol
* that says to compile the code in; otherwise no code will be compiled
* for these obsolete symbols.
*/
#ifdef FNDELAY
# ifdef O_NDELAY
# if O_NDELAY != FNDELAY
# define _CMA_FNDELAY_
# endif
# else
# define _CMA_FNDELAY_
# endif
#endif
#ifdef FNBLOCK
# ifdef O_NONBLOCK
# if O_NONBLOCK != FNBLOCK
# define _CMA_FNBLOCK_
# endif
# else
# define _CMA_FNBLOCK_
# endif
#endif
extern cma_t_boolean cma_is_open(int);
/*
* Maximum number of files (ie, max_fd+1)
*/
#define cma__c_mx_file FD_SETSIZE
/*
* Number of bits per file descriptor bit mask (ie number of bytes * bits/byte)
*/
#define cma__c_nbpm NFDBITS
/*
* TYPE DEFINITIONS
*/
typedef enum CMA__T_IO_TYPE {
cma__c_io_read = 0,
cma__c_io_write = 1,
cma__c_io_except = 2
} cma__t_io_type;
#define cma__c_max_io_type 2
/*
* From our local <sys/types.h>:
*
* typedef long fd_mask;
*
* typedef struct fd_set {
* fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
* } fd_set;
*
*/
typedef fd_mask cma__t_mask;
typedef fd_set cma__t_file_mask;
/*
* GLOBAL DATA
*/
/*
* Maximum number of files (ie, max_fd+1) as determined by getdtablesize().
*/
extern int cma__g_mx_file;
/*
* Number of submasks (ie "int" sized chunks) per file descriptor mask as
* determined by getdtablesize().
*/
extern int cma__g_nspm;
/*
* MACROS
*/
/*
* Define a constant for the errno value which indicates that the requested
* operation was not performed because it would block the process.
*/
# define cma__is_blocking(s) \
((s == EAGAIN) || (s == EWOULDBLOCK) || (s == EINPROGRESS) || \
(s == EALREADY) || (s == EDEADLK))
/*
* It is necessary to issue an I/O function, before calling cma__io_wait()
* in the following cases:
*
* * This file descriptor has been set non-blocking by CMA
* * This file descriptor has been set non-blocking by the user.
*/
#define cma__issue_io_call(fd) \
( (cma__g_file[fd]->non_blocking) || \
(cma__g_file[fd]->user_fl.user_non_blocking) )
#define cma__set_user_nonblocking(flags) \
/*
* Determine if the file is open
*/
/*
* If the file gets closed while waiting for the mutex cma__g_file[rfd]
* gets set to null. This results in a crash if NDEBUG is set to 0
* since cma__int_lock tries to dereference it to set the mutex ownership
* after it gets the mutex. The following will still set the ownership
* in cma__int_lock so we'll set it back to noone if cma__g_file is null
* when we come back just in case it matters. It shouldn't since its no
* longer in use but.....
* Callers of this should recheck cma__g_file after the reservation to
* make sure continueing makes sense.
*/
#define cma__fd_reserve(rfd) \
{ \
cma__t_int_mutex *__mutex__; \
__mutex__ = cma__g_file[rfd]->mutex; \
cma__int_lock (__mutex__); \
if(cma__g_file[rfd] == (cma__t_file_obj *)cma_c_null_ptr) \
cma__int_unlock(__mutex__); \
}
/*
* Unreserve a file descriptor
*/
#define cma__fd_unreserve(ufd) cma__int_unlock (cma__g_file[ufd]->mutex)
/*
* AND together two select file descriptor masks
*/
#define cma__fdm_and(target,a,b) \
{ \
int __i__ = cma__g_nspm; \
while (__i__--) \
(target)->fds_bits[__i__] = \
(a)->fds_bits[__i__] & (b)->fds_bits[__i__]; \
}
/*
* Clear a bit in a select file descriptor mask
*
* FD_CLR(n, p) := ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
*/
#define cma__fdm_clr_bit(n,p) FD_CLR (n, p)
/*
* Copy the contents of one file descriptor mask into another. If the
* destination operand is null, do nothing; if the source operand is null,
* simply zero the destination.
*/
#define cma__fdm_copy(src,dst,nfds) { \
if (dst) \
if (src) { \
cma__t_mask *__s__ = (cma__t_mask *)(src); \
cma__t_mask *__d__ = (cma__t_mask *)(dst); \
int __i__; \
for (__i__ = 0; __i__ < (nfds); __i__ += cma__c_nbpm) \
*__d__++ = *__s__++; \
} \
else \
cma__fdm_zero (dst); \
}
/*
* To increment count for each bit set in fd - mask
*/
#define cma__fdm_count_bits(map,count) \
{ \
int __i__ = cma__g_nspm; \
while (__i__--) { \
cma__t_mask __tm__; \
__tm__ = (map)->fds_bits[__i__]; \
while(__tm__) { \
(count)++; \
__tm__ &= ~(__tm__ & (-__tm__)); /* Assumes 2's comp */ \
} \
} \
}
/*
* Test if a bit is set in a select file descriptor mask
*
* FD_ISSET(n,p) := ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
*/
#define cma__fdm_is_set(n,p) FD_ISSET (n, p)
/*
* OR together two select file descriptor masks
*/
#define cma__fdm_or(target,a,b) \
{ \
int __i__ = cma__g_nspm; \
while (__i__--) \
(target)->fds_bits[__i__] = \
(a)->fds_bits[__i__] | (b)->fds_bits[__i__]; \
}
/*
* Set a bit in a select file descriptor mask
*
* FD_SET(n,p) := ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
*/
#define cma__fdm_set_bit(n,p) FD_SET (n, p)
/*
* Clear a select file descriptor mask.
*/
#define cma__fdm_zero(n) \
cma__memset ((char *) n, 0, cma__g_nspm * sizeof(cma__t_mask))
/*
* CMA "thread-synchronous" I/O read/write operations
*/
/*
* Since all CMA "thread-synchronous" I/O (read or write) operations on
* U*ix follow the exact same structure, the wrapper routines have been
* condensed into a macro.
*
* The steps performed are as follows:
* 1. Check that the file descriptor is a legitimate value.
* 2. Check that the entry in the CMA file "database" which corresponds to
* the file descriptor indicates that the "file" was "opened" by CMA.
* 3. Reserve the file, to serialized access to files. This not only
* simplifies things, but also defends against non-reentrancy.
* 4. If the "file" is "set" for non-blocking I/O, check if we
* have actually set the file non-blocking yet, and if not do so.
* Then, issue the I/O operantion.
* Success or failure is returned immediately, after unreserving the
* file. If the error indicates that the operation would have caused
* the process to block, continue to the next step.
* 5. The I/O prolog adds this "file" to the global bit mask, which
* represents all "files" which have threads waiting to perform I/O on
* them, and causes the thread to block on the condition variable for
* this "file". Periodically, a select is done on this global bit
* mask, and the condition variables corresponding to "files" which
* are ready for I/O are signaled, releasing those waiting threads to
* perform their I/O.
* 6. When the thread returns from the I/O prolog, it can (hopefully)
* perform its operation without blocking the process.
* 7. The I/O epilog clears the bit in the global mask and/or signals the
* the next thread waiting for this "file", as appropriate.
* 8. If the I/O failed, continue to loop.
* 9. Finally, the "file" is unreserved, as we're done with it, and the
* result of the operation is returned.
*
*
* Note: currently, we believe that timeslicing which is based on the
* virtual-time timer does not cause system calls to return EINTR.
* Threfore, any EINTR returns are relayed directly to the caller.
* On platforms which do not support a virtual-time timer, the code
* should probably catch EINTR returns and restart the system call.
*/
/*
* This macro is used for both read-type and write-type functions.
*
* Note: the second call to "func" may require being bracketed in a
* cma__interrupt_disable/cma__interrupt_enable pair, but we'll
* wait and see if this is necessary.
*/
#define cma__ts_func(func,fd,arglist,type,post_process) { \
cma_t_integer __res__; \
cma_t_boolean __done__ = cma_c_false; \
if ((fd < 0) || (fd >= cma__g_mx_file)) return (cma__set_errno (EBADF), -1); \
if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
cma__fd_reserve (fd); \
if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
if (cma__issue_io_call(fd)) {\
if ((!cma__g_file[fd]->set_non_blocking) && \
(cma__g_file[fd]->non_blocking == cma_c_true)) \
cma__set_nonblocking(fd); \
cma__interrupt_disable (0); \
TRY { \
__res__ = func arglist; \
} \
CATCH_ALL { \
cma__interrupt_enable (0); \
cma__fd_unreserve (fd); \
RERAISE; \
} \
ENDTRY \
cma__interrupt_enable (0); \
if ((__res__ != -1) \
|| (!cma__is_blocking (errno)) \
|| (cma__g_file[fd]->user_fl.user_non_blocking)) \
__done__ = cma_c_true; \
} \
if (__done__) { \
cma__fd_unreserve (fd); \
} \
else { \
TRY { \
cma__io_prolog (type, fd); \
while (!__done__) { \
cma__io_wait (type, fd); \
__res__ = func arglist; \
if ((__res__ != -1) \
|| (!cma__is_blocking (errno)) \
|| (cma__g_file[fd]->user_fl.user_non_blocking)) \
__done__ = cma_c_true; \
} \
} \
FINALLY { \
cma__io_epilog (type, fd); \
cma__fd_unreserve (fd); \
} \
ENDTRY \
} \
if (__res__ != -1) post_process; \
return __res__; \
}
/*
* Since most CMA "thread-synchronous" I/O ("open"-type) operations on
* U*ix follow the exact same structure, the wrapper routines have been
* condensed into a macro.
*
* The steps performed are as follows:
* 1. Issue the open function.
* 2. If the value returned indicates an error, return it to the caller.
* 3. If the file descriptor returned is larger than what we think is the
* maximum value (ie if it is too big for our database) then bugcheck.
* 4. "Open" the "file" in the CMA file database.
* 5. Return the file descriptor value to the caller.
*
* FIX-ME: for the time being, if the I/O operation returns EINTR, we
* simply return it to the caller; eventually, we should catch this
* and "do the right thing" (if we can figure out what that is).
*/
/*
* This macro is used for all "open"-type functions which return a single file
* desciptor by immediate value.
*/
#define cma__ts_open(func,arglist,post_process) { \
int __fd__; \
TRY { \
cma__int_init (); \
cma__int_lock (cma__g_io_data_mutex); \
__fd__ = func arglist; \
cma__int_unlock (cma__g_io_data_mutex); \
if (__fd__ >= 0 && __fd__ < cma__g_mx_file) \
post_process; \
} \
CATCH_ALL \
{ \
cma__set_errno (EBADF); \
__fd__ = -1; \
} \
ENDTRY \
if (__fd__ >= cma__g_mx_file) \
cma__bugcheck ("cma__ts_open: fd is too large"); \
return __fd__; \
}
/*
* This macro is used for all "open"-type functions which return a pair of file
* desciptors by reference parameter.
*/
#define cma__ts_open2(func,fdpair,arglist,post_process) { \
int __res__; \
TRY { \
cma__int_init (); \
cma__int_lock (cma__g_io_data_mutex); \
__res__ = func arglist; \
cma__int_unlock (cma__g_io_data_mutex); \
if (__res__ >= 0 && fdpair[0] < cma__g_mx_file \
&& fdpair[1] < cma__g_mx_file) \
post_process; \
} \
CATCH_ALL \
{ \
cma__set_errno (EBADF); \
__res__ = -1; \
} \
ENDTRY \
if ((fdpair[0] >= cma__g_mx_file) || (fdpair[1] >= cma__g_mx_file)) \
cma__bugcheck ("cma__ts_open2: one of fd's is too large"); \
return __res__; \
}
/*
* INTERNAL INTERFACES
*/
extern void cma__close_general (int);
extern void cma__init_thread_io (void);
extern cma_t_boolean cma__io_available (cma__t_io_type,int,struct timeval *);
extern void cma__io_epilog (cma__t_io_type,int);
extern void cma__io_prolog (cma__t_io_type,int);
extern void cma__io_wait (cma__t_io_type,int);
extern void cma__open_general (int);
extern void cma__reinit_thread_io (int);
extern void cma__set_nonblocking (int);
extern void cma__set_user_nonblock_flags (int,int);
extern cma_t_boolean cma__is_open (int);
#endif

View File

@ -1,432 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
*
* Header file for thread synchrounous I/O
*/
#ifndef CMA_THREAD_IO
#define CMA_THREAD_IO
/*
* INCLUDE FILES
*/
#include <cma_config.h>
#include <sys/file.h>
#include <cma.h>
#include <sys/types.h>
#include <sys/time.h>
#include <cma_init.h>
#include <cma_errors.h>
/*
* CONSTANTS
*/
/*
* Maximum number of files (ie, max_fd+1)
*/
#define cma__c_mx_file FD_SETSIZE
/*
* Number of bits per file descriptor bit mask (ie number of bytes * bits/byte)
*/
#define cma__c_nbpm NFDBITS
/*
* TYPE DEFINITIONS
*/
typedef enum CMA__T_IO_TYPE {
cma__c_io_read = 0,
cma__c_io_write = 1,
cma__c_io_except = 2
} cma__t_io_type;
#define cma__c_max_io_type 2
/*
* From our local <sys/types.h>:
*
* typedef long fd_mask;
*
* typedef struct fd_set {
* fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
* } fd_set;
*
*/
typedef fd_mask cma__t_mask;
typedef fd_set cma__t_file_mask;
/*
* GLOBAL DATA
*/
/*
* Maximum number of files (ie, max_fd+1) as determined by getdtablesize().
*/
extern int cma__g_mx_file;
/*
* Number of submasks (ie "int" sized chunks) per file descriptor mask as
* determined by getdtablesize().
*/
extern int cma__g_nspm;
/*
* MACROS
*/
/*
* Define a constant for the errno value which indicates that the requested
* operation was not performed because it would block the process.
*/
# define cma__is_blocking(s) \
((s == EAGAIN) || (s == EWOULDBLOCK) || (s == EINPROGRESS) || \
(s == EALREADY) || (s == EDEADLK))
/*
* It is necessary to issue an I/O function, before calling cma__io_wait()
* in the following cases:
*
* * This file descriptor has been set non-blocking by CMA
* * This file descriptor has been set non-blocking by the user.
*/
#define cma__issue_io_call(fd) \
( (cma__g_file[fd]->non_blocking) || \
(cma__g_file[fd]->user_fl.user_non_blocking) )
#define cma__set_user_nonblocking(flags) \
/*
* Determine if the file is open
*/
/*
* If the file gets closed while waiting for the mutex cma__g_file[rfd]
* gets set to null. This results in a crash if NDEBUG is set to 0
* since cma__int_lock tries to dereference it to set the mutex ownership
* after it gets the mutex. The following will still set the ownership
* in cma__int_lock so we'll set it back to noone if cma__g_file is null
* when we come back just in case it matters. It shouldn't since its no
* longer in use but.....
* Callers of this should recheck cma__g_file after the reservation to
* make sure continueing makes sense.
*/
#define cma__fd_reserve(rfd) \
{ \
cma__t_int_mutex *__mutex__; \
__mutex__ = cma__g_file[rfd]->mutex; \
cma__int_lock (__mutex__); \
if(cma__g_file[rfd] == (cma__t_file_obj *)cma_c_null_ptr) \
cma__int_unlock(__mutex__); \
}
/*
* Unreserve a file descriptor
*/
#define cma__fd_unreserve(ufd) cma__int_unlock (cma__g_file[ufd]->mutex)
/*
* AND together two select file descriptor masks
*/
#define cma__fdm_and(target,a,b) \
{ \
int __i__ = cma__g_nspm; \
while (__i__--) \
(target)->fds_bits[__i__] = \
(a)->fds_bits[__i__] & (b)->fds_bits[__i__]; \
}
/*
* Clear a bit in a select file descriptor mask
*
* FD_CLR(n, p) := ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
*/
#define cma__fdm_clr_bit(n,p) FD_CLR (n, p)
/*
* Copy the contents of one file descriptor mask into another. If the
* destination operand is null, do nothing; if the source operand is null,
* simply zero the destination.
*/
#define cma__fdm_copy(src,dst,nfds) { \
if (dst) \
if (src) { \
cma__t_mask *__s__ = (cma__t_mask *)(src); \
cma__t_mask *__d__ = (cma__t_mask *)(dst); \
int __i__; \
for (__i__ = 0; __i__ < (nfds); __i__ += cma__c_nbpm) \
*__d__++ = *__s__++; \
} \
else \
cma__fdm_zero (dst); \
}
/*
* To increment count for each bit set in fd - mask
*/
#define cma__fdm_count_bits(map,count) \
{ \
int __i__ = cma__g_nspm; \
while (__i__--) { \
cma__t_mask __tm__; \
__tm__ = (map)->fds_bits[__i__]; \
while(__tm__) { \
(count)++; \
__tm__ &= ~(__tm__ & (-__tm__)); /* Assumes 2's comp */ \
} \
} \
}
/*
* Test if a bit is set in a select file descriptor mask
*
* FD_ISSET(n,p) := ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
*/
#define cma__fdm_is_set(n,p) FD_ISSET (n, p)
/*
* OR together two select file descriptor masks
*/
#define cma__fdm_or(target,a,b) \
{ \
int __i__ = cma__g_nspm; \
while (__i__--) \
(target)->fds_bits[__i__] = \
(a)->fds_bits[__i__] | (b)->fds_bits[__i__]; \
}
/*
* Set a bit in a select file descriptor mask
*
* FD_SET(n,p) := ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
*/
#define cma__fdm_set_bit(n,p) FD_SET (n, p)
/*
* Clear a select file descriptor mask.
*/
#define cma__fdm_zero(n) \
cma__memset ((char *) n, 0, cma__g_nspm * sizeof(cma__t_mask))
/*
* CMA "thread-synchronous" I/O read/write operations
*/
/*
* Since all CMA "thread-synchronous" I/O (read or write) operations on
* U*ix follow the exact same structure, the wrapper routines have been
* condensed into a macro.
*
* The steps performed are as follows:
* 1. Check that the file descriptor is a legitimate value.
* 2. Check that the entry in the CMA file "database" which corresponds to
* the file descriptor indicates that the "file" was "opened" by CMA.
* 3. Reserve the file, to serialized access to files. This not only
* simplifies things, but also defends against non-reentrancy.
* 4. If the "file" is "set" for non-blocking I/O, check if we
* have actually set the file non-blocking yet, and if not do so.
* Then, issue the I/O operantion.
* Success or failure is returned immediately, after unreserving the
* file. If the error indicates that the operation would have caused
* the process to block, continue to the next step.
* 5. The I/O prolog adds this "file" to the global bit mask, which
* represents all "files" which have threads waiting to perform I/O on
* them, and causes the thread to block on the condition variable for
* this "file". Periodically, a select is done on this global bit
* mask, and the condition variables corresponding to "files" which
* are ready for I/O are signaled, releasing those waiting threads to
* perform their I/O.
* 6. When the thread returns from the I/O prolog, it can (hopefully)
* perform its operation without blocking the process.
* 7. The I/O epilog clears the bit in the global mask and/or signals the
* the next thread waiting for this "file", as appropriate.
* 8. If the I/O failed, continue to loop.
* 9. Finally, the "file" is unreserved, as we're done with it, and the
* result of the operation is returned.
*
*
* Note: currently, we believe that timeslicing which is based on the
* virtual-time timer does not cause system calls to return EINTR.
* Threfore, any EINTR returns are relayed directly to the caller.
* On platforms which do not support a virtual-time timer, the code
* should probably catch EINTR returns and restart the system call.
*/
/*
* This macro is used for both read-type and write-type functions.
*
* Note: the second call to "func" may require being bracketed in a
* cma__interrupt_disable/cma__interrupt_enable pair, but we'll
* wait and see if this is necessary.
*/
#define cma__ts_func(func,fd,arglist,type,post_process) { \
cma_t_integer __res__; \
cma_t_boolean __done__ = cma_c_false; \
if ((fd < 0) || (fd >= cma__g_mx_file)) return (cma__set_errno (EBADF), -1); \
if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
cma__fd_reserve (fd); \
if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
if (cma__issue_io_call(fd)) {\
if ((!cma__g_file[fd]->set_non_blocking) && \
(cma__g_file[fd]->non_blocking == cma_c_true)) \
cma__set_nonblocking(fd); \
cma__interrupt_disable (0); \
TRY { \
__res__ = func arglist; \
} \
CATCH_ALL { \
cma__interrupt_enable (0); \
cma__fd_unreserve (fd); \
RERAISE; \
} \
ENDTRY \
cma__interrupt_enable (0); \
if ((__res__ != -1) \
|| (!cma__is_blocking (errno)) \
|| (cma__g_file[fd]->user_fl.user_non_blocking)) \
__done__ = cma_c_true; \
} \
if (__done__) { \
cma__fd_unreserve (fd); \
} \
else { \
TRY { \
cma__io_prolog (type, fd); \
while (!__done__) { \
cma__io_wait (type, fd); \
__res__ = func arglist; \
if ((__res__ != -1) \
|| (!cma__is_blocking (errno)) \
|| (cma__g_file[fd]->user_fl.user_non_blocking)) \
__done__ = cma_c_true; \
} \
} \
FINALLY { \
cma__io_epilog (type, fd); \
cma__fd_unreserve (fd); \
} \
ENDTRY \
} \
if (__res__ != -1) post_process; \
return __res__; \
}
/*
* Since most CMA "thread-synchronous" I/O ("open"-type) operations on
* U*ix follow the exact same structure, the wrapper routines have been
* condensed into a macro.
*
* The steps performed are as follows:
* 1. Issue the open function.
* 2. If the value returned indicates an error, return it to the caller.
* 3. If the file descriptor returned is larger than what we think is the
* maximum value (ie if it is too big for our database) then bugcheck.
* 4. "Open" the "file" in the CMA file database.
* 5. Return the file descriptor value to the caller.
*
* FIX-ME: for the time being, if the I/O operation returns EINTR, we
* simply return it to the caller; eventually, we should catch this
* and "do the right thing" (if we can figure out what that is).
*/
/*
* This macro is used for all "open"-type functions which return a single file
* desciptor by immediate value.
*/
#define cma__ts_open(func,arglist,post_process) { \
int __fd__; \
TRY { \
cma__int_init (); \
cma__int_lock (cma__g_io_data_mutex); \
__fd__ = func arglist; \
cma__int_unlock (cma__g_io_data_mutex); \
if (__fd__ >= 0 && __fd__ < cma__g_mx_file) \
post_process; \
} \
CATCH_ALL \
{ \
cma__set_errno (EBADF); \
__fd__ = -1; \
} \
ENDTRY \
if (__fd__ >= cma__g_mx_file) \
cma__bugcheck ("cma__ts_open: fd is too large"); \
return __fd__; \
}
/*
* This macro is used for all "open"-type functions which return a pair of file
* desciptors by reference parameter.
*/
#define cma__ts_open2(func,fdpair,arglist,post_process) { \
int __res__; \
TRY { \
cma__int_init (); \
cma__int_lock (cma__g_io_data_mutex); \
__res__ = func arglist; \
cma__int_unlock (cma__g_io_data_mutex); \
if (__res__ >= 0 && fdpair[0] < cma__g_mx_file \
&& fdpair[1] < cma__g_mx_file) \
post_process; \
} \
CATCH_ALL \
{ \
cma__set_errno (EBADF); \
__res__ = -1; \
} \
ENDTRY \
if ((fdpair[0] >= cma__g_mx_file) || (fdpair[1] >= cma__g_mx_file)) \
cma__bugcheck ("cma__ts_open2: one of fd's is too large"); \
return __res__; \
}
/*
* INTERNAL INTERFACES
*/
extern void cma__close_general (int);
extern void cma__init_thread_io (void);
extern cma_t_boolean cma__io_available (cma__t_io_type,int,struct timeval *);
extern void cma__io_epilog (cma__t_io_type,int);
extern void cma__io_prolog (cma__t_io_type,int);
extern void cma__io_wait (cma__t_io_type,int);
extern void cma__open_general (int);
extern void cma__reinit_thread_io (int);
extern void cma__set_nonblocking (int);
extern void cma__set_user_nonblock_flags (int,int);
extern cma_t_boolean cma__is_open (int);
#endif

View File

@ -1,8 +0,0 @@
This directory contains header files necessary to build a thread-aware GDB on
systems based on OSF's CMA threads package.
The latest version of these header files are available for free from:
http://www.osf.org/mall/dce/SW-code
Currently, the only port of GDB which supports CMA threads is HP/UX-10.10.

View File

@ -1,434 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
* Header file for thread synchrounous I/O
*/
#ifndef CMA_THREAD_IO
#define CMA_THREAD_IO
/*
* INCLUDE FILES
*/
#include <cma_config.h>
#include <sys/select.h>
#include <cma.h>
#include <sys/types.h>
#include <sys/time.h>
#include <cma_init.h>
#include <cma_errors.h>
/*
* CONSTANTS
*/
/*
* Maximum number of files (ie, max_fd+1)
*/
#define cma__c_mx_file FD_SETSIZE
/*
* Number of bits per file descriptor bit mask (ie number of bytes * bits/byte)
*/
#define cma__c_nbpm NFDBITS
/*
* TYPE DEFINITIONS
*/
typedef enum CMA__T_IO_TYPE {
cma__c_io_read = 0,
cma__c_io_write = 1,
cma__c_io_except = 2
} cma__t_io_type;
#define cma__c_max_io_type 2
/*
* From our local <sys/types.h>:
*
* typedef long fd_mask;
*
* typedef struct fd_set {
* fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
* } fd_set;
*
*/
typedef fd_mask cma__t_mask;
typedef fd_set cma__t_file_mask;
/*
* GLOBAL DATA
*/
/*
* Maximum number of files (ie, max_fd+1) as determined by getdtablesize().
*/
extern int cma__g_mx_file;
/*
* Number of submasks (ie "int" sized chunks) per file descriptor mask as
* determined by getdtablesize().
*/
extern int cma__g_nspm;
/*
* MACROS
*/
/*
* Define a constant for the errno value which indicates that the requested
* operation was not performed because it would block the process.
*/
# define cma__is_blocking(s) \
((s == EAGAIN) || (s == EWOULDBLOCK) || (s == EINPROGRESS) || \
(s == EALREADY) || (s == EDEADLK))
/*
* It is necessary to issue an I/O function, before calling cma__io_wait()
* in the following cases:
*
* * This file descriptor has been set non-blocking by CMA
* * This file descriptor has been set non-blocking by the user.
*/
#define cma__issue_io_call(fd) \
( (cma__g_file[fd]->non_blocking) || \
(cma__g_file[fd]->user_fl.user_non_blocking) )
#define cma__set_user_nonblocking(flags) \
/*
* Determine if the file is open
*/
/*
* If the file gets closed while waiting for the mutex cma__g_file[rfd]
* gets set to null. This results in a crash if NDEBUG is set to 0
* since cma__int_lock tries to dereference it to set the mutex ownership
* after it gets the mutex. The following will still set the ownership
* in cma__int_lock so we'll set it back to noone if cma__g_file is null
* when we come back just in case it matters. It shouldn't since its no
* longer in use but.....
* Callers of this should recheck cma__g_file after the reservation to
* make sure continueing makes sense.
*/
#define cma__fd_reserve(rfd) \
{ \
cma__t_int_mutex *__mutex__; \
__mutex__ = cma__g_file[rfd]->mutex; \
cma__int_lock (__mutex__); \
if(cma__g_file[rfd] == (cma__t_file_obj *)cma_c_null_ptr) \
cma__int_unlock(__mutex__); \
}
/*
* Unreserve a file descriptor
*/
#define cma__fd_unreserve(ufd) cma__int_unlock (cma__g_file[ufd]->mutex)
/*
* AND together two select file descriptor masks
*/
#define cma__fdm_and(target,a,b) \
{ \
int __i__ = cma__g_nspm; \
while (__i__--) \
(target)->fds_bits[__i__] = \
(a)->fds_bits[__i__] & (b)->fds_bits[__i__]; \
}
/*
* Clear a bit in a select file descriptor mask
*
* FD_CLR(n, p) := ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
*/
#define cma__fdm_clr_bit(n,p) FD_CLR (n, p)
/*
* Copy the contents of one file descriptor mask into another. If the
* destination operand is null, do nothing; if the source operand is null,
* simply zero the destination.
*/
#define cma__fdm_copy(src,dst,nfds) { \
if (dst) \
if (src) { \
cma__t_mask *__s__ = (cma__t_mask *)(src); \
cma__t_mask *__d__ = (cma__t_mask *)(dst); \
int __i__; \
for (__i__ = 0; __i__ < (nfds); __i__ += cma__c_nbpm) \
*__d__++ = *__s__++; \
} \
else \
cma__fdm_zero (dst); \
}
/*
* To increment count for each bit set in fd - mask
*/
#define cma__fdm_count_bits(map,count) \
{ \
int __i__ = cma__g_nspm; \
while (__i__--) { \
cma__t_mask __tm__; \
__tm__ = (map)->fds_bits[__i__]; \
while(__tm__) { \
(count)++; \
__tm__ &= ~(__tm__ & (-__tm__)); /* Assumes 2's comp */ \
} \
} \
}
/*
* Test if a bit is set in a select file descriptor mask
*
* FD_ISSET(n,p) := ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
*/
#define cma__fdm_is_set(n,p) FD_ISSET (n, p)
/*
* OR together two select file descriptor masks
*/
#define cma__fdm_or(target,a,b) \
{ \
int __i__ = cma__g_nspm; \
while (__i__--) \
(target)->fds_bits[__i__] = \
(a)->fds_bits[__i__] | (b)->fds_bits[__i__]; \
}
/*
* Set a bit in a select file descriptor mask
*
* FD_SET(n,p) := ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
*/
#define cma__fdm_set_bit(n,p) FD_SET (n, p)
/*
* Clear a select file descriptor mask.
*/
#define cma__fdm_zero(n) \
cma__memset ((char *) n, 0, cma__g_nspm * sizeof(cma__t_mask))
/*
* CMA "thread-synchronous" I/O read/write operations
*/
/*
* Since all CMA "thread-synchronous" I/O (read or write) operations on
* U*ix follow the exact same structure, the wrapper routines have been
* condensed into a macro.
*
* The steps performed are as follows:
* 1. Check that the file descriptor is a legitimate value.
* 2. Check that the entry in the CMA file "database" which corresponds to
* the file descriptor indicates that the "file" was "opened" by CMA.
* 3. Reserve the file, to serialized access to files. This not only
* simplifies things, but also defends against non-reentrancy.
* 4. If the "file" is "set" for non-blocking I/O, check if we
* have actually set the file non-blocking yet, and if not do so.
* Then, issue the I/O operantion.
* Success or failure is returned immediately, after unreserving the
* file. If the error indicates that the operation would have caused
* the process to block, continue to the next step.
* 5. The I/O prolog adds this "file" to the global bit mask, which
* represents all "files" which have threads waiting to perform I/O on
* them, and causes the thread to block on the condition variable for
* this "file". Periodically, a select is done on this global bit
* mask, and the condition variables corresponding to "files" which
* are ready for I/O are signaled, releasing those waiting threads to
* perform their I/O.
* 6. When the thread returns from the I/O prolog, it can (hopefully)
* perform its operation without blocking the process.
* 7. The I/O epilog clears the bit in the global mask and/or signals the
* the next thread waiting for this "file", as appropriate.
* 8. If the I/O failed, continue to loop.
* 9. Finally, the "file" is unreserved, as we're done with it, and the
* result of the operation is returned.
*
*
* Note: currently, we believe that timeslicing which is based on the
* virtual-time timer does not cause system calls to return EINTR.
* Threfore, any EINTR returns are relayed directly to the caller.
* On platforms which do not support a virtual-time timer, the code
* should probably catch EINTR returns and restart the system call.
*/
/*
* This macro is used for both read-type and write-type functions.
*
* Note: the second call to "func" may require being bracketed in a
* cma__interrupt_disable/cma__interrupt_enable pair, but we'll
* wait and see if this is necessary.
*/
#define cma__ts_func(func,fd,arglist,type,post_process) { \
cma_t_integer __res__; \
cma_t_boolean __done__ = cma_c_false; \
if ((fd < 0) || (fd >= cma__g_mx_file)) return (cma__set_errno (EBADF), -1); \
if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
cma__fd_reserve (fd); \
if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
if (cma__issue_io_call(fd)) {\
if ((!cma__g_file[fd]->set_non_blocking) && \
(cma__g_file[fd]->non_blocking == cma_c_true)) \
cma__set_nonblocking(fd); \
cma__interrupt_disable (0); \
TRY { \
__res__ = func arglist; \
} \
CATCH_ALL { \
cma__interrupt_enable (0); \
cma__fd_unreserve (fd); \
RERAISE; \
} \
ENDTRY \
cma__interrupt_enable (0); \
if ((__res__ != -1) \
|| (!cma__is_blocking (errno)) \
|| (cma__g_file[fd]->user_fl.user_non_blocking)) \
__done__ = cma_c_true; \
} \
if (__done__) { \
cma__fd_unreserve (fd); \
} \
else { \
TRY { \
cma__io_prolog (type, fd); \
while (!__done__) { \
cma__io_wait (type, fd); \
__res__ = func arglist; \
if ((__res__ != -1) \
|| (!cma__is_blocking (errno)) \
|| (cma__g_file[fd]->user_fl.user_non_blocking)) \
__done__ = cma_c_true; \
} \
} \
FINALLY { \
cma__io_epilog (type, fd); \
cma__fd_unreserve (fd); \
} \
ENDTRY \
} \
if (__res__ != -1) post_process; \
return __res__; \
}
/*
* Since most CMA "thread-synchronous" I/O ("open"-type) operations on
* U*ix follow the exact same structure, the wrapper routines have been
* condensed into a macro.
*
* The steps performed are as follows:
* 1. Issue the open function.
* 2. If the value returned indicates an error, return it to the caller.
* 3. If the file descriptor returned is larger than what we think is the
* maximum value (ie if it is too big for our database) then bugcheck.
* 4. "Open" the "file" in the CMA file database.
* 5. Return the file descriptor value to the caller.
*
* FIX-ME: for the time being, if the I/O operation returns EINTR, we
* simply return it to the caller; eventually, we should catch this
* and "do the right thing" (if we can figure out what that is).
*/
/*
* This macro is used for all "open"-type functions which return a single file
* desciptor by immediate value.
*/
#define cma__ts_open(func,arglist,post_process) { \
int __fd__; \
TRY { \
cma__int_init (); \
cma__int_lock (cma__g_io_data_mutex); \
__fd__ = func arglist; \
cma__int_unlock (cma__g_io_data_mutex); \
if (__fd__ >= 0 && __fd__ < cma__g_mx_file) \
post_process; \
} \
CATCH_ALL \
{ \
cma__set_errno (EBADF); \
__fd__ = -1; \
} \
ENDTRY \
if (__fd__ >= cma__g_mx_file) \
cma__bugcheck ("cma__ts_open: fd is too large"); \
return __fd__; \
}
/*
* This macro is used for all "open"-type functions which return a pair of file
* desciptors by reference parameter.
*/
#define cma__ts_open2(func,fdpair,arglist,post_process) { \
int __res__; \
TRY { \
cma__int_init (); \
cma__int_lock (cma__g_io_data_mutex); \
__res__ = func arglist; \
cma__int_unlock (cma__g_io_data_mutex); \
if (__res__ >= 0 && fdpair[0] < cma__g_mx_file \
&& fdpair[1] < cma__g_mx_file) \
post_process; \
} \
CATCH_ALL \
{ \
cma__set_errno (EBADF); \
__res__ = -1; \
} \
ENDTRY \
if ((fdpair[0] >= cma__g_mx_file) || (fdpair[1] >= cma__g_mx_file)) \
cma__bugcheck ("cma__ts_open2: one of fd's is too large"); \
return __res__; \
}
/*
* INTERNAL INTERFACES
*/
extern void cma__close_general (int);
extern void
cma__init_thread_io (void);
extern cma_t_boolean cma__io_available (cma__t_io_type,int,struct timeval *);
extern void cma__io_epilog (cma__t_io_type,int);
extern void cma__io_prolog (cma__t_io_type,int);
extern void cma__io_wait (cma__t_io_type,int);
extern void cma__open_general (int);
extern void cma__reinit_thread_io (int);
extern void cma__set_nonblocking (int);
extern void cma__set_user_nonblock_flags (int,int);
extern cma_t_boolean
cma__is_open (int fd);
#endif

View File

@ -1,341 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
* Header file for attributes object
*/
#ifndef CMA_ATTR
#define CMA_ATTR
/*
* INCLUDE FILES
*/
#include <cma_defs.h>
#include <cma_queue.h>
#ifdef __hpux
# include <sys/param.h>
#endif
#if _CMA_UNIX_TYPE == _CMA__SVR4
#include <sys/unistd.h>
#endif
/*
* CONSTANTS AND MACROS
*/
/*
* FUNCTIONAL DESCRIPTION:
*
* cma__int_attr_get_priority - Performs the work of cma_attr_get_priority
*
* FORMAL PARAMETERS:
*
* cma_t_attr *_att_ - Attribute object to get from
* cma_t_priority *_setting_ - Current setting
*
* IMPLICIT INPUTS:
*
* none
*
* IMPLICIT OUTPUTS:
*
* priority
*
* FUNCTION VALUE:
*
* none
*
* SIDE EFFECTS:
*
* none
*/
#define cma__int_attr_get_priority(_att_,_setting_) { \
cma__t_int_attr *_int_att_; \
(_int_att_) = cma__validate_default_attr (_att_); \
cma__int_lock ((_int_att_)->mutex); \
(*(_setting_)) = (_int_att_)->priority; \
cma__int_unlock ((_int_att_)->mutex); \
}
/*
* FUNCTIONAL DESCRIPTION:
*
* cma__int_attr_get_sched - Performs work of cma_attr_get_sched
*
* FORMAL PARAMETERS:
*
* cma_t_attr *_att_ _ Attributes object used
* cma_t_sched_policy *_setting_ - Current setting
*
* IMPLICIT INPUTS:
*
* none
*
* IMPLICIT OUTPUTS:
*
* scheduling policy
*
* FUNCTION VALUE:
*
* none
*
* SIDE EFFECTS:
*
* none
*/
#define cma__int_attr_get_sched(_att_,_setting_) { \
cma__t_int_attr *_int_att_; \
(_int_att_) = cma__validate_default_attr (_att_); \
cma__int_lock ((_int_att_)->mutex); \
(*(_setting_)) = (_int_att_)->policy; \
cma__int_unlock ((_int_att_)->mutex); \
}
/*
* FUNCTIONAL DESCRIPTION:
*
* cma__int_attr_get_inherit_sched - Performs work of
* cma_attr_get_inherit_sched
*
* FORMAL PARAMETERS:
*
* cma_t_attr *_att_ - Attributes object to use
* cma_t_sched_inherit *_setting_ - Current setting
*
* IMPLICIT INPUTS:
*
* none
*
* IMPLICIT OUTPUTS:
*
* Inheritable scheduling policy
*
* FUNCTION VALUE:
*
* none
*
* SIDE EFFECTS:
*
* none
*/
#define cma__int_attr_get_inherit_sched(_att_,_setting_) { \
cma__t_int_attr *_int_att_; \
(_int_att_) = cma__validate_default_attr (_att_); \
cma__int_lock ((_int_att_)->mutex); \
(*(_setting_)) \
= ((_int_att_)->inherit_sched ? cma_c_sched_inherit : cma_c_sched_use_default); \
cma__int_unlock ((_int_att_)->mutex); \
}
/*
* FUNCTIONAL DESCRIPTION:
*
* cma__int_attr_set_stacksize - Performs work for cma_attr_set_stacksize
*
* FORMAL PARAMETERS:
*
* cma_t_attr *_att_ - Attributes object to use
* cma_t_natural _setting_ - Setting
*
* IMPLICIT INPUTS:
*
* none
*
* IMPLICIT OUTPUTS:
*
* none
*
* FUNCTION VALUE:
*
* none
*
* SIDE EFFECTS:
*
* Change attribute objects stack size setting
*/
#define cma__int_attr_set_stacksize(_att_,_setting_) { \
cma__t_int_attr *_int_att_; \
if ((_setting_) <= 0) \
cma__error (cma_s_badparam); \
_int_att_ = cma__validate_attr (_att_); \
cma__int_lock ((_int_att_)->mutex); \
_int_att_->stack_size = cma__roundup_chunksize(_setting_); \
cma__free_cache (_int_att_, cma__c_obj_tcb); \
_int_att_->cache[cma__c_obj_tcb].revision++; \
_int_att_->cache[cma__c_obj_stack].revision++; \
cma__int_unlock (_int_att_->mutex); \
}
/*
* FUNCTIONAL DESCRIPTION:
*
* cma__int_attr_get_stacksize - Performs work of cma_attr_get_stacksize
*
* FORMAL PARAMETERS:
*
* cma_t_attr *_att_ - Attributes object to use
* cma_t_natural *_setting_ - Current setting
*
* IMPLICIT INPUTS:
*
* none
*
* IMPLICIT OUTPUTS:
*
* Attribute objects stack size setting
*
* FUNCTION VALUE:
*
* none
*
* SIDE EFFECTS:
*
* none
*/
#define cma__int_attr_get_stacksize(_att_,_setting_) { \
cma__t_int_attr *_int_att_; \
(_int_att_) = cma__validate_default_attr (_att_); \
cma__int_lock ((_int_att_)->mutex); \
(*(_setting_)) = (_int_att_)->stack_size; \
cma__int_unlock ((_int_att_)->mutex); \
}
/*
* FUNCTIONAL DESCRIPTION:
*
* cma__int_attr_set_guardsize - Performs work for cma_attr_set_guardsize
*
* FORMAL PARAMETERS:
*
* cma_t_attr *_att_ - Attributes object to use
* cma_t_natural _setting_ - Setting
*
* IMPLICIT INPUTS:
*
* none
*
* IMPLICIT OUTPUTS:
*
* none
*
* FUNCTION VALUE:
*
* none
*
* SIDE EFFECTS:
*
* Change attribute objects guard size setting
*/
#define cma__int_attr_set_guardsize(_att_,_setting_) { \
cma__t_int_attr *_int_att_; \
_int_att_ = cma__validate_attr (_att_); \
cma__int_lock ((_int_att_)->mutex); \
_int_att_->guard_size = cma__roundup_chunksize(_setting_); \
cma__free_cache (_int_att_, cma__c_obj_tcb); \
_int_att_->cache[cma__c_obj_tcb].revision++; \
_int_att_->cache[cma__c_obj_stack].revision++; \
cma__int_unlock (_int_att_->mutex); \
}
/*
* FUNCTIONAL DESCRIPTION:
*
* cma__int_attr_get_guardsize - Performs work of cma_attr_get_guardsize
*
* FORMAL PARAMETERS:
*
* cma_t_attr *_att_ - Attributes object to use
* cma_t_natural *_setting_ - Current setting
*
* IMPLICIT INPUTS:
*
* none
*
* IMPLICIT OUTPUTS:
*
* Attribute objects guard size setting
*
* FUNCTION VALUE:
*
* none
*
* SIDE EFFECTS:
*
* none
*/
#define cma__int_attr_get_guardsize(_att_,_setting_) { \
cma__t_int_attr *_int_att_; \
(_int_att_) = cma__validate_default_attr (_att_); \
cma__int_lock ((_int_att_)->mutex); \
(*(_setting_)) = (_int_att_)->guard_size; \
cma__int_unlock ((_int_att_)->mutex); \
}
/*
* TYPEDEFS
*/
#ifndef __STDC__
struct CMA__T_INT_MUTEX; /* Avoid circular dependency */
#endif
typedef struct CMA__T_CACHE {
cma_t_natural revision; /* Revisions */
cma_t_natural count;
cma__t_queue queue; /* Cache headers */
} cma__t_cache;
typedef struct CMA__T_INT_ATTR {
cma__t_object header; /* Common header */
struct CMA__T_INT_ATTR *attributes; /* Point to controlling attr */
struct CMA__T_INT_MUTEX *mutex; /* Serialize access to object */
cma_t_priority priority; /* Priority of new thread */
cma_t_sched_policy policy; /* Sched policy of thread */
cma_t_boolean inherit_sched; /* Is scheduling inherited? */
cma_t_natural stack_size; /* Size of stack (bytes) */
cma_t_natural guard_size; /* Size of guard (bytes) */
cma_t_mutex_kind mutex_kind; /* Mutex kind */
cma__t_cache cache[cma__c_obj_num]; /* Cache information */
cma_t_boolean delete_pending; /* attr. obj. is deleted */
cma_t_natural refcnt; /* Number of objects using attr. obj */
} cma__t_int_attr;
/*
* GLOBAL DATA
*/
extern cma__t_int_attr cma__g_def_attr;
/*
* INTERNAL INTERFACES
*/
extern void cma__destroy_attributes (cma__t_int_attr *);
extern void cma__free_attributes (cma__t_int_attr *);
extern void cma__free_cache (cma__t_int_attr *,cma_t_natural );
extern cma__t_int_attr *cma__get_attributes (cma__t_int_attr *);
extern void cma__init_attr (void);
extern void cma__reinit_attr (cma_t_integer);
#endif

View File

@ -1,164 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
* This file defines the internal interface to the core of CMA
* debugging services. (The client interface to debugging services
* is provided by cma_debug_client.h).
*/
#ifndef CMA_DEB_CORE
#define CMA_DEB_CORE
/*
* INCLUDE FILES
*/
#include <cma.h>
#include <cma_mutex.h>
#include <cma_queue.h>
#include <cma_tcb_defs.h>
#include <cma_util.h>
/*
* CONSTANTS AND MACROS
*/
/*
* TYPEDEFS
*/
/*FIX-ME* Need to use sizes that are platform specific */
typedef long int cma___t_debug_ctx[17];
/*
* Type defing the format of known object lists
*/
typedef struct CMA__T_KNOWN_OBJECT {
cma__t_queue queue; /* Queue header for known objects */
cma__t_int_mutex *mutex; /* Mutex to control access to queue */
} cma__t_known_object;
/*
* Type defining the registration for one debug client (e.g. Ada)
*/
typedef struct CMA__T_DEB_REGISTRY {
cma_t_address entry; /* Client's debug entry point */
cma_t_key key; /* Client's context key */
cma_t_integer fac; /* Client's debug facility number */
cma_t_boolean has_prolog; /* Client's TCBs have std prolog */
} cma__t_deb_registry;
#define cma__c_deb_max_clients 10
/*
* Type defining the global debugging state for all threads.
*/
typedef struct CMA__T_DEBUG_STATE {
/*
* The following flag is set if changes were made while in the
* debugger that may make the ready lists inconsistent. For
* example, if a thread priority is changed in the debugger, the
* thread is not moved between queues. Making things consistent
* is deferred to when the dispatcher is next invoked -- which we
* try to make very soon.
*/
cma_t_boolean is_inconsistency; /* Ready lists are inconsistent */
cma_t_boolean events_enabled; /* Set if _any_ event is enabled */
cma_t_boolean flags[cma__c_debevt__dim];
/* Which events are enabled */
cma__t_int_tcb *next_to_run; /* TCB of thread to run next */
cma__t_int_mutex *mutex; /* Mutex for registering clients */
cma_t_integer client_count; /* Count of debug clients */
cma__t_deb_registry clients[cma__c_deb_max_clients+1];
/* Array of current debug clients */
} cma__t_debug_state;
/*
* Routine that will symbolize and address and print it.
*/
typedef void (*cma__t_print_symbol) (cma_t_address);
/*
* GLOBAL DATA
*/
/*
* Variable holding the global debugging state
*
* (This is primarily written by the debugger interface and read
* by the thread dispatcher).
*/
extern cma__t_debug_state cma__g_debug_state;
/*
* Known object queues
*/
extern cma__t_known_object cma__g_known_atts;
extern cma__t_known_object cma__g_known_cvs;
extern cma__t_known_object cma__g_known_mutexes;
extern cma__t_known_object cma__g_known_threads;
/*
* INTERNAL INTERFACES
*/
/* Get information while in debugger context */
extern void cma__deb_get
(cma__t_int_tcb *,cma_t_debug_get,cma_t_address,cma_t_integer,cma_t_integer);
/* Set information while in debugger context */
extern void cma__deb_set (cma__t_int_tcb *,cma_t_debug_set,cma_t_address,cma_t_integer);
extern void cma__init_debug (void);
extern void cma__reinit_debug (cma_t_integer);
extern void cma__deb_anytcb_to_tcb (cma_t_tcb_header *,cma__t_int_tcb **);
extern void cma__deb_fac_to_client (cma_t_integer,cma_t_key *);
extern void cma__deb_get_client_info (cma_t_key,cma_t_address *,cma_t_boolean *);
extern void cma__deb_get_context (cma__t_int_tcb *,cma_t_key,cma_t_address *);
extern cma__t_int_tcb *cma__deb_get_self_tcb (void);
extern void cma__deb_get_time_slice (cma_t_interval *);
extern cma__t_int_tcb *cma__deb_next_tcb
(cma__t_int_tcb *,cma_t_integer *,cma_t_integer *,cma_t_boolean *);
extern cma_t_boolean cma__deb_set_alert (cma__t_int_tcb *);
extern void cma__deb_set_next_thread (cma__t_int_tcb *);
extern void cma__deb_set_force_dispatch (cma_t_address );
extern void cma__deb_set_time_slice (cma_t_interval);
extern void cma__deb_show_thread
(cma__t_int_tcb *,cma_t_boolean,cma_t_boolean,cma___t_debug_ctx,cma__t_eol_routine,
cma__t_eol_routine,cma__t_print_symbol);
extern void
cma__deb_show_stats (cma__t_int_tcb *,cma_t_boolean,cma_t_boolean,cma__t_eol_routine,cma__t_eol_routine,cma__t_print_symbol);
#endif

View File

@ -1,195 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
* Header file providing access to CMA clients that implement
* language run-times to the CMA debugger capabilities.
*
* NOTE: the clients that are able to use this interface is
* very limited because clients needing task debugging must have
* support in the system debugger as well as here (at present).
* The following are the only legitimate clients of this interface:
* ADA runtime, C++ tasking library, and CMA.
*
*FIX-ME* We shall endeavor to extend these capabilities so that the
* all-platform CMA debugger CMA_DEBUG and any client can layer
* on thread debugging. But that is still an open design problem.
* The design here does not preclude that extension (for example,
* the identity of the debug-client is indicated in an "open"
* manner by using the CMA context key as the identifier.
*/
#ifndef CMA_DEBUG_CLIENT
#define CMA_DEBUG_CLIENT
/*
* INCLUDE FILES
*/
#include <cma.h>
/*
* CONSTANTS AND MACROS
*/
/*
* TYPEDEFS
*/
/*
* Type describing constants for a valid TCB sentinel.
* Exactly one value is valid, but we provide a symbolic name for
* at least one invalid sentinel as a convenience.
*/
typedef enum CMA_T_TCB_SENTINEL {
cma_c_tcb_sentinel_nogood = 0, /* Invalid sentinel constant */
cma_c_tcb_sentinel = 0x0ACEFACE /* Valid TCB sentinel */
} cma_t_tcb_sentinel;
/*
* Type describing pad fields needed to align the "standard prolog"
* to the right byte at the front of each TCB. These fields are
* free to be put to any use by the client.
*
* This is 32 bytes long and is fixed at this size for all clients
* and CMA, for all time.
*/
typedef struct CMA_T_TCB_PRIVATE {
cma_t_integer pad1;
cma_t_integer pad2;
cma_t_integer pad3;
cma_t_integer pad4;
cma_t_integer pad5;
cma_t_integer pad6;
cma_t_integer pad7;
cma_t_integer pad8;
} cma_t_tcb_private;
/*
* Type describing the "standard prolog" that clients should use
* within their task control blocks. We assume that the client will
* store their "task control block" as a per-thread context under
* the context key specified here.
*/
typedef struct CMA_T_TCB_PROLOG {
cma_t_tcb_sentinel sentinel; /* Validity sentinel */
cma_t_thread client_thread; /* Thread corresonding to task */
cma_t_key client_key; /* Context key this is stored under */
cma_t_address reserved1; /* Must be zero, reserved to CMA */
} cma_t_tcb_prolog;
/*
* Type defining the layout of all TCBs and TASKS. This format
* ensures that tasks will be self-identifying to the debugger.
* this layout must never change as the CMA DEBUG Clients cannot
* be changed after CMA ships.
*/
typedef struct CMA_T_TCB_HEADER {
cma_t_tcb_private IGNORED; /* TCB fields private to the client */
cma_t_tcb_prolog prolog; /* The standard prolog goes here */
} cma_t_tcb_header;
/*
* Type describing the kinds of information that a CMA debug
* client can GET about a thread.
*/
typedef enum CMA_T_DEBUG_GET {
/*
* All of the following items use a buffer whose size is
* four bytes. (That is four must be passed as the buffer_size
* parameter to cma_debug_get.)
*/
cma_c_debget_guardsize = 1, /* Current guard size (bytes) */
cma_c_debget_is_held = 2, /* Is it on hold? */
cma_c_debget_is_initial = 3, /* Is it the initial thread? */
cma_c_debget_number = 4, /* Thread's number */
cma_c_debget_stack_ptr = 5, /* Current stack pointer */
cma_c_debget_stack_base = 6, /* Stack base address */
cma_c_debget_stack_top = 7, /* Stack top address */
cma_c_debget_sched_state = 8, /* Scheduler state
* 0 - run
* 1 - ready
* 2 - blocked
* 3 - terminated
*/
cma_c_debget_reserve_size = 9, /* Size of stack reserve (bytes) */
cma_c_debget_base_prio = 10, /* Base priority */
cma_c_debget_priority = 11, /* Current priority */
cma_c_debget_regs = 12, /* Register set (and proc. state) */
cma_c_debget_alt_pending = 13, /* Alert is pending */
cma_c_debget_alt_a_enable = 14, /* Asynch alert delivery enabled */
cma_c_debget_alt_g_enable = 15, /* General alert delivery enabled */
cma_c_debget_substate = 16, /* Substate (or wait state) */
cma_c_debget_object_addr = 17, /* Address of thread object */
cma_c_debget_thkind = 18, /* Kind of thread */
cma_c_debget_detached = 19, /* Thread is detached */
cma_c_debget_tcb_size = 20, /* TCB size */
cma_c_debget_start_pc = 21, /* Start address */
cma_c_debget_next_pc = 22, /* Next instruction */
cma_c_debget_policy = 23, /* Sched policy */
cma_c_debget_stack_yellow = 24, /* Addr of start of guard area */
cma_c_debget_stack_default = 25 /* True if on default stack */
} cma_t_debug_get;
/*
* Type describing the kinds of information that a CMA debug
* client can SET (or change) about a thread using cma_debug_set.
*/
typedef enum CMA_T_DEBUG_SET {
/*
* All of the following items use a buffer whose size is
* four bytes. (That is four must be passed as the buffer_size
* parameter to cma_debug_set.)
*/
cma_c_debset_priority = 1, /* Set the priority */
cma_c_debset_policy = 2, /* Set the sched policy */
cma_c_debset_hold = 3, /* Put thread on hold */
cma_c_debset_regs = 4 /* Set the regs and proc. state */
} cma_t_debug_set;
/*
* GLOBAL DATA
*
* none
*/
/*
* EXTERNAL INTERFACES
*/
/*
* Routine to register with the CMA debug dispatcher.
*/
extern void cma_debug_register (cma_t_address,cma_t_key,cma_t_integer,cma_t_boolean);
/*
* Routine to get get thread state needed by the CMA debug client.
*/
extern void cma_debug_get (cma_t_thread *,cma_t_debug_get,cma_t_address,cma_t_integer);
/*
* Get thread context given an sp and a key
*/
extern void cma_debug_get_sp_context (cma_t_address,cma_t_key,cma_t_address *);
/*
* Routine to set thread state as needed by the CMA debug client.
*/
extern void cma_debug_set (cma_t_thread *,cma_t_debug_set,cma_t_address,cma_t_integer);
#endif

View File

@ -1,55 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
* This module is the interface between CMA services and
* the platform-specific error reporting mechanism.
*/
#ifndef CMA_ERRORS
#define CMA_ERRORS
/*
* INCLUDE FILES
*/
/*
* CONSTANTS AND MACROS
*/
/*
* TYPEDEFS
*/
/*
* GLOBAL DATA
*/
/*
* INTERNAL INTERFACES
*/
/*
* The cma__bugcheck function will print information to stderr (or sys$error
* on VMS), and more extensive information to the file cma_dump.log in the
* current working directory.
*/
extern void cma__bugcheck (char *,...);
extern void cma__error (int);
extern void cma__unimplemented (void);
#endif

View File

@ -1,182 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
* Header file for handles
*/
#ifndef CMA_HANDLE
#define CMA_HANDLE
/*
* INCLUDE FILES
*/
#include <cma_defs.h>
#include <cma_attr.h>
/*
* CONSTANTS AND MACROS
*/
#define cma__validate_attr(handle) \
((cma__t_int_attr *)cma__validate_handle ( \
(cma_t_handle *)(handle), \
cma__c_obj_attr))
#define cma__validate_cv(handle) \
((cma__t_int_cv *)cma__validate_handle ( \
(cma_t_handle *)(handle), \
cma__c_obj_cv))
#define cma__validate_mutex(handle) \
((cma__t_int_mutex *)cma__validate_handle ( \
(cma_t_handle *)(handle), \
cma__c_obj_mutex))
#define cma__validate_tcb(handle) \
((cma__t_int_tcb *)cma__validate_handle ( \
(cma_t_handle *)(handle), \
cma__c_obj_tcb))
#define cma__validate_stack(handle) \
((cma__t_int_stack *)cma__validate_handle ( \
(cma_t_handle *)(handle), \
cma__c_obj_stack))
#define cma__validate_null_attr(handle) \
((cma__t_int_attr *)cma__validate_handle_null ( \
(cma_t_handle *)(handle), \
cma__c_obj_attr))
#define cma__validate_null_cv(handle) \
((cma__t_int_cv *)cma__validate_handle_null ( \
(cma_t_handle *)(handle), \
cma__c_obj_cv))
#define cma__validate_null_mutex(handle) \
((cma__t_int_mutex *)cma__validate_handle_null ( \
(cma_t_handle *)(handle), \
cma__c_obj_mutex))
#define cma__validate_null_tcb(handle) \
((cma__t_int_tcb *)cma__validate_handle_null ( \
(cma_t_handle *)(handle), \
cma__c_obj_tcb))
#define cma__validate_null_stack(handle) \
((cma__t_int_stack *)cma__validate_handle_null ( \
(cma_t_handle *)(handle), \
cma__c_obj_stack))
#define cma__val_attr_stat(handle,obj) \
cma__val_hand_stat ( \
(cma_t_handle *)(handle), \
cma__c_obj_attr, \
(cma__t_object **)obj)
#define cma__val_cv_stat(handle,obj) \
cma__val_hand_stat ( \
(cma_t_handle *)(handle), \
cma__c_obj_cv, \
(cma__t_object **)obj)
#define cma__val_mutex_stat(handle,obj) \
cma__val_hand_stat ( \
(cma_t_handle *)(handle), \
cma__c_obj_mutex, \
(cma__t_object **)obj)
#define cma__val_tcb_stat(handle) \
cma__val_hand_stat ( \
(cma_t_handle *)(handle), \
cma__c_obj_tcb, \
(cma__t_object **)obj)
#define cma__val_stack_stat(handle,obj) \
cma__val_hand_stat ( \
(cma_t_handle *)(handle), \
cma__c_obj_stack, \
(cma__t_object **)obj)
#define cma__val_nullattr_stat(handle,obj) \
cma__val_handnull_stat ( \
(cma_t_handle *)(handle), \
cma__c_obj_attr, \
(cma__t_object **)obj)
#define cma__val_nullcv_stat(handle,obj) \
cma__val_handnull_stat ( \
(cma_t_handle *)(handle), \
cma__c_obj_cv, \
(cma__t_object **)obj)
#define cma__val_nullmutex_stat(handle,obj) \
cma__val_handnull_stat ( \
(cma_t_handle *)(handle), \
cma__c_obj_mutex, \
(cma__t_object **)obj)
#define cma__val_nulltcb_stat(handle,obj) \
cma__val_handnull_stat ( \
(cma_t_handle *)(handle), \
cma__c_obj_tcb, \
(cma__t_object **)obj)
#define cma__val_nullstack_stat(handle) \
cma__val_handnull_stat ( \
(cma_t_handle *)(handle), \
cma__c_obj_stack, \
(cma__t_object **)obj)
/*
* TYPEDEFS
*/
/*
* Internal format of a handle (to the outside world it's an array of two
* addresses, but we know better).
*/
typedef struct CMA__T_INT_HANDLE {
cma__t_object *pointer; /* Address of internal structure */
cma__t_short sequence; /* Sequence number of object */
cma__t_short type; /* Type code of object */
} cma__t_int_handle;
/*
* GLOBAL DATA
*/
/*
* INTERNAL INTERFACES
*/
extern void cma__clear_handle (cma_t_handle *);
extern void cma__object_to_handle (cma__t_object *,cma_t_handle *);
extern cma__t_int_attr * cma__validate_default_attr (cma_t_handle *);
extern cma_t_status cma__val_defattr_stat (cma_t_handle *,cma__t_int_attr **);
extern cma__t_object * cma__validate_handle (cma_t_handle *,cma_t_natural );
extern cma_t_status cma__val_hand_stat (cma_t_handle *,cma_t_natural,cma__t_object **);
extern cma__t_object *cma__validate_handle_null (cma_t_handle *,cma_t_natural);
extern cma_t_status cma__val_handnull_stat (cma_t_handle *,cma_t_natural,cma__t_object **);
#endif

View File

@ -1,114 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
* Header file for CMA initialization
*/
#ifndef CMA_INIT
#define CMA_INIT
/*
* INCLUDE FILES
*/
#include <dce/cma_host.h>
#include <cma_errors.h>
/*
* CONSTANTS AND MACROS
*/
#define cma__c_env_maxattr 0
#define cma__c_env_minattr 1
#define cma__c_env_maxcond 2
#define cma__c_env_mincond 3
#define cma__c_env_maxmutex 4
#define cma__c_env_minmutex 5
#define cma__c_env_maxthread 6
#define cma__c_env_minthread 7
#define cma__c_env_maxcluster 8
#define cma__c_env_mincluster 9
#define cma__c_env_maxvp 10
#define cma__c_env_multiplex 11
#define cma__c_env_trace 12
#define cma__c_env_trace_file 13
#define cma__c_env_count 13
/*
* cma__int_init
*
* Initialize the main body of CMA exactly once.
*
* We raise an exception if, for some odd reason, there are already threads
* in the environment (e.g. kernel threads), and one of them is trying to
* initialize CMA before the first thread got all the way through the actual
* initialization. This code maintains the invariants: "after successfully
* calling CMA_INIT, you can call any CMA function", and "CMA is actually
* initialized at most once".
*/
/*#ifndef _HP_LIBC_R */
#if defined _HP_LIBC_R ||(defined(SNI_SVR4) && !defined(CMA_INIT_NEEDED))
# define cma__int_init()
#else
# define cma__int_init() { \
if (!cma__tac_isset(&cma__g_init_started)) { \
if (!cma__test_and_set (&cma__g_init_started)) { \
cma__init_static (); \
cma__test_and_set (&cma__g_init_done); \
} \
else if (!cma__tac_isset (&cma__g_init_done)) { \
cma__error (cma_s_inialrpro); \
}}}
#endif
/*
* TYPEDEFS
*/
typedef enum CMA__T_ENV_TYPE {
cma__c_env_type_int,
cma__c_env_type_file
} cma__t_env_type;
typedef struct CMA__T_ENV {
char *name; /* Name of environment variable */
cma__t_env_type type; /* Type of variable */
cma_t_integer value; /* Numeric value of the variable */
} cma__t_env;
/*
* GLOBAL DATA
*/
extern cma__t_env cma__g_env[cma__c_env_count];
extern cma__t_atomic_bit cma__g_init_started;
extern cma__t_atomic_bit cma__g_init_done;
extern char *cma__g_version;
/*
* INTERNAL INTERFACES
*/
extern void
cma__init_static (void); /* Initialize static data */
#if _CMA_OS_ != _CMA__VMS
extern void cma__init_atfork (void);
#endif
#endif

View File

@ -1,84 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
* Header file for generic list functions operating on singly linked
* null-terminated lists. Items may not be REMOVED from the list! The
* intent is that the list can be traversed (for read-only operations)
* without locking, since insertion is "safe" (though not truely
* atomic). THIS ASSUMES THAT THE HARDWARE MAKES WRITES VISIBLE TO READS
* IN THE ORDER IN WHICH THEY OCCURRED! WITHOUT SUCH READ/WRITE
* ORDERING, IT MAY BE NECESSARY TO INSERT "BARRIERS" TO PRODUCE THE
* REQUIRED VISIBILITY!
*/
#ifndef CMA_LIST
#define CMA_LIST
/*
* INCLUDE FILES
*/
#include <cma.h>
/*
* CONSTANTS AND MACROS
*/
#define cma__c_null_list ((cma__t_list *)cma_c_null_ptr)
/*
* Test whether a list is empty. Return cma_c_true if so, else
* cma_c_false.
*/
#define cma__list_empty(head) ((head)->link == cma__c_null_list)
/*
* Initialize a queue header to empty.
*/
#define cma__list_init(head) (void)((head)->link = cma__c_null_list)
/*
* Insert an element in a list following the specified item (or at the
* beginning of the list if "list" is the list head). NOTE: insertion
* operations should be interlocked by the caller!
*/
#define cma__list_insert(element,list) (void)( \
(element)->link = (list)->link, \
(list)->link = (element))
/*
* Return the next item in a list (or the first, if the address is of the
* list header)
*/
#define cma__list_next(element) ((element)->link)
/*
* TYPEDEFS
*/
typedef struct CMA__T_LIST {
struct CMA__T_LIST *link; /* Forward link */
} cma__t_list;
/*
* GLOBAL DATA
*/
/*
* INTERNAL INTERFACES
*/
#endif

View File

@ -1,230 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
* Header file for mutex operations
*/
#ifndef CMA_MUTEX
#define CMA_MUTEX
/*
* INCLUDE FILES
*/
#include <cma.h>
#include <cma_attr.h>
#include <cma_defs.h>
#include <cma_semaphore_defs.h>
#include <cma_sequence.h>
#include <cma_tcb_defs.h>
#include <cma_stack.h>
/*
* CONSTANTS AND MACROS
*/
/*
* TYPEDEFS
*/
typedef struct CMA__T_INT_MUTEX {
cma__t_object header; /* Common header (sequence, type) */
cma__t_int_attr *attributes; /* Back link */
cma__t_int_tcb *owner; /* Current owner (if any) */
cma_t_integer nest_count; /* Nesting level for recursive mutex */
cma__t_atomic_bit *unlock; /* Pointer used for unlock operation */
cma__t_atomic_bit lock; /* Set if currently locked */
struct CMA__T_INT_MUTEX *int_lock; /* Internal protection for mutex */
cma__t_atomic_bit event; /* Clear when unlock requires action */
cma__t_atomic_bit waiters; /* Clear when threads are waiting */
cma__t_atomic_bit bitbucket; /* Fake bit to keep friendlies locked */
cma_t_mutex_kind mutex_kind; /* Kind of mutex */
cma__t_semaphore semaphore; /* Semaphore for low-level wait */
} cma__t_int_mutex;
/*
* FUNCTIONAL DESCRIPTION:
*
* Lock a mutex (internal)
*
* FORMAL PARAMETERS:
*
* mutex Pointer to mutex object to lock
*
* IMPLICIT INPUTS:
*
* none
*
* IMPLICIT OUTPUTS:
*
* none
*
* FUNCTION VALUE:
*
* none
*
* SIDE EFFECTS:
*
* none
*/
#ifdef NDEBUG
# define cma__int_lock(mutex) { \
if (cma__test_and_set (&((cma__t_int_mutex *)mutex)->lock)) { \
cma_t_status res;\
res = cma__int_mutex_block ((cma__t_int_mutex *)mutex); \
if (res != cma_s_normal) cma__error (res); \
} \
}
#else
# define cma__int_lock(mutex) { \
cma__t_int_tcb *__ltcb__; \
__ltcb__ = cma__get_self_tcb (); \
if (cma__test_and_set (&((cma__t_int_mutex *)mutex)->lock)) { \
cma_t_status res;\
res = cma__int_mutex_block ((cma__t_int_mutex *)mutex); \
if (res != cma_s_normal) cma__error (res); \
} \
((cma__t_int_mutex *)mutex)->owner = __ltcb__; \
}
#endif
/*
* FUNCTIONAL DESCRIPTION:
*
* Unlock a mutex (internal)
*
* FORMAL PARAMETERS:
*
* mutex Pointer to mutex object to unlock
*
* IMPLICIT INPUTS:
*
* none
*
* IMPLICIT OUTPUTS:
*
* none
*
* FUNCTION VALUE:
*
* none
*
* SIDE EFFECTS:
*
* none
*/
#ifdef NDEBUG
# define cma__int_unlock(mutex) { \
cma__unset (((cma__t_int_mutex *)mutex)->unlock); \
if (!cma__test_and_set (&((cma__t_int_mutex *)mutex)->event)) { \
cma_t_status res;\
res = cma__int_mutex_unblock ((cma__t_int_mutex *)mutex); \
if (res != cma_s_normal) cma__error (res); \
} \
}
#else
# define cma__int_unlock(mutex) { \
cma__t_int_tcb *__utcb__; \
__utcb__ = cma__get_self_tcb (); \
if (((cma__t_int_mutex *)mutex)->mutex_kind == cma_c_mutex_fast) { \
cma__assert_warn ( \
(__utcb__ == ((cma__t_int_mutex *)mutex)->owner), \
"attempt to release mutx owned by another thread"); \
((cma__t_int_mutex *)mutex)->owner = (cma__t_int_tcb *)cma_c_null_ptr; \
} \
cma__unset (((cma__t_int_mutex *)mutex)->unlock); \
if (!cma__test_and_set (&((cma__t_int_mutex *)mutex)->event)) { \
cma_t_status res;\
res = cma__int_mutex_unblock ((cma__t_int_mutex *)mutex); \
if (res != cma_s_normal) cma__error (res); \
} \
}
#endif
/*
* FUNCTIONAL DESCRIPTION:
*
* cma__int_mutex_delete - Performs work for cma_mutex_delete
*
* FORMAL PARAMETERS:
*
* cma__t_mutex _mutex_ - Mutex to be deleted
*
* IMPLICIT INPUTS:
*
* none
*
* IMPLICIT OUTPUTS:
*
* none
*
* FUNCTION VALUE:
*
* none
*
* SIDE EFFECTS:
*
* none
*/
#define cma__int_mutex_delete(_mutex_) { \
cma__t_int_mutex *_int_mutex_; \
_int_mutex_ = cma__validate_null_mutex (_mutex_); \
if (_int_mutex_ == (cma__t_int_mutex *)cma_c_null_ptr) \
return; \
if (cma__int_mutex_locked (_int_mutex_)) \
cma__error (cma_s_in_use); \
cma__free_mutex (_int_mutex_); \
cma__clear_handle (_mutex_); \
}
/*
* GLOBAL DATA
*/
extern cma__t_sequence cma__g_mutex_seq;
extern cma__t_int_mutex *cma__g_global_lock;
/*
* INTERNAL INTERFACES
*/
extern void cma__destroy_mutex (cma__t_int_mutex *);
extern void cma__free_mutex (cma__t_int_mutex *);
extern void cma__free_mutex_nolock (cma__t_int_mutex *);
extern cma__t_int_mutex * cma__get_first_mutex (cma__t_int_attr *);
extern cma__t_int_mutex * cma__get_mutex (cma__t_int_attr *);
extern void cma__init_mutex (void);
extern cma_t_status cma__int_mutex_block (cma__t_int_mutex *);
extern cma_t_boolean cma__int_mutex_locked (cma__t_int_mutex *);
extern cma_t_boolean cma__int_try_lock (cma__t_int_mutex *);
extern cma_t_status cma__int_mutex_unblock (cma__t_int_mutex *);
extern cma_t_boolean cma__mutex_locked (cma_t_mutex);
extern void cma__reinit_mutex (cma_t_integer);
#endif

View File

@ -1,279 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
* Header file for priority scheduling
*/
#ifndef CMA_SCHED
#define CMA_SCHED
/*
* INCLUDE FILES
*/
/*
* CONSTANTS AND MACROS
*/
/*
* Scaling factor for integer priority calculations
*/
#define cma__c_prio_scale 8
#if _CMA_VENDOR_ == _CMA__APOLLO
/*
* FIX-ME: Apollo cc 6.8 blows contant folded "<<" and ">>"
*/
# define cma__scale_up(exp) ((exp) * 256)
# define cma__scale_dn(exp) ((exp) / 256)
#else
# define cma__scale_up(exp) ((exp) << cma__c_prio_scale)
# define cma__scale_dn(exp) ((exp) >> cma__c_prio_scale)
#endif
/*
* Min. num. of ticks between self-adjustments for priority adjusting policies.
*/
#define cma__c_prio_interval 10
/*
* Number of queues in each class of queues
*/
#define cma__c_prio_n_id 1 /* Very-low-priority class threads */
#define cma__c_prio_n_bg 8 /* Background class threads */
#define cma__c_prio_n_0 1 /* Very low priority throughput quartile */
#define cma__c_prio_n_1 2 /* Low priority throughput quartile */
#define cma__c_prio_n_2 3 /* Medium priority throughput quartile */
#define cma__c_prio_n_3 4 /* High priority throughput quartile */
#define cma__c_prio_n_rt 1 /* Real Time priority queues */
/*
* Number of queues to skip (offset) to get to the queues in this section of LA
*/
#define cma__c_prio_o_id 0
#define cma__c_prio_o_bg cma__c_prio_o_id + cma__c_prio_n_id
#define cma__c_prio_o_0 cma__c_prio_o_bg + cma__c_prio_n_bg
#define cma__c_prio_o_1 cma__c_prio_o_0 + cma__c_prio_n_0
#define cma__c_prio_o_2 cma__c_prio_o_1 + cma__c_prio_n_1
#define cma__c_prio_o_3 cma__c_prio_o_2 + cma__c_prio_n_2
#define cma__c_prio_o_rt cma__c_prio_o_3 + cma__c_prio_n_3
/*
* Ada_low: These threads are queued in the background queues, thus there
* must be enough queues to allow one queue for each Ada priority below the
* Ada default.
*/
#define cma__c_prio_o_al cma__c_prio_o_bg
/*
* Total number of ready queues, for declaration purposes
*/
#define cma__c_prio_n_tot \
cma__c_prio_n_id + cma__c_prio_n_bg + cma__c_prio_n_rt \
+ cma__c_prio_n_0 + cma__c_prio_n_1 + cma__c_prio_n_2 + cma__c_prio_n_3
/*
* Formulae for determining a thread's priority. Variable priorities (such
* as foreground and background) are scaled values.
*/
#define cma__sched_priority(tcb) \
((tcb)->sched.class == cma__c_class_fore ? cma__sched_prio_fore (tcb) \
:((tcb)->sched.class == cma__c_class_back ? cma__sched_prio_back (tcb) \
:((tcb)->sched.class == cma__c_class_rt ? cma__sched_prio_rt (tcb) \
:((tcb)->sched.class == cma__c_class_idle ? cma__sched_prio_idle (tcb) \
:(cma__bugcheck ("cma__sched_priority: unrecognized class"), 0) ))))
#define cma__sched_prio_fore(tcb) cma__sched_prio_fore_var (tcb)
#define cma__sched_prio_back(tcb) ((tcb)->sched.fixed_prio \
? cma__sched_prio_back_fix (tcb) : cma__sched_prio_back_var (tcb) )
#define cma__sched_prio_rt(tcb) ((tcb)->sched.priority)
#define cma__sched_prio_idle(tcb) ((tcb)->sched.priority)
#define cma__sched_prio_back_fix(tcb) \
(cma__g_prio_bg_min + (cma__g_prio_bg_max - cma__g_prio_bg_min) \
* ((tcb)->sched.priority + cma__c_prio_o_al - cma__c_prio_o_bg) \
/ cma__c_prio_n_bg)
/*
* FIX-ME: Enable after modeling (if we like it)
*/
#if 1
# define cma__sched_prio_fore_var(tcb) \
((cma__g_prio_fg_max + cma__g_prio_fg_min)/2)
# define cma__sched_prio_back_var(tcb) \
((cma__g_prio_bg_max + cma__g_prio_bg_min)/2)
#else
# define cma__sched_prio_back_var(tcb) cma__sched_prio_fore_var (tcb)
# if 1
/*
* Re-scale, since the division removes the scale factor.
* Scale and multiply before dividing to avoid loss of precision.
*/
# define cma__sched_prio_fore_var(tcb) \
((cma__g_vp_count * cma__scale_up((tcb)->sched.tot_time)) \
/ (tcb)->sched.cpu_time)
# else
/*
* Re-scale, since the division removes the scale factor.
* Scale and multiply before dividing to avoid loss of precision.
* Left shift the numerator to multiply by two.
*/
# define cma__sched_prio_fore_var(tcb) \
(((cma__g_vp_count * cma__scale_up((tcb)->sched.tot_time) \
* (tcb)->sched.priority * cma__g_init_frac_sum) << 1) \
/ ((tcb)->sched.cpu_time * (tcb)->sched.priority * cma__g_init_frac_sum \
+ (tcb)->sched.tot_time))
# endif
#endif
/*
* Update weighted-averaged, scaled tick counters
*/
#define cma__sched_update_time(ave, new) \
(ave) = (ave) - ((cma__scale_dn((ave)) - (new)) << (cma__c_prio_scale - 4))
#define cma__sched_parameterize(tcb, policy) { \
switch (policy) { \
case cma_c_sched_fifo : { \
(tcb)->sched.rtb = cma_c_true; \
(tcb)->sched.spp = cma_c_true; \
(tcb)->sched.fixed_prio = cma_c_true; \
(tcb)->sched.class = cma__c_class_rt; \
break; \
} \
case cma_c_sched_rr : { \
(tcb)->sched.rtb = cma_c_false; \
(tcb)->sched.spp = cma_c_true; \
(tcb)->sched.fixed_prio = cma_c_true; \
(tcb)->sched.class = cma__c_class_rt; \
break; \
} \
case cma_c_sched_throughput : { \
(tcb)->sched.rtb = cma_c_false; \
(tcb)->sched.spp = cma_c_false; \
(tcb)->sched.fixed_prio = cma_c_false; \
(tcb)->sched.class = cma__c_class_fore; \
break; \
} \
case cma_c_sched_background : { \
(tcb)->sched.rtb = cma_c_false; \
(tcb)->sched.spp = cma_c_false; \
(tcb)->sched.fixed_prio = cma_c_false; \
(tcb)->sched.class = cma__c_class_back; \
break; \
} \
case cma_c_sched_ada_low : { \
(tcb)->sched.rtb = cma_c_false; \
(tcb)->sched.spp = cma_c_true; \
(tcb)->sched.fixed_prio = cma_c_true; \
(tcb)->sched.class = cma__c_class_back; \
break; \
} \
case cma_c_sched_idle : { \
(tcb)->sched.rtb = cma_c_false; \
(tcb)->sched.spp = cma_c_false; \
(tcb)->sched.fixed_prio = cma_c_false; \
(tcb)->sched.class = cma__c_class_idle; \
break; \
} \
default : { \
cma__bugcheck ("cma__sched_parameterize: bad scheduling Policy"); \
break; \
} \
} \
}
/*
* TYPEDEFS
*/
/*
* Scheduling classes
*/
typedef enum CMA__T_SCHED_CLASS {
cma__c_class_rt,
cma__c_class_fore,
cma__c_class_back,
cma__c_class_idle
} cma__t_sched_class;
/*
* GLOBAL DATA
*/
/*
* Minimuma and maximum prioirities, for foreground and background threads,
* as of the last time the scheduler ran. (Scaled once.)
*/
extern cma_t_integer cma__g_prio_fg_min;
extern cma_t_integer cma__g_prio_fg_max;
extern cma_t_integer cma__g_prio_bg_min;
extern cma_t_integer cma__g_prio_bg_max;
/*
* The "m" values are the slopes of the four sections of linear approximation.
*
* cma__g_prio_m_I = 4*N(I)/cma__g_prio_range (Scaled once.)
*/
extern cma_t_integer cma__g_prio_m_0,
cma__g_prio_m_1,
cma__g_prio_m_2,
cma__g_prio_m_3;
/*
* The "b" values are the intercepts of the four sections of linear approx.
* (Not scaled.)
*
* cma__g_prio_b_I = -N(I)*(I*prio_max + (4-I)*prio_min)/prio_range + prio_o_I
*/
extern cma_t_integer cma__g_prio_b_0,
cma__g_prio_b_1,
cma__g_prio_b_2,
cma__g_prio_b_3;
/*
* The "p" values are the end points of the four sections of linear approx.
*
* cma__g_prio_p_I = cma__g_prio_fg_min + (I/4)*cma__g_prio_range
*
* [cma__g_prio_p_0 is not defined since it is not used (also, it is the same
* as cma__g_prio_fg_min).] (Scaled once.)
*/
extern cma_t_integer cma__g_prio_p_1,
cma__g_prio_p_2,
cma__g_prio_p_3;
/*
* Points to the next queue for the dispatcher to check for ready threads.
*/
extern cma_t_integer cma__g_next_ready_queue;
/*
* Points to the queues of virtual processors (for preempt victim search)
*/
extern cma__t_queue cma__g_run_vps;
extern cma__t_queue cma__g_susp_vps;
extern cma_t_integer cma__g_vp_count;
/*
* INTERNAL INTERFACES
*/
#endif

View File

@ -1,46 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
* Header file for semaphore structure definition.
*/
#ifndef CMA_SEMAPHORE_DEFS
#define CMA_SEMAPHORE_DEFS
/*
* INCLUDE FILES
*/
#include <cma.h>
#include <cma_queue.h>
#include <cma_defs.h>
/*
* CONSTANTS AND MACROS
*/
#define cma__c_semaphore_timeout 1
#define cma__c_semaphore_event 0
#define cma__c_select_timeout 2
/*
* TYPEDEFS
*/
typedef struct CMA__T_SEMAPHORE {
cma__t_queue queue;
cma__t_atomic_bit nopending;
} cma__t_semaphore;
#endif

View File

@ -1,56 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
* Header file for sequence generator functions
*/
#ifndef CMA_SEQUENCE
#define CMA_SEQUENCE
/*
* INCLUDE FILES
*/
/*
* CONSTANTS AND MACROS
*/
/*
* TYPEDEFS
*/
#ifndef __STDC__
struct CMA__T_INT_MUTEX;
#endif
typedef struct CMA__T_SEQUENCE {
struct CMA__T_INT_MUTEX *mutex; /* Serialize access to counter */
cma_t_natural seq; /* Sequence number for object */
} cma__t_sequence;
/*
* GLOBAL DATA
*/
/*
* INTERNAL INTERFACES
*/
extern cma_t_natural cma__assign_sequence (cma__t_sequence *);
extern void cma__init_sequence (cma__t_sequence *);
#endif

View File

@ -1,83 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
* Header file for stack management
*/
#ifndef CMA_STACK
#define CMA_STACK
/*
* INCLUDE FILES
*/
#include <cma_tcb_defs.h>
#include <cma.h>
#include <cma_attr.h>
#include <cma_queue.h>
#include <cma_stack_int.h>
/*
* CONSTANTS AND MACROS
*/
#if _CMA_UNIPROCESSOR_
# define cma__get_self_tcb() (cma__g_current_thread)
#endif
/*
* Round the given value (a) upto cma__g_chunk_size
*/
#define cma__roundup_chunksize(a) (cma__roundup(a,cma__g_chunk_size))
/*
* TYPEDEFS
*/
/*
* GLOBAL DATA
*/
extern cma__t_list cma__g_stack_clusters;
extern cma__t_int_tcb *cma__g_current_thread;
extern cma_t_integer cma__g_chunk_size;
/*
* INTERNAL INTERFACES
*/
extern void cma__assign_stack (cma__t_int_stack *,cma__t_int_tcb *);
extern void cma__free_stack (cma__t_int_stack *);
extern void cma__free_stack_list (cma__t_queue *);
#if !_CMA_UNIPROCESSOR_
extern cma__t_int_tcb * cma__get_self_tcb (void);
#endif
extern cma__t_int_tcb * cma__get_sp_tcb (cma_t_address);
extern cma__t_int_stack * cma__get_stack (cma__t_int_attr *);
extern void cma__init_stack (void);
extern void cma__reinit_stack (cma_t_integer);
#if _CMA_PROTECT_MEMORY_
extern void cma__remap_stack_holes (void);
#endif
#endif

View File

@ -1,136 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
* Header file for stack management (internal to cma_stack.c, but
* separate for convenience, and unit testing).
*/
#ifndef CMA_STACK_INT
#define CMA_STACK_INT
/*
* INCLUDE FILES
*/
#include <cma.h>
#include <cma_queue.h>
#include <cma_list.h>
#include <cma_tcb_defs.h>
/*
* CONSTANTS AND MACROS
*/
#define cma___c_first_free_chunk 0
#define cma___c_min_count 2 /* Smallest number of chunks to leave */
#define cma___c_end (-1) /* End of free list (flag) */
#define cma__c_yellow_size 0
/*
* Cluster types
*/
#define cma___c_cluster 0 /* Default cluster */
#define cma___c_bigstack 1 /* Looks like a cluster, but it's a stack */
#define cma___c_null_cluster (cma___t_cluster *)cma_c_null_ptr
/*
* TYPEDEFS
*/
#ifndef __STDC__
struct CMA__T_INT_STACK;
#endif
typedef cma_t_natural cma___t_index; /* Type for chunk index */
typedef struct CMA___T_CLU_DESC {
cma__t_list list; /* Queue element for cluster list */
cma_t_integer type; /* Type of cluster */
cma_t_address stacks;
cma_t_address limit;
} cma___t_clu_desc;
typedef union CMA___T_MAP_ENTRY {
struct {
cma__t_int_tcb *tcb; /* TCB associated with stack chunk */
struct CMA__T_INT_STACK *stack; /* Stack desc. ass. with stack chunk */
} mapped;
struct {
cma___t_index size; /* Number of chunks in block */
cma___t_index next; /* Next free block */
} free;
} cma___t_map_entry;
/*
* NOTE: It is VERY IMPORTANT that both cma___t_cluster and cma___t_bigstack
* begin with the cma___t_clu_desc structure, as there is some code in the
* stack manager that relies on being able to treat both as equivalent!
*/
typedef struct CMA___T_CLUSTER {
cma___t_clu_desc desc; /* Describe this cluster */
cma___t_map_entry map[cma__c_chunk_count]; /* thread map */
cma___t_index free; /* First free chunk index */
} cma___t_cluster;
/*
* NOTE: It is VERY IMPORTANT that both cma___t_cluster and cma___t_bigstack
* begin with the cma___t_clu_desc structure, as there is some code in the
* stack manager that relies on being able to treat both as equivalent!
*/
typedef struct CMA___T_BIGSTACK {
cma___t_clu_desc desc; /* Describe this cluster */
cma__t_int_tcb *tcb; /* TCB associated with stack */
struct CMA__T_INT_STACK *stack; /* Stack desc. ass. with stack */
cma_t_natural size; /* Size of big stack */
cma_t_boolean in_use; /* Set if allocated */
} cma___t_bigstack;
#if _CMA_PROTECT_MEMORY_
typedef struct CMA___T_INT_HOLE {
cma__t_queue link; /* Link holes together */
cma_t_boolean protected; /* Set when pages are protected */
cma_t_address first; /* First protected byte */
cma_t_address last; /* Last protected byte */
} cma___t_int_hole;
#endif
typedef struct CMA__T_INT_STACK {
cma__t_object header; /* Common header (sequence, type info */
cma__t_int_attr *attributes; /* Backpointer to attr obj */
cma___t_cluster *cluster; /* Stack's cluster */
cma_t_address stack_base; /* base address of stack */
cma_t_address yellow_zone; /* first address of yellow zone */
cma_t_address last_guard; /* last address of guard pages */
cma_t_natural first_chunk; /* First chunk allocated */
cma_t_natural chunk_count; /* Count of chunks allocated */
cma__t_int_tcb *tcb; /* TCB backpointer */
#if _CMA_PROTECT_MEMORY_
cma___t_int_hole hole; /* Description of hole */
#endif
} cma__t_int_stack;
/*
* GLOBAL DATA
*/
/*
* INTERNAL INTERFACES
*/
#endif

View File

@ -1,269 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
* TCB-related type definitions.
*/
#ifndef CMA_TCB_DEFS
#define CMA_TCB_DEFS
/*
* INCLUDE FILES
*/
# if !_CMA_THREAD_SYNC_IO_
# include <cma_thread_io.h>
# endif
#include <cma.h>
#include <cma_debug_client.h>
#include <cma_attr.h>
#include <cma_defs.h>
#include <cma_handle.h>
#include <cma_queue.h>
#if _CMA_OS_ == _CMA__UNIX
# if defined(SNI_DCOSX)
# include <sys/ucontext.h>
# endif
# include <signal.h>
#endif
#include <cma_sched.h>
/*
* CONSTANTS AND MACROS
*/
#if _CMA_PLATFORM_ == _CMA__IBMR2_UNIX
# define cma__c_ibmr2_ctx_stack_size 2048
# define cma__c_ibmr2_ctx_stack_top (cma__c_ibmr2_ctx_stack_size - 1)
#endif
/*
* TYPEDEFS
*/
#ifndef __STDC__
# if _CMA_HARDWARE_ != _CMA__HPPA
struct CMA__T_SEMAPHORE;
# endif
struct CMA__T_INT_CV;
struct CMA__T_INT_MUTEX;
struct CMA__T_INT_TCB;
#endif
typedef cma_t_address *cma__t_context_list;
typedef struct CMA__T_TCB_PAD {
/*
* Adjust to align the tcb prolog at byte 32.
* 12 bytes are required as object header is currently
* 20 bytes long.
*/
cma_t_integer pad1; /* pad bytes */
cma_t_integer pad2; /* pad bytes */
cma_t_integer pad3; /* pad bytes */
} cma__t_tcb_pad;
#if (_CMA_OS_ == _CMA__UNIX) && !_CMA_THREAD_SYNC_IO_
typedef struct CMA__T_TCB_SELECT {
cma__t_queue queue;
#if (_CMA_UNIX_TYPE != _CMA__SVR4)
cma__t_file_mask *rfds;
cma__t_file_mask *wfds;
cma__t_file_mask *efds;
#else
cma__t_poll_info poll_info;
#endif /* (_CMA_UNIX_TYPE != _CMA__SVR4) */
cma_t_integer nfound;
} cma__t_tcb_select;
#endif
typedef struct CMA__T_TCB_TIME {
cma__t_queue queue; /* must be first entry! */
cma_t_integer mode;
struct CMA__T_SEMAPHORE *semaphore; /* used for timed semaphores */
cma_t_date_time wakeup_time;
cma_t_integer quanta_remaining;
} cma__t_tcb_time;
typedef enum CMA__T_DEBEVT {
cma__c_debevt_activating = 1, /* First transition to running */
cma__c_debevt_running = 2, /* Any transition to running */
cma__c_debevt_preempting = 3, /* Preemted (replaced) another thread */
cma__c_debevt_blocking = 4, /* Any transition to blocked */
cma__c_debevt_terminating = 5, /* Final state transition */
cma__c_debevt_term_alert = 6, /* Terminated due to alert/cancel */
cma__c_debevt_term_exc = 7, /* Terminated due to exception */
cma__c_debevt_exc_handled = 8 /* Exception is being handled */
} cma__t_debevt;
#define cma__c_debevt__first ((cma_t_integer)cma__c_debevt_activating)
#define cma__c_debevt__last ((cma_t_integer)cma__c_debevt_exc_handled)
#define cma__c_debevt__dim (cma__c_debevt__last + 1)
/*
* Type defining thread substate, which is used by the debugger.
* If the state is blocked, substate indicates WHY the thread is blocked.
*/
typedef enum CMA__T_SUBSTATE {
cma__c_substa_normal = 0,
cma__c_substa_mutex = 1,
cma__c_substa_cv = 2,
cma__c_substa_timed_cv = 3,
cma__c_substa_term_alt = 4,
cma__c_substa_term_exc = 5,
cma__c_substa_delay =6,
cma__c_substa_not_yet_run = 7
} cma__t_substate;
#define cma__c_substa__first ((cma_t_integer)cma__c_substa_normal)
#define cma__c_substa__last ((cma_t_integer)cma__c_substa_not_yet_run)
#define cma__c_substa__dim (cma__c_substa__last + 1)
/*
* Per-thread state for the debugger
*/
typedef struct CMA__T_TCB_DEBUG {
cma_t_boolean on_hold; /* Thread was put on hold by debugger */
cma_t_boolean activated; /* Activation event was reported */
cma_t_boolean did_preempt; /* Thread preempted prior one */
cma_t_address start_pc; /* Start routine address */
cma_t_address object_addr; /* Addr of thread object */
cma__t_substate substate; /* Reason blocked, terminated, etc.*/
cma_t_boolean notify_debugger;/* Notify debugger thread is running */
cma_t_address SPARE2; /* SPARE */
cma_t_address SPARE3; /* SPARE */
struct CMA__T_INT_TCB
*preempted_tcb; /* TCB of thread that got preempted */
cma_t_boolean flags[cma__c_debevt__dim];
/* Events enabled for this thread */
} cma__t_tcb_debug;
typedef struct CMA__T_TCB_SCHED {
cma_t_integer adj_time; /* Abs. time in ticks of last prio adj */
cma_t_integer tot_time; /* Weighted ave in ticks (scaled) */
cma_t_integer time_stamp; /* Abs. time in ticks of last update */
cma_t_integer cpu_time; /* Weighted average in ticks */
cma_t_integer cpu_ticks; /* # of ticks while comp. (scaled) */
cma_t_integer q_num; /* Number of last ready queue on */
cma_t_priority priority; /* Thread priority */
cma_t_sched_policy policy; /* Scheduling policy of thread */
cma_t_boolean rtb; /* "Run 'Till Block" scheduling */
cma_t_boolean spp; /* "Strict Priority Preemption" sched */
cma_t_boolean fixed_prio; /* Fixed priority */
cma__t_sched_class class; /* Scheduling class */
struct CMA__T_VP *processor; /* Current processor (if running) */
} cma__t_tcb_sched;
typedef struct CMA__T_INT_ALERT {
cma_t_boolean pending : 1; /* alert_pending bit */
cma_t_boolean g_enable : 1; /* general delivery state */
cma_t_boolean a_enable : 1; /* asynchronous delivery state */
cma_t_integer spare : 29; /* Pad to longword */
cma_t_natural count; /* Alert scope nesting count */
} cma__t_int_alert;
typedef enum CMA__T_STATE {
cma__c_state_running = 0, /* For consistency with initial TCB */
cma__c_state_ready = 1,
cma__c_state_blocked = 2,
cma__c_state_terminated = 3
} cma__t_state;
#define cma__c_state__first ((cma_t_integer)cma__c_state_running)
#define cma__c_state__last ((cma_t_integer)cma__c_state_terminated)
#define cma__c_state__dim (cma__c_state__last + 1)
typedef enum CMA__T_THKIND {
cma__c_thkind_initial = 0, /* Initial thread */
cma__c_thkind_normal = 1, /* Normal thread */
cma__c_thkind_null = 2 /* A null thread */
} cma__t_thkind;
#define cma__c_thkind__first ((cma_t_integer)cma__c_thkind_initial)
#define cma__c_thkind__last ((cma_t_integer)cma__c_thkind_null)
#define cma__c_thkind__dim (cma__c_thkind__last + 1)
typedef enum CMA__T_SYSCALL_STATE {
cma__c_syscall_ok = 1, /* syscall was not interrupted */
cma__c_syscall_intintrpt = 1, /* syscall was interrupted by VTALRM */
cma__c_syscall_extintrpt = 2 /* syscall was interrupted by external signal */
} cma__t_syscall_state;
typedef struct CMA__T_INT_TCB {
/*
* Fixed part of TCB.
* Modifications to the following three fields must be coordinated.
* The object header must always be first, and the prolog must always
* remain at the same offset (32) for all time. Thus the object header
* must never grow beyond a maximum of 32 bytes.
*/
cma__t_object header; /* Common object header */
cma__t_tcb_pad pad1; /* Pad required to align prolog */
cma_t_tcb_prolog prolog; /* Standard prolog for tasks, threads */
/*
* Floating part of TCB (fields here on are free to be moved and resized).
*/
cma__t_queue threads; /* List of all known threads */
cma__t_int_attr *attributes; /* Backpointer to attr obj */
cma__t_state state; /* Current state of thread */
cma__t_thkind kind; /* Which kind of thread */
struct CMA__T_INT_MUTEX
*mutex; /* Mutex to control TCB access */
struct CMA__T_INT_CV
*term_cv; /* CV for join */
struct CMA__T_INT_MUTEX
*tswait_mutex; /* Mutex for thread-synchronous waits */
struct CMA__T_INT_CV
*tswait_cv; /* CV for thread-synchronous waits */
cma_t_start_routine start_code; /* Address of start routine */
cma_t_address start_arg; /* Argument to pass to start_code */
cma__t_queue stack; /* Queue header for stack descr. */
cma_t_natural context_count; /* Size of context array */
cma__t_context_list contexts; /* Context value array pointer */
cma_t_exit_status exit_status; /* Exit status of thread */
cma_t_address return_value; /* Thread's return value */
cma__t_async_ctx async_ctx; /* Asynchronous context switch info */
cma__t_static_ctx static_ctx; /* Static context switch information */
cma_t_integer event_status; /* Status of semaphore operation */
cma__t_tcb_time timer; /* Time info for dispatcher */
cma__t_tcb_sched sched; /* Scheduler info */
cma__t_tcb_debug debug; /* Debugger info */
#if _CMA_OS_ == _CMA__UNIX
# if !_CMA_THREAD_SYNC_IO_
cma__t_tcb_select select; /* Select info for timed selects */
# endif
struct sigaction sigaction_data[NSIG];
#endif
cma_t_natural syscall_state; /* set if one of the cma wrapped syscalls was interrupted. */
cma_t_boolean detached; /* Set if already detached */
cma_t_boolean terminated; /* Set if terminated */
cma_t_integer joiners; /* Count of joiners, for zombie frees */
cma__t_int_alert alert; /* Current alert state info */
struct CMA__T_INT_CV
*wait_cv; /* CV thread is currently waiting on */
struct CMA__T_INT_MUTEX
*wait_mutex; /* Mutex thread is waiting on */
struct EXC_CONTEXT_T
*exc_stack; /* Top of exception stack */
#if _CMA_PLATFORM_ == _CMA__IBMR2_UNIX
char ctx_stack[cma__c_ibmr2_ctx_stack_size];
#endif
cma_t_integer thd_errno; /* Per-thread errno value */
#if _CMA_OS_ == _CMA__VMS
cma_t_integer thd_vmserrno; /* Per-thread VMS errno value */
#endif
} cma__t_int_tcb;
#endif

View File

@ -1,125 +0,0 @@
/*
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
* To anyone who acknowledges that this file is provided "AS IS" without
* any express or implied warranty: permission to use, copy, modify, and
* distribute this file for any purpose is hereby granted without fee,
* provided that the above copyright notices and this notice appears in
* all source code copies, and that none of the names listed above be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. None of these organizations
* makes any representations about the suitability of this software for
* any purpose.
*/
/*
* Header file for CMA internal UTIL operations
*/
#ifndef CMA_UTIL
#define CMA_UTIL
/*
* INCLUDE FILES
*/
#include <cma.h>
#include <cma_attr.h>
#include <cma_defs.h>
#if _CMA_OS_ == _CMA__VMS
# include <cma_rms.h>
#endif
#if _CMA_VENDOR_ == _CMA__SUN
# include <sys/time.h>
#else
# include <time.h>
#endif
#if _CMA_OS_ == _CMA__UNIX
# include <stdio.h>
#endif
/*
* CONSTANTS AND MACROS
*/
#define cma__c_buffer_size 256 /* Size of output buffer */
/*
* TYPEDEFS
*/
/*
* Alternate eol routine
*/
typedef void (*cma__t_eol_routine) (char *);
#if _CMA_OS_ == _CMA__VMS
typedef struct CMA__T_VMSFILE {
struct RAB rab;
struct FAB fab;
} cma__t_vmsfile, *cma__t_file;
#elif ( _CMA_UNIX_TYPE == _CMA__SVR4 )
typedef int cma__t_file;
#else
typedef FILE *cma__t_file;
#endif
/*
* GLOBAL DATA
*/
/*
* INTERNAL INTERFACES
*/
extern void cma__abort (void);
extern cma_t_integer cma__atol (char *);
extern cma_t_integer cma__atoi (char *);
extern char * cma__getenv (char *,char *,int);
extern int cma__gettimespec (struct timespec *);
extern cma__t_file cma__int_fopen (char *,char *);
#ifndef NDEBUG
extern void cma__init_trace (char *_env);
#endif
extern char * cma__memcpy (char *,char *,cma_t_integer);
#ifndef cma__memset
extern char * cma__memset (char *,cma_t_integer,cma_t_integer);
#endif
extern void cma__putformat (char *,char *,...);
extern void cma__putstring (char *,char *);
extern void cma__putint (char *,cma_t_integer);
extern void cma__putint_5 (char *,cma_t_integer);
extern void cma__putint_10 (char *,cma_t_integer);
extern void cma__puthex (char *,cma_t_integer);
extern void cma__puthex_8 (char *,cma_t_integer);
extern void cma__puteol (char *);
extern void cma__set_eol_routine (cma__t_eol_routine,cma__t_eol_routine *);
extern cma_t_integer cma__strlen (char *);
extern int cma__strncmp (char *,char *,cma_t_integer);
extern char *cma__gets (char *,char *);
#endif

View File

@ -1,165 +0,0 @@
prefix = /usr/local
program_transform_name =
exec_prefix = $(prefix)
bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
tooldir = $(libdir)/$(target_alias)
datadir = $(prefix)/share
mandir = $(prefix)/man
man1dir = $(mandir)/man1
man2dir = $(mandir)/man2
man3dir = $(mandir)/man3
man4dir = $(mandir)/man4
man5dir = $(mandir)/man5
man6dir = $(mandir)/man6
man7dir = $(mandir)/man7
man8dir = $(mandir)/man8
man9dir = $(mandir)/man9
infodir = $(prefix)/info
includedir = $(prefix)/include
ARM_RELEASE='"Berkeley Licence for Cygnus"'
SHELL = /bin/sh
INSTALL = `cd $(srcdir)/../..;pwd`/install.sh -c
INSTALL_PROGRAM = $(INSTALL)
INSTALL_DATA = $(INSTALL)
INSTALL_XFORM = $(INSTALL) -t='$(program_transform_name)'
INSTALL_XFORM1 = $(INSTALL_XFORM) -b=.1
AR = ar
AR_FLAGS = qv
RANLIB = ranlib
LD = ld
# If you are compiling with GCC, make sure that either 1) You use the
# -traditional flag, or 2) You have the fixed include files where GCC
# can reach them. Otherwise the ioctl calls in inflow.c
# will be incorrectly compiled. The "fixincludes" script in the gcc
# distribution will fix your include files up.
#CC=cc
#CC=gcc -traditional
GCC=gcc
# Directory containing source files. Don't clean up the spacing,
# this exact string is matched for by the "configure" script.
srcdir = .
# It is also possible that you will need to add -I/usr/include/sys to the
# CFLAGS section if your system doesn't have fcntl.h in /usr/include (which
# is where it should be according to Posix).
# Set this up with gcc if you have gnu ld and the loader will print out
# line numbers for undefinded refs.
#CC-LD=gcc -static
CC-LD=${CC}
# All the includes used for CFLAGS and for lint.
# -I. for config files.
# -I${srcdir} possibly for regex.h also.
# -I${srcdir}/config for more generic config files.
INCLUDE_CFLAGS = -I. -I${srcdir}
# M{H,T}_CFLAGS, if defined, has host- and target-dependent CFLAGS
# from the config/ directory.
GLOBAL_CFLAGS = ${MT_CFLAGS} ${MH_CFLAGS} -DRETRANS -DARM_RELEASE=$(ARM_RELEASE)
#PROFILE_CFLAGS = -pg
# CFLAGS is specifically reserved for setting from the command line
# when running make. I.E. "make CFLAGS=-Wmissing-prototypes".
CFLAGS = -g
# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros.
INTERNAL_CFLAGS = ${CFLAGS} ${GLOBAL_CFLAGS} ${PROFILE_CFLAGS} \
${BFD_CFLAGS} ${MMALLOC_CFLAGS} ${INCLUDE_CFLAGS}
# LDFLAGS is specifically reserved for setting from the command line
# when running make.
# Host and target-dependent makefile fragments come in here.
####
# End of host and target-dependent makefile fragments
# All source files that go into linking GDB remote server.
SFILES = $(srcdir)/
DEPFILES =
SOURCES = $(SFILES) $(ALLDEPFILES)
TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
OBS = hostchan.o drivers.o devsw.o rx.o tx.o params.o hsys.o crc.o \
logging.o msgbuild.o ardi.o serdrv.o serpardr.o etherdrv.o bytesex.o \
unixcomm.o
# Prevent Sun make from putting in the machine type. Setting
# TARGET_ARCH to nothing works for SunOS 3, 4.0, but not for 4.1.
.c.o:
${CC} -c ${INTERNAL_CFLAGS} $<
all: libangsd.a
libangsd.a: $(OBS)
rm -f libangsd.a
$(AR) $(AR_FLAGS) libangsd.a $(OBS)
$(RANLIB) libangsd.a
# Traditionally "install" depends on "all". But it may be useful
# not to; for example, if the user has made some trivial change to a
# source file and doesn't care about rebuilding or just wants to save the
# time it takes for make to check that all is up to date.
# install-only is intended to address that need.
install: all install-only
install-only:
uninstall:
installcheck:
check:
info dvi:
install-info:
clean-info:
config.status:
@echo "You must configure rdi-share. Look at the README file for details."
@false
clean:
rm -f *.o ${ADD_FILES} *~
rm -f gdbserver core make.log
distclean: clean
rm -f config.status
rm -f Makefile
maintainer-clean realclean: clean
rm -f config.status
rm -f Makefile
Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) $(target_makefile_frag)
$(SHELL) ./config.status
force:
# GNU Make has an annoying habit of putting *all* the Makefile variables
# into the environment, unless you include this target as a circumvention.
# Rumor is that this will be fixed (and this target can be removed)
# in GNU Make 4.0.
.NOEXPORT:
# GNU Make 3.63 has a different problem: it keeps tacking command line
# overrides onto the definition of $(MAKE). This variable setting
# will remove them.
MAKEOVERRIDES=
## This is ugly, but I don't want GNU make to put these variables in
## the environment. Older makes will see this as a set of targets
## with no dependencies and no actions.
unexport CHILLFLAGS CHILL_LIB CHILL_FOR_TARGET :
# This is the end of "Makefile.in".

View File

@ -1,6 +0,0 @@
This is a version of ARM's RDI library which has been been put under a
free software license.
See ARM's Software Development Tools Reference Manual (Remote
Debugging chapter), and the file gdb/remote-rdi.c for information
about how to use it.

File diff suppressed because it is too large Load Diff

View File

@ -1,72 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* Project: ANGEL
*
* Title: Definitions of ADP error codes
*/
#ifndef angsd_adperrs_h
#define angsd_adperrs_h
/*
* ADP failure codes start at 256 to distinguish them for debug purposes
*/
enum AdpErrs
{
adp_ok = 0,
adp_failed = 256,
adp_malloc_failure,
adp_illegal_args,
adp_device_not_found,
adp_device_open_failed,
adp_device_already_open,
adp_device_not_open,
adp_bad_channel_id,
adp_callback_already_registered,
adp_write_busy,
adp_bad_packet,
adp_seq_high,
adp_seq_low,
adp_timeout_on_open,
adp_abandon_boot_wait,
adp_late_startup,
adp_new_agent_starting
};
#ifndef __cplusplus
typedef enum AdpErrs AdpErrs;
#endif
#define AdpMess_Failed "ADP Error - unspecific failure"
#define AdpMess_MallocFailed "ADP Error - malloc failed"
#define AdpMess_IllegalArgs "ADP Error - illegal arguments"
#define AdpMess_DeviceNotFound "ADP Error - invalid device specified"
#define AdpMess_DeviceOpenFailed "ADP Error - specified device failed to open"
#define AdpMess_DeviceAlreadyOpen "ADP Error - device already open"
#define AdpMess_DeviceNotOpen "ADP Error - device not open"
#define AdpMess_BadChannelId "ADP Error - bad channel Id"
#define AdpMess_CBAlreadyRegd "ADP Error - callback already registered"
#define AdpMess_WriteBusy "ADP Error - write busy"
#define AdpMess_BadPacket "ADP Error - bad packet"
#define AdpMess_SeqHigh "ADP Error - sequence number too high"
#define AdpMess_SeqLow "ADP Error - sequence number too low"
#define AdpMess_TimeoutOnOpen "ADP Error - target did not respond"
#define AdpMess_AbandonBootWait "abandoned wait for late startup"
#define AdpMess_LateStartup "Target compiled with LATE_STARTUP set.\n" \
"Waiting for target...\n" \
"Press <Ctrl-C> to abort.\n"
#define AdpMessLen_LateStartup (3*80)
#define AdpMess_NewAgentStarting "New Debug Agent about to start.\n"
#endif /* ndef angsd_adperr_h */
/* EOF adperr.h */

View File

@ -1,175 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/*> angel.h <*/
/*---------------------------------------------------------------------------*/
/* This header file is the main holder for the declarations and
* prototypes for the core Angel system. Some Angel concepts are
* described at the start of this file to ensure that a complete view
* of the Angel world can be derived purely from the source.
*
*
*
* NOTE: Currently the Angel source is designed to be simple,
* understandable and easy to port to new hardware platforms. However,
* this does not always yield the highest performing system. The
* current layered approach introduces an overhead to the performance
* of the system. In a true commercial target, this code should be
* re-designed to build a system where the Angel logical message
* system, device driver and hardware accesses are merged to provide
* the best performance.
*/
/*---------------------------------------------------------------------------*/
/* Angel overview:
... some comments describing Angel ...
* Angel is designed as a kit-of-parts that can be used to provide
* run-time support for the development of ARM applications. The main
* core of Angel is in providing support for the "debug" message
* communication with a host system. These messages do not just cover
* debugging ARM processes, but also the process of downloading ARM
* programs or attaching to executing processes on the target.
*
* A stand-alone ROM based Angel world is the basic starting point for
* a system, since it will allow programs to be downloaded to the
* target. The ROM version of Angel will provide the generic debug
* support, but no system specific routines. The preferred method of
* using Angel is as a link library. This ensures that applications
* carry with them the Angel routines necessary to support debugging
* (and also ensure that the Angel version is up-to-date, independant
* of the version in the target ROM). Eventually, once a program has
* been fully debugged, a ROMmed version of the program can be
* generated with the Angel code being provided in the application.
.. more comments ..
* The standard Angel routines do *NOT* perform any dynamic memory
* allocation. To simplify the source, and aid the porting to a non C
* library world, memory is either pre-allocated (as build-time
* globals) or actually given to the particular Angel routine by the
* active run-time. This ensures that the interaction between Angel
* and the target O/S is minimised.
*
* Notes: We sub-include more header files to keep the source
* modular. Since Angel is a kit-of-parts alternative systems may need
* to change the prototypes of particular functions, whilst
* maintaining a fixed external interface. e.g. using the standard
* DEBUG messages, but with a different communications world.
*/
/*---------------------------------------------------------------------------*/
#ifndef __angel_h
#define __angel_h
/*---------------------------------------------------------------------------*/
/*-- Global Angel definitions and manifests ---------------------------------*/
/*---------------------------------------------------------------------------*/
/* When building Angel we may not include the standard library
* headers. However, it is useful coding using standard macro names
* since it makes the code easier to understand.
*/
typedef unsigned int word ;
typedef unsigned char byte ;
/* The following typedefs can be used to access I/O registers: */
typedef volatile unsigned int vuword ;
typedef volatile unsigned char vubyte ;
/*
* The following typedefs are used when defining objects that may also
* be created on a host system, where the word size is not
* 32bits. This ensures that the same data values are manipulated.
*/
#ifdef TARGET
typedef unsigned int unsigned32;
typedef signed int signed32;
typedef int int32;
typedef unsigned short int unsigned16;
typedef signed short int signed16;
/*
* yet another solution for the bool/boolean problem, this one is
* copied from Scott's modifications to clx/host.h
*/
# ifdef IMPLEMENT_BOOL_AS_ENUM
enum _bool { _false, _true };
# define _bool enum _bool
# elif defined(IMPLEMENT_BOOL_AS_INT) || !defined(__cplusplus)
# define _bool int
# define _false 0
# define _true 1
# endif
# ifdef _bool
# define bool _bool
# endif
# ifndef true
# define true _true
# define false _false
# endif
# ifndef YES
# define YES true
# define NO false
# endif
# undef TRUE /* some OSF headers define as 1 */
# define TRUE true
# undef FALSE /* some OSF headers define as 1 */
# define FALSE false
# ifndef NULL
# define NULL 0
# endif
#else
# include "host.h"
#endif
#ifndef IGNORE
# define IGNORE(x) ((x)=(x))
#endif
/* The following typedef allows us to cast between integral and
* function pointers. This isn't allowed by direct casting when
* conforming to the ANSI spec.
*/
typedef union ansibodge
{
word w ;
word *wp ;
void *vp ;
byte *bp ;
void (*vfn)(void) ;
word (*wfn)(void) ;
int (*ifn)(void) ;
byte (*bfn)(void) ;
} ansibodge ;
/*---------------------------------------------------------------------------*/
/* The amount setup aside by the run-time system for stack overflow
* handlers to execute in. This must be at least 256bytes, since that
* value is assumed by the current ARM Ltd compiler.
* This space is _only_ kept for the USR stack, not any of the privileged
* mode stacks, as stack overflow on these is always fatal - there is
* no point attemptingto recover. In addition is is important that
* Angel should keep privileged stack space requirements to a minimum.
*/
#define APCS_STACKGUARD 256
#endif /* __angel_h */
/* EOF angel.h */

File diff suppressed because it is too large Load Diff

View File

@ -1,83 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/*
* ardi.h
* ADP RDI interfaces
*
*/
#include "host.h"
typedef unsigned32 ARMword;
#include "dbg_rdi.h"
#include "dbg_conf.h"
extern char *commandline;
extern ARMword last_vector_catch;
/* This is the size of buffers that are asked for by standard channels
* Non standard channels may wish to copy this!
*/
extern int Armsd_BufferSize;
typedef int (*host_ChannelBufferFilledFnPtr)(unsigned int ,unsigned char ** ,void *);
int angel_RDI_open(
unsigned type, Dbg_ConfigBlock const *config,
Dbg_HostosInterface const *hostif, struct Dbg_MCState *dbg_state);
int angel_RDI_close(void);
int angel_RDI_read(ARMword source, void *dest, unsigned *nbytes);
int angel_RDI_write(const void *source, ARMword dest, unsigned *nbytes);
int angel_RDI_CPUread(unsigned mode, unsigned long mask, ARMword *buffer);
int angel_RDI_CPUwrite(unsigned mode, unsigned long mask,
ARMword const *buffer);
int angel_RDI_CPread(unsigned CPnum, unsigned long mask, ARMword *buffer);
int angel_RDI_CPwrite(unsigned CPnum, unsigned long mask,
ARMword const *buffer);
int angel_RDI_setbreak(ARMword address, unsigned type, ARMword bound,
PointHandle *handle);
int angel_RDI_clearbreak(PointHandle handle);
int angel_RDI_setwatch(ARMword address, unsigned type, unsigned datatype,
ARMword bound, PointHandle *handle);
int angel_RDI_clearwatch(PointHandle handle);
int angel_RDI_pointinq(ARMword *address, unsigned type, unsigned datatype,
ARMword *bound);
int angel_RDI_execute(PointHandle *handle);
int angel_RDI_step(unsigned ninstr, PointHandle *handle);
int angel_RDI_info(unsigned type, ARMword *arg1, ARMword *arg2);
int angel_RDI_AddConfig(unsigned long nbytes);
int angel_RDI_LoadConfigData(unsigned long nbytes, char const *data);
int angel_RDI_SelectConfig(RDI_ConfigAspect aspect, char const *name,
RDI_ConfigMatchType matchtype, unsigned versionreq,
unsigned *versionp);
RDI_NameList const *angel_RDI_drivernames(void);
int angel_RDI_LoadAgent(ARMword dest, unsigned long size, getbufferproc *getb,
void *getbarg);
extern const struct Dbg_HostosInterface *angel_hostif;
typedef int angel_RDI_TargetStoppedProc(unsigned stopped_reason, void *arg);
extern int angel_RDI_OnTargetStopping(angel_RDI_TargetStoppedProc *fn,
void *arg);

File diff suppressed because it is too large Load Diff

View File

@ -1,109 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* Project: ANGEL
*
* Title: Public interface to buffer management
*/
#ifndef angel_buffers_h
#define angel_buffers_h
#include "chandefs.h" /* CHAN_HEADER_SIZE */
/* the handle to a buffer */
typedef unsigned char *p_Buffer;
/*
* Angel Packets are structured as a fixed size header, followed
* by the packet data
*/
#ifdef TARGET
# define BUFFERDATA(b) (b) /* channels layer takes care of it */
#else
# define BUFFERDATA(b) (&((b)[CHAN_HEADER_SIZE]))
#endif
/*
* The buffer management function prototypes are only applicable
* when compiling target code
*/
#ifdef TARGET
/*
* Function: Angel_BufferQuerySizes
* Purpose: Request infomation on the default and maximum buffer sizes
* that can be allocated
*
* Params:
* In/Out: default_size, max_size: pointers to place the
* sizes in on return
*/
void Angel_BufferQuerySizes(unsigned int *default_size,
unsigned int *max_size );
/*
* Function: Angel_RxEnginBuffersLeft
* Purpose: return the number of free buffers
*
* Params:
* Returns: number of free buffers
*/
unsigned int Angel_BuffersLeft( void );
/*
* Function: Angel_BufferAlloc
* Purpose: allocate a buffer that is at least req_size bytes long
*
* Params:
* Input: req_size the required size of the buffer
*
* Returns: pointer to the buffer NULL if unable to
* fulfil the request
*/
p_Buffer Angel_BufferAlloc(unsigned int req_size);
/*
* Function: Angel_BufferRelease
* Purpose: release a buffer back to the free pool
*
* Params:
* Input: pointer to the buffer to free
*/
void Angel_BufferRelease(p_Buffer buffer);
/* return values for angel_InitBuffers */
typedef enum buf_init_error{
INIT_BUF_OK,
INIT_BUF_FAIL
} buf_init_error;
/*
* Function: Angel_InitBuffers
* Purpose: Initalised and malloc the buffer pool
*
* Params:
* Returns: see above
*/
buf_init_error Angel_InitBuffers(void);
#endif /* def TARGET */
#endif /* ndef angel_buffers_h */
/* EOF buffers.h */

View File

@ -1,55 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/*
* bytesex.c - Code to support byte-sex independence
* Copyright: (C) 1991, Advanced RISC Machines Ltd., Cambridge, England.
*/
/*
*/
#include "bytesex.h"
static int reversing_bytes = 0;
void bytesex_reverse(yes_or_no)
int yes_or_no;
{ reversing_bytes = yes_or_no;
}
int bytesex_reversing()
{
return reversing_bytes;
}
int32 bytesex_hostval(v)
int32 v;
{ /* Return v with the same endian-ness as the host */
/* This mess generates better ARM code than the more obvious mess */
/* and may eventually peephole to optimal code... */
if (reversing_bytes)
{ unsigned32 t;
/* t = v ^ (v ror 16) */
t = v ^ ((v << 16) | (((unsigned32)v) >> 16));
t &= ~0xff0000;
/* v = v ror 8 */
v = (v << 24) | (((unsigned32)v) >> 8);
v = v ^ (t >> 8);
}
return v;
}
int32 bytesex_hostval_16(v)
int32 v;
{
if (reversing_bytes) {
v = ((v >> 8) & 0xff) | ((v << 8) & 0xff00);
}
return v;
}

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/*
Title: Code to support byte-sex independence
Copyright: (C) 1991, Advanced RISC Machines Ltd., Cambridge, England.
*/
/*
*/
#ifndef __bytesex_h
#define __bytesex_h
#include "host.h"
void bytesex_reverse(int yes_or_no);
/*
* Turn sex-reversal on or off - 0 means off, non-0 means on.
*/
int bytesex_reversing(void);
/*
* Return non-0 if reversing the byte sex, else 0.
*/
int32 bytesex_hostval(int32 v);
/*
* Return v or byte-reversed v, according to whether sex-reversval
* is on or off.
*/
int32 bytesex_hostval_16(int32 v);
/* Return v or byte-reversed v for a 16 bit value */
#endif

View File

@ -1,48 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* Project: ANGEL
*
* Title: Enumeration with all supported channels
*/
#ifndef angel_chandefs_h
#define angel_chandefs_h
enum channelIDs {
CI_PRIVATE = 0, /* channels protocol control messages */
CI_HADP, /* ADP, host originated */
CI_TADP, /* ADP, target originated */
CI_HBOOT, /* Boot, host originated */
CI_TBOOT, /* Boot, target originated */
CI_CLIB, /* Semihosting C library support */
CI_HUDBG, /* User debug support, host originated */
CI_TUDBG, /* User debug support, target originated */
CI_HTDCC, /* Thumb direct comms channel, host orig. */
CI_TTDCC, /* Thumb direct comms channel, target orig. */
CI_TLOG, /* Target debug/logging */
CI_NUM_CHANNELS
};
typedef unsigned ChannelID;
/*
* Size in bytes of the channel header.
* This is a duplicate of XXX in chanpriv.h, but we don't want everyone
* to have access to all of chanpriv.h, so we'll double-check in chanpriv.h.
*/
#define CHAN_HEADER_SIZE (4)
#endif /* ndef angel_chandefs_h */
/* EOF chandefs.h */

View File

@ -1,382 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* Project: ANGEL
*
* Title: User interface to the channels layer
*/
#ifndef angel_channels_h
#define angel_channels_h
/*
* This provides the public interface to the channels layer read and write
* routines, and buffer management routines.
*/
/* Nested header files, if required */
#include "devices.h"
#include "chandefs.h"
#include "adperr.h"
/* General purpose constants, macros, enums, typedefs */
/* use the default device */
#define CH_DEFAULT_DEV ((DeviceID)-1)
/* return codes */
typedef enum ChanError {
CE_OKAY, /* no error */
CE_ABANDONED, /* abandoned due to device switch */
CE_DEV_ERROR, /* unexpected error from device driver */
CE_BUSY, /* channel in use */
CE_BUFF_ERROR, /* unable to get buffer */
CE_PRIVATE /* start of internal error codes */
} ChanError;
/* Publically-accessible globals */
/*
* The following two globals are only valid after angel_InitialiseChannels()
* has been called.
*/
/* the default size of a channel buffer, for global use */
extern unsigned Angel_ChanBuffSize;
/* the size of a long buffer, for global use */
extern unsigned Angel_ChanLongSize;
#ifdef TARGET
AdpErrs send_resend_msg(DeviceID devid);
#endif
/*
* Function: angel_InitialiseChannels
* Purpose: initialise the channels layer
*
* Params:
* Input: -
* Output: -
* In/Out: -
*
* Returns: -
*
* Reads globals: -
* Modifies globals: -
*
* Other side effects: -
*/
void angel_InitialiseChannels( void );
/*
* Function: adp_init_seq
* Purpose: initialise sequence numbers and free anyt leftover buffers
*
* Params:
* Input: -
* Output: -
* In/Out: -
*
* Returns: - adp_ok if things went ok else an error code
*
* Reads globals: -
* Modifies globals: -
*
* Other side effects: -
*/
AdpErrs adp_init_seq(void);
/*
* Function: angel_ChannelAllocBuffer
* Purpose: allocate a buffer that is at least req_size bytes long
*
* Params:
* Input: req_size the minimum size required
* Output: -
* In/Out: -
*
* Returns: pointer to allocated buffer, or
* NULL if unable to allocate suitable buffer
*
* Reads globals: -
* Modifies globals: -
*
* Other side effects: -
*/
p_Buffer angel_ChannelAllocBuffer(unsigned req_size);
/*
* Function: angel_ChannelReleaseBuffer
* Purpose: release a buffer back to the free pool
*
* Params:
* Input: buffer the buffer to release
* Output: -
* In/Out: -
*
* Returns: -
*
* Reads globals: -
* Modifies globals: -
*
* Other side effects: -
*/
void angel_ChannelReleaseBuffer(p_Buffer buffer);
/*
* Function: angel_ChannelSend
* Purpose: blocking send of a packet via a channel
*
* Params:
* Input: devid Device to use, or CH_DEFAULT_DEV
* chanid Channel to use for tx
* buffer Pointer to data to send
* len Length of data to send
* Output: -
* In/Out: -
*
* Returns: CE_OKAY Transmission completed
* CE_BAD_CHAN Channel id invalid
* CE_ABANDONED Tx abandoned due to device switch
*
* Reads globals: -
* Modifies globals: -
*
* Other side effects: -
*/
ChanError angel_ChannelSend(DeviceID devid, ChannelID chanid,
const p_Buffer buffer, unsigned len);
/*
* Function: angel_ChannelSendAsync
* Purpose: asynchronous send of a packet via a channel
*
* Params:
* Input: devid Device to use, or CH_DEFAULT_DEV
* chanid Channel to use for tx
* buffer Pointer to data to send
* len Length of data to send
* callback Function to call on completion
* callback_data Pointer to pass to callback
* Output: -
* In/Out: -
*
* Returns: CE_OKAY Transmission underway
* CE_BAD_CHAN Channel id invalid
* CE_ABANDONED Tx abandoned due to device switch
*
* Reads globals: -
* Modifies globals: -
*
* Other side effects: -
*
* register an asynchronous send on the given channel
* (blocks until send can be commenced)
*/
typedef void (*ChanTx_CB_Fn)(ChannelID chanid, /* which channel */
void *callback_data); /* as supplied... */
ChanError angel_ChannelSendAsync( DeviceID devid,
ChannelID chanid,
const p_Buffer buffer,
unsigned len,
ChanTx_CB_Fn callback,
void *callback_data);
/*
* Function: angel_ChannelRead
* Purpose: blocking read of a packet from a channel
*
* Params:
* Input: devid Device to use, or CH_DEFAULT_DEV
* chanid Channel to use for rx
* Output: buffer The buffer, supplied and filled
* len How many bytes there are in the buffer
* In/Out: -
*
* Returns: CE_OKAY Reception successful
* CE_BAD_CHAN Channel id invalid
* CE_ABANDONED Tx abandoned due to device switch
*
* Reads globals: -
* Modifies globals: -
*
* Other side effects: -
*
* Note that in the present version, if an asynchronous read has been
* registered, a blocking read will be refused with CE_BUSY.
*/
ChanError angel_ChannelRead(DeviceID devid,
ChannelID chanid,
p_Buffer *buffer,
unsigned *len);
/*
* Function: angel_ChannelReadAsync
* Purpose: asynchronous read of a packet via a channel
*
* Params:
* Input: devid Device to use, or CH_DEFAULT_DEV
* chanid Channel to wait on
* callback Function to call on completion, or NULL
* callback_data Pointer to pass to callback
* Output: -
* In/Out: -
*
* Returns: CE_OKAY Read request registered
* CE_BAD_CHAN Channel id invalid
* CE_BUSY Someone else is using the channel
* (in a single threaded world)
*
* Reads globals: -
* Modifies globals: -
*
* Other side effects: -
*
* Register an asynchronous read on the given channel. There can only be one
* async. reader per channel, and blocking reads are not permitted whilst
* an async. reader is registered.
*
* Reader can unregister by specifying NULL as the callback function.
*/
typedef void (*ChanRx_CB_Fn)(DeviceID devID, /* ID of receiving device */
ChannelID chanID, /* ID of receiving channel */
p_Buffer buff, /* pointer to buffer */
unsigned len, /* length of data */
void *cb_data /* callback data */
);
ChanError angel_ChannelReadAsync(DeviceID devid,
ChannelID chanid,
ChanRx_CB_Fn callback,
void *callback_data);
/*
* Function: angel_ChannelReadAll
* Purpose: register an asynchronous read across all devices
*
* Params:
* Input: chanid Channel to look for (usually HBOOT)
* callback Function to call on completion
* callback_data Pointer to pass to callback
* Output: -
* In/Out: -
*
* Returns: CE_OKAY Read request registered
* CE_BAD_CHAN Channel id invalid
* CE_BUSY Someone else is reading all devices
*
* Reads globals: -
* Modifies globals: -
*
* Other side effects: -
*
* Register an asynchronous read across all devices. This is a 'fallback',
* which will be superseded (temporarily) by a registered reader or blocking
* read on a specific device.
*/
ChanError angel_ChannelReadAll( ChannelID chanid,
ChanRx_CB_Fn callback,
void *callback_data);
/*
* Function: angel_ChannelSendThenRead
* Purpose: blocking write to followed by read from a channel
*
* Params:
* Input: devid Device to use, or CH_DEFAULT_DEV
* chanid Channel to use for rx
* In/Out: buffer On entry: the packet to be sent
* On return: the packet received
* len On entry: length of packet to be sent
* On return: length of packet rx'd
* In/Out: -
*
* Returns: CE_OKAY Tx and Reception successful
* CE_BAD_CHAN Channel id invalid
* CE_ABANDONED Tx abandoned due to device switch
*
* Reads globals: -
* Modifies globals: -
*
* Other side effects: -
*
* Note that in the present version, if an asynchronous read has been
* registered, this will be refused with CE_BUSY.
*/
ChanError angel_ChannelSendThenRead(DeviceID devid,
ChannelID chanid,
p_Buffer *buffer,
unsigned *len);
/*
* Function: angel_ChannelSelectDevice
* Purpose: select the device to be used for all channel comms
*
* Params:
* Input: device ID of device to use as the default
* Output: -
* In/Out: -
*
* Returns: CE_OKAY Default device selected
* CE_BAD_DEV Invalid device ID
*
* Reads globals: -
* Modifies globals: -
*
* Other side effects: Any channel operations in progress are
* abandoned.
*
* select the device for all channels comms
*/
ChanError angel_ChannelSelectDevice(DeviceID device);
/*
* Function: angel_ChannelReadActiveDevice
* Purpose: reads the device id of the currently active device
*
* Params:
* Input: device address of a DeviceID variable
* Output: *device ID of device currently being used
* In/Out: -
*
* Returns: CE_OKAY Default device selected
*/
ChanError angel_ChannelReadActiveDevice(DeviceID *device);
#endif /* ndef angel_channels_h */
/* EOF channels.h */

View File

@ -1,55 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* Project: ANGEL
*
* Title: Private header for channels implementations
*/
#ifndef angel_chanpriv_h
#define angel_chanpriv_h
/*
* This describes the internal structure and flags for a channels packet.
*/
/* byte positions within channel packet */
#define CF_CHANNEL_BYTE_POS 0
#define CF_HOME_SEQ_BYTE_POS 1
#define CF_OPPO_SEQ_BYTE_POS 2
#define CF_FLAGS_BYTE_POS 3
#define CF_DATA_BYTE_POS 4
/* flags for FLAGS field */
#define CF_RELIABLE (1 << 0) /* use reliable channels protocol */
#define CF_RESEND (1 << 1) /* this is a renegotiation packet */
#define CF_HEARTBEAT (1 << 2) /* heartbeat packet - prod target into sync */
/* byte positions within buffer */
#define CB_LINK_BYTE_POS 0 /* the link pointer */
#define CB_CHAN_HEADER_BYTE_POS 4 /* the channel frame starts here */
/* macro to get buffer position of packet component */
#define CB_PACKET(x) (CB_CHAN_HEADER_BYTE_POS + (x))
/* byte offset of packet data within buffer */
#define CB_CHAN_DATA_BYTE_POS (CB_PACKET(CF_DATA_BYTE_POS))
/* access the link in a buffer, where b is byte pointer to buffer */
#define CB_LINK(b) ((p_Buffer)(&(b)[0]))
#define invalidChannelID(chan) (((int)(chan)) < 0 || \
(chan) >= CI_NUM_CHANNELS)
#endif /* ndef angel_chanpriv_h */
/* EOF chanpriv.h */

View File

@ -1,44 +0,0 @@
srcname="RDI library"
srctrigger=ardi.c
# per-host:
. ${srcdir}/../configure.host
echo "rdi-share/configure.in: host is $host, target is $target"
if [ ! -f ${srcdir}/../config/${gdb_host_cpu}/${gdb_host}.mh ]; then
echo '***' "GDB remote does not support host ${host}" 1>&2
exit 1
fi
# We really shouldn't depend on there being a space after XM_FILE= ...
hostfile=`awk '$1 == "XM_FILE=" { print $2 }' <${srcdir}/../config/${gdb_host_cpu}/${gdb_host}.mh`
# per-target:
. ${srcdir}/../configure.tgt
echo "rdi-share/configure.in: host_cpu is $host_cpu, target_cpu is $target_cpu"
if [ ! -f ${srcdir}/../config/${gdb_target_cpu}/${gdb_target}.mt ]; then
echo '***' "GDB remote does not support target ${target}" 1>&2
exit 1
fi
if [ -z "${removing}" ] ; then
cat ${srcdir}/../config/${gdb_host_cpu}/${gdb_host}.mh ${srcdir}/../config/${gdb_target_cpu}/${gdb_target}.mt | awk '$1 == "#msg" {
print substr($0,6)}'
fi
# We really shouldn't depend on there being a space after TM_FILE= ...
targetfile=`awk '$1 == "TM_FILE=" { print $2 }' <${srcdir}/../config/${gdb_target_cpu}/${gdb_target}.mt`
if [ "${target}" = "${host}" ] ; then
nativefile=`awk '$1 == "NAT_FILE=" { print $2 }' <${srcdir}/../config/${gdb_host_cpu}/${gdb_host}.mh`
fi
host_makefile_frag=../config/${gdb_host_cpu}/${gdb_host}.mh
target_makefile_frag=../config/${gdb_target_cpu}/${gdb_target}.mt
# post-target:

View File

@ -1,255 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* crc.c - provides some "standard" CRC calculation routines.
*
*/
#include "crc.h" /* describes this code */
/**********************************************************************/
/*
* crc32 IEEE-802.3 32bit CRC
* ----- --------------------
*/
/* This table was generated by the "crctable" program */
static const unsigned int crc32table[256] = {
/* 0x00 */ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
/* 0x04 */ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
/* 0x08 */ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
/* 0x0C */ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
/* 0x10 */ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
/* 0x14 */ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
/* 0x18 */ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
/* 0x1C */ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
/* 0x20 */ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
/* 0x24 */ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
/* 0x28 */ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
/* 0x2C */ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
/* 0x30 */ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
/* 0x34 */ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
/* 0x38 */ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
/* 0x3C */ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
/* 0x40 */ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
/* 0x44 */ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
/* 0x48 */ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
/* 0x4C */ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
/* 0x50 */ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
/* 0x54 */ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
/* 0x58 */ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
/* 0x5C */ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
/* 0x60 */ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
/* 0x64 */ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
/* 0x68 */ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
/* 0x6C */ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
/* 0x70 */ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
/* 0x74 */ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
/* 0x78 */ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
/* 0x7C */ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
/* 0x80 */ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
/* 0x84 */ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
/* 0x88 */ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
/* 0x8C */ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
/* 0x90 */ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
/* 0x94 */ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
/* 0x98 */ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
/* 0x9C */ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
/* 0xA0 */ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
/* 0xA4 */ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
/* 0xA8 */ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
/* 0xAC */ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
/* 0xB0 */ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
/* 0xB4 */ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
/* 0xB8 */ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
/* 0xBC */ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
/* 0xC0 */ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
/* 0xC4 */ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
/* 0xC8 */ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
/* 0xCC */ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
/* 0xD0 */ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
/* 0xD4 */ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
/* 0xD8 */ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
/* 0xDC */ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
/* 0xE0 */ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
/* 0xE4 */ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
/* 0xE8 */ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
/* 0xEC */ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
/* 0xF0 */ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
/* 0xF4 */ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
/* 0xF8 */ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
/* 0xFC */ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
};
unsigned int crc32(unsigned char *address, unsigned int size, unsigned int crc)
{
#if 0
/* FAST, but bigger and only good for word-aligned data */
unsigned int *daddr = (unsigned int *)address;
unsigned int data = FALSE; /* little-endian by default */
/*
* TODO: We should really get the current processor big- or
* little-endian state and set "data" accordingly.
*/
/* Perform word loop to save on memory accesses */
if (data)
/* big-endian */
for (; (size > 0); size -= sizeof(unsigned int))
{
data = *daddr++;
crc = (((crc >> 8) & 0x00FFFFFF) ^
crc32table[(crc ^ ((data >> 24) & 0xFF)) & 0xFF]);
crc = (((crc >> 8) & 0x00FFFFFF) ^
crc32table[(crc ^ ((data >> 16) & 0xFF)) & 0xFF]);
crc = (((crc >> 8) & 0x00FFFFFF) ^
crc32table[(crc ^ ((data >> 8) & 0xFF)) & 0xFF]);
crc = (((crc >> 8) & 0x00FFFFFF) ^
crc32table[(crc ^ ((data >> 0) & 0xFF)) & 0xFF]);
}
else
for (; (size > 0); size -= sizeof(unsigned int))
{
data = *daddr++;
crc = (((crc >> 8) & 0x00FFFFFF) ^
crc32table[(crc ^ ((data >> 0) & 0xFF)) & 0xFF]);
crc = (((crc >> 8) & 0x00FFFFFF) ^
crc32table[(crc ^ ((data >> 8) & 0xFF)) & 0xFF]);
crc = (((crc >> 8) & 0x00FFFFFF) ^
crc32table[(crc ^ ((data >> 16) & 0xFF)) & 0xFF]);
crc = (((crc >> 8) & 0x00FFFFFF) ^
crc32table[(crc ^ ((data >> 24) & 0xFF)) & 0xFF]);
}
#else
for (; (size > 0); size--)
/* byte loop */
crc = (((crc >> 8) & 0x00FFFFFF) ^
crc32table[(crc ^ *address++) & 0x000000FF]);
#endif
return(crc);
}
/**********************************************************************/
/*
* crc16 16bit CRC-CCITT
* ----- ---------------
* This function provides a table driven 16bit CRC generation for byte data.
* This CRC is also known as the HDLC CRC.
*/
/*
* 960201 KWelton
*
*TODO: Is this correct? The compiler predefines __arm, *not* __ARM
*/
#ifdef __ARM
/*
* To make the code quicker on the ARM, we double the table size and
* use integer slots rather than short slots for the table.
*/
static const unsigned int crctableA[16] = {
#else
static const unsigned short crctableA[16] = {
#endif
0x0000,
0x1081,
0x2102,
0x3183,
0x4204,
0x5285,
0x6306,
0x7387,
0x8408,
0x9489,
0xA50A,
0xB58B,
0xC60C,
0xD68D,
0xE70E,
0xF78F
};
#ifdef __ARM
/* See comments above */
static const unsigned int crctableB[16] = {
#else
static const unsigned short crctableB[16] = {
#endif
0x0000,
0x1189,
0x2312,
0x329B,
0x4624,
0x57AD,
0x6536,
0x74BF,
0x8C48,
0x9DC1,
0xAF5A,
0xBED3,
0xCA6C,
0xDBE5,
0xE97E,
0xF8F7
};
unsigned short crc16(unsigned char *address, unsigned int size,
unsigned short crc)
{
for (; (size > 0); size--)
{
/* byte loop */
unsigned char data = *address++; /* fetch the next data byte */
data ^= crc; /* EOR data with current CRC value */
crc = ((crctableA[(data & 0xF0) >> 4] ^ crctableB[data & 0x0F]) ^
(crc >> 8));
}
return(crc);
}
/**********************************************************************/
#if 0 /* not required at the moment */
/*
* elf_hash
* --------
* This function is derived from the one on page 68 of chapter of the "Unix
* SVR4 Programmer's Guide". It is used to generate a hash-code from a
* symbol name.
*/
unsigned int elf_hash(const unsigned char *name)
{
unsigned int h = 0;
unsigned int g;
/* NULL pointer returns a hash of zero */
while (name && (*name))
{
h = ((h << 4) + *name++);
if (g = (h & 0xF0000000))
h ^= (g >> 24);
h &= ~g;
}
return(h);
}
#endif
/**********************************************************************/
/* EOF crc.c */

View File

@ -1,88 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* crc.h - describes some "standard" CRC calculation routines.
*/
#ifndef angel_crc_h
#define angel_crc_h
/*
* manifests
*/
/*
* When using "crc32" or "crc16" these initial CRC values must be given to
* the respective function the first time it is called. The function can
* then be called with the return value from the last call of the function
* to generate a running CRC over multiple data blocks.
* When the last data block has been processed using the "crc32" algorithm
* the CRC value should be inverted to produce the final CRC value:
* e.g. CRC = ~CRC
*/
#define startCRC32 (0xFFFFFFFF) /* CRC initialised to all 1s */
#define startCRC16 (0x0000) /* CRC initialised to all 0s */
/*
* For the CRC-32 residual to be calculated correctly requires that the CRC
* value is in memory little-endian due to the byte read, bit-ordering
* nature of the algorithm.
*/
#define CRC32residual (0xDEBB20E3) /* good CRC-32 residual */
/**********************************************************************/
/*
* exported functions
*/
/*
* Function: crc32
* Purpose: Provides a table driven implementation of the IEEE-802.3
* 32-bit CRC algorithm for byte data.
*
* Params:
* Input: address pointer to the byte data
* size number of bytes of data to be processed
* crc initial CRC value to be used (can be the output
* from a previous call to this function).
* Returns:
* OK: 32-bit CRC value for the specified data
*/
extern unsigned int crc32(unsigned char *address, unsigned int size,
unsigned int crc);
/**********************************************************************/
/*
*
* Function: crc16
* Purpose: Generates a table driven 16-bit CRC-CCITT for byte data
*
* Params:
* Input: address pointer to the byte data
* size number of bytes of data to be processed
* crc initial CRC value to be used (can be the output
* from a previous call to this function).
*
* Returns:
* OK: 16-bit CRC value for the specified data
*/
extern unsigned short crc16(unsigned char *address, unsigned int size,
unsigned short crc);
/**********************************************************************/
#endif /* !defined(angel_crc_h) */
/* EOF crc.h */

View File

@ -1,52 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/*
* ARM symbolic debugger toolbox: dbg_conf.h
*/
/*
*/
#ifndef Dbg_Conf__h
#define Dbg_Conf__h
typedef struct Dbg_ConfigBlock {
int bytesex;
int fpe; /* Target should initialise FPE */
long memorysize;
unsigned long cpu_speed;/* Cpu speed (HZ) */
int serialport; /*) remote connection parameters */
int seriallinespeed; /*) (serial connection) */
int parallelport; /*) ditto */
int parallellinespeed; /*) (parallel connection) */
char *ethernettarget; /* name of remote ethernet target */
int processor; /* processor the armulator is to emulate (eg ARM60) */
int rditype; /* armulator / remote processor */
int heartbeat_on; /* angel heartbeat */
int drivertype; /* parallel / serial / etc */
char const *configtoload;
char const *memconfigtoload;
int flags;
} Dbg_ConfigBlock;
#define Dbg_ConfigFlag_Reset 1
#define Dbg_ConfigFlag_LLSymsNeedPrefix 2
typedef struct Dbg_HostosInterface Dbg_HostosInterface;
/* This structure allows access by the (host-independent) C-library support
module of armulator or pisd (armos.c) to host-dependent functions for
which there is no host-independent interface. Its contents are unknown
to the debugger toolbox.
The assumption is that, in a windowed system, fputc(stderr) for example
may not achieve the desired effect of the character appearing in some
window.
*/
#endif

View File

@ -1,60 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/*
* ARM symbolic debugger toolbox: dbg_cp.h
*/
/*
*/
#ifndef Dbg_CP__h
#define Dbg_CP__h
#define Dbg_Access_Readable 1
#define Dbg_Access_Writable 2
#define Dbg_Access_CPDT 4 /* else CPRT */
typedef struct {
unsigned short rmin, rmax;
/* a single description can be used for a range of registers with
the same properties *accessed via CPDT instructions*
*/
unsigned char nbytes; /* size of register */
unsigned char access; /* see above (Access_xxx) */
union {
struct { /* CPDT instructions do not allow the coprocessor much freedom:
only bit 22 ('N') and 12-15 ('CRd') are free for the
coprocessor to use as it sees fit.
*/
unsigned char nbit;
unsigned char rdbits;
} cpdt;
struct { /* CPRT instructions have much more latitude. The bits fixed
by the ARM are 24..31 (condition mask & opcode)
20 (direction)
8..15 (cpnum, arm register)
4 (CPRT not CPDO)
leaving 14 bits free to the coprocessor (fortunately
falling within two bytes).
*/
unsigned char read_b0, read_b1,
write_b0, write_b1;
} cprt;
} accessinst;
} Dbg_CoProRegDesc;
struct Dbg_CoProDesc {
int entries;
Dbg_CoProRegDesc regdesc[1/* really nentries */];
};
#define Dbg_CoProDesc_Size(n) (sizeof(struct Dbg_CoProDesc) + ((n)-1)*sizeof(Dbg_CoProRegDesc))
#endif

View File

@ -1,54 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/*
* ARM debugger toolbox : dbg_hif.c
* Description of the Dbg_HostosInterface structure. This is *NOT*
* part of the debugger toolbox, but it is required by 2 back ends
* (armul & pisd) and two front ends (armsd & wdbg), so putting it
* in the toolbox is the only way of avoiding multiple copies.
*/
/*
*/
#ifndef dbg_hif__h
#define dbg_hif__h
#if defined __STDC__ || defined ALMOST_STDC
# include <stdarg.h>
#else
# include <varargs.h>
#endif
typedef void Hif_DbgPrint(void *arg, const char *format, va_list ap);
typedef void Hif_DbgPause(void *arg);
typedef void Hif_WriteC(void *arg, int c);
typedef int Hif_ReadC(void *arg);
typedef int Hif_Write(void *arg, char const *buffer, int len);
typedef char *Hif_GetS(void *arg, char *buffer, int len);
typedef void Hif_RDIResetProc(void *arg);
struct Dbg_HostosInterface {
Hif_DbgPrint *dbgprint;
Hif_DbgPause *dbgpause;
void *dbgarg;
Hif_WriteC *writec;
Hif_ReadC *readc;
Hif_Write *write;
Hif_GetS *gets;
void *hostosarg;
Hif_RDIResetProc *reset;
void *resetarg;
};
#endif

View File

@ -1,509 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/*
* ARM debugger toolbox : dbg_rdi.h
*/
/*
*/
#ifndef dbg_rdi__h
#define dbg_rdi__h
/***************************************************************************\
* Other RDI values *
\***************************************************************************/
#define RDISex_Little 0 /* the byte sex of the debuggee */
#define RDISex_Big 1
#define RDISex_DontCare 2
#define RDIPoint_EQ 0 /* the different types of break/watchpoints */
#define RDIPoint_GT 1
#define RDIPoint_GE 2
#define RDIPoint_LT 3
#define RDIPoint_LE 4
#define RDIPoint_IN 5
#define RDIPoint_OUT 6
#define RDIPoint_MASK 7
#define RDIPoint_16Bit 16 /* 16-bit breakpoint */
#define RDIPoint_Conditional 32
/* ORRed with point type in extended RDP break and watch messages */
#define RDIPoint_Inquiry 64
#define RDIPoint_Handle 128 /* messages */
#define RDIWatch_ByteRead 1 /* types of data accesses to watch for*/
#define RDIWatch_HalfRead 2
#define RDIWatch_WordRead 4
#define RDIWatch_ByteWrite 8
#define RDIWatch_HalfWrite 16
#define RDIWatch_WordWrite 32
#define RDIReg_R15 (1L << 15) /* mask values for CPU */
#define RDIReg_PC (1L << 16)
#define RDIReg_CPSR (1L << 17)
#define RDIReg_SPSR (1L << 18)
#define RDINumCPURegs 19
#define RDINumCPRegs 10 /* current maximum */
#define RDIMode_Curr 255
/* RDI_Info subcodes */
/* rdp in parameters are all preceded by */
/* in byte = RDP_Info, word = info subcode */
/* out parameters are all preceded by */
/* out byte = RDP_Return */
#define RDIInfo_Target 0
/* rdi: out ARMword *targetflags, out ARMword *processor id */
/* rdp: in none, out word targetflags, word processorid, byte status */
/* the following bits are defined in targetflags */
# define RDITarget_LogSpeed 0x0f
# define RDITarget_HW 0x10 /* else emulator */
# define RDITarget_AgentMaxLevel 0xe0
# define RDITarget_AgentLevelShift 5
# define RDITarget_DebuggerMinLevel 0x700
# define RDITarget_DebuggerLevelShift 8
# define RDITarget_CanReloadAgent 0x800
# define RDITarget_CanInquireLoadSize 0x1000
# define RDITarget_UnderstandsRDPInterrupt 0x2000
# define RDITarget_CanProfile 0x4000
# define RDITarget_Code16 0x8000
# define RDITarget_HasCommsChannel 0x10000
#define RDIInfo_Points 1
/* rdi: out ARMword *pointcapabilities */
/* rdp: in none, out word pointcapabilities, byte status */
/* the following bits are defined in pointcapabilities */
# define RDIPointCapability_Comparison 1
# define RDIPointCapability_Range 2
/* 4 to 128 are RDIWatch_xx{Read,Write} left-shifted by two */
# define RDIPointCapability_Mask 0x100
# define RDIPointCapability_ThreadBreak 0x200
# define RDIPointCapability_ThreadWatch 0x400
# define RDIPointCapability_CondBreak 0x800
# define RDIPointCapability_Status 0x1000 /* status enquiries available */
#define RDIInfo_Step 2
/* rdi: out ARMword *stepcapabilities */
/* rdp: in none, out word stepcapabilities, byte status */
/* the following bits are defined in stepcapabilities */
# define RDIStep_Multiple 1
# define RDIStep_PCChange 2
# define RDIStep_Single 4
#define RDIInfo_MMU 3
/* rdi: out ARMword *mmuidentity */
/* rdp: in none, out word mmuidentity, byte status */
#define RDIInfo_DownLoad 4
/* Inquires whether configuration download and selection is available. */
/* rdp: in none, out byte status */
/* No argument, no return value. status == ok if available */
#define RDIInfo_SemiHosting 5
/* Inquires whether RDISemiHosting_* RDI_Info calls are available. */
/* rdp: in none, out byte status */
/* No argument, no return value. status == ok if available */
#define RDIInfo_CoPro 6
/* Inquires whether CoPro RDI_Info calls are available. */
/* rdp: in none, out byte status */
/* No argument, no return value. status == ok if available */
#define RDIInfo_Icebreaker 7
/* Inquires whether debuggee controlled by IceBreaker. */
/* rdp: in none, out byte status */
/* No argument, no return value. status == ok if available */
#define RDIMemory_Access 8
/* rdi: out RDI_MemAccessStats *p, in ARMword *handle */
/* rdp: in word handle */
/* out word nreads, word nwrites, word sreads, word swrites, */
/* word ns, word s, byte status */
/* Get memory access information for memory block with specified handle */
#define RDIMemory_Map 9
/* rdi: in RDI_MemDescr md[n], in ARMword *n */
/* rdp: in word n, n * { */
/* word handle, word start, word limit, */
/* byte width, byte access */
/* word Nread_ns, word Nwrite_ns, */
/* word Sread_ns, word Swrite_ns} */
/* out byte status */
/* Sets memory characteristics. */
#define RDISet_CPUSpeed 10
/* rdi: in ARMword *speed */
/* rdp: in word speed, out byte status */
/* Sets CPU speed (in ns) */
#define RDIRead_Clock 12
/* rdi: out ARMword *ns, out ARMword *s */
/* rdp: in none, out word ns, word s, byte status */
/* Reads simulated time */
#define RDIInfo_Memory_Stats 13
/* Inquires whether RDI_Info codes 8-10 are available */
/* rdp: in none, out byte status */
/* No argument, no return value. status == ok if available */
/* The next two are only to be used if RDIInfo_DownLoad returned no */
/* error */
#define RDIConfig_Count 14
/* rdi: out ARMword *count */
/* rdp: out byte status, word count (if status == OK) */
/* In addition, the next one is only to be used if RDIConfig_Count */
/* returned no error */
typedef struct { unsigned32 version; char name[32]; } RDI_ConfigDesc;
#define RDIConfig_Nth 15
/* rdi: in ARMword *n, out RDI_ConfigDesc * */
/* rdp: in word n */
/* out word version, byte namelen, bytes * bytelen name, */
/* byte status */
/* Set a front-end polling function to be used from within driver poll */
/* loops */
typedef void RDI_PollProc(void *);
typedef struct { RDI_PollProc *p; void *arg; } RDI_PollDesc;
#define RDISet_PollProc 16
/* rdi: in RDI_PollDesc const *from, RDI_PollDesc *to */
/* if from non-NULL, sets the polling function from it */
/* if to non-NULL, returns the previous polling function to it */
/* No corresponding RDP operation */
/* Called on debugger startup to see if the target is ready to execute */
#define RDIInfo_CanTargetExecute 20
/* rdi: in void
* out byte status (RDIError_NoError => Yes, Otherwise No)
*/
/* Called to set the top of target memory in an ICEman2 system
* This is then used by ICEman to tell the C Library via the INFOHEAP
* SWI where the stack should start.
* Note that only ICEman2 supports this call. Other systems eg.
* Demon, Angel, will simply return an error, which means that setting
* the top of memory in this fashion is not supported.
*/
#define RDIInfo_SetTopMem 21
/* rdi: in word mem_top
* out byte status (RDIError_NoError => Done, Other => Not supported
*/
/* Called before performing a loadagent to determine the endianess of
* the debug agent, so that images of the wrong bytesex can be
* complained about
*/
#define RDIInfo_AgentEndianess 22
/* rdi: in void
* out byte status
* status should be RDIError_LittleEndian or RDIError_BigEndian
* any other value indicates the target does not support this
* request, so the debugger will have to make a best guess, which
* probably means only allow little endian loadagenting.
*/
/* The next two are only to be used if the value returned by */
/* RDIInfo_Points has RDIPointCapability_Status set. */
#define RDIPointStatus_Watch 0x80
#define RDIPointStatus_Break 0x81
/* rdi: inout ARMword * (in handle, out hwresource), out ARMword *type */
/* rdp: in word handle, out word hwresource, word type, byte status */
#define RDISignal_Stop 0x100
/* Requests that the debuggee stop */
/* No arguments, no return value */
/* rdp: no reply (when the debuggee stops, there will be a reply to the */
/* step or execute request which started it) */
#define RDIVector_Catch 0x180
/* rdi: in ARMword *bitmap */
/* rdp: int word bitmap, out byte status */
/* bit i in bitmap set to cause vector i to cause entry to debugger */
/* The next four are only to be used if RDIInfo_Semihosting returned */
/* no error */
#define RDISemiHosting_SetState 0x181
/* rdi: in ARMword *semihostingstate */
/* rdp: in word semihostingstate, out byte status */
#define RDISemiHosting_GetState 0x182
/* rdi: out ARMword *semihostingstate */
/* rdp: in none, out word semihostingstate, byte status */
#define RDISemiHosting_SetVector 0x183
/* rdi: in ARMword *semihostingvector */
/* rdp: in word semihostingvector, out byte status */
#define RDISemiHosting_GetVector 0x184
/* rdi: out ARMword *semihostingvector */
/* rdp: in none, out word semihostingvector, byte status */
/* The next two are only to be used if RDIInfo_Icebreaker returned */
/* no error */
#define RDIIcebreaker_GetLocks 0x185
/* rdi: out ARMword *lockedstate */
/* rdp: in none, out word lockedstate, byte status */
#define RDIIcebreaker_SetLocks 0x186
/* rdi: in ARMword *lockedstate */
/* rdp: in word lockedstate, out byte status */
/* lockedstate is a bitmap of the icebreaker registers locked against */
/* use by IceMan (because explicitly written by the user) */
#define RDIInfo_GetLoadSize 0x187
/* rdi: out ARMword *maxloadsize */
/* rdp: in none, out word maxloadsize, byte status */
/* Inquires the maximum length of data transfer the agent is prepared */
/* to receive */
/* Only usable if RDIInfo_Target returned RDITarget_CanInquireLoadSize */
/* rdi: out ARMword *size */
/* Only to be used if the value returned by RDIInfo_Target had */
/* RDITarget_HasCommsChannel set */
typedef void RDICCProc_ToHost(void *arg, ARMword data);
typedef void RDICCProc_FromHost(void *arg, ARMword *data, int *valid);
#define RDICommsChannel_ToHost 0x188
/* rdi: in RDICCProc_ToHost *, in void *arg */
/* rdp: in byte connect, out byte status */
#define RDICommsChannel_FromHost 0x189
/* rdi: in RDICCProc_FromHost *, in void *arg */
/* rdp: in byte connect, out byte status */
/* These 4 are only to be used if RDIInfo_Semihosting returns no error */
#define RDISemiHosting_SetARMSWI 0x190
/* rdi: in ARMword ARM_SWI_number */
/* rdp: in ARMword ARM_SWI_number, out byte status */
#define RDISemiHosting_GetARMSWI 0x191
/* rdi: out ARMword ARM_SWI_number */
/* rdp: out ARMword ARM_SWI_number, byte status */
#define RDISemiHosting_SetThumbSWI 0x192
/* rdi: in ARMword Thumb_SWI_number */
/* rdp: in ARMword Thumb_SWI_number, out byte status */
#define RDISemiHosting_GetThumbSWI 0x193
/* rdi: out ARMword ARM_Thumb_number */
/* rdp: out ARMword ARM_Thumb_number, byte status */
#define RDICycles 0x200
/* rdi: out ARMword cycles[12] */
/* rdp: in none, out 6 words cycles, byte status */
/* the rdi result represents 6 big-endian doublewords; the rdp results */
/* return values for the ls halves of these */
# define RDICycles_Size 48
#define RDIErrorP 0x201
/* rdi: out ARMaddress *errorp */
/* rdp: in none, out word errorp, byte status */
/* Returns the error pointer associated with the last return from step */
/* or execute with status RDIError_Error. */
#define RDISet_Cmdline 0x300
/* rdi: in char *commandline (a null-terminated string) */
/* No corresponding RDP operation (cmdline is sent to the agent in */
/* response to SWI_GetEnv) */
#define RDISet_RDILevel 0x301
/* rdi: in ARMword *level */
/* rdp: in word level, out byte status */
/* Sets the RDI/RDP protocol level to be used (must lie between the */
/* limits returned by RDIInfo_Target). */
#define RDISet_Thread 0x302
/* rdi: in ARMword *threadhandle */
/* rdp: in word threadhandle, out byte status */
/* Sets the thread context for subsequent thread-sensitive operations */
/* (null value sets no thread) */
/* The next two are only to be used if RDI_read or RDI_write returned */
/* RDIError_LittleEndian or RDIError_BigEndian, to signify that the */
/* debugger has noticed. */
#define RDIInfo_AckByteSex 0x303
/* rdi: in ARMword *sex (RDISex_Little or RDISex_Big) */
/* The next two are only to be used if RDIInfo_CoPro returned no error */
#define RDIInfo_DescribeCoPro 0x400
/* rdi: in int *cpno, Dbg_CoProDesc *cpd */
/* rdp: in byte cpno, */
/* cpd->entries * { */
/* byte rmin, byte rmax, byte nbytes, byte access, */
/* byte cprt_r_b0, cprt_r_b1, cprt_w_b0, cprt_w_b1} */
/* byte = 255 */
/* out byte status */
#define RDIInfo_RequestCoProDesc 0x401
/* rdi: in int *cpno, out Dbg_CoProDesc *cpd */
/* rpd: in byte cpno */
/* out nentries * { */
/* byte rmin, byte rmax, byte nbytes, byte access, */
/* } */
/* byte = 255, byte status */
#define RDIInfo_Log 0x800
/* rdi: out ARMword *logsetting */
/* No corresponding RDP operation */
#define RDIInfo_SetLog 0x801
/* rdi: in ARMword *logsetting */
/* No corresponding RDP operation */
#define RDIProfile_Stop 0x500
/* No arguments, no return value */
/* rdp: in none, out byte status */
/* Requests that pc sampling stop */
#define RDIProfile_Start 0x501
/* rdi: in ARMword *interval */
/* rdp: in word interval, out byte status */
/* Requests that pc sampling start, with period <interval> usec */
#define RDIProfile_WriteMap 0x502
/* rdi: in ARMword map[] */
/* map[0] is the length of the array, subsequent elements are sorted */
/* and are the base of ranges for pc sampling (so if the sampled pc */
/* lies between map[i] and map[i+1], count[i] is incremented). */
/* rdp: a number of messages, each of form: */
/* in word len, word size, word offset, <size> words map data */
/* out status */
/* len, size and offset are all word counts. */
#define RDIProfile_ReadMap 0x503
/* rdi: in ARMword *len, out ARMword counts[len] */
/* Requests that the counts array be set to the accumulated pc sample */
/* counts */
/* rdp: a number of messages, each of form: */
/* in word offset, word size */
/* out <size> words, status */
/* len, size and offset are all word counts. */
#define RDIProfile_ClearCounts 0x504
/* No arguments, no return value */
/* rdp: in none, out byte status */
/* Requests that pc sample counts be set to zero */
#define RDIInfo_RequestReset 0x900
/* Request reset of the target environment */
/* No arguments, no return value */
/* No RDP equivalent, sends an RDP reset */
#define RDIInfo_CapabilityRequest 0x8000
/* Request whether the interface supports the named capability. The */
/* capability is specified by or'ing the RDIInfo number with this, and */
/* sending that request */
/* rdi: in none */
/* rdp: in none, out byte status */
typedef struct {
ARMword len;
ARMword map[1];
} RDI_ProfileMap;
typedef unsigned32 PointHandle;
typedef unsigned32 ThreadHandle;
#define RDINoPointHandle ((PointHandle)-1L)
#define RDINoHandle ((ThreadHandle)-1L)
struct Dbg_ConfigBlock;
struct Dbg_HostosInterface;
struct Dbg_MCState;
typedef int rdi_open_proc(unsigned type, struct Dbg_ConfigBlock const *config,
struct Dbg_HostosInterface const *i,
struct Dbg_MCState *dbg_state);
typedef int rdi_close_proc(void);
typedef int rdi_read_proc(ARMword source, void *dest, unsigned *nbytes);
typedef int rdi_write_proc(const void *source, ARMword dest, unsigned *nbytes);
typedef int rdi_CPUread_proc(unsigned mode, unsigned32 mask, ARMword *state);
typedef int rdi_CPUwrite_proc(unsigned mode, unsigned32 mask, ARMword const *state);
typedef int rdi_CPread_proc(unsigned CPnum, unsigned32 mask, ARMword *state);
typedef int rdi_CPwrite_proc(unsigned CPnum, unsigned32 mask, ARMword const *state);
typedef int rdi_setbreak_proc(ARMword address, unsigned type, ARMword bound,
PointHandle *handle);
typedef int rdi_clearbreak_proc(PointHandle handle);
typedef int rdi_setwatch_proc(ARMword address, unsigned type, unsigned datatype,
ARMword bound, PointHandle *handle);
typedef int rdi_clearwatch_proc(PointHandle handle);
typedef int rdi_execute_proc(PointHandle *handle);
typedef int rdi_step_proc(unsigned ninstr, PointHandle *handle);
typedef int rdi_info_proc(unsigned type, ARMword *arg1, ARMword *arg2);
typedef int rdi_pointinq_proc(ARMword *address, unsigned type,
unsigned datatype, ARMword *bound);
typedef enum {
RDI_ConfigCPU,
RDI_ConfigSystem
} RDI_ConfigAspect;
typedef enum {
RDI_MatchAny,
RDI_MatchExactly,
RDI_MatchNoEarlier
} RDI_ConfigMatchType;
typedef int rdi_addconfig_proc(unsigned32 nbytes);
typedef int rdi_loadconfigdata_proc(unsigned32 nbytes, char const *data);
typedef int rdi_selectconfig_proc(RDI_ConfigAspect aspect, char const *name,
RDI_ConfigMatchType matchtype, unsigned versionreq,
unsigned *versionp);
typedef char *getbufferproc(void *getbarg, unsigned32 *sizep);
typedef int rdi_loadagentproc(ARMword dest, unsigned32 size, getbufferproc *getb, void *getbarg);
typedef int rdi_targetisdead(void);
typedef struct {
int itemmax;
char const * const *names;
} RDI_NameList;
typedef RDI_NameList const *rdi_namelistproc(void);
typedef int rdi_errmessproc(char *buf, int buflen, int errnum);
struct RDIProcVec {
char rditypename[12];
rdi_open_proc *open;
rdi_close_proc *close;
rdi_read_proc *read;
rdi_write_proc *write;
rdi_CPUread_proc *CPUread;
rdi_CPUwrite_proc *CPUwrite;
rdi_CPread_proc *CPread;
rdi_CPwrite_proc *CPwrite;
rdi_setbreak_proc *setbreak;
rdi_clearbreak_proc *clearbreak;
rdi_setwatch_proc *setwatch;
rdi_clearwatch_proc *clearwatch;
rdi_execute_proc *execute;
rdi_step_proc *step;
rdi_info_proc *info;
/* V2 RDI */
rdi_pointinq_proc *pointinquiry;
/* These three useable only if RDIInfo_DownLoad returns no error */
rdi_addconfig_proc *addconfig;
rdi_loadconfigdata_proc *loadconfigdata;
rdi_selectconfig_proc *selectconfig;
rdi_namelistproc *drivernames;
rdi_namelistproc *cpunames;
rdi_errmessproc *errmess;
/* Only if RDIInfo_Target returns a value with RDITarget_LoadAgent set */
rdi_loadagentproc *loadagent;
rdi_targetisdead *targetisdead;
};
#endif

View File

@ -1,258 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* Project: ANGEL
*
* Title: Public client interface to devices
*/
#ifndef angel_devclnt_h
#define angel_devclnt_h
/*
* This header exports the public interface to Angel-compliant device
* drivers.
*
* They are intended to be used solely by Angel, not by the User
* Application. See devappl.h for the User Application interface to
* the device drivers.
*/
#include "devices.h"
/* General purpose constants, macros, enums, typedefs */
/*
* possible channels at device level
*
* XXX
*
* these are used as array indices, so be specific about their values
*/
typedef enum DevChanID {
DC_DBUG = 0, /* reliable debug packets
* containing SDBG, CLIB,UDBG, etc.) */
DC_APPL = 1, /* application packets */
DC_NUM_CHANNELS
} DevChanID;
/* Publically-accessible globals */
/* none */
/* Public functions */
/*
* Function: angel_DeviceWrite
* Purpose: The main entry point for asynchronous writes to a device.
*
* Params:
* Input: devID index of the device to write to
* buff data to write
* length how much data to write
* callback callback here when write finished
* or error
* cb_data data to be passed to callback
* chanID device channel to use
* Output: -
* In/Out: -
*
* Returns: DE_OKAY write request is underway
* DE_NO_DEV no such device
* DE_BAD_DEV device does not support angel writes
* DE_BAD_CHAN no such device channel
* DE_BUSY device busy with another write
* DE_INVAL silly length
*
* Reads globals: -
* Modifies globals: -
*
* Other side effects: -
*
* Commence asynchronous transmission of a buffer on a device. The
* callback will occur when the write completes or if there is an
* error.
*
* This must be called for each packet to be sent.
*/
DevError angel_DeviceWrite(DeviceID devID, p_Buffer buff,
unsigned length, DevWrite_CB_Fn callback,
void *cb_data, DevChanID chanID);
/*
* Function: angel_DeviceRegisterRead
* Purpose: The main entry point for asynchronous reads from a device.
*
* Params:
* Input: devID index of the device to read from
* callback callback here when read finished
* or error
* cb_data data to be passed to callback
* get_buff callback to be used to acquire buffer
* for incoming packets
* getb_data data to be passed to get_buff
* chanID device channel to use
* Output: -
* In/Out: -
*
* Returns: DE_OKAY read request is underway
* DE_NO_DEV no such device
* DE_BAD_DEV device does not support angel reads
* DE_BAD_CHAN no such device channel
* DE_BUSY device busy with another read
* DE_INVAL silly length
*
* Reads globals: -
* Modifies globals: -
*
* Other side effects: -
*
* Register asynchronous packet read from a device. The callback will
* occur when the read completes or if there is an error.
*
* This is persistent: the read remains registered for all incoming
* packets on the device channel.
*/
DevError angel_DeviceRegisterRead(DeviceID devID,
DevRead_CB_Fn callback, void *cb_data,
DevGetBuff_Fn get_buff, void *getb_data,
DevChanID chanID);
/*
* Function: angel_DeviceControl
* Purpose: Call a control function for a device
*
* Params:
* Input: devID index of the device to control to
* op operation to perform
* arg parameter depending on op
*
* Returns: DE_OKAY control request is underway
* DE_NO_DEV no such device
* DE_BAD_OP device does not support operation
*
* Reads globals: -
* Modifies globals: -
*
* Other side effects: -
*
* Have a device perform a control operation. Extra parameters vary
* according to the operation requested.
*/
DevError angel_DeviceControl(DeviceID devID, DeviceControl op, void *arg);
/*
* Function: angel_ReceiveMode
* Purpose: enable or disable reception across all devices
*
* Params:
* Input: mode choose enable or disable
*
* Pass the mode parameter to the receive_mode control method of each device
*/
void angel_ReceiveMode(DevRecvMode mode);
/*
* Function: angel_ResetDevices
* Purpose: reset all devices
*
* Params: none
*
* Call the reset control method for each device
*/
void angel_ResetDevices(void);
/*
* Function: angel_InitialiseDevices
* Purpose: initialise the device driver layer
*
* Params: none
*
* Set up the device driver layer and call the init method for each device
*/
void angel_InitialiseDevices(void);
/*
* Function: angel_IsAngelDevice
* Purpose: Find out if a device supports Angel packets
*
* Params:
* Input: devID index of the device to control to
*
* Returns: TRUE supports Angel packets
* FALSE raw device
*
* Reads globals: -
* Modifies globals: -
*
* Other side effects: -
*/
bool angel_IsAngelDevice(DeviceID devID);
#if !defined(MINIMAL_ANGEL) || MINIMAL_ANGEL == 0
/*
* Function: angel_ApplDeviceHandler
* Purpose: The entry point for User Application Device Driver requests
* in a full functiionality version of Angel.
* It will never be called directly by the User Application,
* but gets called indirectly, via the SWI handler.
*
* Params:
* Input: swi_r0 Argument to SWI indicating that
* angel_ApplDeviceHandler was to be called. This
* will not be used in this function, but is needed
* by the SWI handler.
* arg_blk pointer to block of arguments
* arg_blk[0] is one of
* angel_SWIreason_ApplDevice_{Read,Write,Yield}
* which indicates which angel_Device* fn is to
* be called. arg_blk[1] - arg_blk[n] are the
* arguments to the corresponding
* angel_ApplDevice* function.
* Output: -
* In/Out: -
*
* Returns: whatever the specified angel_Device* function
* returns.
*
* Reads globals: -
* Modifies globals: -
*
* Other side effects: -
*
* This has the side effects of angel_Device{Read,Write,Yield}
* depending upon which is operation is specified as described above.
*/
DevError angel_ApplDeviceHandler(
unsigned swi_r0, unsigned *arg_blk
);
#endif /* ndef MINIMAL_ANGEL */
#endif /* ndef angel_devclnt_h */
/* EOF devclnt.h */

View File

@ -1,102 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* Project: ANGEL
*
* Title: Devices header file
*/
#ifndef angel_devices_h
#define angel_devices_h
/*
* Provides common types for using devices, and provides access to the
* device table.
*/
#include "angel.h"
#include "buffers.h"
/* General purpose constants, macros, enums, typedefs */
/* a non-enum holder for device IDs */
typedef unsigned int DeviceID;
/* device error codes */
typedef enum DevError {
DE_OKAY, /* no error */
DE_NO_DEV, /* no such device */
DE_BAD_DEV, /* device does not support angel */
DE_BAD_CHAN, /* no such device channel */
DE_BAD_OP, /* operation not supported by this device */
DE_BUSY, /* device already busy */
DE_INVAL, /* length invalid */
DE_FAILED /* something else went wrong */
} DevError;
/* return codes from asynchronous calls - primarily for channels' benefit */
typedef enum DevStatus {
DS_DONE, /* operation succeeded */
DS_OVERFLOW, /* not enough buffer space */
DS_BAD_PACKET, /* packet failed */
DS_DEV_ERROR, /* device error */
DS_INT_ERROR /* internal error */
} DevStatus;
/* Callback for async. writes */
typedef void (*DevWrite_CB_Fn)(
void *buff, /* pointer to data -- cast to p_Buffer */
void *length, /* how much done -- cast to unsigned */
void *status, /* success code -- cast to DevStatus */
void *cb_data /* as supplied */
);
/* Callback for async. reads */
typedef void (*DevRead_CB_Fn)(
void *buff, /* pointer to data -- cast to p_Buffer */
void *length, /* how much read -- cast to unsigned */
void *status, /* success code -- cast to DevStatus */
void *cb_data /* as supplied */
);
/* control operations */
typedef enum DeviceControl {
DC_INIT, /* initialise device */
DC_RESET, /* reset device */
DC_RECEIVE_MODE, /* control reception */
DC_SET_PARAMS, /* set parameters of device */
#ifndef TARGET
DC_GET_USER_PARAMS, /* params set by user at open */
DC_GET_DEFAULT_PARAMS, /* device default parameters */
DC_RESYNC, /* resynchronise with new agent */
#endif
DC_PRIVATE /* start of private device codes */
} DeviceControl;
typedef enum DevRecvMode {
DR_DISABLE,
DR_ENABLE
} DevRecvMode;
/*
* callback to allow a device driver to request a buffer, to be filled
* with an incoming packet
*/
typedef p_Buffer (*DevGetBuff_Fn)(unsigned req_size, void *cb_data);
/* Publically-accessible globals */
/* none */
#endif /* ndef angel_devices_h */
/* EOF devices.h */

View File

@ -1,398 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include "adp.h"
#include "hsys.h"
#include "rxtx.h"
#include "drivers.h"
#include "buffers.h"
#include "devclnt.h"
#include "adperr.h"
#include "devsw.h"
#include "hostchan.h"
#include "logging.h"
/*
* TODO: this should be adjustable - it could be done by defining
* a reason code for DevSW_Ioctl. It could even be a
* per-devicechannel parameter.
*/
static const unsigned int allocsize = ADP_BUFFER_MIN_SIZE;
#define illegalDevChanID(type) ((type) >= DC_NUM_CHANNELS)
/**********************************************************************/
/*
* Function: initialise_read
* Purpose: Set up a read request for another packet
*
* Params:
* In/Out: ds State structure to be initialised
*
* Returns:
* OK: 0
* Error: -1
*/
static int initialise_read(DevSWState *ds)
{
struct data_packet *dp;
/*
* try to claim the structure that will
* eventually hold the new packet.
*/
if ((ds->ds_nextreadpacket = DevSW_AllocatePacket(allocsize)) == NULL)
return -1;
/*
* Calls into the device driver use the DriverCall structure: use
* the buffer we have just allocated, and declare its size. We
* are also obliged to clear the driver's context pointer.
*/
dp = &ds->ds_activeread.dc_packet;
dp->buf_len = allocsize;
dp->data = ds->ds_nextreadpacket->pk_buffer;
ds->ds_activeread.dc_context = NULL;
return 0;
}
/*
* Function: initialise_write
* Purpose: Set up a write request for another packet
*
* Params:
* Input: packet The packet to be written
*
* type The type of the packet
*
* In/Out: dc The structure to be intialised
*
* Returns: Nothing
*/
static void initialise_write(DriverCall *dc, Packet *packet, DevChanID type)
{
struct data_packet *dp = &dc->dc_packet;
dp->len = packet->pk_length;
dp->data = packet->pk_buffer;
dp->type = type;
/*
* we are required to clear the state structure for the driver
*/
dc->dc_context = NULL;
}
/*
* Function: enqueue_packet
* Purpose: move a newly read packet onto the appropriate queue
* of read packets
*
* Params:
* In/Out: ds State structure with new packet
*
* Returns: Nothing
*/
static void enqueue_packet(DevSWState *ds)
{
struct data_packet *dp = &ds->ds_activeread.dc_packet;
Packet *packet = ds->ds_nextreadpacket;
/*
* transfer the length
*/
packet->pk_length = dp->len;
/*
* take this packet out of the incoming slot
*/
ds->ds_nextreadpacket = NULL;
/*
* try to put it on the correct input queue
*/
if (illegalDevChanID(dp->type))
{
/* this shouldn't happen */
WARN("Illegal type for Rx packet");
DevSW_FreePacket(packet);
}
else
Adp_addToQueue(&ds->ds_readqueue[dp->type], packet);
}
/*
* Function: flush_packet
* Purpose: Send a packet to the device driver
*
* Params:
* Input: device The device to be written to
*
* In/Out: dc Describes the packet to be sent
*
* Returns: Nothing
*
* Post-conditions: If the whole packet was accepted by the device
* driver, then dc->dc_packet.data will be
* set to NULL.
*/
static void flush_packet(const DeviceDescr *device, DriverCall *dc)
{
if (device->DeviceWrite(dc) > 0)
/*
* the whole packet was swallowed
*/
dc->dc_packet.data = NULL;
}
/**********************************************************************/
/*
* These are the externally visible functions. They are documented in
* devsw.h
*/
Packet *DevSW_AllocatePacket(const unsigned int length)
{
Packet *pk;
if ((pk = malloc(sizeof(*pk))) == NULL)
{
WARN("malloc failure");
return NULL;
}
if ((pk->pk_buffer = malloc(length+CHAN_HEADER_SIZE)) == NULL)
{
WARN("malloc failure");
free(pk);
return NULL;
}
return pk;
}
void DevSW_FreePacket(Packet *pk)
{
free(pk->pk_buffer);
free(pk);
}
AdpErrs DevSW_Open(DeviceDescr *device, const char *name, const char *arg,
const DevChanID type)
{
DevSWState *ds;
/*
* is this the very first open call for this driver?
*/
if ((ds = (DevSWState *)(device->SwitcherState)) == NULL)
{
/*
* yes, it is: initialise state
*/
if ((ds = malloc(sizeof(*ds))) == NULL)
/* give up */
return adp_malloc_failure;
(void)memset(ds, 0, sizeof(*ds));
device->SwitcherState = (void *)ds;
}
/*
* check that we haven't already been opened for this type
*/
if ((ds->ds_opendevchans & (1 << type)) != 0)
return adp_device_already_open;
/*
* if no opens have been done for this device, then do it now
*/
if (ds->ds_opendevchans == 0)
if (device->DeviceOpen(name, arg) < 0)
return adp_device_open_failed;
/*
* open has finished
*/
ds->ds_opendevchans |= (1 << type);
return adp_ok;
}
AdpErrs DevSW_Match(const DeviceDescr *device, const char *name,
const char *arg)
{
return (device->DeviceMatch(name, arg) == -1) ? adp_failed : adp_ok;
}
AdpErrs DevSW_Close(const DeviceDescr *device, const DevChanID type)
{
DevSWState *ds = (DevSWState *)(device->SwitcherState);
Packet *pk;
if ((ds->ds_opendevchans & (1 << type)) == 0)
return adp_device_not_open;
ds->ds_opendevchans &= ~(1 << type);
/*
* if this is the last close for this channel, then inform the driver
*/
if (ds->ds_opendevchans == 0)
device->DeviceClose();
/*
* release all packets of the appropriate type
*/
for (pk = Adp_removeFromQueue(&(ds->ds_readqueue[type]));
pk != NULL;
pk = Adp_removeFromQueue(&(ds->ds_readqueue[type])))
DevSW_FreePacket(pk);
/* that's all */
return adp_ok;
}
AdpErrs DevSW_Read(const DeviceDescr *device, const DevChanID type,
Packet **packet, bool block)
{
int read_err;
DevSWState *ds = device->SwitcherState;
/*
* To try to get information out of the device driver as
* quickly as possible, we try and read more packets, even
* if a completed packet is already available.
*/
/*
* have we got a packet currently pending?
*/
if (ds->ds_nextreadpacket == NULL)
/*
* no - set things up
*/
if (initialise_read(ds) < 0) {
/*
* we failed to initialise the next packet, but can
* still return a packet that has already arrived.
*/
*packet = Adp_removeFromQueue(&ds->ds_readqueue[type]);
return adp_ok;
}
read_err = device->DeviceRead(&ds->ds_activeread, block);
switch (read_err) {
case 1:
/*
* driver has pulled in a complete packet, queue it up
*/
#ifdef RET_DEBUG
printf("got a complete packet\n");
#endif
enqueue_packet(ds);
*packet = Adp_removeFromQueue(&ds->ds_readqueue[type]);
return adp_ok;
case 0:
/*
* OK, return the head of the read queue for the given type
*/
/* enqueue_packet(ds); */
*packet = Adp_removeFromQueue(&ds->ds_readqueue[type]);
return adp_ok;
case -1:
#ifdef RET_DEBUG
printf("got a bad packet\n");
#endif
/* bad packet */
*packet = NULL;
return adp_bad_packet;
default:
panic("DevSW_Read: bad read status %d", read_err);
}
return 0; /* get rid of a potential compiler warning */
}
AdpErrs DevSW_FlushPendingWrite(const DeviceDescr *device)
{
struct DriverCall *dc;
struct data_packet *dp;
dc = &((DevSWState *)(device->SwitcherState))->ds_activewrite;
dp = &dc->dc_packet;
/*
* try to flush any packet that is still being written
*/
if (dp->data != NULL)
{
flush_packet(device, dc);
/* see if it has gone */
if (dp->data != NULL)
return adp_write_busy;
else
return adp_ok;
}
else
return adp_ok;
}
AdpErrs DevSW_Write(const DeviceDescr *device, Packet *packet, DevChanID type)
{
struct DriverCall *dc;
struct data_packet *dp;
dc = &((DevSWState *)(device->SwitcherState))->ds_activewrite;
dp = &dc->dc_packet;
if (illegalDevChanID(type))
return adp_illegal_args;
/*
* try to flush any packet that is still being written
*/
if (DevSW_FlushPendingWrite(device) != adp_ok)
return adp_write_busy;
/*
* we can take this packet - set things up, then try to get rid of it
*/
initialise_write(dc, packet, type);
flush_packet(device, dc);
return adp_ok;
}
AdpErrs DevSW_Ioctl(const DeviceDescr *device, const int opcode, void *args)
{
return (device->DeviceIoctl(opcode, args) < 0) ? adp_failed : adp_ok;
}
bool DevSW_WriteFinished(const DeviceDescr *device)
{
struct DriverCall *dc;
struct data_packet *dp;
dc = &((DevSWState *)(device->SwitcherState))->ds_activewrite;
dp = &dc->dc_packet;
return (dp == NULL || dp->data == NULL);
}
/* EOF devsw.c */

View File

@ -1,266 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*/
#ifndef angsd_devsw_h
#define angsd_devsw_h
#include "devclnt.h"
#include "adperr.h"
#include "drivers.h"
#ifndef __cplusplus
typedef struct Packet Packet;
typedef struct DevSWState DevSWState;
#endif
/*
* the basic structure used for passing packets around
*/
struct Packet
{
struct Packet *pk_next; /* XXX first field in struct */
unsigned int pk_length;
unsigned char *pk_buffer;
};
/*
* control structure, used for maintaining device switcher state
*/
struct DevSWState
{
unsigned int ds_opendevchans; /* bitmap of open device channels */
/*
* queue of packets read for the various device channels
*/
Packet *ds_readqueue[DC_NUM_CHANNELS];
/*
* structures for managing active read and write operations
*/
Packet *ds_nextreadpacket;
DriverCall ds_activeread;
DriverCall ds_activewrite;
};
#ifdef __cplusplus
extern "C" {
#endif
/*
* Function: DevSW_AllocatePacket
* Purpose: Claim some memory to hold a struct Packet, and the buffer for
* that packet.
*
* Params:
* Input: length Size of the buffer in struct Packet.
*
* Returns:
* OK: Pointer to the newly malloc()ed Packet.
* Error: NULL
*/
Packet *DevSW_AllocatePacket(const unsigned int length);
/*
* Function: DevSW_FreePacket
* Purpose: Free the memory associated with a struct Packet.
*
* Pre-conditions The structure must have been originally claimed
* via DevSW_AllocatePacket.
*
* Params:
* Input: pk The packet to be freed.
*
* Returns: Nothing
*/
void DevSW_FreePacket(Packet *pk);
/*
* Function: DevSW_Open
* Purpose: Open the specified device driver
*
* Params:
* Input: name Identifies which device to open. This can either be
* a host specific identifier (e.g. "/dev/ttya",
* "COM1:"), or a number which is used to refer to
* `standard' interfaces, so "1" would be the first host
* interface, "2" the second, and so on.
*
* arg Driver specific arguments. For example, some serial
* drivers accept speed and control arguments such as
* "9600" or "19200/NO_BREAK". These arguments are
* completely free-form: it is the individual drivers
* which do the necessary interpretation.
*
* type The type of packet the caller is interested in. Only
* one open is allowed for each type of packet.
*
* In/Out: device The device driver to open
*
* Returns:
* OK: adp_ok
* Error: adp_device_open_failed
* adp_device_already_open
* adp_malloc_failure
*/
AdpErrs DevSW_Open(DeviceDescr *device, const char *name, const char *arg,
const DevChanID type);
/*
* Function: DevSW_Match
* Purpose: Minimal veneer for DeviceMatch
*
* Params:
* Input: device The device driver to match.
*
* name Identifies which device to open. This can either be
* a host specific identifier (e.g. "/dev/ttya",
* "COM1:"), or a number which is used to refer to
* `standard' interfaces, so "1" would be the first host
* interface, "2" the second, and so on.
*
* arg Driver specific arguments. For example, some serial
* drivers accept speed and control arguments such as
* "9600" or "19200/NO_BREAK". These arguments are
* completely free-form: it is the individual drivers
* which do the necessary interpretation.
*
* Returns:
* OK: adp_ok
* Error: adp_failed
*/
AdpErrs DevSW_Match(const DeviceDescr *device, const char *name,
const char *arg);
/*
* Function: DevSW_Close
* Purpose: Close the specified device driver. All packets of the type
* used by the caller held within the switching layer will
* be discarded.
*
* Pre-conditions: Device must have been previously opened.
*
* Params:
* Input: device The device driver to close
*
* type The type of packet the caller was interested in.
*
* Returns:
* OK: adp_ok
* Error: adp_device_not_open
*/
AdpErrs DevSW_Close(const DeviceDescr *device, const DevChanID type);
/*
* Function: DevSW_Read
* Purpose: Read a packet of appropriate type from the device driver
*
* Params:
* Input: device The device driver to read packet from.
*
* type The type of packet the caller is interested in.
*
* Output: packet Pointer to new packet (if one is available)
* NULL (if no complete packet is available)
*
* Input: block If TRUE, read may safely block for a short period
* of time (say up to 20ms), to avoid high CPU load
* whilst waiting for a reply.
* If FALSE, read MUST NOT block.
*
* Returns:
* OK: adp_ok
* Error: adp_bad_packet
*
* Post-conditions: The calling function is responsible for freeing the
* resources used by the packet when it is no longer
* needed.
*/
AdpErrs DevSW_Read(const DeviceDescr *device, const DevChanID type,
Packet **packet, bool block);
/*
* Function: DevSW_Write
* Purpose: Try to write a packet to the device driver. The write will
* be bounced if another write is still in progress.
*
* Params:
* Input: device The device driver to write a packet to.
*
* packet The packet to be written.
*
* type The type to be assigned to the packet.
*
* Returns:
* OK: adp_ok
* Error: adp_illegal_args
* adp_write_busy
*
* Post-conditions: The calling function retains "ownership" of the packet,
* i.e. it is responsible for freeing the resources used
* by the packet when it is no longer needed.
*/
AdpErrs DevSW_Write(const DeviceDescr *device, Packet *packet, DevChanID type);
/*
* Function: DevSW_FlushPendingWrite
* Purpose: If a write is in progress, give it a chance to finish.
*
* Params:
* Input: device The device driver to flush.
*
* Returns:
* adp_ok no pending write, or write flushed completely
* adp_write_busy pending write not flushed completely
*/
AdpErrs DevSW_FlushPendingWrite(const DeviceDescr *device);
/*
* Function: DevSW_Ioctl
* Purpose: Perform miscellaneous control operations. This is a minimal
* veneer to DeviceIoctl.
*
* Params:
* Input: device The device driver to control.
*
* opcode Reason code indicating the operation to perform.
*
* In/Out: args Pointer to opcode-sensitive arguments/result space.
*
* Returns:
* OK: adp_ok
* Error: adp_failed
*/
AdpErrs DevSW_Ioctl(const DeviceDescr *device, const int opcode, void *args);
/*
* Function: DevSW_WriteFinished
* Purpose: Return TRUE if the active device has finished writing
* the last packet to be sent, or FALSE if a packet is still
* being transmitted.
*
* Params:
* Input: device The device driver to check.
*
* Returns:
* TRUE: write finished or inactive
* FALSE: write in progress
*/
bool DevSW_WriteFinished(const DeviceDescr *device);
#ifdef __cplusplus
}
#endif
#endif /* ndef angsd_devsw_h */
/* EOF devsw.h */

View File

@ -1,32 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* drivers.c - declares a NULL terminated list of device driver
* descriptors supported by the host.
*/
#include <stdio.h>
#include "drivers.h"
extern DeviceDescr angel_SerialDevice;
extern DeviceDescr angel_SerparDevice;
extern DeviceDescr angel_EthernetDevice;
DeviceDescr *devices[] =
{
&angel_SerialDevice,
&angel_SerparDevice,
&angel_EthernetDevice,
NULL
};
/* EOF drivers.c */

View File

@ -1,191 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* Project: ANGEL
*
* Title: Definitions for device driver interface.
*/
#ifndef angsd_drivers_h
#define angsd_drivers_h
#include "rxtx.h"
#ifndef __cplusplus
typedef struct DeviceDescr DeviceDescr;
typedef struct DriverCall DriverCall;
#endif
/*
* used to pass packets across the driver interface
*/
struct DriverCall
{
struct data_packet dc_packet;
void *dc_context;
};
/*
* used to describe a device driver
*/
struct DeviceDescr
{
char *DeviceName;
int (*DeviceOpen)(const char *name, const char *arg);
int (*DeviceMatch)(const char *name, const char *arg);
void (*DeviceClose)(void);
int (*DeviceRead)(DriverCall *dc, bool block);
int (*DeviceWrite)(DriverCall *dc);
int (*DeviceIoctl)(const int opcode, void *args);
void *SwitcherState; /* used by switcher interface */
};
/*
* Function: DeviceOpen
*
* Purpose: Open a communications device
*
* Pre-conditions: No previous open is still active
*
* Params:
* Input: name Identifies which device to open. This can either be
* a host specific identifier (e.g. "/dev/ttya",
* "COM1:"), or a number which is used to refer to
* `standard' interfaces, so "1" would be the first host
* interface, "2" the second, and so on.
*
* arg Driver specific arguments. For example, some serial
* drivers accept speed and control arguments such as
* "9600" or "19200/NO_BREAK". These arguments are
* completely free-form: it is the individual drivers
* which do the necessary interpretation.
*
* Returns:
* OK: 0
* Error: -1
*/
extern int DeviceOpen(const char *name, const char *arg);
/*
* Function: DeviceMatch
*
* Purpose: Check whether parameters are OK to be passed to DeviceOpen
*
* Params:
* Input: name Identifies which device to open. This can either be
* a host specific identifier (e.g. "/dev/ttya",
* "COM1:"), or a number which is used to refer to
* `standard' interfaces, so "1" would be the first host
* interface, "2" the second, and so on.
*
* arg Driver specific arguments. For example, some serial
* drivers accept speed and control arguments such as
* "9600" or "19200/NO_BREAK". These arguments are
* completely free-form: it is the individual drivers
* which do the necessary interpretation.
*
* Returns:
* OK: 0
* Error: -1
*/
extern int DeviceMatch(const char *name, const char *arg);
/*
* Function: DeviceClose
*
* Purpose: Close a communications device
*
* Pre-conditions: Device must have been previously opened
*
* Params: None
*
* Returns: Nothing
*/
extern void DeviceClose(void);
/*
* Function: DeviceRead
*
* Purpose: Try to read a complete packet from a communications device.
* This read must usually be non-blocking, i.e. it should read as
* many data from the device as needed to complete the packet,
* but it should not wait if the packet is not complete, and no
* more data are currently available from the device.
* As an optimisation the read can optionally block when 'block'
* is TRUE, but only for a short time. It is acceptable for the
* 'block' parameter to be ignored in which case all reads
* should be non-blocking.
*
* Pre-conditions: Device has been opened via DeviceOpen()
*
* Params:
* In/Out: dc Describes the packet being read (dc->dc_packet);
* dc->dc_context is for the driver to store private
* context, and is guaranteed to be NULL the first
* time DeviceRead is called for a given packet.
*
* In: block If TRUE, read may safely block for a short period
* of time (say up to 20ms), to avoid high CPU load
* whilst waiting for a reply.
* If FALSE, read MUST NOT block.
*
* Returns:
* OK: 1 (packet is complete)
* 0 (packet is not yet complete)
* Error: -1 bad packet
*
* Post-conditions: should a calamatous error occur panic() will be called
*/
extern int DeviceRead(DriverCall *dc, bool block);
/*
* Function: DeviceWrite
*
* Purpose: Try to write a packet to a communications device. This write
* must be non-blocking, i.e. it should write as many data to
* the device as is immediately possible, but should not wait
* for space to send any more after that.
*
* Pre-conditions: Device has been opened via DeviceOpen()
*
* Params:
* In/Out: dc Describes the packet being written (dc->dc_packet);
* dc->dc_context is for the driver to store private
* context, and is guaranteed to be NULL the first
* time DeviceWrite is called for a given packet.
*
* Returns:
* OK: 1 (all of the packet has been written)
* 0 (some of the packet remains to be written)
* Error: -1
*/
extern int DeviceWrite(DriverCall *dc);
/*
* Function: DeviceIoctl
*
* Purpose: Perform miscellaneous driver operations
*
* Pre-conditions: Device has been open via DeviceOpen()
*
* Params:
* Input: opcode Reason code indicating the operation to perform
* In/Out: args Pointer to opcode-sensitive arguments/result space
*
* Returns:
* OK: 0
* Error: -1
*/
extern int DeviceIoctl(const int opcode, void *args);
#endif /* !defined(angsd_drivers_h) */
/* EOF drivers.h */

View File

@ -1,123 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* endian.h - target endianness independent read/write primitives.
*/
#ifndef angel_endian_h
#define angel_endian_h
/*
* The endianness of the data being processed needs to be known, but
* the host endianness is not required (since the data is constructed
* using bytes). At the moment these are provided as macros. This
* gives the compiler freedom in optimising individual calls. However,
* if space is at a premium then functions should be provided.
*
* NOTE: These macros assume that the data has been packed in the same format
* as the packing on the build host. If this is not the case then
* the wrong addresses could be used when dealing with structures.
*
*/
/*
* For all the following routines the target endianness is defined by the
* following boolean definitions.
*/
#define BE (1 == 1) /* TRUE : big-endian */
#define LE (1 == 0) /* FALSE : little-endian */
/*
* The following type definitions are used by the endianness converting
* macros.
*/
typedef unsigned char U8;
typedef U8 *P_U8;
typedef const U8 *CP_U8;
typedef unsigned short U16;
typedef U16 *P_U16;
typedef unsigned int U32;
typedef U32 *P_U32;
/*
* If the endianness of the host and target are known (fixed) and the same
* then the following macro definitions can be used. These just directly copy
* the data.
*
* #define READ(e,a) (a)
* #define WRITE(e,a,v) ((a) = (v))
* #define PREAD(e,a) (a)
* #define PWRITE(e,a,v) (*(a) = (v))
*/
/*
* These macros assume that a byte (char) is 8bits in size, and that the
* endianness is not important when reading or writing bytes.
*/
#define PUT8(a,v) (*((P_U8)(a)) = (U8)(v))
#define PUT16LE(a,v) (PUT8(a,((v) & 0xFF)), \
PUT8((((P_U8)(a)) + sizeof(char)),((v) >> 8)))
#define PUT16BE(a,v) (PUT8(a,((v) >> 8)), \
PUT8((((P_U8)(a)) + sizeof(char)),((v) & 0xFF)))
#define PUT32LE(a,v) (PUT16LE(a,v), \
PUT16LE((((P_U8)(a)) + sizeof(short)),((v) >> 16)))
#define PUT32BE(a,v) (PUT16BE(a,((v) >> 16)), \
PUT16BE((((P_U8)(a)) + sizeof(short)),v))
#define GET8(a) (*((CP_U8)(a)))
#define GET16LE(a) (GET8(a) | (((U16)GET8(((CP_U8)(a)) + sizeof(char))) << 8))
#define GET16BE(a) ((((U16)GET8(a)) << 8) | GET8(((CP_U8)(a)) + sizeof(char)))
#define GET32LE(a) (GET16LE(a) | \
(((U32)GET16LE(((CP_U8)(a)) + sizeof(short))) << 16))
#define GET32BE(a) ((((U32)GET16BE(a)) << 16) | \
GET16BE(((CP_U8)(a)) + sizeof(short)))
/*
* These macros simplify the code in respect to reading and writing the
* correct size data when dealing with endianness. "e" is TRUE if we are
* dealing with big-endian data, FALSE if we are dealing with little-endian.
*/
/* void WRITE(int endianness, void *address, unsigned value); */
#define WRITE16(e,a,v) ((e) ? PUT16BE(&(a),v) : PUT16LE(&(a),v))
#define WRITE32(e,a,v) ((e) ? PUT32BE(&(a),v) : PUT32LE(&(a),v))
#define WRITE(e,a,v) ((sizeof(v) == sizeof(char)) ? \
PUT8(&(a),v) : ((sizeof(v) == sizeof(short)) ? \
WRITE16(e,a,v) : WRITE32(e,a,v)))
/* unsigned READ(int endianness, void *address) */
#define READ16(e,a) ((e) ? GET16BE(&(a)) : GET16LE(&(a)))
#define READ32(e,a) ((e) ? GET32BE(&(a)) : GET32LE(&(a)))
#define READ(e,a) ((sizeof(a) == sizeof(char)) ? \
GET8((CP_U8)&(a)) : ((sizeof(a) == sizeof(short)) ? \
READ16(e,a) : READ32(e,a)))
/* void PWRITE(int endianness, void *address, unsigned value); */
#define PWRITE16(e,a,v) ((e) ? PUT16BE(a,v) : PUT16LE(a,v))
#define PWRITE32(e,a,v) ((e) ? PUT32BE(a,v) : PUT32LE(a,v))
#define PWRITE(e,a,v) ((sizeof(v) == sizeof(char)) ? \
PUT8(a,v) : ((sizeof(v) == sizeof(short)) ? \
PWRITE16(e,a,v) : PWRITE32(e,a,v)))
/* unsigned PREAD(int endianness, void *address) */
#define PREAD16(e,a) ((e) ? GET16BE(a) : GET16LE(a))
#define PREAD32(e,a) ((e) ? GET32BE(a) : GET32LE(a))
#define PREAD(e,a) ((sizeof(*(a)) == sizeof(char)) ? \
GET8((CP_U8)a) : ((sizeof(*(a)) == sizeof(short)) ? \
PREAD16(e,a) : PREAD32(e,a)))
#endif /* !defined(angel_endian_h) */
/* EOF endian.h */

View File

@ -1,723 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* etherdrv.c - Ethernet Driver for Angel.
*/
#ifdef __hpux
# define _POSIX_SOURCE 1
# define _HPUX_SOURCE 1
# define _XOPEN_SOURCE 1
#endif
#include <stdio.h>
#ifdef __hpux
# define uint hide_HPs_uint
#endif
#ifdef __unix
# include <unistd.h>
# ifdef __hpux
# undef uint
# endif
#endif
#include <stdlib.h>
#include <string.h>
#ifdef __hpux
# define uint hide_HPs_uint
#endif
#include <fcntl.h>
#ifdef __hpux
# undef uint
#endif
#include <errno.h>
#include <stdarg.h>
#include <ctype.h>
#include "host.h"
#ifdef COMPILING_ON_WINDOWS
typedef char * caddr_t;
# undef IGNORE
# include <winsock.h>
# include "angeldll.h"
#else
# ifdef __hpux
# define uint hide_HPs_uint
# endif
# include <sys/types.h>
# include <sys/socket.h>
# ifdef __hpux
# undef uint
# endif
# include <netdb.h>
# include <sys/time.h>
# include <sys/ioctl.h>
# if !defined(__hpux) && !defined(__linux__) && !defined(_WIN32)
# include <sys/filio.h>
# endif
# include <netinet/in.h>
# include <arpa/inet.h>
#endif
#include "hsys.h"
#include "devices.h"
#include "endian.h"
#include "buffers.h"
#include "hostchan.h"
#include "params.h"
#include "logging.h"
#include "ethernet.h"
#ifndef COMPILING_ON_WINDOWS
/* these two might not work for windows */
extern int sys_nerr;
extern char *sys_errlist[];
#endif
#ifndef UNUSED
# define UNUSED(x) (x = x) /* Silence compiler warnings */
#endif
/*
* forward declarations of static functions
*/
static int EthernetOpen(const char *name, const char *arg);
static int EthernetMatch(const char *name, const char *arg);
static void EthernetClose(void);
static int EthernetRead(DriverCall *dc, bool block);
static int EthernetWrite(DriverCall *dc);
static int EthernetIoctl(const int opcode, void *args);
/*
* the device descriptor for Ethernet
*/
DeviceDescr angel_EthernetDevice =
{
"Ethernet",
EthernetOpen,
EthernetMatch,
EthernetClose,
EthernetRead,
EthernetWrite,
EthernetIoctl
};
/*
* descriptor for the socket that we talk down
*/
static int sock = -1;
/*
* address of the remote target
*/
static struct sockaddr_in remote, *ia = &remote;
/*
* array of dynamic port numbers on target
*/
static unsigned short int ports[2];
/*
* Function: set_address
* Purpose: Try to get an address into an understandable form
*
* Params:
* Input: addr The address to parse
*
* Output: ia Structure to hold the parsed address
*
* Returns:
* OK: 0
* Error: -1
*/
static int set_address(const char *const addr, struct sockaddr_in *const ia)
{
ia->sin_family = AF_INET;
/*
* Try address as a dotted decimal
*/
ia->sin_addr.s_addr = inet_addr(addr);
/*
* If that failed, try it as a hostname
*/
if (ia->sin_addr.s_addr == (u_int)-1)
{
struct hostent *hp = gethostbyname(addr);
if (hp == NULL)
return -1;
(void)memcpy((caddr_t)&ia->sin_addr, hp->h_addr, hp->h_length);
}
return 0;
}
/*
* Function: open_socket
* Purpose: Open a non-blocking UDP socket, and bind it to a port
* assigned by the system.
*
* Params: None
*
* Returns:
* OK: socket descriptor
* Error: -1
*/
static int open_socket(void)
{
int sfd;
#if 0 /* see #if 0 just below -VVV- */
int yesplease = 1;
#endif
struct sockaddr_in local;
/*
* open the socket
*/
#ifdef COMPILING_ON_WINDOWS
if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
return -1;
#else
if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
# ifdef DEBUG
perror("socket");
# endif
return -1;
}
#endif
/*
* 960731 KWelton
*
* I don't believe that this should be necessary - if we
* use select(), then non-blocking I/O is redundant.
* Unfortunately, select() appears to be broken (under
* Solaris, with a limited amount of time available for
* debug), so this code stays in for the time being
*/
#if 0
/*
* enable non-blocking I/O
*/
if (ioctlsocket(sfd, FIONBIO, &yesplease) < 0)
{
# ifdef DEBUG
perror("ioctl(FIONBIO)");
# endif
closesocket(sfd);
return -1;
}
#endif /* 0/1 */
/*
* bind local address to a system-assigned port
*/
memset((char *)&local, 0, sizeof(local));
local.sin_family = AF_INET;
local.sin_port = htons(0);
local.sin_addr.s_addr = INADDR_ANY;
if (bind(sfd, (struct sockaddr *)&local, sizeof(local)) < 0)
{
#ifdef DEBUG
perror("bind");
#endif
closesocket(sfd);
return -1;
}
/*
* all done
*/
return sfd;
}
/*
* Function: fetch_ports
* Purpose: Request assigned port numbers from remote target
*
* Params: None
*
* Returns: Nothing
*
* Post-conditions: This routine will *always* return something for the
* port numbers. If the remote target does not
* respond, then it makes something up - this allows
* the standard error message (from ardi.c) to be
* generated when the target is dead for whatever
* reason.
*/
static void fetch_ports(void)
{
int i;
const char ctrlpacket[] = CTRL_MAGIC;
CtrlResponse response;
/*
* we will try 3 times to elicit a response from the target
*/
for (i = 0; i < 3; ++i)
{
struct timeval tv;
fd_set fdset;
/*
* send the magic string to the control
* port on the remote target
*/
ia->sin_port = htons(CTRL_PORT);
if (sendto(sock, ctrlpacket, sizeof(ctrlpacket), 0,
(struct sockaddr *)ia, sizeof(*ia)) < 0)
{
#ifdef DEBUG
perror("fetch_ports: sendto");
#endif
return;
}
FD_ZERO(&fdset);
FD_SET(sock, &fdset);
tv.tv_sec = 0;
tv.tv_usec = 250000;
if (select(sock + 1, &fdset, NULL, NULL, &tv) < 0)
{
#ifdef DEBUG
perror("fetch_ports: select");
#endif
return;
}
if (FD_ISSET(sock, &fdset))
{
/*
* there is something there - read it
*/
if (recv(sock, (char *)&response, sizeof(response), 0) < 0)
{
#ifdef COMPILING_ON_WINDOWS
unsigned int werrno = WSAGetLastError();
if (werrno == WSAEWOULDBLOCK || werrno == 0)
#else
if (errno == EWOULDBLOCK)
#endif
{
--i;
continue;
}
else
{
#ifdef DEBUG
perror("fetch_ports: recv");
#endif
return;
}
}
{
/*
* XXX
*
* this is *very* unpleasant - try to match the structure
* layout
*/
unsigned short *sptr = (unsigned short *)(response + RESP_DBUG);
if (strcmp(response, ctrlpacket) == 0)
{
ports[DBUG_INDEX] = htons(*sptr);
sptr++;
ports[APPL_INDEX] = htons(*sptr);
}
#ifdef DEBUG
printf("fetch_ports: got response, DBUG=%d, APPL=%d\n",
ports[DBUG_INDEX], ports[APPL_INDEX]);
#endif
return;
}
}
}
/*
* we failed to get a response
*/
#ifdef DEBUG
printf("fetch_ports: failed to get a real answer\n");
#endif
}
/*
* Function: read_packet
* Purpose: read a packet, and pass it back to higher levels
*
* Params:
* In/Out: packet Holder for the read packet
*
* Returns: 1 - Packet is complete
* 0 - No complete packet read
*
* Post-conditions: Will call panic() if something goes wrong with the OS
*/
static int read_packet(struct data_packet *const packet)
{
struct sockaddr_in from;
int nbytes, fromlen = sizeof(from);
DevChanID devchan;
/*
* try to get the packet
*/
if ((nbytes = recvfrom(sock, (char *)(packet->data), packet->buf_len, 0,
(struct sockaddr *)&from, &fromlen)) < 0)
{
#ifdef COMPILING_ON_WINDOWS
if (nbytes == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
MessageBox(GetFocus(), "Error receiving packet\n", "Angel", MB_OK | MB_ICONSTOP);
#else
if (errno != EWOULDBLOCK)
{
# ifdef DEBUG
perror("recv");
# endif
panic("ethernet recv failure");
}
#endif
return 0;
}
#ifdef COMPILING_ON_WINDOWS
if (pfnProgressCallback != NULL && nbytes != SOCKET_ERROR)
{
progressInfo.nRead += nbytes;
(*pfnProgressCallback)(&progressInfo);
}
#endif
/*
* work out where the packet was from
*/
if (from.sin_addr.s_addr != remote.sin_addr.s_addr)
{
/*
* not from our target - ignore it
*/
#ifdef DEBUG
printf("read_packet: ignoring packet from %s\n",
inet_ntoa(from.sin_addr));
#endif
return 0;
}
else if (ntohs(from.sin_port) == ports[DBUG_INDEX])
devchan = DC_DBUG;
else if (ntohs(from.sin_port) == ports[APPL_INDEX])
devchan = DC_APPL;
else
{
/*
* unknown port number - ignore it
*/
#ifdef DEBUG
printf("read_packet: ignore packet from port %hd\n",
htons(from.sin_port));
#endif
return 0;
}
#if defined(DEBUG) && !defined(DO_TRACE)
printf("EthernetRead: %d bytes from %s channel\n",
nbytes, (devchan == DC_DBUG) ? "DBUG" : "APPL");
#endif
#ifdef DO_TRACE
printf("[%d on %d]\n", nbytes, devchan);
{
int i = 0;
unsigned char *cptr = packet->data;
while (i < nbytes)
{
printf("<%02X ", *(cptr++));
if (!(++i % 16))
printf("\n");
}
if (i % 16)
printf("\n");
}
#endif
/*
* OK - fill in the details
*/
packet->type = devchan;
packet->len = nbytes;
return 1;
}
/**********************************************************************/
/*
* Function: Ethernet_Open
* Purpose: Open the Ethernet device. See the documentation for
* DeviceOpen in drivers.h
*
* Post-conditions: Will have updated struct sockaddr_in remote (*ia)
* with the address of the remote target.
*/
static int EthernetOpen(const char *name, const char *arg)
{
#ifdef COMPILING_ON_WINDOWS
WORD wVersionRequested;
WSADATA wsaData;
#endif
/*
* name is passed as e=<blah>, so skip 1st two characters
*/
const char *etheraddr = name + 2;
#ifdef DEBUG
printf("EthernetOpen: name `%s'\n", name);
#endif
/* Check that the name is a valid one */
if (EthernetMatch(name, arg) != 0)
return -1;
#ifdef COMPILING_ON_WINDOWS
wVersionRequested = MAKEWORD(1, 1);
if (WSAStartup(wVersionRequested, &wsaData) != 0)
/*
* Couldn't find a useable winsock.dll.
*/
return -1;
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup();
/*
* Couldn't find a winsock.dll with supported version.
*/
return -1;
}
#endif
memset((char *)ia, 0, sizeof(*ia));
if (set_address(etheraddr, ia) < 0)
{
#ifdef COMPILING_ON_WINDOWS
/*
* SJ - I'm not sure that this is the correct way to handle this
* as Fail calls remote_disable and exits, while panic just exits.
* However at the time of writing remote_disable does nothing!
*/
/* Panic("EthernetOpen: bad name `%s'\n", etheraddr); */
#else
Fail("EthernetOpen: bad name `%s'\n", etheraddr);
#endif
return -1;
}
if ((sock = open_socket()) < 0)
return -1;
/*
* fetch the port numbers assigned by the remote target
* to its Debug and Application sockets
*/
fetch_ports();
return 0;
}
static int EthernetMatch(const char *name, const char *arg)
{
/* IGNORE arg */
if (0)
arg = arg;
if (name == NULL)
return -1;
if (tolower(name[0]) != 'e' || name[1] != '=')
return -1;
return 0;
}
static void EthernetClose(void)
{
if (sock >= 0)
{
closesocket(sock);
sock = -1;
}
#ifdef COMPILING_ON_WINDOWS
WSACleanup();
#endif
}
static int EthernetRead(DriverCall *dc, bool block)
{
fd_set fdset;
struct timeval tv;
int err;
FD_ZERO(&fdset);
FD_SET(sock, &fdset);
#ifdef COMPILING_ON_WINDOWS
UNUSED(block);
tv.tv_sec = tv.tv_usec = 0;
#else
tv.tv_sec = 0;
tv.tv_usec = (block ? 10000 : 0);
#endif
err = select(sock + 1, &fdset, NULL, NULL, &tv);
if (err < 0) {
if (errno == EINTR) {
return 0;
}
panic("ethernet select failure (errno=%i)",errno);
return 0;
}
if (FD_ISSET(sock, &fdset))
return read_packet(&dc->dc_packet);
else
return 0;
}
static int EthernetWrite(DriverCall *dc)
{
int nbytes;
struct data_packet *packet = &dc->dc_packet;
if (packet->type == DC_DBUG)
ia->sin_port = htons(ports[DBUG_INDEX]);
else if (packet->type == DC_APPL)
ia->sin_port = htons(ports[APPL_INDEX]);
else
{
panic("EthernetWrite: unknown devchan");
return 0;
}
#if defined(DEBUG) && !defined(DO_TRACE)
printf("EthernetWrite: %d bytes to %s channel\n",
packet->len, (packet->type == DC_DBUG) ? "DBUG" : "APPL");
#endif
#ifdef DO_TRACE
printf("[%d on %d]\n", packet->len, packet->type);
{
int i = 0;
unsigned char *cptr = packet->data;
while (i < packet->len)
{
printf(">%02X ", *(cptr++));
if (!(++i % 16))
printf("\n");
}
if (i % 16)
printf("\n");
}
#endif
if ((nbytes = sendto(sock, (char *)(packet->data), packet->len, 0,
(struct sockaddr *)ia, sizeof(*ia))) != packet->len)
{
#ifdef COMPILING_ON_WINDOWS
if (nbytes == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
#else
if (nbytes < 0 && errno != EWOULDBLOCK)
#endif
{
#ifdef DEBUG
perror("sendto");
#endif
#ifdef COMPILING_ON_WINDOWS
panic("ethernet send failure\n");
#else
/* might not work for Windows */
panic("ethernet send failure [%s]\n",
errno < sys_nerr ? sys_errlist[errno] : "unknown errno");
#endif
}
#ifdef DEBUG
else if (nbytes >= 0)
fprintf(stderr, "ethernet send: asked for %d, sent %d\n", packet->len, nbytes);
#endif
return 0;
}
#ifdef COMPILING_ON_WINDOWS
if (pfnProgressCallback != NULL && nbytes != SOCKET_ERROR)
{
progressInfo.nWritten += nbytes;
(*pfnProgressCallback)(&progressInfo);
}
#endif
return 1;
}
static int EthernetIoctl(const int opcode, void *args)
{
#ifdef DEBUG
printf( "EthernetIoctl: op %d arg %x\n", opcode, args );
#endif
/*
* IGNORE(opcode)
*/
if (0)
{
int dummy = opcode;
UNUSED(dummy);
}
UNUSED(args);
switch ( opcode )
{
case DC_RESYNC:
{
#ifdef DEBUG
printf( "EthernetIoctl: resync\n" );
#endif
fetch_ports();
return 0;
}
default:
{
return -1;
}
}
}
/* EOF etherdrv.c */

View File

@ -1,97 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* ethernet.h: Angel drivers for Ethernet using Fusion UDP/IP stack
*/
#ifndef angel_ethernet_h
#define angel_ethernet_h
/*
* the UDP ports that Angel Ethernet uses
*/
#define CTRL_PORT 1913
/*
* the size of the largest packet accepted on the control socket
*/
#define CTRL_MAXPACKET 6
/*
* This is the "magic number" sent to the control port to
* request that the channel port numbers are returned
*/
#define CTRL_MAGIC "Angel"
/*
* Array used for responding to a request on the control port
*/
typedef unsigned char CtrlResponse[10];
#define RESP_MAGIC 0
#define RESP_DBUG 6
#define RESP_APPL 8
/*
* indices for accessing the array of port numbers sent
* over the control socket
*/
#define DBUG_INDEX 0
#define APPL_INDEX 1
#ifdef TARGET
# include "devdriv.h"
extern const struct angel_DeviceEntry angel_EthernetDevice;
/*
* Function: angel_EthernetPoll
* Purpose: Poll Fusion for newly arrived packets
*
* Pre-conditions: Called in SVC mode with the lock
*
* Params:
* Input: data IGNORE'd
*
* Returns: Nothing
*
* Post-conditions: Will have passed any packets received along to
* higher levels
*/
void angel_EthernetPoll(unsigned int data);
void angel_EthernetNOP(unsigned int data);
/*
* Function: angel_FindEthernetConfigBlock
* Purpose: Search the Flash for an ethernet config block and return
* it if found.
*
* Params: None
*
* Returns: NULL if no config block found, the address if one is found.
*
*/
extern angel_EthernetConfigBlock *angel_FindEthernetConfigBlock(void);
#else /* def TARGET */
# ifndef COMPILING_ON_WINDOWS
# define ioctlsocket(x, y, z) ioctl((x), (y), (z))
# define closesocket(x) close(x)
# endif
#endif /* def TARGET */
#endif /* ndef angel_ethernet_h */
/* EOF ethernet.h */

View File

@ -1,222 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
#ifndef _host_LOADED
#define _host_LOADED 1
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#ifndef SEEK_SET
# define SEEK_SET 0
#endif
#ifndef SEEK_CUR
# define SEEK_CUR 1
#endif
#ifndef SEEK_END
# define SEEK_END 2
#endif
/* The following for the benefit of compiling on SunOS */
#ifndef offsetof
# define offsetof(T, member) ((char *)&(((T *)0)->member) - (char *)0)
#endif
#ifdef unix /* A temporary sop to older compilers */
# ifndef __unix /* (good for long-term portability?) */
# define __unix 1
# endif
#endif
#ifdef __unix
/* Generic unix -- hopefully a split into other variants will not be */
/* needed. However, beware the 'bsd' test above and safe_toupper etc. */
/* which cope with backwards (pre-posix/X/open) unix compatility. */
# define COMPILING_ON_UNIX 1
#endif
#if defined(_WIN32)
# define COMPILING_ON_WIN32 1
# if !defined(__CYGWIN32__)
# define COMPILING_ON_WINDOWS 1
# endif
#endif
#if defined(_CONSOLE)
# define COMPILING_ON_WINDOWS_CONSOLE 1
# define COMPILING_ON_WINDOWS 1
#endif
#ifdef _MSC_VER
# define COMPILING_ON_MSDOS 1
# define COMPILING_ON_WINDOWS 1
# if defined(__cplusplus)
# define IMPLEMENT_BOOL_AS_INT 1 /* VC++ doesn't have 'bool' (yet) */
# endif
#endif
/* The '(defined(__sparc) && defined(P_tmpdir) */
/* && !defined(__svr4__))' is to detect gcc on SunOS. */
/* C++ compilers don't have to define __STDC__ */
#if (defined(__sparc) && defined(P_tmpdir))
# if defined(__svr4__)
# define COMPILING_ON_SOLARIS
# else
# define COMPILING_ON_SUNOS
# endif
#endif
#ifdef __hppa
# define COMPILING_ON_HPUX
#endif
/*
* The following typedefs may need alteration for obscure host machines.
*/
#if defined(__alpha) && defined(__osf__) /* =========================== */
/* Under OSF the alpha has 64-bit pointers and 64-bit longs. */
typedef int int32;
typedef unsigned int unsigned32;
/* IPtr and UPtr are 'ints of same size as pointer'. Do not use in */
/* new code. Currently only used within 'ncc'. */
typedef long int IPtr;
typedef unsigned long int UPtr;
#else /* all hosts except alpha under OSF ============================= */
typedef long int int32;
typedef unsigned long int unsigned32;
/* IPtr and UPtr are 'ints of same size as pointer'. Do not use in */
/* new code. Currently only used within 'ncc'. */
#define IPtr int32
#define UPtr unsigned32
#endif /* ============================================================= */
typedef short int int16;
typedef unsigned short int unsigned16;
typedef signed char int8;
typedef unsigned char unsigned8;
/* The following code defines the 'bool' type to be 'int' under C */
/* and real 'bool' under C++. It also avoids warnings such as */
/* C++ keyword 'bool' used as identifier. It can be overridden by */
/* defining IMPLEMENT_BOOL_AS_ENUM or IMPLEMENT_BOOL_AS_INT. */
#undef _bool
#ifdef IMPLEMENT_BOOL_AS_ENUM
enum _bool { _false, _true };
# define _bool enum _bool
#elif defined(IMPLEMENT_BOOL_AS_INT) || !defined(__cplusplus)
# define _bool int
# define _false 0
# define _true 1
#endif
#ifdef _bool
# if defined(_MFC_VER) || defined(__CC_NORCROFT) /* When using MS Visual C/C++ v4.2 */
# define bool _bool /* avoids "'bool' is reserved word" warning */
# else
typedef _bool bool;
# endif
# define true _true
# define false _false
#endif
#define YES true
#define NO false
#undef TRUE /* some OSF headers define as 1 */
#define TRUE true
#undef FALSE /* some OSF headers define as 1 */
#define FALSE false
/* 'uint' conflicts with some Unixen sys/types.h, so we now don't define it */
typedef unsigned8 uint8;
typedef unsigned16 uint16;
typedef unsigned32 uint32;
typedef unsigned Uint;
typedef unsigned8 Uint8;
typedef unsigned16 Uint16;
typedef unsigned32 Uint32;
#ifdef ALPHA_TASO_SHORT_ON_OSF /* was __alpha && __osf. */
/* The following sets ArgvType for 64-bit pointers so that */
/* DEC Unix (OSF) cc can be used with the -xtaso_short compiler option */
/* to force pointers to be 32-bit. Not currently used since most/all */
/* ARM tools accept 32 or 64 bit pointers transparently. See IPtr. */
#pragma pointer_size (save)
#pragma pointer_size (long)
typedef char *ArgvType;
#pragma pointer_size (restore)
#else
typedef char *ArgvType;
#endif
/*
* Rotate macros
*/
#define ROL_32(val, n) \
((((unsigned32)(val) << (n)) | ((unsigned32)(val) >> (32-(n)))) & 0xFFFFFFFFL)
#define ROR_32(val, n) \
((((unsigned32)(val) >> (n)) | ((unsigned32)(val) << (32-(n)))) & 0xFFFFFFFFL)
#ifdef COMPILING_ON_UNIX
# define FOPEN_WB "w"
# define FOPEN_RB "r"
# define FOPEN_RWB "r+"
# ifndef __STDC__ /* caveat RISCiX... */
# define remove(file) unlink(file) /* a horrid hack, but probably best? */
# endif
#else
# define FOPEN_WB "wb"
# define FOPEN_RB "rb"
# define FOPEN_RWB "rb+"
#endif
#ifndef FILENAME_MAX
# define FILENAME_MAX 256
#endif
#if (!defined(__STDC__) && !defined(__cplusplus) && !defined(_MSC_VER)) || \
defined(COMPILING_ON_SUNOS)
/* Use bcopy rather than memmove, as memmove is not available. */
/* There does not seem to be a header for bcopy. */
void bcopy(const char *src, char *dst, int length);
# define memmove(d,s,l) bcopy(s,d,l)
/* BSD/SUN don't have strtoul(), but then strtol() doesn't barf on */
/* overflow as required by ANSI... This bodge is horrid. */
# define strtoul(s, ptr, base) strtol(s, ptr, base)
/* strtod is present in the C-library but is not in stdlib.h */
extern double strtod(const char *str, char **ptr);
#endif
/* For systems that do not define EXIT_SUCCESS and EXIT_FAILURE */
#ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
#endif
#ifndef EXIT_FAILURE
# define EXIT_FAILURE 1
#endif
#ifndef IGNORE
#define IGNORE(x) (x = x) /* Silence compiler warnings for unused arguments */
#endif
/* Define endian-ness of host */
#if defined(__acorn) || defined(__mvs) || defined(_WIN32) || \
(defined(__alpha) && defined(__osf__))
# define HOST_ENDIAN_LITTLE
#elif defined(__sparc) || defined(macintosh)
# define HOST_ENDIAN_BIG
#else
# define HOST_ENDIAN_UNKNOWN
#endif
#endif
/* end of host.h */

File diff suppressed because it is too large Load Diff

View File

@ -1,298 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*/
#ifndef angsd_hostchan_h
#define angsd_hostchan_h
/* struct timeval */
#if defined(__unix) || defined(__CYGWIN32__)
# include <sys/time.h>
#else
# include "winsock.h"
# include "time.h"
#endif
#include "chandefs.h"
#include "adperr.h"
#include "devsw.h"
/*
* asynchronous processing modes
*/
enum AsyncMode
{
async_block_on_nothing,
async_block_on_read,
async_block_on_write
};
#ifndef __cplusplus
typedef enum AsyncMode AsyncMode;
#endif
/*
* prototype for channels callback function
*/
typedef void (*ChannelCallback)(Packet *packet, void *state);
/*
* Function: Adp_initSeq
* Purpose: initialise the channel protocol and sequence numbers
*
* Params: none
*
* Returns: Nothing
*/
extern void Adp_initSeq(void);
/*
* Function: Adp_addToQueue
* Purpose: chain a Packet to the end of a linked list of such structures
*
* Params:
* In/Out: head Head of the linked list
*
* newpkt Packet to be chained onto the list
*
* Returns: Nothing
*/
extern void Adp_addToQueue(Packet **head, Packet *newpkt);
/*
* Function: removeFromQueue
* Purpose: remove a Packet from the head of a linked list of such structures
*
* Params:
* In/Out: head Head of the linked list
*
* Returns: Old head from the linked list
*
* Post-conditions: Second element in the list will be the new head.
*/
extern Packet *Adp_removeFromQueue(Packet **head);
/*
* Function: Adp_OpenDevice
* Purpose: Open a device to use for channels communication. This is a
* very thin veneer to the device drivers: what hostchan.c
* will do is call DeviceMatch for each device driver until it
* finds a driver that will accept name and arg, then call
* DeviceOpen for that device.
*
* Pre-conditions: No previous open is still active
*
* Params:
* Input: name Identifies which device to open. This can either be
* a host specific identifier (e.g. "/dev/ttya",
* "COM1:"), or a number which is used to refer to
* `standard' interfaces, so "1" would be the first host
* interface, "2" the second, and so on.
*
* arg Driver specific arguments. For example, some serial
* drivers accept speed and control arguments such as
* "9600" or "19200/NO_BREAK". These arguments are
* completely free-form: it is the individual drivers
* which do the necessary interpretation.
*
* heartbeat_on Incicates if the heartbeat is configured to be
* used or not, true if it is, false otherwise
*
* Returns:
* OK: adp_ok
* Error: adp_device_not_known,
* adp_device_open_failed
* adp_device_already_open
*/
AdpErrs Adp_OpenDevice(const char *name, const char *arg,
unsigned int heartbeat_on);
/*
* Function: Adp_CloseDevice
* Purpose: Close the device used for channels communication.
*
* Params: None
*
* Returns:
* OK: adp_ok
* Error: adp_device_not_open
*/
AdpErrs Adp_CloseDevice(void);
/*
* Function: Adp_Ioctl
* Purpose: Perform miscellaneous control operations on
* the device used for channels communication.
* This is a minimal veneer to DevSW_Ioctl.
*
* Params:
* Input: opcode Reason code indicating the operation to perform.
* In/Out: args Pointer to opcode-sensitive arguments/result space.
*
*
* Returns:
* OK: adp_ok
* Error: adp_device_not_open, adp_failed
*/
AdpErrs Adp_Ioctl(int opcode, void *args);
/*
* Function: Adp_ChannelRegisterRead
* Purpose: Register a callback function for received packets on a given
* channel
*
* Params:
* Input: chan The channel the callback function is for.
*
* cbfunc The callback function. If NULL, then the current
* callback is removed.
*
* cbstate State pointer to pass into the callback function
*
* Returns:
* OK: adp_ok
* Error: adp_device_not_open
* adp_bad_channel_id
*
* Post-conditions: The callback function is responsible for freeing the
* packet that is passed to it, when that packet is
* no longer needed.
*/
#ifdef __cplusplus
extern "C" {
#endif
extern AdpErrs Adp_ChannelRegisterRead(const ChannelID chan,
const ChannelCallback cbfunc,
void *cbstate);
#ifdef __cplusplus
}
#endif
/*
* Function: Adp_ChannelRead
* Purpose: Wait until a packet has been read for a given channel, and
* then return it. Callbacks for other channels are still
* active while this read is blocking.
*
* Pre-conditions: No callback has been already been registered for
* the channel.
*
* Params:
* Input: chan The channel to read.
*
* Output: packet The received packet.
*
* Returns:
* OK: adp_ok
* Error: adp_device_not_open
* adp_bad_channel_id
* adp_callback_already_registered
*
* Post-conditions: The calling function is responsible for freeing the
* received packet, when that packet is no longer
* needed.
*/
AdpErrs Adp_ChannelRead(const ChannelID chan, Packet **packet);
/*
* Function: Adp_ChannelWrite
* Purpose: Write a packet to the given channel
*
* Pre-conditions: Channel must have been previously opened.
*
* Params:
* Input: chan The channel to write.
*
* packet The packet to write.
*
* Returns:
* OK: adp_ok
* Error: adp_device_not_open
* adp_bad_channel_id
*
* Post-conditions: The packet being written becomes the "property" of
* Adp_ChannelWrite, which is responsible for freeing
* the packet when it is no longer needed.
*/
AdpErrs Adp_ChannelWrite(const ChannelID chan, Packet *packet);
/*
* Function: Adp_ChannelWriteAsync
* Purpose: Write a packet to the given channel, but don't wait
* for the write to complete before returning.
*
* Pre-conditions: Channel must have been previously opened.
*
* Params:
* Input: chan The channel to write.
*
* packet The packet to write.
*
* Returns:
* OK: adp_ok
* Error: adp_device_not_open
* adp_bad_channel_id
*
* Post-conditions: The packet being written becomes the "property" of
* Adp_ChannelWrite, which is responsible for freeing
* the packet when it is no longer needed.
*/
AdpErrs Adp_ChannelWriteAsync(const ChannelID chan, Packet *packet);
/*
* Function: Adp_AsynchronousProcessing
* Purpose: This routine should be called from persistent any idle loop
* to give the data I/O routines a chance to poll for packet
* activity. Depending upon the requested mode, this routine
* may, or may not, block.
*
* Params:
* Input: mode Specifies whether to block until a complete packet
* has been read, all pending writes have completed,
* or not to block at all.
*
* Returns: Nothing.
*/
void Adp_AsynchronousProcessing(const AsyncMode mode);
/*
* prototype for DC_APPL packet handler
*/
typedef void (*DC_Appl_Handler)(const DeviceDescr *device, Packet *packet);
/*
* install a handler for DC_APPL packets (can be NULL), returning old one.
*/
DC_Appl_Handler Adp_Install_DC_Appl_Handler(const DC_Appl_Handler handler);
/*
* prototype for asynchronous processing callback
*/
typedef void (*Adp_Async_Callback)(const DeviceDescr *device,
const struct timeval *const time_now);
/*
* add an asynchronous processing callback to the list
* TRUE == okay, FALSE == no more async processing slots
*/
bool Adp_Install_Async_Callback( const Adp_Async_Callback callback_proc );
/*
* delay for a given period (in microseconds)
*/
void Adp_delay(unsigned int period);
#endif /* ndef angsd_hostchan_h */
/* EOF hostchan.h */

View File

@ -1,913 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/*
* Host C Library support functions.
*
*/
#ifdef DEBUG
# include <ctype.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <time.h>
#include "adp.h"
#include "host.h"
#include "ardi.h"
#include "buffers.h"
#include "channels.h" /* Channel interface. */
#include "endian.h"
#include "logging.h" /* Angel support functions. */
#include "msgbuild.h"
#include "sys.h"
#include "hsys.h" /* Function and structure declarations. */
#include "hostchan.h"
#define FILEHANDLE int
/* Note: no statics allowed. All globals must be malloc()ed on the heap.
The state struct is used for this purpose. See 'hsys.h'. */
/* This is the message handler function passed to the channel manager in
HostSysInit. It is called whenever a message is received. 'buffptr'
points to the message body. Functionality is provided by the debugger
toolkit. The routine is very loosely based on the HandleSWI routine from
armos.c in the armulator source. */
/* These routines could be tested by providing a simple interface to armsd,
and running them in that. */
/* taken staight from armulator source */
#ifdef __riscos
extern int _fisatty(FILE *);
# define isatty_(f) _fisatty(f)
# define EMFILE -1
# define EBADF -1
int _kernel_escape_seen(void) { return 0 ;}
#else
# if defined(_WINDOWS) || defined(_CONSOLE)
# define isatty_(f) (f == stdin || f == stdout)
# else
# ifdef __ZTC__
# include <io.h>
# define isatty_(f) isatty((f)->_file)
# else
# ifdef macintosh
# include <ioctl.h>
# define isatty_(f) (~ioctl((f)->_file,FIOINTERACTIVE,NULL))
# else
# define isatty_(f) isatty(fileno(f))
# endif
# endif
# endif
#endif
/* Set up the state block, filetable and register the C lib callback fn */
int HostSysInit(const struct Dbg_HostosInterface *hostif, char **cmdline,
hsys_state **stateptr)
{
ChannelCallback HandleMessageFPtr = (ChannelCallback) HandleSysMessage;
int i;
*stateptr = (hsys_state *)malloc(sizeof(hsys_state));
if (*stateptr == NULL) return RDIError_OutOfStore;
(*stateptr)->hostif=hostif;
(*stateptr)->last_errno=0;
(*stateptr)->OSptr=(OSblock *)malloc(sizeof(OSblock));
if ((*stateptr)->OSptr == NULL) return RDIError_OutOfStore;
for (i=0; i<UNIQUETEMPS; i++) (*stateptr)->OSptr->TempNames[i]=NULL;
for (i=0; i<HSYS_FOPEN_MAX; i++) {
(*stateptr)->OSptr->FileTable[i]=NULL;
(*stateptr)->OSptr->FileFlags[i]=0;
}
(*stateptr)->CommandLine=cmdline;
return Adp_ChannelRegisterRead(CI_CLIB, (ChannelCallback)HandleMessageFPtr,
*stateptr);
}
/* Shut down the Clib support, this will probably never get called though */
int HostSysExit(hsys_state *stateptr)
{
free(stateptr->OSptr);
free(stateptr);
return RDIError_NoError;
}
#ifdef DEBUG
static void DebugCheckNullTermString(char *prefix, bool nl,
unsigned int len, unsigned char *strp)
{
printf("%s: %d: ", prefix, len);
if (strp[len]=='\0')
printf("\"%s\"", strp);
else
printf("NOT NULL TERMINATED");
if (nl)
printf("\n");
else
{
printf(" ");
fflush(stdout);
}
}
extern int sys_nerr;
extern char *sys_errlist[];
static char *DebugStrError(int last_errno)
{
if (last_errno < sys_nerr)
return sys_errlist[last_errno];
else
return "NO MSG (errno>sys_nerr)";
}
static void DebugCheckErr(char *prefix, bool nl, int err, int last_errno)
{
printf("\t%s: returned ", prefix);
if (err == 0)
printf("okay");
else
printf("%d, errno = %d \"%s\"", err, last_errno,
DebugStrError(last_errno));
if (nl)
printf("\n");
else
{
printf(" ");
fflush(stdout);
}
}
static void DebugCheckNonNull(char *prefix, bool nl,
void *handle, int last_errno)
{
printf("\t%s: returned ", prefix);
if (handle != NULL)
printf("okay [%08x]", (unsigned int)handle);
else
printf("NULL, errno = %d \"%s\"", last_errno,
DebugStrError(last_errno));
if (nl)
printf("\n");
else
{
printf(" ");
fflush(stdout);
}
}
#define DebugPrintF(c) printf c;
#else
#define DebugCheckNullTermString(p, n, l, s) ((void)(0))
#define DebugCheckErr(p, n, e, l) ((void)(0))
#define DebugCheckNonNull(p, n, h, l) ((void)(0))
#define DebugPrintF(c) ((void)(0))
#endif /* ifdef DEBUG ... else */
static FILE *hsysGetRealFileHandle(hsys_state *stateptr, int fh, char *flags)
{
FILE *file_p = NULL;
if (fh < 0 || fh >= HSYS_FOPEN_MAX)
{
stateptr->last_errno = EBADF;
DebugPrintF(("\tfh %d out-of-bounds!\n", fh));
return NULL;
}
else
{
file_p = stateptr->OSptr->FileTable[fh];
if (file_p != NULL) {
if (flags != NULL)
*flags = stateptr->OSptr->FileFlags[fh];
}
else {
stateptr->last_errno = EBADF;
DebugPrintF(("\tFileTable[%d] is NULL\n", fh));
}
return file_p;
}
}
int HandleSysMessage(Packet *packet, hsys_state *stateptr)
{
unsigned int reason_code, mode, len, c, nbytes, nbtotal, nbtogo = 0;
long posn, fl;
char character;
int err;
/* Note: We must not free the buffer passed in as the callback handler */
/* expects to do this. Freeing any other buffers we have malloced */
/* ourselves is acceptable */
unsigned char *buffp = ((unsigned char *)BUFFERDATA(packet->pk_buffer))+16;
/* buffp points to the parameters*/
/* the invidual messages, excluding*/
/* standard SYS fields (debugID, */
/* osinfo and reasoncode) */
unsigned char *buffhead = (unsigned char *)(packet->pk_buffer);
int DebugID, OSInfo1, OSInfo2, count;
const char* fmode[] = {"r","rb","r+","r+b",
"w","wb","w+","w+b",
"a","ab","a+","a+b",
"r","r","r","r"} /* last 4 are illegal */ ;
FILEHANDLE fh; /* fh is used as an index to the real file handle
* in OSptr */
FILE *fhreal;
unpack_message(BUFFERDATA(buffhead), "%w%w%w%w", &reason_code,
&DebugID, &OSInfo1, &OSInfo2);
/* Extract reason code from buffer. */
reason_code &= 0xFFFF; /* Strip away direction bit, OSInfo and */
/* DebugInfo fields. Will want to do some */
/* sort of validation on this later. */
switch(reason_code)
{
case CL_WriteC: /* Write a character to the terminal. */
/* byte data -> word status */
{
#ifdef DEBUG
int c = (int)(*buffp);
printf("CL_WriteC: [%02x]>%c<", c, isprint(c) ? c : '.');
#endif
stateptr->hostif->writec(stateptr->hostif->hostosarg, (int)(*buffp));
DevSW_FreePacket(packet);
return msgsend(CI_CLIB,"%w%w%w%w%w", CL_WriteC|HtoT,
DebugID, OSInfo1, OSInfo2, NoError);
}
case CL_Write0: /* Write a null terminated string to the terminal. */
{
unpack_message(buffp, "%w", &len);
DebugCheckNullTermString("CL_Write0", TRUE, len, buffp+4);
stateptr->hostif->write(stateptr->hostif->hostosarg,
(char *) buffp+4, len);
DevSW_FreePacket(packet);
return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Write0|HtoT, DebugID,
OSInfo1, OSInfo2, NoError);
}
case CL_ReadC: /* Read a byte from the terminal */
{
DebugPrintF(("CL_ReadC: "));
DevSW_FreePacket(packet);
character = stateptr->hostif->readc(stateptr->hostif->hostosarg);
DebugPrintF(("\nCL_ReadC returning [%02x]>%c<\n", character,
isprint(character) ? character : '.'));
return msgsend(CI_CLIB, "%w%w%w%w%w%b", CL_ReadC|HtoT,
DebugID, OSInfo1, OSInfo2, NoError, character);
}
case CL_System: /* Pass NULL terminated string to the hosts command
* interpreter. As it is nULL terminated we dont need
* the length
*/
{
unpack_message(buffp, "%w", &len);
DebugCheckNullTermString("CL_System", TRUE, len, buffp+4);
err = system((char *)buffp+4); /* Use the string in the buffer */
stateptr->last_errno = errno;
DebugCheckErr("system", TRUE, err, stateptr->last_errno);
err = msgsend(CI_CLIB, "%w%w%w%w%w%w", CL_System|HtoT,
DebugID, OSInfo1, OSInfo2, NoError, err);
DevSW_FreePacket(packet);
return err;
}
case CL_GetCmdLine: /* Returns the command line used to call the program */
{
/* Note: we reuse the packet here, this may not always be desirable */
/* /* TODO: Use long buffers if possible */
DebugPrintF(("CL_GetCmdLine: \"%s\"\n", *(stateptr->CommandLine)));
if (buffhead!=NULL) {
len = strlen(*(stateptr->CommandLine));
if (len > Armsd_BufferSize-24) len = Armsd_BufferSize-24;
packet->pk_length = len + msgbuild(BUFFERDATA(buffhead),
"%w%w%w%w%w%w", CL_GetCmdLine|HtoT,
DebugID, OSInfo1, OSInfo2,
NoError, len);
strncpy((char *) BUFFERDATA(buffhead)+24,*(stateptr->CommandLine),
len);
Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */
return 0;
}
else return -1;
}
case CL_Clock: /* Return the number of centiseconds since the support */
/* code started executing */
{
time_t retTime = time(NULL);
if (retTime == (time_t)-1)
stateptr->last_errno = errno;
else
retTime *=100;
DebugPrintF(("CL_Clock: %lu\n", retTime));
DebugCheckErr("time", TRUE, (retTime == (time_t)-1),
stateptr->last_errno);
DevSW_FreePacket(packet);
return msgsend(CI_CLIB, "%w%w%w%w%w%w",CL_Clock|HtoT,
DebugID, OSInfo1, OSInfo2, NoError, retTime);
}
case CL_Time: /* return time, in seconds since the start of 1970 */
{
time_t retTime = time(NULL);
if (retTime == (time_t)-1)
stateptr->last_errno = errno;
DebugPrintF(("CL_Time: %lu\n", retTime));
DebugCheckErr("time", TRUE, (retTime == (time_t)-1),
stateptr->last_errno);
DevSW_FreePacket(packet);
return msgsend(CI_CLIB,"%w%w%w%w%w%w",CL_Time|HtoT,
DebugID, OSInfo1, OSInfo2, NoError, retTime);
}
case CL_Remove: /* delete named in the null terminated string */
{
/* Removing an open file will cause problems but once again
* its not our problem, likely result is a tangled FileTable */
/* As the filename is passed with a null terminator we can use it
* straight out of the buffer without copying it.*/
unpack_message(buffp, "%w", &len);
DebugCheckNullTermString("CL_Remove", TRUE, len, buffp+4);
err=remove((char *)buffp+4);
stateptr->last_errno = errno;
DevSW_FreePacket(packet);
DebugCheckErr("remove", TRUE, err, stateptr->last_errno);
return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Remove|HtoT,
DebugID, OSInfo1, OSInfo2, err?-1:NoError);
}
case CL_Rename: /* rename file */
{
/* Rename(word nbytes, bytes oname, word nbytes, bytes nname)
* return(byte status)
*/
unsigned int len2;
unpack_message(buffp, "%w", &len);
DebugCheckNullTermString("CL_Rename", FALSE, len, buffp+4);
unpack_message(buffp+5+len, "%w", &len2);
DebugCheckNullTermString("to", TRUE, len2, buffp+9+len);
/* Both names are passed with null terminators so we can use them
* directly from the buffer. */
err = rename((char *)buffp+4, (char *)buffp+9+len);
stateptr->last_errno = errno;
DebugCheckErr("rename", TRUE, err, stateptr->last_errno);
DevSW_FreePacket(packet);
return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Rename|HtoT,
DebugID, OSInfo1, OSInfo2, (err==0)? NoError : -1);
}
case CL_Open: /* open the file */
{
/* Open(word nbytes, bytes name, byte mode)
* return(word handle)
*/
unpack_message(buffp, "%w", &len);
/* get the open mode */
unpack_message((buffp)+4+len+1, "%w", &mode);
DebugCheckNullTermString("CL_Open", FALSE, len, buffp+4);
DebugPrintF(("mode: %d\n", mode));
/* do some checking on the file first? */
/* check if its a tty */
if (strcmp((char *)buffp+4, ":tt")==0 && (mode==0||mode==1)) {
/* opening tty "r" */
fhreal = stdin;
stateptr->last_errno = errno;
DebugPrintF(("\tstdin "));
}
else if (strcmp((char *)buffp+4, ":tt")== 0 && (mode==4||mode==5)) {
/* opening tty "w" */
fhreal = stdout;
stateptr->last_errno = errno;
DebugPrintF(("\tstdout "));
}
else
{
fhreal = fopen((char *)buffp+4, fmode[mode&0xFF]);
stateptr->last_errno = errno;
DebugCheckNonNull("fopen", FALSE, fhreal, stateptr->last_errno);
}
DevSW_FreePacket(packet);
c = NONHANDLE;
if (fhreal != NULL) {
/* update filetable */
for (c=3; c < HSYS_FOPEN_MAX; c++) {
/* allow for stdin, stdout, stderr (!!! WHY? MJG) */
if (stateptr->OSptr->FileTable[c] == NULL) {
stateptr->OSptr->FileTable[c]= fhreal;
stateptr->OSptr->FileFlags[c]= mode & 1;
DebugPrintF(("fh: %d\n", c));
break;
}
else if (c == HSYS_FOPEN_MAX) {
/* no filehandles free */
DebugPrintF(("no free fh: %d\n", c));
stateptr->last_errno = EMFILE;
}
}
}
else {
/* c = NULL;*/
DebugPrintF(("error fh: %d\n", c));
}
(void) msgsend(CI_CLIB, "%w%w%w%w%w", CL_Open|HtoT,
DebugID, OSInfo1, OSInfo2, c);
return 0;
}
case CL_Close: /* close the file pointed to by the filehandle */
{
unpack_message(buffp, "%w", &fh);
DebugPrintF(("CL_Close: fh %d\n", fh));
DevSW_FreePacket(packet);
fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
if (fhreal == NULL)
err = -1;
else {
if (fhreal == stdin || fhreal == stdout || fhreal == stderr) {
stateptr->last_errno = errno;
DebugPrintF(("\tskipping close of std*\n"));
err = 0;
}
else {
err = fclose(fhreal);
if (err == 0)
stateptr->OSptr->FileTable[fh]=NULL;
stateptr->last_errno = errno;
DebugCheckErr("fclose", TRUE, err, stateptr->last_errno);
}
}
return msgsend(CI_CLIB,"%w%w%w%w%w", CL_Close|HtoT, DebugID,
OSInfo1, OSInfo2, err);
}
case CL_Write:
{
/* Write(word handle, word nbtotal, word nbytes, bytes data)
* return(word nbytes)
* WriteX(word nbytes, bytes data)
* return(word nbytes)
*/
unsigned char *rwdata = NULL, *rwhead = NULL;
unsigned char *write_source = NULL;
char flags;
FILE *fhreal;
unsigned int ack_reason = CL_Write; /* first ack is for CL_Write */
err = -1; /* err == 0 is fwrite() error indication */
unpack_message(buffp, "%w%w%w", &fh, &nbtotal, &nbytes);
DebugPrintF(("CL_Write: fh %d nbtotal %u nbytes %u\n",
fh, nbtotal, nbytes));
fhreal = hsysGetRealFileHandle(stateptr, fh, &flags);
nbtogo = nbtotal;
/* deal with the file handle */
if (fhreal == NULL)
err = 0;
else {
if (flags & READOP)
fseek(fhreal,0,SEEK_CUR);
stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP;
nbtogo -= nbytes;
if (nbtogo > 0) {
write_source = rwdata = rwhead = (unsigned char *)malloc(nbtotal);
if (rwhead == NULL) {
fprintf(stderr, "OUT OF MEMORY at line %d in %s\n",
__LINE__, __FILE__);
return -1;
}
memcpy(rwdata, buffp+12, nbytes);
rwdata += nbytes;
}
else
write_source = buffp+12;
}
do {
/* at least once!! */
if (nbtogo == 0 && err != 0) {
/* Do the actual write! */
if (fhreal == stdout || fhreal == stderr) {
stateptr->hostif->write(stateptr->hostif->hostosarg,
(char *)write_source, nbtotal);
}
else
err = fwrite(write_source, 1, nbtotal, fhreal);
stateptr->last_errno = errno;
DebugCheckErr("fwrite", TRUE, (err == 0), stateptr->last_errno);
}
DevSW_FreePacket(packet);
if (msgsend(CI_CLIB,"%w%w%w%w%w%w", ack_reason|HtoT,
DebugID, OSInfo1, OSInfo2, (err == 0), nbtogo))
{
fprintf(stderr, "COULD NOT REPLY at line %d in %s\n",
__LINE__, __FILE__);
if (rwhead != NULL)
free(rwhead);
return -1;
}
if (nbtogo == 0 || err == 0) {
DebugPrintF(("\twrite complete - returning\n"));
if (rwhead != NULL)
free(rwhead);
return 0;
}
else {
/* await extension */
ack_reason = CL_WriteX;
packet = DevSW_AllocatePacket(Armsd_BufferSize);
if (packet == NULL)
{
fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
__LINE__, __FILE__);
if (rwhead != NULL)
free(rwhead);
return -1;
}
Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL);
Adp_ChannelRead(CI_CLIB, &packet);
Adp_ChannelRegisterRead(CI_CLIB,
(ChannelCallback)HandleSysMessage,
stateptr);
buffhead = packet->pk_buffer;
unpack_message(BUFFERDATA(buffhead), "%w%w%w%w%w", &reason_code,
&DebugID, &OSInfo1, &OSInfo2, &nbytes);
if (reason_code != (CL_WriteX|TtoH)) {
DevSW_FreePacket(packet);
free(rwhead);
fprintf(stderr, "EXPECTING CL_WriteX GOT %u at line %d in %s\n",
reason_code, __LINE__, __FILE__);
return -1;
}
DebugPrintF(("CL_WriteX: nbytes %u\n", nbytes));
memcpy(rwdata, BUFFERDATA(buffhead)+20, nbytes);
rwdata += nbytes;
nbtogo -= nbytes;
}
} while (TRUE); /* will return when done */
}
case CL_WriteX: /*
* NOTE: if we've got here something has gone wrong
* CL_WriteX's should all be picked up within the
* CL_Write loop, probably best to return an error here
* do this for the moment just so we do actually return
*/
fprintf(stderr, "ERROR: unexpected CL_WriteX message received\n");
return -1;
case CL_Read:
{
/* Read(word handle, word nbtotal)
* return(word nbytes, word nbmore, bytes data)
*/
/* ReadX()
* return(word nbytes, word nbmore, bytes data) */
unsigned char *rwdata, *rwhead;
int gotlen;
unsigned int max_data_in_buffer=Armsd_BufferSize-28;
char flags;
FILE *fhreal;
unsigned int nbleft = 0, reason = CL_Read;
err = NoError;
unpack_message(buffp, "%w%w", &fh, &nbtotal);
DebugPrintF(("CL_Read: fh %d, nbtotal %d: ", fh, nbtotal));
rwdata = rwhead = (unsigned char *)malloc(nbtotal);
if (rwdata == NULL) {
fprintf(stderr, "OUT OF MEMORY at line %d in %s\n",
__LINE__, __FILE__);
DevSW_FreePacket(packet);
return -1;
}
/* perform the actual read */
fhreal = hsysGetRealFileHandle(stateptr, fh, &flags);
if (fhreal == NULL)
{
/* bad file handle */
err = -1;
nbytes = 0;
gotlen = 0;
}
else
{
if (flags & WRITEOP)
fseek(fhreal,0,SEEK_CUR);
stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP;
if (isatty_(fhreal)) {
/* reading from a tty, so do some nasty stuff, reading into rwdata */
if (angel_hostif->gets(stateptr->hostif->hostosarg, (char *)rwdata,
nbtotal) != 0)
gotlen = strlen((char *)rwdata);
else
gotlen = 0;
stateptr->last_errno = errno;
DebugPrintF(("ttyread %d\n", gotlen));
}
else {
/* not a tty, reading from a real file */
gotlen = fread(rwdata, 1, nbtotal, fhreal);
stateptr->last_errno = errno;
DebugCheckErr("fread", FALSE, (gotlen == 0), stateptr->last_errno);
DebugPrintF(("(%d)\n", gotlen));
}
}
nbtogo = gotlen;
do {
/* at least once */
if ((unsigned int) nbtogo <= max_data_in_buffer)
nbytes = nbtogo;
else
nbytes = max_data_in_buffer;
nbtogo -= nbytes;
/* last ReadX needs subtle adjustment to returned nbtogo */
if (nbtogo == 0 && err == NoError && reason == CL_ReadX)
nbleft = nbtotal - gotlen;
else
nbleft = nbtogo;
count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w%w",
reason|HtoT, 0, ADP_HandleUnknown,
ADP_HandleUnknown, err, nbytes, nbleft);
if (err == NoError) {
/* copy data into buffptr */
memcpy(BUFFERDATA(buffhead)+28, rwdata, nbytes);
rwdata += nbytes;
count += nbytes;
}
DebugPrintF(("\treplying err %d, nbytes %d, nbtogo %d\n",
err, nbytes, nbtogo));
packet->pk_length = count;
Adp_ChannelWrite(CI_CLIB, packet);
if (nbtogo == 0 || err != NoError) {
/* done */
free(rwhead);
return 0;
}
else {
/* await extension */
reason = CL_ReadX;
packet = DevSW_AllocatePacket(Armsd_BufferSize);
if (packet == NULL) {
fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
__LINE__, __FILE__);
free(rwhead);
return -1;
}
Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL);
Adp_ChannelRead(CI_CLIB, &packet);
Adp_ChannelRegisterRead(CI_CLIB,
(ChannelCallback)HandleSysMessage,
stateptr);
buffhead = packet->pk_buffer;
unpack_message(BUFFERDATA(buffhead),"%w", &reason_code);
if (reason_code != (CL_ReadX|TtoH)) {
fprintf(stderr, "EXPECTING CL_ReadX GOT %u at line %d in %s\n",
reason_code, __LINE__, __FILE__);
DevSW_FreePacket(packet);
free(rwdata);
return -1;
}
}
} while (TRUE); /* will return above on error or when done */
}
case CL_ReadX: /* If we're here something has probably gone wrong */
fprintf(stderr, "ERROR: Got unexpected CL_ReadX message\n");
return -1;
case CL_Seek:
{
unpack_message(buffp, "%w%w", &fh, &posn);
DebugPrintF(("CL_Seek: fh %d, posn %ld\n", fh, posn));
DevSW_FreePacket(packet);
fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
if (fhreal == NULL)
err = -1;
else {
err = fseek(fhreal, posn, SEEK_SET);
stateptr->last_errno = errno;
DebugCheckErr("fseek", TRUE, err, stateptr->last_errno);
}
return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Seek|HtoT,
DebugID, OSInfo1, OSInfo2, err);
}
case CL_Flen:
{
unpack_message(buffp, "%w", &fh);
DebugPrintF(("CL_Flen: fh %d ", fh));
DevSW_FreePacket(packet);
fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
if (fhreal == NULL)
fl = -1;
else {
posn = ftell(fhreal);
if (fseek(fhreal, 0L, SEEK_END) < 0) {
fl=-1;
}
else {
fl = ftell(fhreal);
fseek(fhreal, posn, SEEK_SET);
}
stateptr->last_errno = errno;
}
DebugPrintF(("returning len %ld\n", fl));
return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Flen|HtoT, DebugID, OSInfo1,
OSInfo2, fl);
}
case CL_IsTTY:
{
int ttyOrNot;
unpack_message(buffp, "%w", &fh);
DebugPrintF(("CL_IsTTY: fh %d ", fh));
DevSW_FreePacket(packet);
fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
if (fhreal == NULL)
ttyOrNot = FALSE;
else {
ttyOrNot = isatty_(fhreal);
stateptr->last_errno = errno;
}
DebugPrintF(("returning %s\n", ttyOrNot ? "tty (1)" : "not (0)"));
return msgsend(CI_CLIB, "%w%w%w%w%w",CL_IsTTY|HtoT,
DebugID, OSInfo1, OSInfo2, ttyOrNot);
}
case CL_TmpNam:
{
char *name;
unsigned int tnamelen, TargetID;
unpack_message(buffp, "%w%w", &tnamelen, &TargetID);
DebugPrintF(("CL_TmpNam: tnamelen %d TargetID %d: ",
tnamelen, TargetID));
DevSW_FreePacket(packet);
TargetID = TargetID & 0xFF;
if (stateptr->OSptr->TempNames[TargetID] == NULL) {
if ((stateptr->OSptr->TempNames[TargetID] =
(char *)malloc(L_tmpnam)) == NULL)
{
fprintf(stderr, "OUT OF MEMORY at line %d in %s\n",
__LINE__, __FILE__);
return -1;
}
tmpnam(stateptr->OSptr->TempNames[TargetID]);
}
name = stateptr->OSptr->TempNames[TargetID];
len = strlen(name) + 1;
packet = DevSW_AllocatePacket(Armsd_BufferSize);
if (packet == NULL)
{
fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
__LINE__, __FILE__);
return -1;
}
buffhead = packet->pk_buffer;
if (len > tnamelen) {
DebugPrintF(("TMPNAME TOO LONG!\n"));
count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w",
CL_TmpNam|HtoT, DebugID, OSInfo1, OSInfo2, -1);
}
else {
DebugPrintF(("returning \"%s\"\n", name));
count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w", CL_TmpNam|HtoT,
DebugID, OSInfo1, OSInfo2, 0, len);
strcpy((char *)BUFFERDATA(buffhead)+count, name);
count +=len+1;
}
packet->pk_length = count;
Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */
return 0;
}
case CL_Unrecognised:
DebugPrintF(("CL_Unrecognised!!\n"));
return 0;
default:
fprintf(stderr, "UNRECOGNISED CL code %08x\n", reason_code);
break;
/* Need some sort of error handling here. */
/* A call to CL_Unrecognised should suffice */
}
return -1; /* Stop a potential compiler warning */
}
#ifdef COMPILING_ON_WINDOWS
#include <windows.h>
extern HWND hwndParent;
void panic(const char *format, ...)
{
char buf[2048];
va_list args;
Adp_CloseDevice();
va_start(args, format);
vsprintf(buf, format, args);
MessageBox(hwndParent, (LPCTSTR)buf, (LPCTSTR)"Fatal Error:", MB_OK);
/* SJ - Not the proper way to shutdown the app */
exit(EXIT_FAILURE);
/*
if (hwndParent != NULL)
SendMessage(hwndParent, WM_QUIT, 0, 0);
*/
va_end(args);
}
#else
void panic(const char *format, ...)
{
va_list args;
va_start(args, format);
fprintf(stderr, "Fatal error: ");
vfprintf(stderr, format, args);
fprintf(stderr,"\n");
exit(EXIT_FAILURE);
}
#endif
/* EOF hsys.c */

View File

@ -1,99 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/*
* Host C library support header file.
*
*
*/
#ifndef angsd_hsys_h
#define angsd_hsys_h
#define HSYS_FOPEN_MAX 256
#define NONHANDLE -1
#define UNIQUETEMPS 256
#include "dbg_hif.h"
#include "hostchan.h"
typedef struct {
FILE *FileTable[HSYS_FOPEN_MAX] ;
char FileFlags[HSYS_FOPEN_MAX] ;
char *TempNames[UNIQUETEMPS];
} OSblock;
#define NOOP 0
#define BINARY 1
#define READOP 2
#define WRITEOP 4
typedef struct {
const struct Dbg_HostosInterface *hostif; /* Interface to debug toolkit. */
int last_errno; /* Number of the last error. */
OSblock *OSptr;
char **CommandLine ; /* Ptr to cmd line d`string held by ardi.c */
} hsys_state;
/*
* Function: HostSysInit
* Purpose: Set up the state block, filetable and register the and C lib
* callback fn
*
* Params:
* Input: hostif, the host interface from the debug toolbox
* cmdline, the command line used to call the image
* state, the status block for the C lib
*
* Returns:
* OK: an RDIError_* valuee
*/
extern int HostSysInit(
const struct Dbg_HostosInterface *hostif, char **cmdline, hsys_state **state
);
/*
* Function: HostSysExit
* Purpose: Close down the host side C library support
*
* Params:
* Input: hstate, the status block for the C lib
*
* Returns: an RDIError_* valuee
*/
extern int HostSysExit(hsys_state *hstate);
/*
* Function: HandleSysMessage
* Purpose: Handle an incoming C library message as a callback
*
* Params:
* Input: packet is the incoming data packet as described in devsw.h
* hstate, the status block for the C lib
*
* Returns: an RDIError_* valuee
*/
extern int HandleSysMessage(Packet *packet, hsys_state* stateptr);
/*
* Function: panic
* Purpose: Print a fatal error message
*
* Params:
* Input: format printf() style message describing the problem
* ... extra arguments for printf().
*
* Returns: This routine does not return
*
* Post-conditions: Will have called exit(1);
*/
extern void panic(const char *format, ...);
#endif /* ndef angsd_hsys_h */
/* EOF hsys.h */

View File

@ -1,367 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* logging.c - methods for logging warnings, errors and trace info
*
*/
#include <stdarg.h> /* ANSI varargs support */
#ifdef TARGET
# include "angel.h"
# include "devconf.h"
#else
# include "host.h"
#endif
#include "logging.h" /* Header file for this source code */
#ifndef UNUSED
# define UNUSED(x) ((x)=(x))
#endif
/*
* __rt_warning
* ------------
* This routine is provided as a standard method of generating
* run-time system warnings. The actual action taken by this code can
* be board or target application specific, e.g. internal logging,
* debug message, etc.
*/
#ifdef DEBUG
# ifdef DEBUG_METHOD
# define STRINGIFY2(x) #x
# define STRINGIFY(x) STRINGIFY2(x)
# define DEBUG_METHOD_HEADER STRINGIFY(DEBUG_METHOD##.h)
# include DEBUG_METHOD_HEADER
# define METHOD_EXPAND_2(m, p, c) m##p(c)
# define METHOD_EXPAND(m, p, c) METHOD_EXPAND_2(m, p, c)
# define CHAROUT(c) METHOD_EXPAND(DEBUG_METHOD, _PutChar, (c))
# define PRE_DEBUG(l) METHOD_EXPAND(DEBUG_METHOD, _PreWarn, (l))
# define POST_DEBUG(n) METHOD_EXPAND(DEBUG_METHOD, _PostWarn, (n))
# else
# error Must define DEBUG_METHOD
# endif
#endif /* def DEBUG */
/*
* the guts of __rt_warning
*/
#pragma no_check_stack
#ifdef DEBUG
static const char hextab[] = "0123456789ABCDEF";
/*
* If debugging, then we break va_warn into sub-functions which
* allow us to get an easy breakpoint on the formatted string
*/
static int va_warn0(char *format, va_list args)
{
int len = 0;
while ((format != NULL) && (*format != '\0'))
{
if (*format == '%')
{
char fch = *(++format); /* get format character (skipping '%') */
int ival; /* holder for integer arguments */
char *string; /* holder for string arguments */
int width = 0; /* No field width by default */
int padzero = FALSE; /* By default we pad with spaces */
/*
* Check if the format has a width specified. NOTE: We do
* not use the "isdigit" function here, since it will
* require run-time support. The current ARM Ltd header
* defines "isdigit" as a macro, that uses a fixed
* character description table.
*/
if ((fch >= '0') && (fch <= '9'))
{
if (fch == '0')
{
/* Leading zeroes padding */
padzero = TRUE;
fch = *(++format);
}
while ((fch >= '0') && (fch <= '9'))
{
width = ((width * 10) + (fch - '0'));
fch = *(++format);
}
}
if (fch == 'l')
/* skip 'l' in "%lx", etc. */
fch = *(++format);
switch (fch)
{
case 'c':
/* char */
ival = va_arg(args, int);
CHAROUT((char)ival);
len++;
break;
case 'x':
case 'X':
{
/* hexadecimal */
unsigned int uval = va_arg(args, unsigned int);
int loop;
UNUSED(uval);
if ((width == 0) || (width > 8))
width = 8;
for(loop = (width * 4); (loop != 0); loop -= 4)
{
CHAROUT(hextab[(uval >> (loop - 4)) & 0xF]);
len++;
}
}
break;
case 'd':
/* decimal */
ival = va_arg(args, int);
if (ival < 0)
{
ival = -ival;
CHAROUT('-');
len++;
}
if (ival == 0)
{
CHAROUT('0');
len++;
}
else
{
/*
* The simplest method of displaying numbers is
* to provide a small recursive routine, that
* nests until the most-significant digit is
* reached, and then falls back out displaying
* individual digits. However, we want to avoid
* using recursive code within the lo-level
* parts of Angel (to minimise the stack
* usage). The following number conversion is a
* non-recursive solution.
*/
char buffer[16]; /* stack space used to hold number */
int count = 0; /* pointer into buffer */
/*
* Place the conversion into the buffer in
* reverse order:
*/
while (ival != 0)
{
buffer[count++] = ('0' + ((unsigned int)ival % 10));
ival = ((unsigned int)ival / 10);
}
/*
* Check if we are placing the data in a
* fixed width field:
*/
if (width != 0)
{
width -= count;
for (; (width != 0); width--)
{
CHAROUT(padzero ? '0': ' ');
len++;
}
}
/* then display the buffer in reverse order */
for (; (count != 0); count--)
{
CHAROUT(buffer[count - 1]);
len++;
}
}
break;
case 's':
/* string */
string = va_arg(args, char *);
/* we only need this test once */
if (string != NULL)
/* whilst we check this for every character */
while (*string)
{
CHAROUT(*string);
len++;
string++;
/*
* NOTE: We do not use "*string++" as the macro
* parameter, since we do not know how many times
*the parameter may be expanded within the macro.
*/
}
break;
case '\0':
/*
* string terminated by '%' character, bodge things
* to prepare for default "format++" below
*/
format--;
break;
default:
/* just display the character */
CHAROUT(*format);
len++;
break;
}
format++; /* step over format character */
}
else
{
CHAROUT(*format);
len++;
format++;
}
}
return len;
}
/*
* this routine is simply here as a good breakpoint for dumping msg -
* can be used by DEBUG_METHOD macros or functions, if required.
*/
# ifdef DEBUG_NEED_VA_WARN1
static void va_warn1(int len, char *msg)
{
UNUSED(len); UNUSED(msg);
}
# endif
void va_warn(WarnLevel level, char *format, va_list args)
{
int len;
if ( PRE_DEBUG( level ) )
{
len = va_warn0(format, args);
POST_DEBUG( len );
}
}
#else /* ndef DEBUG */
void va_warn(WarnLevel level, char *format, va_list args)
{
UNUSED(level); UNUSED(format); UNUSED(args);
}
#endif /* ... else ndef(DEBUG) ... */
#pragma check_stack
#pragma no_check_stack
void __rt_warning(char *format, ...)
{
va_list args;
/*
* For a multi-threaded system we should provide a lock at this point
* to ensure that the warning messages are sequenced properly.
*/
va_start(args, format);
va_warn(WL_WARN, format, args);
va_end(args);
return;
}
#pragma check_stack
#ifdef TARGET
#pragma no_check_stack
void __rt_uninterruptable_loop( void ); /* in suppasm.s */
void __rt_error(char *format, ...)
{
va_list args;
va_start(args, format);
/* Display warning message */
va_warn(WL_ERROR, format, args);
__rt_uninterruptable_loop();
va_end(args);
return;
}
#pragma check_stack
#endif /* def TARGET */
#ifdef DO_TRACE
static bool trace_on = FALSE; /* must be set true in debugger if req'd */
#pragma no_check_stack
void __rt_trace(char *format, ...)
{
va_list args;
/*
* For a multi-threaded system we should provide a lock at this point
* to ensure that the warning messages are sequenced properly.
*/
if (trace_on)
{
va_start(args, format);
va_warn(WL_TRACE, format, args);
va_end(args);
}
return;
}
#pragma check_stack
#endif /* def DO_TRACE */
/* EOF logging.c */

View File

@ -1,119 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* logging.h - methods for logging warnings, errors and trace info
*/
#ifndef angel_logging_h
#define angel_logging_h
#include <stdarg.h>
/*
* __rt_warning
* ------------
* Provides a standard method of generating run-time system
* warnings. The actual action taken by this code can be board or
* target application specific, e.g. internal logging, debug message,
* etc.
*/
extern void __rt_warning(char *format, ...);
/*---------------------------------------------------------------------------*/
/*
* __rt_error
* ----------
* Raise an internal Angel error. The parameters are passed directly
* to "__rt_warning" for display, and the code then raises a debugger
* event and stops the target processing.
*/
extern void __rt_error(char *format, ...);
/*
* Some macros for debugging and warning messages
*/
typedef enum WarnLevel {
WL_TRACE,
WL_WARN,
WL_ERROR
} WarnLevel;
void va_warn(WarnLevel level, char *format, va_list args);
#ifdef _WINGDI_
/* stupidity in MSVC <wingdi.h> (in <windows.h> in <winsock.h>) */
# undef ERROR
#endif
#ifndef ERROR
# define ERROR_FORMAT "Error \"%s\" in %s at line %d\n"
# define ERROR(e) __rt_error(ERROR_FORMAT, (e), __FILE__, __LINE__)
#endif
#ifndef ASSERT
# ifdef ASSERTIONS_ENABLED
# define ASSERT(x, y) ((x) ? (void)(0) : ERROR((y)))
# else
# define ASSERT(x, y) ((void)(0))
# endif
#endif
#ifndef WARN
# ifdef ASSERTIONS_ENABLED
# define WARN_FORMAT "Warning \"%s\" in %s at line %d\n"
# define WARN(w) __rt_warning(WARN_FORMAT, (w), __FILE__, __LINE__)
# else
# define WARN(w) ((void)(0))
# endif
#endif
#ifdef NO_INFO_MESSAGES
# define __rt_info (void)
# ifndef INFO
# define INFO(w)
# endif
#else
# define __rt_info __rt_warning
# ifndef INFO
# ifdef DEBUG
# define INFO(w) __rt_warning("%s\n", (w))
# else
# define INFO(w) ((void)(0))
# endif
# endif
#endif
#if defined(DEBUG) && !defined(NO_IDLE_CHITCHAT)
# ifndef DO_TRACE
# define DO_TRACE (1)
# endif
#endif
#ifdef DO_TRACE
extern void __rt_trace(char *format, ...);
#endif
#ifndef TRACE
# ifdef DO_TRACE
# define TRACE(w) __rt_trace("%s ", (w))
# else
# define TRACE(w) ((void)(0))
# endif
#endif
#endif /* ndef angel_logging_h */
/* EOF logging.h */

View File

@ -1,280 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* msgbuild.c - utilities for assembling and interpreting ADP messages
*
*/
#include <stdarg.h> /* ANSI varargs support */
#ifdef TARGET
# include "angel.h"
# include "devconf.h"
#else
# include "host.h"
# include "hostchan.h"
#endif
#include "channels.h"
#include "buffers.h"
#include "endian.h" /* Endianness support macros */
#include "msgbuild.h" /* Header file for this source code */
#ifndef UNUSED
# define UNUSED(x) ((x)=(x))
#endif
#ifndef TARGET
extern unsigned int Armsd_BufferSize;
#endif /* ndef TARGET */
unsigned int vmsgbuild(unsigned char *buffer, const char *format, va_list args)
{
unsigned int blen = 0;
int ch;
/* Step through the format string */
while ((ch = *format++) != '\0')
{
if (ch != '%')
{
if (buffer != NULL)
*buffer++ = (unsigned char)ch;
blen++;
}
else
{
switch (ch = *format++)
{
case 'w':
case 'W':
/* 32bit pointer */
case 'p':
case 'P':
{
/* 32bit word / 32bit pointer */
unsigned int na = va_arg(args, unsigned int);
if (buffer != NULL)
{
PUT32LE(buffer, na);
buffer += sizeof(unsigned int);
}
blen += sizeof(unsigned int);
break;
}
case 'h':
case 'H':
{
/* 16bit value */
unsigned int na = va_arg(args, unsigned int);
if (buffer != NULL)
{
PUT16LE(buffer, na);
buffer += sizeof(unsigned short);
}
blen += sizeof(unsigned short);
break;
}
case 'c':
case 'C':
case 'b':
case 'B':
/* 8bit character / 8bit byte */
ch = va_arg(args, int);
/*
* XXX
*
* fall through to the normal character processing
*/
case '%':
default:
/* normal '%' character, or a different normal character */
if (buffer != NULL)
*buffer++ = (unsigned char)ch;
blen++;
break;
}
}
}
return blen;
}
/*
* msgbuild
* --------
* Simple routine to aid in construction of Angel messages. See the
* "msgbuild.h" header file for a detailed description of the operation
* of this routine.
*/
unsigned int msgbuild(unsigned char *buffer, const char *format, ...)
{
va_list args;
unsigned int blen;
va_start(args, format);
blen = vmsgbuild(buffer, format, args);
va_end(args);
return blen;
}
#if !defined(JTAG_ADP_SUPPORTED) && !defined(MSG_UTILS_ONLY)
/*
* This routine allocates a buffer, puts the data supplied as
* parameters into the buffer and sends the message. It does *NOT*
* wait for a reply.
*/
extern int msgsend(ChannelID chan, const char *format,...)
{
unsigned int length;
p_Buffer buffer;
va_list args;
# ifndef TARGET
Packet *packet;
packet = DevSW_AllocatePacket(Armsd_BufferSize);
buffer = packet->pk_buffer;
# else
buffer = angel_ChannelAllocBuffer(Angel_ChanBuffSize);
# endif
if (buffer != NULL)
{
va_start(args, format);
length = vmsgbuild(BUFFERDATA(buffer), format, args);
# ifdef TARGET
angel_ChannelSend(CH_DEFAULT_DEV, chan, buffer, length);
# else
packet->pk_length = length;
Adp_ChannelWrite(chan, packet);
# endif
va_end(args);
return 0;
}
else
return -1;
}
#endif /* ndef JTAG_ADP_SUPPORTED && ndef MSG_UTILS_ONLY */
/*
* unpack_message
* --------------
*/
extern unsigned int unpack_message(unsigned char *buffer, const char *format, ...)
{
va_list args;
unsigned int blen = 0;
int ch;
char *chp = NULL;
va_start(args, format);
/* Step through the format string. */
while ((ch = *format++) != '\0')
{
if (ch != '%')
{
if (buffer != NULL)
ch = (unsigned char)*buffer++;
blen++;
}
else
{
switch (ch = *format++)
{
case 'w':
case 'W':
{
/* 32bit word. */
unsigned int *nap = va_arg(args, unsigned int*);
if (buffer != NULL)
{
*nap = PREAD32(LE, buffer);
buffer += sizeof(unsigned int);
}
blen += sizeof(unsigned int);
break;
}
case 'h':
case 'H':
{
/* 16bit value. */
unsigned int *nap = va_arg(args, unsigned int*);
if (buffer != NULL)
{
*nap = PREAD16(LE,buffer);
buffer += sizeof(unsigned short);
}
blen += sizeof(unsigned short);
break;
}
case 'c':
case 'C':
case 'b':
case 'B':
/* 8-bit character, or 8-bit byte */
chp = va_arg(args, char*);
/*
* XXX
*
* fall through to the normal character processing.
*/
case '%':
default:
/* normal '%' character, or a different normal character */
if (buffer != NULL)
*chp = (unsigned char)*buffer++;
blen++;
break;
}
}
}
va_end(args);
return(blen);
}
/* EOF msgbuild.c */

View File

@ -1,73 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* msgbuild.h - utilities for assembling and interpreting ADP messages
*/
#ifndef angel_msgbuild_h
#define angel_msgbuild_h
#include <stdarg.h>
#include "channels.h"
/*
* msgbuild
* --------
* We use a "varargs" function to enable a description of how the
* final message should look to be provided. We use a function rather
* than in-line macros to keep the size of Angel small.
*
* The "buffer" pointer is the starting point from where the data will
* be written. Note: If a NULL pointer is passed then no data will be
* written, but the size information will be returned. This allows
* code to call this routine with a NULL "buffer" pointer to ascertain
* whether the pointer they are passing contains enough space for the
* message being constructed.
*
* The "format" string should contain sequences of the following
* tokens:
* %w - insert 32bit word value
* %p - insert 32bit target pointer value
* %h - insert 16bit value
* %b - insert 8bit byte value
*
* The return parameter is the final byte length of the data written.
*/
unsigned int msgbuild(unsigned char *buffer, const char *format, ...);
unsigned int vmsgbuild(unsigned char *buffer, const char *format,
va_list args);
/*---------------------------------------------------------------------------*/
/*
* msgsend
* -------
* As for msgbuild except that it allocates a buffer, formats the data as
* for msgbuild and transmits the packet. Returns 0 if successful non 0 if ot
* fails.
* Not for use on cooked channels e.g. debug channels only.
*/
extern int msgsend(ChannelID chan, const char *format, ...);
/*---------------------------------------------------------------------------*/
/*
* Unpack_message
* --------------
* This basically does the opposite of msg_build, it takes a message, and
* a scanf type format string (but much cut down functionality) and returns
* the arguments in the message.
*/
extern unsigned int unpack_message(unsigned char *buffer, const char *format, ...);
#endif /* ndef angel_msgbuild_h */
/* EOF msgbuild.h */

View File

@ -1,323 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* Project: ANGEL
*
* Title: Parameter negotiation utility functions
*/
#include "params.h"
#include "endian.h"
#include "logging.h"
/*
* Function: Angel_FindParam
* Purpose: find the value of a given parameter from a config.
*
* see params.h for details
*/
bool Angel_FindParam( ADP_Parameter type,
const ParameterConfig *config,
unsigned int *value )
{
unsigned int i;
for ( i = 0; i < config->num_parameters; ++i )
if ( config->param[i].type == type )
{
*value = config->param[i].value;
return TRUE;
}
return FALSE;
}
#if !defined(TARGET) || !defined(MINIMAL_ANGEL) || MINIMAL_ANGEL == 0
ParameterList *Angel_FindParamList( const ParameterOptions *options,
ADP_Parameter type )
{
unsigned int i;
for ( i = 0; i < options->num_param_lists; ++i )
if ( options->param_list[i].type == type )
return &options->param_list[i];
return NULL;
}
#if defined(TARGET) || defined(TEST_PARAMS)
/*
* Function: Angel_MatchParams
* Purpose: find a configuration from the requested options which is
* the best match from the supported options.
*
* see params.h for details
*/
const ParameterConfig *Angel_MatchParams( const ParameterOptions *requested,
const ParameterOptions *supported )
{
static Parameter chosen_params[AP_NUM_PARAMS];
static ParameterConfig chosen_config = {
AP_NUM_PARAMS,
chosen_params
};
unsigned int i;
ASSERT( requested != NULL, "requested is NULL" );
ASSERT( requested != NULL, "requested is NULL" );
ASSERT( supported->num_param_lists <= AP_NUM_PARAMS, "supp_num too big" );
if ( requested->num_param_lists > supported->num_param_lists )
{
WARN( "req_num exceeds supp_num" );
return NULL;
}
for ( i = 0; i < requested->num_param_lists; ++i )
{
bool match;
unsigned int j;
const ParameterList *req_list = &requested->param_list[i];
ADP_Parameter req_type = req_list->type;
const ParameterList *sup_list = Angel_FindParamList(
supported, req_type );
if ( sup_list == NULL )
{
#ifdef ASSERTIONS_ENABLED
__rt_warning( "option %x not supported\n", req_type );
#endif
return NULL;
}
for ( j = 0, match = FALSE;
(j < req_list->num_options) && !match;
++j
)
{
unsigned int k;
for ( k = 0;
(k < sup_list->num_options) && !match;
++k
)
{
if ( req_list->option[j] == sup_list->option[k] )
{
#ifdef DEBUG
__rt_info( "chose value %d for option %x\n",
req_list->option[j], req_type );
#endif
match = TRUE;
chosen_config.param[i].type = req_type;
chosen_config.param[i].value = req_list->option[j];
}
}
}
if ( !match )
{
#ifdef ASSERTIONS_ENABLED
__rt_warning( "no match found for option %x\n", req_type );
#endif
return NULL;
}
}
chosen_config.num_parameters = i;
INFO( "match succeeded" );
return &chosen_config;
}
#endif /* defined(TARGET) || defined(TEST_PARAMS) */
#if !defined(TARGET) || defined(TEST_PARAMS)
/*
* Function: Angel_StoreParam
* Purpose: store the value of a given parameter to a config.
*
* see params.h for details
*/
bool Angel_StoreParam( ParameterConfig *config,
ADP_Parameter type,
unsigned int value )
{
unsigned int i;
for ( i = 0; i < config->num_parameters; ++i )
if ( config->param[i].type == type )
{
config->param[i].value = value;
return TRUE;
}
return FALSE;
}
#endif /* !defined(TARGET) || defined(TEST_PARAMS) */
#if defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS)
/*
* Function: Angel_BuildParamConfigMessage
* Purpose: write a parameter config to a buffer in ADP format.
*
* see params.h for details
*/
unsigned int Angel_BuildParamConfigMessage( unsigned char *buffer,
const ParameterConfig *config )
{
unsigned char *start = buffer;
unsigned int i;
PUT32LE( buffer, config->num_parameters );
buffer += sizeof( word );
for ( i = 0; i < config->num_parameters; ++i )
{
PUT32LE( buffer, config->param[i].type );
buffer += sizeof( word );
PUT32LE( buffer, config->param[i].value );
buffer += sizeof( word );
}
return (buffer - start);
}
#endif /* defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS) */
#if !defined(TARGET) || defined(TEST_PARAMS)
/*
* Function: Angel_BuildParamOptionsMessage
* Purpose: write a parameter Options to a buffer in ADP format.
*
* see params.h for details
*/
unsigned int Angel_BuildParamOptionsMessage( unsigned char *buffer,
const ParameterOptions *options )
{
unsigned char *start = buffer;
unsigned int i, j;
PUT32LE( buffer, options->num_param_lists );
buffer += sizeof( word );
for ( i = 0; i < options->num_param_lists; ++i )
{
PUT32LE( buffer, options->param_list[i].type );
buffer += sizeof( word );
PUT32LE( buffer, options->param_list[i].num_options );
buffer += sizeof( word );
for ( j = 0; j < options->param_list[i].num_options; ++j )
{
PUT32LE( buffer, options->param_list[i].option[j] );
buffer += sizeof( word );
}
}
return (buffer - start);
}
#endif /* !defined(TARGET) || defined(TEST_PARAMS) */
#if !defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS)
/*
* Function: Angel_ReadParamConfigMessage
* Purpose: read a parameter config from a buffer where it is in ADP format.
*
* see params.h for details
*/
bool Angel_ReadParamConfigMessage( const unsigned char *buffer,
ParameterConfig *config )
{
unsigned int word;
unsigned int i;
word = GET32LE( buffer );
buffer += sizeof( word );
if ( word > config->num_parameters )
{
WARN( "not enough space" );
return FALSE;
}
config->num_parameters = word;
for ( i = 0; i < config->num_parameters; ++i )
{
config->param[i].type = (ADP_Parameter)GET32LE( buffer );
buffer += sizeof( word );
config->param[i].value = GET32LE( buffer );
buffer += sizeof( word );
}
return TRUE;
}
#endif /* !defined(TARGET) || defined(LINK_RECOVERY) || defined(TEST_PARAMS) */
#if defined(TARGET) || defined(TEST_PARAMS)
/*
* Function: Angel_ReadParamOptionsMessage
* Purpose: read a parameter options block from a buffer
* where it is in ADP format.
*
* see params.h for details
*/
bool Angel_ReadParamOptionsMessage( const unsigned char *buffer,
ParameterOptions *options )
{
unsigned int word;
unsigned int i, j;
word = GET32LE( buffer );
buffer += sizeof( word );
if ( word > options->num_param_lists )
{
WARN( "not enough space" );
return FALSE;
}
options->num_param_lists = word;
for ( i = 0; i < options->num_param_lists; ++i )
{
ParameterList *list = &options->param_list[i];
list->type = (ADP_Parameter)GET32LE( buffer );
buffer += sizeof( word );
word = GET32LE( buffer );
buffer += sizeof( word );
if ( word > list->num_options )
{
WARN( "not enough list space" );
return FALSE;
}
list->num_options = word;
for ( j = 0; j < list->num_options; ++j )
{
list->option[j] = GET32LE( buffer );
buffer += sizeof( word );
}
}
return TRUE;
}
#endif /* defined(TARGET) || defined(TEST_PARAMS) */
#endif /* !define(TARGET) || !defined(MINIMAL_ANGEL) || MINIMAL_ANGEL == 0 */
/* EOF params.c */

View File

@ -1,179 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* Project: ANGEL
*
* Title: Parameter negotiation structures and utilities
*/
#ifndef angel_params_h
#define angel_params_h
#include "angel.h"
#include "adp.h"
#ifndef TARGET
# include "host.h"
#endif
/* A single parameter, with tag */
typedef struct Parameter {
ADP_Parameter type;
unsigned int value;
} Parameter;
/* A list of parameter values, with tag */
typedef struct ParameterList {
ADP_Parameter type;
unsigned int num_options;
unsigned int *option; /* points to array of values */
} ParameterList;
/* A configuration of one or more parameters */
typedef struct ParameterConfig {
unsigned int num_parameters;
Parameter *param; /* pointer to array of Parameters */
} ParameterConfig;
/* A set of parameter options */
typedef struct ParameterOptions {
unsigned int num_param_lists;
ParameterList *param_list; /* pointer to array of ParamLists */
} ParameterOptions;
/*
* Function: Angel_MatchParams
* Purpose: find a configuration from the requested options which is
* the best match from the supported options.
*
* Params:
* Input: requested The offered set of parameters.
* supported The supported set of parameters.
*
* Returns: ptr to config A match has been made, ptr to result
* will remain valid until next call to
* this function.
* NULL Match not possible
*/
const ParameterConfig *Angel_MatchParams( const ParameterOptions *requested,
const ParameterOptions *supported );
/*
* Function: Angel_FindParam
* Purpose: find the value of a given parameter from a config.
*
* Params:
* Input: type parameter type to find
* config config to search
* Output: value parameter value if found
*
* Returns: TRUE parameter found
* FALSE parameter not found
*/
bool Angel_FindParam( ADP_Parameter type,
const ParameterConfig *config,
unsigned int *value );
/*
* Function: Angel_StoreParam
* Purpose: store the value of a given parameter in a config.
*
* Params:
* In/Out: config config to store in
* Input: type parameter type to store
* value parameter value if found
*
* Returns: TRUE parameter found and new value stored
* FALSE parameter not found
*/
bool Angel_StoreParam( ParameterConfig *config,
ADP_Parameter type,
unsigned int value );
/*
* Function: Angel_FindParamList
* Purpose: find the parameter list of a given parameter from an options.
*
* Params:
* Input: type parameter type to find
* options options block to search
*
* Returns: pointer to list
* NULL parameter not found
*/
ParameterList *Angel_FindParamList( const ParameterOptions *options,
ADP_Parameter type );
/*
* Function: Angel_BuildParamConfigMessage
* Purpose: write a parameter config to a buffer in ADP format.
*
* Params:
* Input: buffer where to write to
* config the parameter config to write
*
* Returns: number of characters written to buffer
*/
unsigned int Angel_BuildParamConfigMessage( unsigned char *buffer,
const ParameterConfig *config );
/*
* Function: Angel_BuildParamOptionsMessage
* Purpose: write a parameter Options to a buffer in ADP format.
*
* Params:
* Input: buffer where to write to
* options the options block to write
*
* Returns: number of characters written to buffer
*/
unsigned int Angel_BuildParamOptionsMessage( unsigned char *buffer,
const ParameterOptions *options );
/*
* Function: Angel_ReadParamConfigMessage
* Purpose: read a parameter config from a buffer where it is in ADP format.
*
* Params:
* Input: buffer where to read from
* In/Out: config the parameter config to read to, which must
* be set up on entry with a valid array, and
* the size of the array in num_parameters.
*
* Returns: TRUE okay
* FALSE not enough space in config
*/
bool Angel_ReadParamConfigMessage( const unsigned char *buffer,
ParameterConfig *config );
/*
* Function: Angel_ReadParamOptionsMessage
* Purpose: read a parameter options from a buffer
* where it is in ADP format.
*
* Params:
* Input: buffer where to read from
* In/Out: options the parameter options block to read to,
* which must be set up on entry with a valid
* array, and the size of the array in
* num_parameters. Each param_list must
* also be set up in the same way.
*
* Returns: TRUE okay
* FALSE not enough space in options
*/
bool Angel_ReadParamOptionsMessage( const unsigned char *buffer,
ParameterOptions *options );
#endif /* ndef angel_params_h */
/* EOF params.h */

View File

@ -1,359 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/*-*-C-*-
*
*
*
* Project: ANGEL
*
* Title: Character reception engine
*/
#include <stdarg.h> /* ANSI varargs support */
#include "angel.h" /* Angel system definitions */
#include "endian.h" /* Endian independant memory access macros */
#include "crc.h" /* crc generation definitions and headers */
#include "rxtx.h"
#include "channels.h"
#include "buffers.h"
#ifdef TARGET
# include "devdriv.h"
#endif
#include "logging.h"
static re_status unexp_stx(struct re_state *rxstate);
static re_status unexp_etx(struct re_state *rxstate);
/* bitfield for the rx_engine state */
typedef enum rx_state_flag{
RST_STX,
RST_TYP,
RST_LEN,
RST_DAT,
RST_CRC,
RST_ETX,
RST_ESC = (0x1 << 0x3)
} rx_state_flag;
void Angel_RxEngineInit(const struct re_config *rxconfig,
struct re_state *rxstate)
{
rxstate->rx_state = RST_STX;
rxstate->field_c = 0;
rxstate->index = 0;
rxstate->crc = 0;
rxstate->error = RE_OKAY;
rxstate->config = rxconfig;
}
re_status Angel_RxEngine(unsigned char new_ch, struct data_packet *packet,
struct re_state *rxstate)
{
/*
* TODO: add the flow control bits in
* Note: We test for the data field in a seperate case so we can
* completely avoid entering the switch for most chars
*/
/* see if we're expecting a escaped char */
if ((rxstate->rx_state & RST_ESC) == RST_ESC)
{
/* unescape the char and unset the flag*/
new_ch &= ~serial_ESCAPE;
#ifdef DO_TRACE
__rt_trace("rxe-echar-%2x ", new_ch);
#endif
rxstate->rx_state &= ~RST_ESC;
}
else if ( (1 << new_ch) & rxstate->config->esc_set )
{
/* see if the incoming char is a special one */
if (new_ch == rxstate->config->esc)
{
#ifdef DO_TRACE
__rt_trace("rxe-esc ");
#endif
rxstate->rx_state |= RST_ESC;
return RS_IN_PKT;
}
else
{
/*
* must be a normal packet so do some unexpected etx/stx checking
* we haven't been told to escape or received an escape so unless
* we are expecting an stx or etx then we can take the unexpected
* stx/etx trap
*/
if ((new_ch == (rxstate->config->stx)) && (rxstate->rx_state != RST_STX))
return unexp_stx(rxstate);
if ((new_ch == (rxstate->config->etx)) && (rxstate->rx_state != RST_ETX))
return unexp_etx(rxstate);
}
}
if (rxstate->rx_state == RST_DAT)
{
/*
* do this to speed up the common case, no real penalty for
* other cases
*/
#ifdef DO_TRACE
__rt_trace("rxe-dat ");
#endif
rxstate->crc = crc32(&new_ch, 1, rxstate->crc);
(packet->data)[rxstate->index++] = (unsigned int)new_ch & 0xff;
if (rxstate->index == packet->len)
rxstate->rx_state = RST_CRC;
return RS_IN_PKT;
}
/*
* Now that the common case is out of the way we can test for everything
* else without worrying quite so much about the speed, changing the
* order to len,crc,stx,etx,typ might gain a tiny bit of speed but lets
* leave that for the moment
*/
switch (rxstate->rx_state)
{
case RST_STX:
if (new_ch == rxstate->config->stx)
{
rxstate->rx_state = RST_TYP;
rxstate->error = RE_OKAY;
rxstate->crc = startCRC32;
rxstate->index = 0;
return RS_IN_PKT;
}
else
{
rxstate->error = RE_OKAY;
return RS_WAIT_PKT;
}
case RST_TYP:
packet->type = (DevChanID)new_ch;
rxstate->rx_state = RST_LEN;
rxstate->error = RE_OKAY;
rxstate->field_c = 0; /* set up here for the length that follows */
#ifdef DO_TRACE
__rt_trace("rxe-type-%2x ", packet->type);
#endif
rxstate->crc = crc32(&new_ch, 1, rxstate->crc);
return RS_IN_PKT;
case RST_LEN:
rxstate->crc = crc32(&new_ch, 1, rxstate->crc);
if (rxstate->field_c++ == 0)
{
/* first length byte */
packet->len = ((unsigned int)new_ch) << 8;
return RS_IN_PKT;
}
else
{
/* got the whole legth */
packet->len |= new_ch;
#ifdef DO_TRACE
__rt_trace("rxe-len-%4x\n", packet->len);
#endif
/* check that the length is ok */
if (packet->len == 0)
{
/* empty pkt */
rxstate->field_c = 0;
rxstate->rx_state = RST_CRC;
return RS_IN_PKT;
}
else
{
if (packet->data == NULL)
{
/* need to alloc the data buffer */
if (!rxstate->config->ba_callback(
packet, rxstate->config->ba_data)) {
rxstate->rx_state = RST_STX;
rxstate->error = RE_INTERNAL;
return RS_BAD_PKT;
}
}
if (packet->len > packet->buf_len)
{
/* pkt bigger than buffer */
rxstate->field_c = 0;
rxstate->rx_state = RST_STX;
rxstate->error = RE_LEN;
return RS_BAD_PKT;
}
else
{
/* packet ok */
rxstate->field_c = 0;
rxstate->rx_state = RST_DAT;
return RS_IN_PKT;
}
}
}
case RST_DAT:
/* dummy case (dealt with earlier) */
#ifdef ASSERTIONS_ENABLED
__rt_warning("ERROR: hit RST_dat in switch\n");
#endif
rxstate->rx_state = RST_STX;
rxstate->error = RE_INTERNAL;
return RS_BAD_PKT;
case RST_CRC:
if (rxstate->field_c == 0)
packet->crc = 0;
packet->crc |= (new_ch & 0xFF) << ((3 - rxstate->field_c) * 8);
rxstate->field_c++;
if (rxstate->field_c == 4)
{
/* last crc field */
rxstate->field_c = 0;
rxstate->rx_state = RST_ETX;
#ifdef DO_TRACE
__rt_trace("rxe-rcrc-%8x ", packet->crc);
#endif
}
return RS_IN_PKT;
case RST_ETX:
if (new_ch == rxstate->config->etx)
{
#if defined(DEBUG) && !defined(NO_PKT_DATA)
{
int c;
# ifdef DO_TRACE
__rt_trace("\n");
# endif
__rt_info("RXE Data =");
for (c=0; c < packet->len; c++)
__rt_info("%02x", packet->data[c]);
__rt_info("\n");
}
#endif
/* check crc */
if (rxstate->crc == packet->crc)
{
/* crc ok */
rxstate->rx_state = RST_STX;
rxstate->field_c = 0;
return RS_GOOD_PKT;
}
else
{
#ifdef ASSERTIONS_ENABLED
__rt_warning("Bad crc, rx calculates it should be 0x%x\n", rxstate->crc);
#endif
rxstate->rx_state = RST_STX;
rxstate->error = RE_CRC;
return RS_BAD_PKT;
}
}
else if (new_ch == rxstate->config->stx)
return unexp_stx(rxstate);
else
{
rxstate->rx_state = RST_STX;
rxstate->error = RE_NETX;
return RS_BAD_PKT;
}
default:
#ifdef ASSERTIONS_ENABLED
__rt_warning("ERROR fell through rxengine\n");
#endif
rxstate->rx_state = RST_STX;
rxstate->error = RE_INTERNAL;
return RS_BAD_PKT;
}
}
static re_status unexp_stx(struct re_state *rxstate)
{
#ifdef ASSERTIONS_ENABLED
__rt_warning("Unexpected stx\n");
#endif
rxstate->crc = startCRC32;
rxstate->index = 0;
rxstate->rx_state = RST_TYP;
rxstate->error = RE_U_STX;
rxstate->field_c = 0;
return RS_BAD_PKT;
}
static re_status unexp_etx(struct re_state *rxstate)
{
#ifdef ASSERTIONS_ENABLED
__rt_warning("Unexpected etx, rxstate: index= 0x%2x, field_c=0x%2x, state=0x%2x\n", rxstate->index, rxstate->field_c, rxstate->rx_state);
#endif
rxstate->crc = 0;
rxstate->index = 0;
rxstate->rx_state = RST_STX;
rxstate->error = RE_U_ETX;
rxstate->field_c = 0;
return RS_BAD_PKT;
}
/*
* This can be used as the buffer allocation callback for the rx engine,
* and makes use of angel_DD_GetBuffer() [in devdrv.h].
*
* Saves duplicating this callback function in every device driver that
* uses the rx engine.
*
* Note that this REQUIRES that the device id is installed as ba_data
* in the rx engine config structure for the driver.
*/
bool angel_DD_RxEng_BufferAlloc( struct data_packet *packet, void *cb_data )
{
#ifdef TARGET
DeviceID devid = (DeviceID)cb_data;
#else
IGNORE(cb_data);
#endif
if ( packet->type < DC_NUM_CHANNELS )
{
/* request a buffer down from the channels layer */
#ifdef TARGET
packet->data = angel_DD_GetBuffer( devid, packet->type,
packet->len );
#else
packet->data = malloc(packet->len);
#endif
if ( packet->data == NULL )
return FALSE;
else
{
packet->buf_len = packet->len;
return TRUE;
}
}
else
{
/* bad type field */
return FALSE;
}
}
/* EOF rx.c */

View File

@ -1,261 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/*-*-C-*-
*
*
*
* Project: ANGEL
*
* Title: Definitions required for the rx and tx engines
*/
#ifndef angel_rxtx_h
#define angel_rxtx_h
/*
* we need a definition for bool, which is "system" dependent
*/
#ifdef TARGET
# include "angel.h"
#else
# include "host.h"
#endif
#include "devclnt.h"
/* return status codes for the rx engine */
typedef enum re_status {
RS_WAIT_PKT,
RS_IN_PKT,
RS_BAD_PKT,
RS_GOOD_PKT
} re_status;
/* return status codes for the tx engine */
typedef enum te_status {
TS_IDLE,
TS_IN_PKT,
TS_DONE_PKT
} te_status;
/*
* required serial definitions, they should all be <32, refer to the
* re_config struct comments for more details
*/
#define serial_STX (0x1c) /* data packet start */
#define serial_ETX (0x1d) /* packet end */
#define serial_ESC (0x1b) /* standard escape character */
#define serial_XON (0x11) /* software flow control - enable transmission */
#define serial_XOFF (0x13) /* software flow control - disable transmission */
/*
* All other characters are transmitted clean. If any of the above
* characters need to be transmitted as part of the serial data stream
* then the character will be preceded by the "serial_ESC" character,
* and then the required character transmitted (OR-ed with the
* "serial_ESCAPE" value, to ensure that the serial stream never has
* any of the exceptional characters generated by data transfers).
*/
#define serial_ESCAPE (0x40) /* OR-ed with escaped characters */
/* bad packet error codes */
typedef enum re_error {
RE_OKAY,
RE_U_STX,
RE_U_ETX,
RE_LEN,
RE_CRC,
RE_NETX,
RE_INTERNAL
} re_error;
/* a decoded packet */
struct data_packet {
unsigned short buf_len; /* should be set by caller */
DevChanID type; /* valid when status is RS_GOOD_PKT */
unsigned short len; /* --"-- */
unsigned int crc; /* crc for the unescaped pkt */
unsigned char *data; /* should be set by caller */
};
/*
* Purpose: typedef for flow control function
*
* Params:
* Input: fc_char the flow control character in question
* In/Out: cb_data callback data as set in the fc_data
* field of re_config, typically device id
*
* This callback would tpyically respond to received XON and XOFF
* characters by controlling the transmit side of the device.
*/
typedef void (*fc_cb_func)(char fc_char, void *cb_data);
/*
* Purpose: typedef for the function to alloc the data buffer
*
* Params:
* In/Out: packet the data packet: len and type will be set on
* entry, and buf_len and data should
* be set by this routine if successful.
* cb_data callback data as set in the ba_data
* field of re_config, typically device id
*
* Returns: TRUE buffer allocated okay
* FALSE couldn't allocate buffer of required size
* for given type
*
* This callback should attempt to acquire a buffer for the data portion
* of the packet which is currently being received, based on the len and
* type fields supplied in packet.
*
* angel_DD_RxEng_BufferAlloc() is supplied for use as this callback,
* and will be sufficient for most devices.
*/
typedef bool (*BufferAlloc_CB_Fn)(struct data_packet *packet, void *cb_data);
/*
* The static info needed by the engine, may vary per device.
*
* fc_set and esc_set are bitmaps, e.g. bit 3 == charcode 3 == ASCII ETX.
* Thus any of the first 32 charcodes can be set for flow control or to
* be escaped.
*
* Note that esc_set should include all of fc_set, and should have bits
* set for stx, etx and esc, as a minimum.
*
* If character codes > 31 need to be used then fc_set and esc_set
* and their handling can be extended to use arrays and bit manipulation
* macros, potentially up to the full 256 possible chars.
*
* Note too that this could/should be shared with the tx engine.
*/
struct re_config {
unsigned char stx; /* the STX char for this device */
unsigned char etx; /* the ETX --"-- */
unsigned char esc; /* the ESC --"-- */
unsigned int fc_set; /* bitmap of flow control chars */
unsigned int esc_set; /* bitmap of special chars */
fc_cb_func fc_callback; /* flow control callback func */
void *fc_data; /* data to pass to fc_callback */
BufferAlloc_CB_Fn ba_callback; /* buffer alloc callback */
void *ba_data; /* data to pass to ba_calback */
};
/* the dynamic info needed by the rx engine */
struct re_state {
unsigned char rx_state; /* 3 bits pkt state, 1 prepro state */
unsigned short field_c; /* chars left in current field */
unsigned short index; /* index into buffer */
unsigned int crc; /* crc accumulator */
re_error error; /* valid only if status is RS_BAD_PKT */
const struct re_config *config; /* pointer to static config */
};
/* dynamic state info needed by the tx engine */
struct te_state {
unsigned short field_c; /* position in current field */
unsigned char tx_state; /* encodes n,e, and f (2+1+2=5 bits) */
unsigned char encoded; /* escape-encoded char for transmission */
const struct re_config *config; /* pointer to static config */
unsigned int crc; /* space for CRC (before escaping) */
};
/*
* Function: Angel_RxEngineInit
* Purpose: Initialise state (during device init) for engine.
*
* Params:
* Input: config static config info
* In/Out: state internal state
*/
void Angel_RxEngineInit(const struct re_config *config,
struct re_state *state);
/*
* Function: Angel_RxEngine
* Purpose: Rx Engine for character-based devices
*
* Params:
* Input: new_ch the latest character
*
* In/Out: packet details of packet
* packet.buf_len and packet.data must
* be set on entry!
* state internal state, intially set by
* angel_RxEngineInit()
*
* Returns: re_status (see above)
*
*/
re_status Angel_RxEngine(unsigned char new_ch, struct data_packet *packet,
struct re_state *state);
/*
* This can be used as the buffer allocation callback for the rx engine,
* and will make use of angel_DD_GetBuffer() [in devdrv.h].
*
* Saves duplicating this callback function in every device driver that
* uses the rx engine.
*
* Note that this REQUIRES that the device id is installed as ba_data
* in the rx engine config structure for the driver.
*/
bool angel_DD_RxEng_BufferAlloc( struct data_packet *packet, void *cb_data );
/*
* Function: Angel_TxEngineInit
* Purpose: Set up tx engine at start of new packet, calculate CRC etc.
* (This should perform the actions described under
* "Initialisation" above)
*
* Params:
* Input: config static config info
* packet the packet to transmit
* In/Out: state internal state
*/
void Angel_TxEngineInit(const struct re_config *config,
const struct data_packet *packet,
struct te_state *state);
/*
* Function: Angel_TxEngine
* Purpose: Tx Engine for character-based devices
*
* Params:
* Input: packet details of packet
* packet.len, packet.data and
* packet.type must
* be set on entry!
* In/Out: state internal state, intially set by
* angel_TxEngineStart()
* Output: tx_ch the character to be transmitted
* (NOT SET if return code is TS_IDLE)
*
* Returns: te_status (see above)
*/
te_status Angel_TxEngine(const struct data_packet *packet,
struct te_state *state,
unsigned char *tx_ch);
#endif /* !defined(angel_rxtx_h) */
/* EOF rxtx.h */

View File

@ -1,647 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* serdrv.c - Synchronous Serial Driver for Angel.
* This is nice and simple just to get something going.
*/
#ifdef __hpux
# define _POSIX_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "crc.h"
#include "devices.h"
#include "buffers.h"
#include "rxtx.h"
#include "hostchan.h"
#include "params.h"
#include "logging.h"
#ifdef COMPILING_ON_WINDOWS
# undef ERROR
# undef IGNORE
# include <windows.h>
# include "angeldll.h"
# include "comb_api.h"
#else
# ifdef __hpux
# define _TERMIOS_INCLUDED
# include <sys/termio.h>
# undef _TERMIOS_INCLUDED
# else
# include <termios.h>
# endif
# include "unixcomm.h"
#endif
#ifndef UNUSED
# define UNUSED(x) (x = x) /* Silence compiler warnings */
#endif
#define MAXREADSIZE 512
#define MAXWRITESIZE 512
#define SERIAL_FC_SET ((1<<serial_XON)|(1<<serial_XOFF))
#define SERIAL_CTL_SET ((1<<serial_STX)|(1<<serial_ETX)|(1<<serial_ESC))
#define SERIAL_ESC_SET (SERIAL_FC_SET|SERIAL_CTL_SET)
static const struct re_config config = {
serial_STX, serial_ETX, serial_ESC, /* self-explanatory? */
SERIAL_FC_SET, /* set of flow-control characters */
SERIAL_ESC_SET, /* set of characters to be escaped */
NULL /* serial_flow_control */, NULL , /* what to do with FC chars */
angel_DD_RxEng_BufferAlloc, NULL /* how to get a buffer */
};
static struct re_state rxstate;
typedef struct writestate {
unsigned int wbindex;
/* static te_status testatus;*/
unsigned char writebuf[MAXWRITESIZE];
struct te_state txstate;
} writestate;
static struct writestate wstate;
/*
* The set of parameter options supported by the device
*/
static unsigned int baud_options[] = {
#ifdef __hpux
115200, 57600,
#endif
38400, 19200, 9600
};
static ParameterList param_list[] = {
{ AP_BAUD_RATE,
sizeof(baud_options)/sizeof(unsigned int),
baud_options }
};
static const ParameterOptions serial_options = {
sizeof(param_list)/sizeof(ParameterList), param_list };
/*
* The default parameter config for the device
*/
static Parameter param_default[] = {
{ AP_BAUD_RATE, 9600 }
};
static ParameterConfig serial_defaults = {
sizeof(param_default)/sizeof(Parameter), param_default };
/*
* The user-modified options for the device
*/
static unsigned int user_baud_options[sizeof(baud_options)/sizeof(unsigned)];
static ParameterList param_user_list[] = {
{ AP_BAUD_RATE,
sizeof(user_baud_options)/sizeof(unsigned),
user_baud_options }
};
static ParameterOptions user_options = {
sizeof(param_user_list)/sizeof(ParameterList), param_user_list };
static bool user_options_set;
/* forward declarations */
static int serial_reset( void );
static int serial_set_params( const ParameterConfig *config );
static int SerialMatch(const char *name, const char *arg);
static void process_baud_rate( unsigned int target_baud_rate )
{
const ParameterList *full_list;
ParameterList *user_list;
/* create subset of full options */
full_list = Angel_FindParamList( &serial_options, AP_BAUD_RATE );
user_list = Angel_FindParamList( &user_options, AP_BAUD_RATE );
if ( full_list != NULL && user_list != NULL )
{
unsigned int i, j;
unsigned int def_baud = 0;
/* find lower or equal to */
for ( i = 0; i < full_list->num_options; ++i )
if ( target_baud_rate >= full_list->option[i] )
{
/* copy remaining */
for ( j = 0; j < (full_list->num_options - i); ++j )
user_list->option[j] = full_list->option[i+j];
user_list->num_options = j;
/* check this is not the default */
Angel_FindParam( AP_BAUD_RATE, &serial_defaults, &def_baud );
if ( (j == 1) && (user_list->option[0] == def_baud) )
{
#ifdef DEBUG
printf( "user selected default\n" );
#endif
}
else
{
user_options_set = TRUE;
#ifdef DEBUG
printf( "user options are: " );
for ( j = 0; j < user_list->num_options; ++j )
printf( "%u ", user_list->option[j] );
printf( "\n" );
#endif
}
break; /* out of i loop */
}
#ifdef DEBUG
if ( i >= full_list->num_options )
printf( "couldn't match baud rate %u\n", target_baud_rate );
#endif
}
#ifdef DEBUG
else
printf( "failed to find lists\n" );
#endif
}
static int SerialOpen(const char *name, const char *arg)
{
const char *port_name = name;
#ifdef DEBUG
printf("SerialOpen: name %s arg %s\n", name, arg ? arg : "<NULL>");
#endif
#ifdef COMPILING_ON_WINDOWS
if (IsOpenSerial()) return -1;
#else
if (Unix_IsSerialInUse()) return -1;
#endif
#ifdef COMPILING_ON_WINDOWS
if (SerialMatch(name, arg) != adp_ok)
return adp_failed;
#else
port_name = Unix_MatchValidSerialDevice(port_name);
# ifdef DEBUG
printf("translated port to %s\n", port_name == 0 ? "NULL" : port_name);
# endif
if (port_name == 0) return adp_failed;
#endif
user_options_set = FALSE;
/* interpret and store the arguments */
if ( arg != NULL )
{
unsigned int target_baud_rate;
target_baud_rate = (unsigned int)strtoul(arg, NULL, 10);
if (target_baud_rate > 0)
{
#ifdef DEBUG
printf( "user selected baud rate %u\n", target_baud_rate );
#endif
process_baud_rate( target_baud_rate );
}
#ifdef DEBUG
else
printf( "could not understand baud rate %s\n", arg );
#endif
}
#ifdef COMPILING_ON_WINDOWS
{
int port = IsValidDevice(name);
if (OpenSerial(port, FALSE) != COM_OK)
return -1;
}
#else
if (Unix_OpenSerial(port_name) < 0)
return -1;
#endif
serial_reset();
#if defined(__unix) || defined(__CYGWIN32__)
Unix_ioctlNonBlocking();
#endif
Angel_RxEngineInit(&config, &rxstate);
/*
* DANGER!: passing in NULL as the packet is ok for now as it is just
* IGNOREd but this may well change
*/
Angel_TxEngineInit(&config, NULL, &wstate.txstate);
return 0;
}
static int SerialMatch(const char *name, const char *arg)
{
UNUSED(arg);
#ifdef COMPILING_ON_WINDOWS
if (IsValidDevice(name) == COM_DEVICENOTVALID)
return -1;
else
return 0;
#else
return Unix_MatchValidSerialDevice(name) == 0 ? -1 : 0;
#endif
}
static void SerialClose(void)
{
#ifdef DO_TRACE
printf("SerialClose()\n");
#endif
#ifdef COMPILING_ON_WINDOWS
CloseSerial();
#else
Unix_CloseSerial();
#endif
}
static int SerialRead(DriverCall *dc, bool block) {
static unsigned char readbuf[MAXREADSIZE];
static int rbindex=0;
int nread;
int read_errno;
int c=0;
re_status restatus;
int ret_code = -1; /* assume bad packet or error */
/* must not overflow buffer and must start after the existing data */
#ifdef COMPILING_ON_WINDOWS
{
BOOL dummy = FALSE;
nread = BytesInRXBufferSerial();
if (nread > MAXREADSIZE - rbindex)
nread = MAXREADSIZE - rbindex;
if ((read_errno = ReadSerial(readbuf+rbindex, nread, &dummy)) == COM_READFAIL)
{
MessageBox(GetFocus(), "Read error\n", "Angel", MB_OK | MB_ICONSTOP);
return -1; /* SJ - This really needs to return a value, which is picked up in */
/* DevSW_Read as meaning stop debugger but don't kill. */
}
else if (pfnProgressCallback != NULL && read_errno == COM_OK)
{
progressInfo.nRead += nread;
(*pfnProgressCallback)(&progressInfo);
}
}
#else
nread = Unix_ReadSerial(readbuf+rbindex, MAXREADSIZE-rbindex, block);
read_errno = errno;
#endif
if ((nread > 0) || (rbindex > 0)) {
#ifdef DO_TRACE
printf("[%d@%d] ", nread, rbindex);
#endif
if (nread>0)
rbindex = rbindex+nread;
do {
restatus = Angel_RxEngine(readbuf[c], &(dc->dc_packet), &rxstate);
#ifdef DO_TRACE
printf("<%02X ",readbuf[c]);
if (!(++c % 16))
printf("\n");
#else
c++;
#endif
} while (c<rbindex &&
((restatus == RS_IN_PKT) || (restatus == RS_WAIT_PKT)));
#ifdef DO_TRACE
if (c % 16)
printf("\n");
#endif
switch(restatus) {
case RS_GOOD_PKT:
ret_code = 1;
/* fall through to: */
case RS_BAD_PKT:
/*
* We now need to shuffle any left over data down to the
* beginning of our private buffer ready to be used
*for the next packet
*/
#ifdef DO_TRACE
printf("SerialRead() processed %d, moving down %d\n", c, rbindex-c);
#endif
if (c != rbindex) memmove((char *) readbuf, (char *) (readbuf+c),
rbindex-c);
rbindex -= c;
break;
case RS_IN_PKT:
case RS_WAIT_PKT:
rbindex = 0; /* will have processed all we had */
ret_code = 0;
break;
default:
#ifdef DEBUG
printf("Bad re_status in serialRead()\n");
#endif
break;
}
} else if (nread == 0)
ret_code = 0; /* nothing to read */
else if (read_errno == ERRNO_FOR_BLOCKED_IO) /* nread < 0 */
ret_code = 0;
#ifdef DEBUG
if ((nread<0) && (read_errno!=ERRNO_FOR_BLOCKED_IO))
perror("read() error in serialRead()");
#endif
return ret_code;
}
static int SerialWrite(DriverCall *dc) {
int nwritten = 0;
te_status testatus = TS_IN_PKT;
if (dc->dc_context == NULL) {
Angel_TxEngineInit(&config, &(dc->dc_packet), &(wstate.txstate));
wstate.wbindex = 0;
dc->dc_context = &wstate;
}
while ((testatus == TS_IN_PKT) && (wstate.wbindex < MAXWRITESIZE))
{
/* send the raw data through the tx engine to escape and encapsulate */
testatus = Angel_TxEngine(&(dc->dc_packet), &(wstate.txstate),
&(wstate.writebuf)[wstate.wbindex]);
if (testatus != TS_IDLE) wstate.wbindex++;
}
if (testatus == TS_IDLE) {
#ifdef DEBUG
printf("SerialWrite: testatus is TS_IDLE during preprocessing\n");
#endif
}
#ifdef DO_TRACE
{
int i = 0;
while (i<wstate.wbindex)
{
printf(">%02X ",wstate.writebuf[i]);
if (!(++i % 16))
printf("\n");
}
if (i % 16)
printf("\n");
}
#endif
#ifdef COMPILING_ON_WINDOWS
if (WriteSerial(wstate.writebuf, wstate.wbindex) == COM_OK)
{
nwritten = wstate.wbindex;
if (pfnProgressCallback != NULL)
{
progressInfo.nWritten += nwritten;
(*pfnProgressCallback)(&progressInfo);
}
}
else
{
MessageBox(GetFocus(), "Write error\n", "Angel", MB_OK | MB_ICONSTOP);
return -1; /* SJ - This really needs to return a value, which is picked up in */
/* DevSW_Read as meaning stop debugger but don't kill. */
}
#else
nwritten = Unix_WriteSerial(wstate.writebuf, wstate.wbindex);
if (nwritten < 0) {
nwritten=0;
}
#endif
#ifdef DEBUG
if (nwritten > 0)
printf("Wrote %#04x bytes\n", nwritten);
#endif
if ((unsigned) nwritten == wstate.wbindex &&
(testatus == TS_DONE_PKT || testatus == TS_IDLE)) {
/* finished sending the packet */
#ifdef DEBUG
printf("SerialWrite: calling Angel_TxEngineInit after sending packet (len=%i)\n",wstate.wbindex);
#endif
testatus = TS_IN_PKT;
wstate.wbindex = 0;
return 1;
}
else {
#ifdef DEBUG
printf("SerialWrite: Wrote part of packet wbindex=%i, nwritten=%i\n",
wstate.wbindex, nwritten);
#endif
/*
* still some data left to send shuffle whats left down and reset
* the ptr
*/
memmove((char *) wstate.writebuf, (char *) (wstate.writebuf+nwritten),
wstate.wbindex-nwritten);
wstate.wbindex -= nwritten;
return 0;
}
return -1;
}
static int serial_reset( void )
{
#ifdef DEBUG
printf( "serial_reset\n" );
#endif
#ifdef COMPILING_ON_WINDOWS
FlushSerial();
#else
Unix_ResetSerial();
#endif
return serial_set_params( &serial_defaults );
}
static int find_baud_rate( unsigned int *speed )
{
static struct {
unsigned int baud;
int termiosValue;
} possibleBaudRates[] = {
#if defined(__hpux)
{115200,_B115200}, {57600,_B57600},
#endif
#ifdef COMPILING_ON_WINDOWS
{38400,CBR_38400}, {19200,CBR_19200}, {9600, CBR_9600}, {0,0}
#else
{38400,B38400}, {19200,B19200}, {9600, B9600}, {0,0}
#endif
};
unsigned int i;
/* look for lower or matching -- will always terminate at 0 end marker */
for ( i = 0; possibleBaudRates[i].baud > *speed; ++i )
/* do nothing */ ;
if ( possibleBaudRates[i].baud > 0 )
*speed = possibleBaudRates[i].baud;
return possibleBaudRates[i].termiosValue;
}
static int serial_set_params( const ParameterConfig *config )
{
unsigned int speed;
int termios_value;
#ifdef DEBUG
printf( "serial_set_params\n" );
#endif
if ( ! Angel_FindParam( AP_BAUD_RATE, config, &speed ) )
{
#ifdef DEBUG
printf( "speed not found in config\n" );
#endif
return DE_OKAY;
}
termios_value = find_baud_rate( &speed );
if ( termios_value == 0 )
{
#ifdef DEBUG
printf( "speed not valid: %u\n", speed );
#endif
return DE_OKAY;
}
#ifdef DEBUG
printf( "setting speed to %u\n", speed );
#endif
#ifdef COMPILING_ON_WINDOWS
SetBaudRate((WORD)termios_value);
#else
Unix_SetSerialBaudRate(termios_value);
#endif
return DE_OKAY;
}
static int serial_get_user_params( ParameterOptions **p_options )
{
#ifdef DEBUG
printf( "serial_get_user_params\n" );
#endif
if ( user_options_set )
{
*p_options = &user_options;
}
else
{
*p_options = NULL;
}
return DE_OKAY;
}
static int serial_get_default_params( ParameterConfig **p_config )
{
#ifdef DEBUG
printf( "serial_get_default_params\n" );
#endif
*p_config = (ParameterConfig *) &serial_defaults;
return DE_OKAY;
}
static int SerialIoctl(const int opcode, void *args) {
int ret_code;
#ifdef DEBUG
printf( "SerialIoctl: op %d arg %p\n", opcode, args ? args : "<NULL>");
#endif
switch (opcode)
{
case DC_RESET:
ret_code = serial_reset();
break;
case DC_SET_PARAMS:
ret_code = serial_set_params((const ParameterConfig *)args);
break;
case DC_GET_USER_PARAMS:
ret_code = serial_get_user_params((ParameterOptions **)args);
break;
case DC_GET_DEFAULT_PARAMS:
ret_code = serial_get_default_params((ParameterConfig **)args);
break;
default:
ret_code = DE_BAD_OP;
break;
}
return ret_code;
}
DeviceDescr angel_SerialDevice = {
"SERIAL",
SerialOpen,
SerialMatch,
SerialClose,
SerialRead,
SerialWrite,
SerialIoctl
};

View File

@ -1,728 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*
* serpardv.c - Serial/Parallel Driver for Angel.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "crc.h"
#include "devices.h"
#include "buffers.h"
#include "rxtx.h"
#include "hostchan.h"
#include "params.h"
#include "logging.h"
#include "hsys.h"
#ifdef COMPILING_ON_WINDOWS
# undef ERROR
# undef IGNORE
# include <windows.h>
# include "angeldll.h"
# include "comb_api.h"
#else
# ifdef __hpux
# define _TERMIOS_INCLUDED
# include <sys/termio.h>
# undef _TERMIOS_INCLUDED
# else
# include <termios.h>
# endif
# include "unixcomm.h"
#endif
#ifndef UNUSED
# define UNUSED(x) (x = x) /* Silence compiler warnings */
#endif
#define MAXREADSIZE 512
#define MAXWRITESIZE 512
#define SERPAR_FC_SET ((1 << serial_XON) | (1 << serial_XOFF))
#define SERPAR_CTL_SET ((1 << serial_STX) | (1 << serial_ETX) | \
(1 << serial_ESC))
#define SERPAR_ESC_SET (SERPAR_FC_SET | SERPAR_CTL_SET)
static const struct re_config config = {
serial_STX, serial_ETX, serial_ESC, /* self-explanatory? */
SERPAR_FC_SET, /* set of flow-control characters */
SERPAR_ESC_SET, /* set of characters to be escaped */
NULL, /* serial_flow_control */
NULL, /* what to do with FC chars */
angel_DD_RxEng_BufferAlloc, NULL /* how to get a buffer */
};
static struct re_state rxstate;
/*
* structure used for manipulating transmit data
*/
typedef struct TxState
{
struct te_state state;
unsigned int index;
unsigned char writebuf[MAXWRITESIZE];
} TxState;
/*
* The set of parameter options supported by the device
*/
static unsigned int baud_options[] =
{
#ifdef __hpux
115200, 57600,
#endif
38400, 19200, 9600
};
static ParameterList param_list[] =
{
{
AP_BAUD_RATE,
sizeof(baud_options) / sizeof(unsigned int),
baud_options
}
};
static const ParameterOptions serpar_options =
{
sizeof(param_list) / sizeof(ParameterList),
param_list
};
/*
* The default parameter config for the device
*/
static Parameter param_default[] =
{
{ AP_BAUD_RATE, 9600 }
};
static const ParameterConfig serpar_defaults =
{
sizeof(param_default)/sizeof(Parameter),
param_default
};
/*
* The user-modified options for the device
*/
static unsigned int user_baud_options[sizeof(baud_options) /
sizeof(unsigned int)];
static ParameterList param_user_list[] =
{
{
AP_BAUD_RATE,
sizeof(user_baud_options) / sizeof(unsigned),
user_baud_options
}
};
static ParameterOptions user_options =
{
sizeof(param_user_list) / sizeof(ParameterList),
param_user_list
};
static bool user_options_set;
/* forward declarations */
static int serpar_reset(void);
static int serpar_set_params(const ParameterConfig *config);
static int SerparMatch(const char *name, const char *arg);
static void process_baud_rate(unsigned int target_baud_rate)
{
const ParameterList *full_list;
ParameterList *user_list;
/* create subset of full options */
full_list = Angel_FindParamList(&serpar_options, AP_BAUD_RATE);
user_list = Angel_FindParamList(&user_options, AP_BAUD_RATE);
if (full_list != NULL && user_list != NULL)
{
unsigned int i, j;
unsigned int def_baud = 0;
/* find lower or equal to */
for (i = 0; i < full_list->num_options; ++i)
if (target_baud_rate >= full_list->option[i])
{
/* copy remaining */
for (j = 0; j < (full_list->num_options - i); ++j)
user_list->option[j] = full_list->option[i+j];
user_list->num_options = j;
/* check this is not the default */
Angel_FindParam(AP_BAUD_RATE, &serpar_defaults, &def_baud);
if ((j == 1) && (user_list->option[0] == def_baud))
{
#ifdef DEBUG
printf("user selected default\n");
#endif
}
else
{
user_options_set = TRUE;
#ifdef DEBUG
printf("user options are: ");
for (j = 0; j < user_list->num_options; ++j)
printf("%u ", user_list->option[j]);
printf("\n");
#endif
}
break; /* out of i loop */
}
#ifdef DEBUG
if (i >= full_list->num_options)
printf("couldn't match baud rate %u\n", target_baud_rate);
#endif
}
#ifdef DEBUG
else
printf("failed to find lists\n");
#endif
}
static int SerparOpen(const char *name, const char *arg)
{
char *sername = NULL;
char *parname = NULL;
#ifdef DEBUG
printf("SerparOpen: name %s arg %s\n", name, arg ? arg : "<NULL>");
#endif
#ifdef COMPILING_ON_WINDOWS
if (IsOpenSerial() || IsOpenParallel()) return -1;
#else
if (Unix_IsSerialInUse() || Unix_IsParallelInUse()) return -1;
#endif
#ifdef COMPILING_ON_WINDOWS
if (SerparMatch(name, arg) == -1)
return -1;
#else
Unix_IsValidParallelDevice(name,&sername,&parname);
# ifdef DEBUG
printf("translated %s to serial %s and parallel %s\n",
name==0 ? "NULL" : name,
sername==0 ? "NULL" : sername,
parname==0 ? "NULL" : parname);
# endif
if (sername==NULL || parname==NULL) return -1;
#endif
user_options_set = FALSE;
/* interpret and store the arguments */
if (arg != NULL)
{
unsigned int target_baud_rate;
target_baud_rate = (unsigned int)strtoul(arg, NULL, 10);
if (target_baud_rate > 0)
{
#ifdef DEBUG
printf("user selected baud rate %u\n", target_baud_rate);
#endif
process_baud_rate(target_baud_rate);
}
#ifdef DEBUG
else
printf("could not understand baud rate %s\n", arg);
#endif
}
#ifdef COMPILING_ON_WINDOWS
{
/*
* The serial port number is in name[0] followed by
* the parallel port number in name[1]
*/
int sport = name[0] - '0';
int pport = name[1] - '0';
if (OpenParallel(pport) != COM_OK)
return -1;
if (OpenSerial(sport, FALSE) != COM_OK)
{
CloseParallel();
return -1;
}
}
#else
Unix_OpenParallel(parname);
Unix_OpenSerial(sername);
#endif
serpar_reset();
#if defined(__unix) || defined(__CYGWIN32__)
Unix_ioctlNonBlocking();
#endif
Angel_RxEngineInit(&config, &rxstate);
return 0;
}
#ifdef COMPILING_ON_WINDOWS
static int SerparMatch(const char *name, const char *arg)
{
char sername[2];
char parname[2];
UNUSED(arg);
sername[0] = name[0];
parname[0] = name[1];
sername[1] = parname[1] = 0;
if (IsValidDevice(sername) == COM_DEVICENOTVALID ||
IsValidDevice(parname) == COM_DEVICENOTVALID)
return -1;
else
return 0;
}
#else
static int SerparMatch(const char *portstring, const char *arg)
{
char *sername=NULL, *parname=NULL;
UNUSED(arg);
Unix_IsValidParallelDevice(portstring,&sername,&parname);
/* Match failed if either sername or parname are still NULL */
if (sername==NULL || parname==NULL) return -1;
return 0;
}
#endif
static void SerparClose(void)
{
#ifdef COMPILING_ON_WINDOWS
CloseParallel();
CloseSerial();
#else
Unix_CloseParallel();
Unix_CloseSerial();
#endif
}
static int SerparRead(DriverCall *dc, bool block)
{
static unsigned char readbuf[MAXREADSIZE];
static int rbindex = 0;
int nread;
int read_errno;
int c = 0;
re_status restatus;
int ret_code = -1; /* assume bad packet or error */
/*
* we must not overflow buffer, and must start after
* the existing data
*/
#ifdef COMPILING_ON_WINDOWS
{
BOOL dummy = FALSE;
nread = BytesInRXBufferSerial();
if (nread > MAXREADSIZE - rbindex)
nread = MAXREADSIZE - rbindex;
read_errno = ReadSerial(readbuf+rbindex, nread, &dummy);
if (pfnProgressCallback != NULL && read_errno == COM_OK)
{
progressInfo.nRead += nread;
(*pfnProgressCallback)(&progressInfo);
}
}
#else
nread = Unix_ReadSerial(readbuf+rbindex, MAXREADSIZE-rbindex, block);
read_errno = errno;
#endif
if ((nread > 0) || (rbindex > 0))
{
#ifdef DO_TRACE
printf("[%d@%d] ", nread, rbindex);
#endif
if (nread > 0)
rbindex = rbindex + nread;
do
{
restatus = Angel_RxEngine(readbuf[c], &(dc->dc_packet), &rxstate);
#ifdef DO_TRACE
printf("<%02X ",readbuf[c]);
#endif
c++;
} while (c < rbindex &&
((restatus == RS_IN_PKT) || (restatus == RS_WAIT_PKT)));
#ifdef DO_TRACE
printf("\n");
#endif
switch(restatus)
{
case RS_GOOD_PKT:
ret_code = 1;
/* fall through to: */
case RS_BAD_PKT:
/*
* We now need to shuffle any left over data down to the
* beginning of our private buffer ready to be used
*for the next packet
*/
#ifdef DO_TRACE
printf("SerparRead() processed %d, moving down %d\n",
c, rbindex - c);
#endif
if (c != rbindex)
memmove((char *) readbuf, (char *) (readbuf + c), rbindex - c);
rbindex -= c;
break;
case RS_IN_PKT:
case RS_WAIT_PKT:
rbindex = 0; /* will have processed all we had */
ret_code = 0;
break;
default:
#ifdef DEBUG
printf("Bad re_status in SerparRead()\n");
#endif
break;
}
}
else if (nread == 0)
/* nothing to read */
ret_code = 0;
else if (read_errno == ERRNO_FOR_BLOCKED_IO) /* nread < 0 */
ret_code = 0;
#ifdef DEBUG
if ((nread < 0) && (read_errno != ERRNO_FOR_BLOCKED_IO))
perror("read() error in SerparRead()");
#endif
return ret_code;
}
/*
* Function: send_packet
* Purpose: Send a stream of bytes to Angel through the parallel port
*
* Algorithm: We need to present the data in a form that all boards can
* swallow. With the PID board, this is a problem: for reasons
* described in the driver (angel/pid/st16c552.c), data are
* sent a nybble at a time on D0-D2 and D4; D3 is wired to ACK,
* which generates an interrupt when it goes low. This routine
* fills in an array of nybbles, with ACK clear in all but the
* last one. If, for whatever reason, the write fails, then
* ACK is forced high (thereby enabling the next write a chance
* to be noticed when the falling edge of ACK generates an
* interrupt (hopefully).
*
* Params:
* Input: txstate Contains the packet to be sent
*
* Returns: Number of *complete* bytes written
*/
static int SerparWrite(DriverCall *dc)
{
te_status status;
int nwritten = 0;
static TxState txstate;
/*
* is this a new packet?
*/
if (dc->dc_context == NULL)
{
/*
* yes - initialise TxEngine
*/
Angel_TxEngineInit(&config, &dc->dc_packet, &txstate.state);
txstate.index = 0;
dc->dc_context = &txstate;
}
/*
* fill the buffer using the Tx Engine
*/
do
{
status = Angel_TxEngine(&dc->dc_packet, &txstate.state,
&txstate.writebuf[txstate.index]);
if (status != TS_IDLE) txstate.index++;
} while (status == TS_IN_PKT && txstate.index < MAXWRITESIZE);
#ifdef DO_TRACE
{
unsigned int i = 0;
while (i < txstate.index)
{
printf(">%02X ", txstate.writebuf[i]);
if (!(++i % 16))
putc('\n', stdout);
}
if (i % 16)
putc('\n', stdout);
}
#endif
/*
* the data are ready, all we need now is to send them out
* in a form that Angel can swallow.
*/
#ifdef COMPILING_ON_WINDOWS
if (WriteParallel(txstate.writebuf, txstate.index) == COM_OK)
{
nwritten = txstate.index;
if (pfnProgressCallback != NULL)
{
progressInfo.nWritten += nwritten;
(*pfnProgressCallback)(&progressInfo);
}
}
else
{
MessageBox(GetFocus(), "Write error\n", "Angel", MB_OK | MB_ICONSTOP);
return -1; /* SJ - This really needs to return a value, which is picked up in */
/* DevSW_Read as meaning stop debugger but don't kill. */
}
#else
nwritten = Unix_WriteParallel(txstate.writebuf, txstate.index);
#endif
if (nwritten < 0) nwritten = 0;
#ifdef DO_TRACE
printf("SerparWrite: wrote %d out of %d bytes\n",
nwritten, txstate.index);
#endif
/*
* has the whole packet gone?
*/
if (nwritten == (int)txstate.index &&
(status == TS_DONE_PKT || status == TS_IDLE))
/*
* yes it has
*/
return 1;
else
{
/*
* if some data are left, shuffle them
* to the start of the buffer
*/
if (nwritten != (int)txstate.index && nwritten != 0)
{
txstate.index -= nwritten;
(void)memmove((char *) txstate.writebuf,
(char *) (txstate.writebuf + nwritten),
txstate.index);
}
else if (nwritten == (int)txstate.index)
txstate.index = 0;
return 0;
}
}
static int serpar_reset(void)
{
#ifdef COMPILING_ON_WINDOWS
FlushParallel();
FlushSerial();
#else
Unix_ResetParallel();
Unix_ResetSerial();
#endif
return serpar_set_params(&serpar_defaults);
}
static int find_baud_rate(unsigned int *speed)
{
static struct
{
unsigned int baud;
int termiosValue;
} possibleBaudRates[] =
{
#if defined(__hpux)
{115200, _B115200}, {57600, _B57600},
#endif
#ifdef COMPILING_ON_WINDOWS
{38400, CBR_38400}, {19200, CBR_19200}, {9600, CBR_9600}, {0, 0}
#else
{38400, B38400}, {19200, B19200}, {9600, B9600}, {0, 0}
#endif
};
unsigned int i;
/* look for lower or matching -- will always terminate at 0 end marker */
for (i = 0; possibleBaudRates[i].baud > *speed; ++i)
/* do nothing */
;
if (possibleBaudRates[i].baud > 0)
*speed = possibleBaudRates[i].baud;
return possibleBaudRates[i].termiosValue;
}
static int serpar_set_params(const ParameterConfig *config)
{
unsigned int speed;
int termios_value;
#ifdef DEBUG
printf("serpar_set_params\n");
#endif
if (!Angel_FindParam(AP_BAUD_RATE, config, &speed))
{
#ifdef DEBUG
printf("speed not found in config\n");
#endif
return DE_OKAY;
}
termios_value = find_baud_rate(&speed);
if (termios_value == 0)
{
#ifdef DEBUG
printf("speed not valid: %u\n", speed);
#endif
return DE_OKAY;
}
#ifdef DEBUG
printf("setting speed to %u\n", speed);
#endif
#ifdef COMPILING_ON_WINDOWS
SetBaudRate((WORD)termios_value);
#else
Unix_SetSerialBaudRate(termios_value);
#endif
return DE_OKAY;
}
static int serpar_get_user_params(ParameterOptions **p_options)
{
#ifdef DEBUG
printf("serpar_get_user_params\n");
#endif
if (user_options_set)
{
*p_options = &user_options;
}
else
{
*p_options = NULL;
}
return DE_OKAY;
}
static int serial_get_default_params( const ParameterConfig **p_config )
{
#ifdef DEBUG
printf( "serial_get_default_params\n" );
#endif
*p_config = &serpar_defaults;
return DE_OKAY;
}
static int SerparIoctl(const int opcode, void *args)
{
int ret_code;
#ifdef DEBUG
printf("SerparIoctl: op %d arg %p\n", opcode, args ? args : "<NULL>");
#endif
switch (opcode)
{
case DC_RESET:
ret_code = serpar_reset();
break;
case DC_SET_PARAMS:
ret_code = serpar_set_params((const ParameterConfig *)args);
break;
case DC_GET_USER_PARAMS:
ret_code = serpar_get_user_params((ParameterOptions **)args);
break;
case DC_GET_DEFAULT_PARAMS:
ret_code =
serial_get_default_params((const ParameterConfig **)args);
break;
default:
ret_code = DE_BAD_OP;
break;
}
return ret_code;
}
DeviceDescr angel_SerparDevice =
{
"SERPAR",
SerparOpen,
SerparMatch,
SerparClose,
SerparRead,
SerparWrite,
SerparIoctl
};
/* EOF serpardr.c */

View File

@ -1,317 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* sys.h
***********************************************************************
* Angel C Libary support channel protocol definitions
*
*
*
*
*
* MESSAGE FORMAT
* --------------
* Format of the "data" section of C Lib Support Channel Messages.
* You will notice that the format is much the same as the format
* of ADP messages - this is so that multi-threaded C Libraries can
* be supported.
*
* unsigned32 reason - Main C Library reason code.
* unsigned32 debugID - Info. describing host debug world;
* private to host and used in any target
* initiated messages.
* unsigned32 OSinfo1 \ Target OS information to identify process/thread
* unsigned32 OSinfo2 / world, etc. These two fields are target defined.
* byte args[n] - Data for message "reason" code.
*
* The "debugID" is defined by the host-end of the protocol, and is used
* by the host to ensure that messages are routed to the correct handler
* program/veneer (eg. imagine several threads having opened stdout and
* each writing to a different window in a windowed debugger).
*
* NOTE: The reason that there is no "size" information, is that the
* message IDs themselves encode the format of any arguments.
*
* For further discussion of the format see adp.h
*
* N.B. All streams are little endian.
*
* CLIB REASON CODE
* ----------------
* The message reason codes contain some information that ties them to
* the channel and direction that the message will be used with. This
* will ensure that even if the message "#define name" is not
* completely descriptive, the message reason code is.
*
* b31 = direction. 0=Host-to-Target; 1=Target-to-Host;
* b30-16 = reserved. should be zero
* b15-0 = message reason code.
*
* Note that typically a request will be initiated by the target side, and
* that the host will then respond with either an acknowledgement or some
* data. In either case the same reason code will be used, but the direction
* bit will be reveresed.
*/
#ifndef __sys_h
#define __sys_h
#ifndef HtoT
#define HtoT ((unsigned)0 << 31) /* Host-to-Target message */
#define TtoH ((unsigned)1 << 31) /* Target-to-Host message */
#endif
/*
* The following are error codes used in the status field returned on
* sending a message. 0 represents no error having occurred, non-zero
* represents a general error. More codes should be added as required.
*/
#ifndef ErrCode
#define NoError 0x0
#endif
/*************************************************************************/
/* The following are direct conversions of the DeMon SWI's */
/* NB: nbytes is the number of bytes INCLUDING THE NULL character where */
/* applicable. */
/* This message is used as a response to a packet whose message
* was not understood. The return parameter, code is the reason
* code which was not understood. Although intended for use as a
* default case on a received message switch it can also be used
* as a proper message*/
#define CL_Unrecognised 0x00
/* Unrecognised()
* return(word code)
*/
/* Write a character to the terminal.
*/
#define CL_WriteC 0x01
/* WriteC(byte data)
* return(word status)
*/
/* Write a NULL terminated string of characters to the terminal. The length
* of the string excluding the NULL terminating character is passed in
* 'nbytes'.
*/
#define CL_Write0 0x02
/* Write0(word nbytes, bytes data)
* return(word status)
*/
/* Read a character from the terminal - probably the keyboard.
*/
#define CL_ReadC 0x04
/* ReadC(void)
* return(word status, byte data)
*/
/* Perform system call, pass NULL terminated string to host's command
* line interpreter(NOT AVAILABLE IN PC/DOS RELEASE). The data byte
* returned holds the return code from the system call.
*/
#define CL_System 0x05
/* CLI(word nbytes, bytes data)
* return(word status, word data)
*/
/* It returns the address of the null terminated command line string used to
* invoke the program. status will be set to NoError if the command line
* can be returned. Other status values will be treated as error conditions.
*/
#define CL_GetCmdLine 0x10
/* GetCmdLine(void)
* return(word status, word nbytes, bytes argline)
*/
/* Return the number of centi-seconds since the support code began
* execution. Only the difference between successive calls can be
* meaningful.
*/
#define CL_Clock 0x61
/* Clock(void)
* return(word status, word clks)
*/
/* Return the number of seconds since the beginning of 1970.
*/
#define CL_Time 0x63
/* Time(void)
* return(word status, word time)
*/
/* Delete(remove, un-link, wipe, destroy) the file named by the
* NULL-terminated string 'name'.
*/
#define CL_Remove 0x64
/* Remove(word nbytes, bytes name)
* return(word status)
*/
/* Rename the file specified by the NULL-terminated string 'oname'
* to 'nname'.
*/
#define CL_Rename 0x65
/* Rename(word nbytes, bytes oname, word nbytes, bytes nname)
* return(word status)
*/
/* 'name' specifies a NULL-terminated string containing a file name or a
* device name. Opens the file/device and returns a non-zero handle on
* success that can be quoted to CL_Close, CL_Read, CL_Write, CL_Seek,
* CL_Flen or CL_IsTTY. The mode is an integer in the range 0-11:-
*
* Mode: 0 1 2 3 4 5 6 7 8 9 10 11
* ANSI C fopen mode: r rb r+ r+b w wb w+ w+b a ab a+ a+b
*
* Values 12-15 are illegal. If 'name' is ":tt" the stdin/stdout is
* opened depending on whether 'mode' is read or write.
*/
#define CL_Open 0x66
/* Open(word nbytes, bytes name, word mode)
* return(word handle)
*/
/* 'handle' is a file handle previously returned by CL_Open. CL_Close
* closes the file.
*/
#define CL_Close 0x68
/* Close(word handle)
* return(word status)
*/
/* Writes data of length nbytes to the file/device specified by
* handle. nbtotal represents the total number of bytes to be
* written, whereas nbytes is the number of bytes in this packet
*
* If nbtotal is <= DATASIZE - CL_Write message header size in the
* packet then nbytes = nbtotal and the number of bytes not written
* is returned. If nbtotal is > the packet size then the CL_Write
* must be followed by a number of CL_WriteX's to complete the write,
* the nbytes returned by CL_Write can be ignored
* If the status word returned is non zero, an error has occurred and
* the write request has been aborted.
*
*/
#define CL_Write 0x69
/* Write(word handle, word nbtotal, word nbytes, bytes data)
* return(word status, word nbytes)
*/
/* Write Extension is a reads a continuation of data from a CL_Write
* which was too big to fit in a single packet.
* nbytes is the number of bytes of data in this packet, the
* returned value of nbytes can be ignored except if it is the
* last packet, in which case it is the number of bytes that were NOT
* written
*/
#define CL_WriteX 0x6A
/* WriteX(word nbytes, bytes data)
* return(word status, word nbytes)
*/
/* Reads 'nbytes' from the file/device specified by 'handle'.
*
* If nbytes <= DATASIZE then the read will occur in a single packet
* and the returned value of nbytes will be the number of bytes actually
* read and nbmore will be 0. If nbytes> DATASIZE then multiple packets
* will have to be used ie CL_Read followed by 1 or more CL_ReadX
* packets. In this case CL_Read will return nbytes read in the current
* packet and nbmore representing how many more bytes are expected to be
* read
* If the status word is non zero then the request has completed with an
* error. If the status word is 0xFFFFFFFF (-1) then an EOF condition
* has been reached.
*/
#define CL_Read 0x6B
/* Read(word handle, word nbytes)
* return(word status, word nbytes, word nbmore, bytes data)
*/
/* Read eXtension returns a continuation of the data that was opened for
* read in the earlier CL_Read. The return value nbytes is the number of
* data bytes in the packet, nbmore is the number of bytes more that are
* expected to be read in subsequent packets.
*/
#define CL_ReadX 0x6C
/* ReadX()
* return(word status, word nbytes, word nbmore, bytes data)
*/
/* Seeks to byte position 'posn' in the file/device specified by 'handle'.
*/
#define CL_Seek 0x6D
/* Seek(word handle, word posn)
* return(word status)
*/
/* Returns the current length of the file specified by 'handle' in 'len'.
* If an error occurs 'len' is set to -1.
*/
#define CL_Flen 0x6E
/* Flen(word handle)
* return(word len)
*/
/* Returns NoError if 'handle' specifies an interactive device, otherwise
* returns GenError
*/
#define CL_IsTTY 0x6F
/* IsTTY(word handle)
* return(word status)
*/
/* Returns a temporary host file name. The maximum length of a file name
* is passed to the host. The TargetID is some identifier from the target
* for this particular temporary filename. This value is could be used
* directly in the generation of the filename.
*
* If the host cannot create a suitable name or the generated name is too
* long then status is non zero. status will be NoError if the host can create
* a name.
*/
#define CL_TmpNam 0x70
/* TmpNam(word maxlength, word TargetID)
* return(word status, word nbytes, bytes fname)
*/
/* Note there is no message for Exit, EnterOS, InstallHandler or
* GenerateError as these will be supported entirely at the host end,
* or by the underlying Operating system.
*/
#define CL_UnknownReason (-1)
extern unsigned int GetRaiseHandler( void );
extern unsigned int SysLibraryHandler(unsigned int sysCode, unsigned int *args);
extern void angel_SysLibraryInit(void);
/*
* Function: Angel_IsSysHandlerRunning
* Purpose: return whether or not SysLibraryHandler is running
*
* No paramaters
*
* Returns 1 if SysLibraryHandler is running
* 0 otherwise
*/
extern int Angel_IsSysHandlerRunning(void);
#ifdef ICEMAN2
/* This function exists in an ICEman2 system only, and can be called by
* debug support code when the debugger tells it how much memory the
* target has. This will then be used to deal with the HEAPINFO SWI
*/
extern void angel_SetTopMem(unsigned addr);
#endif
#endif

View File

@ -1,174 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/*-*-C-*-
*
*
* Project: ANGEL
*
* Title: Character based packet transmission engine
*/
#include <stdarg.h> /* ANSI varargs support */
#include "angel.h" /* Angel system definitions */
#include "endian.h" /* Endian independant memory access macros */
#include "crc.h" /* crc generation definitions and headers */
#include "rxtx.h"
#include "channels.h"
#include "buffers.h"
#include "logging.h"
/* definitions to describe the engines state */
#define N_STX 0x0 /* first 2 bits for N_ */
#define N_BODY 0x1
#define N_ETX 0x2
#define N_IDLE 0x3
#define N_MASK 0x3 /* mask for the Encapsulator state */
#define E_PLAIN (0x0 << 2) /* 3rd bit for E_ */
#define E_ESC (0x1 << 2) /* 3rd bit for E_ */
#define E_MASK (0x1 << 2) /* mask for the Escaper state */
#define F_HEAD (0x0 << 3) /* 4th and 5th bits for F_ */
#define F_DATA (0x1 << 3)
#define F_CRC (0x1 << 4)
#define F_MASK (0x3 << 3) /* mask for the Escaper state */
static unsigned char escape(unsigned char ch_in, struct te_state *txstate);
void Angel_TxEngineInit(const struct re_config *txconfig,
const struct data_packet *packet,
struct te_state *txstate){
IGNORE(packet);
txstate->tx_state = N_STX | E_PLAIN | F_HEAD;
txstate->field_c = 0;
txstate->encoded = 0;
txstate->config = txconfig;
txstate->crc = 0;
}
te_status Angel_TxEngine(const struct data_packet *packet,
struct te_state *txstate,
unsigned char *tx_ch){
/* TODO: gaurd on long/bad packets */
/*
* encapsulate the packet, framing has been moved from a seperate
* function into the encapsulation routine as it needed too much
* inherited state for it to be sensibly located elsewhere
*/
switch ((txstate->tx_state) & N_MASK){
case N_STX:
#ifdef DO_TRACE
__rt_trace("txe-stx ");
#endif
txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_BODY;
*tx_ch = txstate->config->stx;
txstate->field_c = 3; /* set up for the header */
txstate->crc = startCRC32; /* set up basic crc */
return TS_IN_PKT;
case N_BODY:{
switch (txstate->tx_state & F_MASK) {
case F_HEAD:
#ifdef DO_TRACE
__rt_trace("txe-head ");
#endif
if (txstate->field_c == 3) {
/* send type */
*tx_ch = escape(packet->type, txstate);
return TS_IN_PKT;
}
else {
*tx_ch = escape((packet->len >> (txstate->field_c - 1) * 8) & 0xff,
txstate);
if (txstate->field_c == 0) {
/* move on to the next state */
txstate->tx_state = (txstate->tx_state & ~F_MASK) | F_DATA;
txstate->field_c = packet->len;
}
return TS_IN_PKT;
}
case F_DATA:
#ifdef DO_TRACE
__rt_trace("txe-data ");
#endif
*tx_ch = escape(packet->data[packet->len - txstate->field_c], txstate);
if (txstate->field_c == 0) {
/* move on to the next state */
txstate->tx_state = (txstate->tx_state & ~F_MASK) | F_CRC;
txstate->field_c = 4;
}
return TS_IN_PKT;
case F_CRC:
#ifdef DO_TRACE
__rt_trace("txe-crc ");
#endif
*tx_ch = escape((txstate->crc >> ((txstate->field_c - 1) * 8)) & 0xff,
txstate);
if (txstate->field_c == 0) {
#ifdef DO_TRACE
__rt_trace("txe crc = 0x%x\n", txstate->crc);
#endif
/* move on to the next state */
txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_ETX;
}
return TS_IN_PKT;
}
}
case N_ETX:
#ifdef DO_TRACE
__rt_trace("txe-etx\n");
#endif
txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_IDLE;
*tx_ch = txstate->config->etx;
return TS_DONE_PKT;
default:
#ifdef DEBUG
__rt_info("tx default\n");
#endif
txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_IDLE;
return TS_IDLE;
}
/* stop a silly -Wall warning */
return (te_status)-1;
}
/*
* crc generation occurs in the escape function because it is the only
* place where we know that we're putting a real char into the buffer
* rather than an escaped one.
* We must be careful here not to update the crc when we're sending it
*/
static unsigned char escape(unsigned char ch_in, struct te_state *txstate) {
if (((txstate->tx_state) & E_MASK) == E_ESC) {
/* char has been escaped so send the real char */
#ifdef DO_TRACE
__rt_trace("txe-echar ");
#endif
txstate->tx_state = (txstate->tx_state & ~E_MASK) | E_PLAIN;
txstate->field_c--;
if ((txstate->tx_state & F_MASK) != F_CRC)
txstate->crc = crc32( &ch_in, 1, txstate->crc);
return ch_in | serial_ESCAPE;
}
if ((ch_in < 32) && ((txstate->config->esc_set & (1 << ch_in)) != 0)) {
/* char needs escaping */
#ifdef DO_TRACE
__rt_trace("txe-esc ");
#endif
txstate->tx_state = (txstate->tx_state & ~E_MASK) | E_ESC;
return txstate->config->esc;
}
/* must be a char that can be sent plain */
txstate->field_c--;
if ((txstate->tx_state & F_MASK) != F_CRC)
txstate->crc = crc32(&ch_in, 1, txstate->crc);
return ch_in;
}
/* EOF tx.c */

View File

@ -1,533 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*/
#ifdef __hpux
# define _POSIX_SOURCE 1
#endif
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#ifdef __hpux
# define _TERMIOS_INCLUDED
# include <sys/termio.h>
# undef _TERMIOS_INCLUDED
#else
# include <termios.h>
#endif
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/time.h>
#ifdef sun
# include <sys/ioccom.h>
# ifdef __svr4__
# include <sys/bpp_io.h>
# else
# include <sbusdev/bpp_io.h>
# endif
#endif
#ifdef BSD
# ifdef sun
# include <sys/ttydev.h>
# endif
# ifdef __alpha
# include <sys/ioctl.h>
# else
# include <sys/filio.h>
# endif
#endif
#ifdef __hpux
# define _INCLUDE_HPUX_SOURCE
# include <sys/ioctl.h>
# undef _INCLUDE_HPUX_SOURCE
#endif
#include "host.h"
#include "unixcomm.h"
#define PP_TIMEOUT 1 /* seconds */
#ifdef sun
#define SERPORT1 "/dev/ttya"
#define SERPORT2 "/dev/ttyb"
#define PARPORT1 "/dev/bpp0"
#define PARPORT2 "/dev/bpp1"
#endif
#ifdef __hpux
#define SERPORT1 "/dev/tty00"
#define SERPORT2 "/dev/tty01"
#define PARPORT1 "/dev/ptr_parallel"
#define PARPORT2 "/dev/ptr_parallel"
#endif
#ifdef __linux__
#define SERPORT1 "/dev/cua0"
#define SERPORT2 "/dev/cua1"
#define PARPORT1 "/dev/par0"
#define PARPORT2 "/dev/par1"
#endif
#ifdef _WIN32
#define SERPORT1 "com1"
#define SERPORT2 "com2"
#define PARPORT1 "lpt1"
#define PARPORT2 "lpt2"
#endif
/*
* Parallel port output pins, used for signalling to target
*/
#ifdef sun
struct bpp_pins bp;
#endif
static int serpfd = -1;
static int parpfd = -1;
extern const char *Unix_MatchValidSerialDevice(const char *name)
{
int i=0;
char *sername=NULL;
/* Accept no name as the default serial port */
if (name == NULL) {
return SERPORT1;
}
/* Look for the simple cases - 1,2,s,S,/dev/... first, and
* afterwards look for S=... clauses, which need parsing properly.
*/
/* Accept /dev/tty* where * is limited */
if (strlen(name) == strlen(SERPORT1) && strncmp(name, "/dev/tty", 8) == 0) return name;
/* Accept "1" or "2" or "S" - S is equivalent to "1" */
if (strcmp(name, "1") == 0 ||
strcmp(name, "S") == 0 || strcmp(name, "s") == 0) {
return SERPORT1;
}
if (strcmp(name, "2") == 0) return SERPORT2;
/* It wasn't one of the simple cases, so now we have to parse it
* properly
*/
do {
switch (name[i]) {
case ',':
/* Skip over commas */
i++;
break;
default:
return 0;
/* Unexpected character => error - not matched */
case 0:
/* End of string means return whatever we have matched */
return sername;
case 's':
case 'S':
case 'h':
case 'H': {
char ch = tolower(name[i]);
int j, continue_from, len;
/* If the next character is a comma or a NULL then this is
* a request for the default Serial port
*/
if (name[++i] == 0 || name[i] == ',') {
if (ch=='s')
sername=SERPORT1;
break;
}
/* Next character must be an = */
if (name[i] != '=') return 0;
/* Search for the end of the port spec. (ends in NULL or ,) */
for (j= ++i; name[j] != 0 && name[j] != ','; j++)
; /* Do nothing */
/* Notice whether this is the last thing to parse or not
* and also calaculate the length of the string
*/
if (name[j] == '0') continue_from = -1;
else continue_from = j;
len=(j-i);
/* And now try to match the serial / parallel port */
switch (ch) {
case 's': {
/* Match serial port */
if (len==1) {
if (name[i]=='1')
sername=SERPORT1;
else if (name[i]=='2')
sername=SERPORT2;
} else if (len==strlen(SERPORT1)) {
if (strncmp(name+i,SERPORT1,strlen(SERPORT1)) == 0)
sername=SERPORT1;
else if (strncmp(name+i,SERPORT2,strlen(SERPORT2)) == 0)
sername=SERPORT2;
}
break;
}
case 'h':
/* We don't actually deal with the H case here, we just
* match it and allow it through.
*/
break;
}
if (continue_from == -1) return sername;
i = continue_from;
break;
}
}
} while (1);
return 0;
}
extern int Unix_IsSerialInUse(void)
{
if (serpfd >= 0)
return -1;
return 0;
}
extern int Unix_OpenSerial(const char *name)
{
#if defined(BSD)
serpfd = open(name, O_RDWR);
#else
serpfd = open(name, O_RDWR | O_NONBLOCK);
#endif
if (serpfd < 0) {
perror("open");
return -1;
}
return 0;
}
extern void Unix_CloseSerial(void)
{
if (serpfd >= 0)
{
(void)close(serpfd);
serpfd = -1;
}
}
extern int Unix_ReadSerial(unsigned char *buf, int n, bool block)
{
fd_set fdset;
struct timeval tv;
int err;
FD_ZERO(&fdset);
FD_SET(serpfd, &fdset);
tv.tv_sec = 0;
tv.tv_usec = (block ? 10000 : 0);
err = select(serpfd + 1, &fdset, NULL, NULL, &tv);
if (err < 0 && errno != EINTR)
{
#ifdef DEBUG
perror("select");
#endif
panic("select failure");
return -1;
}
else if (err > 0 && FD_ISSET(serpfd, &fdset))
return read(serpfd, buf, n);
else /* err == 0 || FD_CLR(serpfd, &fdset) */
{
errno = ERRNO_FOR_BLOCKED_IO;
return -1;
}
}
extern int Unix_WriteSerial(unsigned char *buf, int n)
{
return write(serpfd, buf, n);
}
extern void Unix_ResetSerial(void)
{
struct termios terminfo;
tcgetattr(serpfd, &terminfo);
#ifdef __CYGWIN32__
/* Expedient, but it works. */
terminfo.c_iflag = 0;
terminfo.c_oflag = 0;
terminfo.c_cflag = 48;
terminfo.c_lflag = 0;
terminfo.c_cc[VMIN] = 0;
terminfo.c_cc[VTIME] = 1;
#else
terminfo.c_lflag &= ~(ICANON | ISIG | ECHO | IEXTEN);
terminfo.c_iflag &= ~(IGNCR | INPCK | ISTRIP | ICRNL | BRKINT);
terminfo.c_iflag |= (IXON | IXOFF | IGNBRK);
terminfo.c_cflag = (terminfo.c_cflag & ~CSIZE) | CS8 | CREAD;
terminfo.c_cflag &= ~PARENB;
terminfo.c_cc[VMIN] = 1;
terminfo.c_cc[VTIME] = 0;
terminfo.c_oflag &= ~OPOST;
#endif
tcsetattr(serpfd, TCSAFLUSH, &terminfo);
}
extern void Unix_SetSerialBaudRate(int baudrate)
{
struct termios terminfo;
tcgetattr(serpfd, &terminfo);
cfsetospeed(&terminfo, baudrate);
cfsetispeed(&terminfo, baudrate);
tcsetattr(serpfd, TCSAFLUSH, &terminfo);
}
extern void Unix_ioctlNonBlocking(void)
{
#if defined(BSD)
int nonblockingIO = 1;
(void)ioctl(serpfd, FIONBIO, &nonblockingIO);
if (parpfd != -1)
(void)ioctl(parpfd, FIONBIO, &nonblockingIO);
#endif
}
extern void Unix_IsValidParallelDevice(
const char *portstring, char **sername, char **parname)
{
int i=0;
*sername=NULL;
*parname=NULL;
/* Do not recognise a NULL portstring */
if (portstring==NULL) return;
do {
switch (portstring[i]) {
case ',':
/* Skip over commas */
i++;
break;
default:
case 0:
/* End of string or bad characcter means we have finished */
return;
case 's':
case 'S':
case 'p':
case 'P':
case 'h':
case 'H': {
char ch = tolower(portstring[i]);
int j, continue_from, len;
/* If the next character is a comma or a NULL then this is
* a request for the default Serial or Parallel port
*/
if (portstring[++i] == 0 || portstring[i] == ',') {
if (ch=='s') *sername=SERPORT1;
else if (ch=='p') *parname=PARPORT1;
break;
}
/* Next character must be an = */
if (portstring[i] != '=') return;
/* Search for the end of the port spec. (ends in NULL or ,) */
for (j= ++i; portstring[j] != 0 && portstring[j] != ','; j++)
; /* Do nothing */
/* Notice whether this is the last thing to parse or not
* and also calaculate the length of the string
*/
if (portstring[j] == '0') continue_from = -1;
else continue_from = j;
len=(j-i);
/* And now try to match the serial / parallel port */
switch (ch) {
case 's': {
/* Match serial port */
if (len==1) {
if (portstring[i]=='1') *sername=SERPORT1;
else if (portstring[i]=='2') *sername=SERPORT2;
} else if (len==strlen(SERPORT1)) {
if (strncmp(portstring+i,SERPORT1,strlen(SERPORT1)) == 0)
*sername=SERPORT1;
else if (strncmp(portstring+i,SERPORT2,strlen(SERPORT2)) == 0)
*sername=SERPORT2;
}
break;
}
case 'p': {
/* Match parallel port */
if (len==1) {
if (portstring[i]=='1') *parname=PARPORT1;
else if (portstring[i]=='2') *parname=PARPORT2;
} else if (len==strlen(PARPORT1)) {
if (strncmp(portstring+i,PARPORT1,strlen(PARPORT1)) == 0)
*parname=PARPORT1;
else if (strncmp(portstring+i,PARPORT2,strlen(PARPORT2)) == 0)
*parname=PARPORT2;
}
break;
}
case 'h':
/* We don't actually deal with the H case here, we just
* match it and allow it through.
*/
break;
}
if (continue_from == -1) return;
i = continue_from;
break;
}
}
} while (1);
return; /* Will never get here */
}
extern int Unix_IsParallelInUse(void)
{
if (parpfd >= 0)
return -1;
return 0;
}
extern int Unix_OpenParallel(const char *name)
{
#if defined(BSD)
parpfd = open(name, O_RDWR);
#else
parpfd = open(name, O_RDWR | O_NONBLOCK);
#endif
if (parpfd < 0)
{
char errbuf[256];
sprintf(errbuf, "open %s", name);
perror(errbuf);
return -1;
}
return 0;
}
extern void Unix_CloseParallel(void)
{
if (parpfd >= 0)
{
(void)close(parpfd);
parpfd = -1;
}
}
extern unsigned int Unix_WriteParallel(unsigned char *buf, int n)
{
int ngone;
if ((ngone = write(parpfd, buf, n)) < 0)
{
/*
* we ignore errors (except for debug purposes)
*/
#ifdef DEBUG
char errbuf[256];
sprintf(errbuf, "send_packet: write");
perror(errbuf);
#endif
ngone = 0;
}
/* finished */
return (unsigned int)ngone;
}
#ifdef sun
extern void Unix_ResetParallel(void)
{
struct bpp_transfer_parms tp;
#ifdef DEBUG
printf("serpar_reset\n");
#endif
/*
* we need to set the parallel port up for BUSY handshaking,
* and select the timeout
*/
if (ioctl(parpfd, BPPIOC_GETPARMS, &tp) < 0)
{
#ifdef DEBUG
perror("ioctl(BPPIOCGETPARMS)");
#endif
panic("serpar_reset: cannot get BPP parameters");
}
tp.write_handshake = BPP_BUSY_HS;
tp.write_timeout = PP_TIMEOUT;
if (ioctl(parpfd, BPPIOC_SETPARMS, &tp) < 0)
{
#ifdef DEBUG
perror("ioctl(BPPIOC_SETPARMS)");
#endif
panic("serpar_reset: cannot set BPP parameters");
}
}
#else
/* Parallel not supported on HP */
extern void Unix_ResetParallel(void)
{
}
#endif

View File

@ -1,210 +0,0 @@
/*
* Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
*
* This software may be freely used, copied, modified, and distributed
* provided that the above copyright notice is preserved in all copies of the
* software.
*/
/* -*-C-*-
*
*
*/
#ifndef angsd_unixcomm_h
#define angsd_unixcomm_h
#include <errno.h>
#if defined(BSD)
# define ERRNO_FOR_BLOCKED_IO EWOULDBLOCK
#else
# define ERRNO_FOR_BLOCKED_IO EAGAIN
#endif
/*
* Function: Unix_MatchValidSerialDevice
* Purpose: check that the serial driver/port name is valid
* and return the actual device name if it is.
*
* Params:
* Input: name Name of device going to be used
*
* Returns:
* OK: Pointer to name of the device matched
* Error or unrecognised deivce: 0
*/
extern const char *Unix_MatchValidSerialDevice(const char *name);
/*
* Function: Unix_IsSerialInUse
* Purpose: check whether the serial port is in use
*
* Params:
* Input: Nothing
*
* Returns:
* OK: 0 Serial device not in use
* Error: -1 Serial device in use
*/
extern int Unix_IsSerialInUse(void);
/*
* Function: Unix_OpenSerial
* Purpose: open the serial port
*
* Params:
* Input: name Name of device to open
*
* Returns: Unix 'open' returns
*/
extern int Unix_OpenSerial(const char *name);
/*
* Function: Unix_CloseSerial
* Purpose: close the serial port
*
* Params:
* Input: Nothing
*
* Returns: Nothing
*/
extern void Unix_CloseSerial(void);
/*
* Function: Unix_ReadSerial
* Purpose: reads a specified number of bytes (or less) from the serial port
*
* Params:
* Input: buf Buffer to store read bytes
* n Maximum number of bytes to read
*
* Returns: Unix 'read' returns
*/
extern int Unix_ReadSerial(unsigned char *buf, int n, bool block);
/*
* Function: Unix_WriteSerial
* Purpose: writes a specified number of bytes (or less) to the serial port
*
* Params:
* Input: buf Buffer to write bytes from
* n Maximum number of bytes to write
*
* Returns: Unix 'write' returns
*/
extern int Unix_WriteSerial(unsigned char *buf, int n);
/*
* Function: Unix_ResetSerial
* Purpose: resets the serial port for another operation
*
* Params:
* Input: Nothing
*
* Returns: Nothing
*/
extern void Unix_ResetSerial(void);
/*
* Function: Unix_SetSerialBaudRate
* Purpose: check that the serial driver/port name is valid
*
* Params:
* Input: baudrate termios value for baud rate
*
* Returns: Nothing
*/
extern void Unix_SetSerialBaudRate(int baudrate);
/*
* Function: Unix_ioctlNonBlocking
* Purpose: sets the serial port to non-blocking IO
*
* Params:
* Input: Nothing
*
* Returns: Nothing
*/
extern void Unix_ioctlNonBlocking(void);
/*
* Function: Unix_IsValidParallelDevice
* Purpose: check whether the combined serial and parallel device specification
* is ok, and return the ports selected
*
* Params:
* Input: portstring - is a string which specifies which serial
* and parallel ports are to be used. Can
* include s=<val> and p=<val> separated by a
* comma.
*
* Returns:
* Output: *sername - returns the device name of the chosen serial port
* *parname - returns the device name of the chosen parallel port
* If either of these is NULL on return then the match failed.
*/
extern void Unix_IsValidParallelDevice(
const char *portstring, char **sername, char **parname
);
/*
* Function: Unix_IsParallelInUse
* Purpose: check whether the parallel port is in use
*
* Params:
* Input: Nothing
*
* Returns:
* OK: 0 Parallel device not in use
* Error: -1 Parallel device in use
*/
extern int Unix_IsParallelInUse(void);
/*
* Function: Unix_OpenParallel
* Purpose: open the parallel port
*
* Params:
* Input: name Name of device to open
*
* Returns: Unix 'open' returns
*/
extern int Unix_OpenParallel(const char *name);
/*
* Function: Unix_CloseParallel
* Purpose: close the parallel port
*
* Params:
* Input: Nothing
*
* Returns: Nothing
*/
extern void Unix_CloseParallel(void);
/*
* Function: Unix_WriteParallel
* Purpose: writes a specified number of bytes (or less) to the parallel port
*
* Params:
* Input: buf Buffer to write bytes from
* n Maximum number of bytes to write
*
* Returns: Unix 'write' returns
*/
extern unsigned int Unix_WriteParallel(unsigned char *buf, int n);
/*
* Function: Unix_ResetParallel
* Purpose: resets the parallel port for another operation
*
* Params:
* Input: Nothing
*
* Returns: Nothing
*/
extern void Unix_ResetParallel(void);
#endif /* ndef angsd_unixcomm_h */
/* EOF unixcomm.h */

View File

@ -1,159 +0,0 @@
@ignore
This file is completely identical to hsuser.texinfo, except that it has the
reference to the programming manual removed. There are definately better ways
to do this!
This file documents the user interface to the GNU History library.
Copyright (C) 1988, 1991 Free Software Foundation, Inc.
Authored by Brian Fox.
Permission is granted to make and distribute verbatim copies of this manual
provided the copyright notice and this permission notice are preserved on
all copies.
Permission is granted to process this file through Tex and print the
results, provided the printed document carries copying permission notice
identical to this one except for the removal of this paragraph (this
paragraph not being relevant to the printed manual).
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
GNU Copyright statement is available to the distributee, and provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ignore
@node Using History Interactively
@appendix Using History Interactively
This chapter describes how to use the GNU History Library interactively,
from a user's standpoint.
@menu
* History Interaction:: What it feels like using History as a user.
@end menu
@node History Interaction
@section History Interaction
@cindex expansion
The History library provides a history expansion feature similar
to the history expansion in @code{csh}. The following text describes the
syntax you use to manipulate history information.
History expansion takes two parts. In the first part, determine
which line from the previous history will be used for substitution.
This line is called the @dfn{event}.
In the second part, select portions of that line for inclusion into the
current line. These portions are called @dfn{words}.
@value{GDBN} breaks the line into words in the same
way that the Bash shell does, so that several English (or Unix) words
surrounded by quotes are considered one word.
@menu
* Event Designators:: How to specify which history line to use.
* Word Designators:: Specifying which words are of interest.
* Modifiers:: Modifying the results of susbstitution.
@end menu
@node Event Designators
@subsection Event Designators
@cindex event designators
An @dfn{event designator} is a reference to a command line entry in the
history list.
@table @asis
@item @code{!}
Start a history subsititution, except when followed by a space, tab, or
the end of the line... @key{=} or @key{(}.
@item @code{!!}
Refer to the previous command. This is a synonym for @code{!-1}.
@item @code{!n}
Refer to command line @var{n}.
@item @code{!-n}
Refer to the command line @var{n} lines back.
@item @code{!string}
Refer to the most recent command starting with @var{string}.
@item @code{!?string}[@code{?}]
Refer to the most recent command containing @var{string}.
@end table
@node Word Designators
@subsection Word Designators
A @key{:} separates the event designator from the @dfn{word designator}.
It can be omitted if the word designator begins with a @key{^}, @key{$},
@key{*} or @key{%}. Words are numbered from the beginning of the line,
with the first word being denoted by a 0 (zero).
@table @code
@item 0 (zero)
The zero'th word. For many applications, this is the command word.
@item n
The @var{n}'th word.
@item ^
The first argument. that is, word 1.
@item $
The last argument.
@item %
The word matched by the most recent @code{?string?} search.
@item x-y
A range of words; @code{-@var{y}} Abbreviates @code{0-@var{y}}.
@item *
All of the words, excepting the zero'th. This is a synonym for @code{1-$}.
It is not an error to use @key{*} if there is just one word in the event.
The empty string is returned in that case.
@end table
@node Modifiers
@subsection Modifiers
After the optional word designator, you can add a sequence of one or more
of the following @dfn{modifiers}, each preceded by a @key{:}.
@table @code
@item #
The entire command line typed so far. This means the current command,
not the previous command.
@c
@c FIXME: If it doesn't belong here, let's put it where it does.
@c
@c so it technically isn't a word designator and doesn't belong in
@c this section.
@item h
Remove a trailing pathname component, leaving only the head.
@item r
Remove a trailing suffix of the form @samp{.}@var{suffix}, leaving the basename.
@item e
Remove all but the suffix.
@item t
Remove all leading pathname components, leaving the tail.
@item p
Print the new command but do not execute it.
@end table

View File

@ -1,566 +0,0 @@
@ignore
This file documents the end user interface to the GNU command line
editing feautres. It is to be an appendix to manuals for programs which
use these features. There is a document entitled "readline.texinfo"
which contains both end-user and programmer documentation for the GNU
Readline Library.
Copyright (C) 1988 Free Software Foundation, Inc.
Authored by Brian Fox.
Permission is granted to process this file through Tex and print the
results, provided the printed document carries copying permission notice
identical to this one except for the removal of this paragraph (this
paragraph not being relevant to the printed manual).
Permission is granted to make and distribute verbatim copies of this manual
provided the copyright notice and this permission notice are preserved on
all copies.
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
GNU Copyright statement is available to the distributee, and provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ignore
@node Command Line Editing
@appendix Command Line Editing
This text describes GNU's command line editing interface.
@menu
* Introduction and Notation:: Notation used in this text.
* Readline Interaction:: The minimum set of commands for editing a line.
* Readline Init File:: Customizing Readline from a user's view.
@end menu
@node Introduction and Notation
@section Introduction to Line Editing
The following paragraphs describe the notation we use to represent
keystrokes.
The text @key{C-k} is read as `Control-K' and describes the character
produced when the Control key is depressed and the @key{k} key is struck.
The text @key{M-k} is read as `Meta-K' and describes the character
produced when the meta key (if you have one) is depressed, and the @key{k}
key is struck. If you do not have a meta key, the identical keystroke
can be generated by typing @key{ESC} @i{first}, and then typing @key{k}.
Either process is known as @dfn{metafying} the @key{k} key.
The text @key{M-C-k} is read as `Meta-Control-k' and describes the
character produced by @dfn{metafying} @key{C-k}.
In addition, several keys have their own names. Specifically,
@key{DEL}, @key{ESC}, @key{LFD}, @key{SPC}, @key{RET}, and @key{TAB} all
stand for themselves when seen in this text, or in an init file
(@pxref{Readline Init File}, for more info).
@node Readline Interaction
@section Readline Interaction
@cindex interaction, readline
Often during an interactive session you type in a long line of text,
only to notice that the first word on the line is misspelled. The
Readline library gives you a set of commands for manipulating the text
as you type it in, allowing you to just fix your typo, and not forcing
you to retype the majority of the line. Using these editing commands,
you move the cursor to the place that needs correction, and delete or
insert the text of the corrections. Then, when you are satisfied with
the line, you simply press @key{RET}. You do not have to be at the
end of the line to press @key{RET}; the entire line is accepted
regardless of the location of the cursor within the line.
@menu
* Readline Bare Essentials:: The least you need to know about Readline.
* Readline Movement Commands:: Moving about the input line.
* Readline Killing Commands:: How to delete text, and how to get it back!
* Readline Arguments:: Giving numeric arguments to commands.
@end menu
@node Readline Bare Essentials
@subsection Readline Bare Essentials
In order to enter characters into the line, simply type them. The typed
character appears where the cursor was, and then the cursor moves one
space to the right. If you mistype a character, you can use @key{DEL} to
back up, and delete the mistyped character.
Sometimes you may miss typing a character that you wanted to type, and
not notice your error until you have typed several other characters. In
that case, you can type @key{C-b} to move the cursor to the left, and then
correct your mistake. Aftwerwards, you can move the cursor to the right
with @key{C-f}.
When you add text in the middle of a line, you will notice that characters
to the right of the cursor get `pushed over' to make room for the text
that you have inserted. Likewise, when you delete text behind the cursor,
characters to the right of the cursor get `pulled back' to fill in the
blank space created by the removal of the text. A list of the basic bare
essentials for editing the text of an input line follows.
@table @asis
@item @key{C-b}
Move back one character.
@item @key{C-f}
Move forward one character.
@item @key{DEL}
Delete the character to the left of the cursor.
@item @key{C-d}
Delete the character underneath the cursor.
@item @w{Printing characters}
Insert itself into the line at the cursor.
@item @key{C-_}
Undo the last thing that you did. You can undo all the way back to an
empty line.
@end table
@node Readline Movement Commands
@subsection Readline Movement Commands
The above table describes the most basic possible keystrokes that you need
in order to do editing of the input line. For your convenience, many
other commands have been added in addition to @key{C-b}, @key{C-f},
@key{C-d}, and @key{DEL}. Here are some commands for moving more rapidly
about the line.
@table @key
@item C-a
Move to the start of the line.
@item C-e
Move to the end of the line.
@item M-f
Move forward a word.
@item M-b
Move backward a word.
@item C-l
Clear the screen, reprinting the current line at the top.
@end table
Notice how @key{C-f} moves forward a character, while @key{M-f} moves
forward a word. It is a loose convention that control keystrokes
operate on characters while meta keystrokes operate on words.
@node Readline Killing Commands
@subsection Readline Killing Commands
@dfn{Killing} text means to delete the text from the line, but to save
it away for later use, usually by @dfn{yanking} it back into the line.
If the description for a command says that it `kills' text, then you can
be sure that you can get the text back in a different (or the same)
place later.
Here is the list of commands for killing text.
@table @key
@item C-k
Kill the text from the current cursor position to the end of the line.
@item M-d
Kill from the cursor to the end of the current word, or if between
words, to the end of the next word.
@item M-DEL
Kill from the cursor to the start of the previous word, or if between
words, to the start of the previous word.
@item C-w
Kill from the cursor to the previous whitespace. This is different than
@key{M-DEL} because the word boundaries differ.
@end table
And, here is how to @dfn{yank} the text back into the line.
@table @key
@item C-y
Yank the most recently killed text back into the buffer at the cursor.
@item M-y
Rotate the kill-ring, and yank the new top. You can only do this if
the prior command is @key{C-y} or @key{M-y}.
@end table
When you use a kill command, the text is saved in a @dfn{kill-ring}.
Any number of consecutive kills save all of the killed text together, so
that when you yank it back, you get it in one clean sweep. The kill
ring is not line specific; the text that you killed on a previously
typed line is available to be yanked back later, when you are typing
another line.
@node Readline Arguments
@subsection Readline Arguments
You can pass numeric arguments to Readline commands. Sometimes the
argument acts as a repeat count, other times it is the @i{sign} of the
argument that is significant. If you pass a negative argument to a
command which normally acts in a forward direction, that command will
act in a backward direction. For example, to kill text back to the
start of the line, you might type @key{M--} @key{C-k}.
The general way to pass numeric arguments to a command is to type meta
digits before the command. If the first `digit' you type is a minus
sign (@key{-}), then the sign of the argument will be negative. Once
you have typed one meta digit to get the argument started, you can type
the remainder of the digits, and then the command. For example, to give
the @key{C-d} command an argument of 10, you could type @key{M-1 0 C-d}.
@node Readline Init File
@section Readline Init File
Although the Readline library comes with a set of @sc{gnu} Emacs-like
keybindings, it is possible that you would like to use a different set
of keybindings. You can customize programs that use Readline by putting
commands in an @dfn{init} file in your home directory. The name of this
file is @file{~/.inputrc}.
When a program which uses the Readline library starts up, the
@file{~/.inputrc} file is read, and the keybindings are set.
In addition, the @key{C-x C-r} command re-reads this init file, thus
incorporating any changes that you might have made to it.
@menu
* Readline Init Syntax:: Syntax for the commands in @file{~/.inputrc}.
* Readline vi Mode:: Switching to @code{vi} mode in Readline.
@end menu
@node Readline Init Syntax
@subsection Readline Init Syntax
There are only four constructs allowed in the @file{~/.inputrc}
file:
@table @asis
@item Variable Settings
You can change the state of a few variables in Readline. You do this by
using the @code{set} command within the init file. Here is how you
would specify that you wish to use @code{vi} line editing commands:
@example
set editing-mode vi
@end example
Right now, there are only a few variables which can be set; so few in
fact, that we just iterate them here:
@table @code
@item editing-mode
@vindex editing-mode
The @code{editing-mode} variable controls which editing mode you are
using. By default, @sc{gnu} Readline starts up in Emacs editing mode, where
the keystrokes are most similar to Emacs. This variable can either be
set to @code{emacs} or @code{vi}.
@item horizontal-scroll-mode
@vindex horizontal-scroll-mode
This variable can either be set to @code{On} or @code{Off}. Setting it
to @code{On} means that the text of the lines that you edit will scroll
horizontally on a single screen line when they are larger than the width
of the screen, instead of wrapping onto a new screen line. By default,
this variable is set to @code{Off}.
@item mark-modified-lines
@vindex mark-modified-lines
This variable when set to @code{On}, says to display an asterisk
(@samp{*}) at the starts of history lines which have been modified.
This variable is off by default.
@item prefer-visible-bell
@vindex prefer-visible-bell
If this variable is set to @code{On} it means to use a visible bell if
one is available, rather than simply ringing the terminal bell. By
default, the value is @code{Off}.
@end table
@item Key Bindings
The syntax for controlling keybindings in the @file{~/.inputrc} file is
simple. First you have to know the @i{name} of the command that you
want to change. The following pages contain tables of the command name,
the default keybinding, and a short description of what the command
does.
Once you know the name of the command, simply place the name of the key
you wish to bind the command to, a colon, and then the name of the
command on a line in the @file{~/.inputrc} file. The name of the key
can be expressed in different ways, depending on which is most
comfortable for you.
@table @asis
@item @w{@var{keyname}: @var{function-name} or @var{macro}}
@var{keyname} is the name of a key spelled out in English. For example:
@example
Control-u: universal-argument
Meta-Rubout: backward-kill-word
Control-o: ">&output"
@end example
In the above example, @key{C-u} is bound to the function
@code{universal-argument}, and @key{C-o} is bound to run the macro
expressed on the right hand side (that is, to insert the text
@samp{>&output} into the line).
@item @w{"@var{keyseq}": @var{function-name} or @var{macro}}
@var{keyseq} differs from @var{keyname} above in that strings denoting
an entire key sequence can be specified. Simply place the key sequence
in double quotes. @sc{gnu} Emacs style key escapes can be used, as in the
following example:
@example
"\C-u": universal-argument
"\C-x\C-r": re-read-init-file
"\e[11~": "Function Key 1"
@end example
In the above example, @key{C-u} is bound to the function
@code{universal-argument} (just as it was in the first example),
@key{C-x C-r} is bound to the function @code{re-read-init-file}, and
@key{ESC [ 1 1 ~} is bound to insert the text @samp{Function Key 1}.
@end table
@end table
@menu
* Commands For Moving:: Moving about the line.
* Commands For History:: Getting at previous lines.
* Commands For Text:: Commands for changing text.
* Commands For Killing:: Commands for killing and yanking.
* Numeric Arguments:: Specifying numeric arguments, repeat counts.
* Commands For Completion:: Getting Readline to do the typing for you.
* Miscellaneous Commands:: Other miscillaneous commands.
@end menu
@need 2000
@node Commands For Moving
@subsubsection Commands For Moving
@ftable @code
@item beginning-of-line (@key{C-a})
Move to the start of the current line.
@item end-of-line (@key{C-e})
Move to the end of the line.
@item forward-char (@key{C-f})
Move forward a character.
@item backward-char (@key{C-b})
Move back a character.
@item forward-word (@key{M-f})
Move forward to the end of the next word.
@item backward-word (@key{M-b})
Move back to the start of this, or the previous, word.
@item clear-screen (@key{C-l})
Clear the screen leaving the current line at the top of the screen.
@end ftable
@need 2000
@node Commands For History
@subsubsection Commands For Manipulating The History
@ftable @code
@item accept-line (Newline, Return)
Accept the line regardless of where the cursor is. If this line is
non-empty, add it to the history list. If this line was a history
line, then restore the history line to its original state.
@item previous-history (@key{C-p})
Move `up' through the history list.
@item next-history (@key{C-n})
Move `down' through the history list.
@item beginning-of-history (@key{M-<})
Move to the first line in the history.
@item end-of-history (@key{M->})
Move to the end of the input history, i.e., the line you are entering.
@item reverse-search-history (@key{C-r})
Search backward starting at the current line and moving `up' through
the history as necessary. This is an incremental search.
@item forward-search-history (@key{C-s})
Search forward starting at the current line and moving `down' through
the the history as necessary.
@end ftable
@need 2000
@node Commands For Text
@subsubsection Commands For Changing Text
@ftable @code
@item delete-char (@key{C-d})
Delete the character under the cursor. If the cursor is at the
beginning of the line, and there are no characters in the line, and
the last character typed was not @key{C-d}, then return EOF.
@item backward-delete-char (Rubout)
Delete the character behind the cursor. A numeric argument says to kill
the characters instead of deleting them.
@item quoted-insert (@key{C-q}, @key{C-v})
Add the next character that you type to the line verbatim. This is
how to insert things like @key{C-q} for example.
@item tab-insert (@key{M-TAB})
Insert a tab character.
@item self-insert (a, b, A, 1, !, ...)
Insert yourself.
@item transpose-chars (@key{C-t})
Drag the character before point forward over the character at point.
Point moves forward as well. If point is at the end of the line, then
transpose the two characters before point. Negative arguments don't work.
@item transpose-words (@key{M-t})
Drag the word behind the cursor past the word in front of the cursor
moving the cursor over that word as well.
@item upcase-word (@key{M-u})
Uppercase all letters in the current (or following) word. With a
negative argument, do the previous word, but do not move point.
@item downcase-word (@key{M-l})
Lowercase all letters in the current (or following) word. With a
negative argument, do the previous word, but do not move point.
@item capitalize-word (@key{M-c})
Uppercase the first letter in the current (or following) word. With a
negative argument, do the previous word, but do not move point.
@end ftable
@need 2000
@node Commands For Killing
@subsubsection Killing And Yanking
@ftable @code
@item kill-line (@key{C-k})
Kill the text from the current cursor position to the end of the line.
@item backward-kill-line ()
Kill backward to the beginning of the line. This is normally unbound.
@item kill-word (@key{M-d})
Kill from the cursor to the end of the current word, or if between
words, to the end of the next word.
@item backward-kill-word (@key{M-DEL})
Kill the word behind the cursor.
@item unix-line-discard (@key{C-u})
Kill the whole line the way @key{C-u} used to in Unix line input.
The killed text is saved on the kill-ring.
@item unix-word-rubout (@key{C-w})
Kill the word the way @key{C-w} used to in Unix line input.
The killed text is saved on the kill-ring. This is different than
backward-kill-word because the word boundaries differ.
@item yank (@key{C-y})
Yank the top of the kill ring into the buffer at point.
@item yank-pop (@key{M-y})
Rotate the kill-ring, and yank the new top. You can only do this if
the prior command is yank or yank-pop.
@end ftable
@need 2000
@node Numeric Arguments
@subsubsection Specifying Numeric Arguments
@ftable @code
@item digit-argument (@key{M-0}, @key{M-1}, ... @key{M--})
Add this digit to the argument already accumulating, or start a new
argument. @key{M--} starts a negative argument.
@item universal-argument ()
Do what @key{C-u} does in @sc{gnu} Emacs. By default, this is not bound.
@end ftable
@need 2000
@node Commands For Completion
@subsubsection Letting Readline Type For You
@ftable @code
@item complete (TAB)
Attempt to do completion on the text before point. This is
implementation defined. Generally, if you are typing a filename
argument, you can do filename completion; if you are typing a command,
you can do command completion, if you are typing in a symbol to GDB, you
can do symbol name completion, if you are typing in a variable to Bash,
you can do variable name completion.
@item possible-completions (M-?)
List the possible completions of the text before point.
@end ftable
@need 2000
@node Miscellaneous Commands
@subsubsection Some Miscellaneous Commands
@ftable @code
@item re-read-init-file (@key{C-x} @key{C-r})
Read in the contents of your @file{~/.inputrc} file, and incorporate
any bindings found there.
@item abort (@key{C-g})
Stop running the current editing command.
@ignore
@c I have no idea what this means, and can't figure it out by
@c experiment, and can't find it in the readline source.
@c doc@cygnus.com, 20may1993.
@item do-uppercase-version (@key{M-a}, @key{M-b}, ...)
Run the command that is bound to your uppercase brother.
@end ignore
@item prefix-meta (ESC)
Make the next character that you type be metafied. This is for people
without a meta key. Typing @key{ESC f} is equivalent to typing
@key{M-f}.
@item undo (@key{C-_})
Incremental undo, separately remembered for each line.
@item revert-line (@key{M-r})
Undo all changes made to this line. This is like typing the `undo'
command enough times to get back to the beginning.
@end ftable
@need 2000
@node Readline vi Mode
@subsection Readline @code{vi} Mode
@cindex @code{vi} style command editing
@kindex toggle-editing-mode
While the Readline library does not have a full set of @code{vi} editing
functions, it does contain enough to allow simple editing of the line.
In order to switch interactively between @sc{gnu} Emacs and @code{vi}
editing modes, use the command @key{M-C-j} (toggle-editing-mode).
When you enter a line in @code{vi} mode, you are already placed in `insertion'
mode, as if you had typed an `i'. Pressing @key{ESC} switches you into
`edit' mode, where you can edit the text of the line with the standard
@code{vi} movement keys, move to previous history lines with `k', and following
lines with `j', and so forth.