Mach.mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Bob Hagmann October 7, 1988 2:22:19 pm PDT
This interface is to Mach.
DIRECTORY
Rope;
Mach: CEDAR DEFINITIONS
~ BEGIN
Kernel error
MachCall: SIGNAL [errorCode: msgReturnT, explanation: Rope.ROPE];
MachAnomaly: SIGNAL [explanation: Rope.ROPE];
Kernel return codes
kernReturnT: TYPE = INT32;
KernSuccess: INT = 0;
KernInvalidAddress: INT = 1;
KernProtectionFailure: INT = 2;
KernNoSpace: INT = 3;
KernInvalidArgument: INT = 4;
KernFailure: INT = 5;
KernResourceShortage: INT = 6;
KernNotReceiver: INT = 7;
KernNoAccess: INT = 8;
Message data types
MsgSizeMax: INT = 8192;
msgSizeT: TYPE = CARD32;
msgOptionT: TYPE = CARD32;
msgHeaderT: TYPE = MACHINE DEPENDENT RECORD [
filler24(0:0..23): CARD [0..2**24) ← 0,
msgSimple(0:24..31): BYTE ← 0,
msgSize(1): msgSizeT,
msgType(2): INT,
msgLocalPort(3): portT,
msgRemotePort(4): portT,
msgId(5): INT
];
msgTypeT: TYPE = MACHINE DEPENDENT RECORD [
msgTypeName(0:0..7): BYTE ← 0,
msgTypeSize(0:8..15): BYTE ← 0,
msgTypeNumber(0:16..27): CARD [0..2**12) ← 0,
msgTypeInline(0:28..28): BOOL ← FALSE,
msgTypeLongform(0:29..29): BOOL ← FALSE,
msgTypeDeallocate(0:30..30): BOOL ← FALSE,
msgTypeFiller1(0:31..31): BOOL ← FALSE
];
msgTypeLongT: TYPE = MACHINE DEPENDENT RECORD [
msgTypeHeader(0): msgTypeT,
msgTypeLongName(1:0..15): CARD16,
msgTypeLongSize(1:16..31): CARD16,
msgTypeLongNumber(2): CARD32
];
notificationT: TYPE = MACHINE DEPENDENT RECORD [
notifyHeader(0): msgHeaderT,
notifyType(6): msgTypeT,
notifyPort(7): portT
];
deathPillT: TYPE = MACHINE DEPENDENT RECORD [
Head(0): msgHeaderT,
RetCodeType(6): msgTypeT,
RetCode(7): kernReturnT
];
msgReturnT: TYPE = INT;
Known values for the msg←type←name field. The only types known to the Mach kernel are the port types, and those types used in the kernel RPC interface.
MsgTypeUnstructured: INT = 0;
MsgTypeBit: INT =  0;
MsgTypeBoolean: INT = 0;
MsgTypeInteger16: INT = 1;
MsgTypeInteger32: INT = 2;
MsgTypePortOwnership: INT = 3;
MsgTypePortReceive: INT = 4;
MsgTypePortAll: INT = 5;
MsgTypePort: INT =  6;
MsgTypeChar: INT =  8;
MsgTypeByte: INT =  9;
MsgTypeInteger8: INT = 9;
MsgTypeReal: INT =  10;
MsgTypeString: INT =  12;
MsgTypeStringC: INT = 12;
MsgTypeInvalid: INT = 13;  -- Used by the kernel to mark invalid data
Options to IPC primitives. These can be combined by or'ing; the combination RPC call uses both SEND← and RCV← options at once.
MsgOptionNone: INT = 0000H;  -- Terminate only when message op works
SendTimeout: INT =  0001H;  -- Terminate on timeout elapsed
SendNotify: INT =  0002H;  -- Terminate with reply message if need be
SendInterrupt: INT = 0004H;  -- Terminate on software interrupt
SendAlways: INT =  0008H;  -- KERNEL only: never block
SendKernel: INT =  0010H;  -- KERNEL only: kernel is originator
RcvTimeout: INT =  0100H;  -- Terminate on timeout elapsed
RcvNoSenders: INT = 0200H;  -- Terminate if I'm the only sender left
RcvInterrupt: INT =  0400H;  -- Terminate on software interrupt
Send codes.
SendSuccess: INT = 0;
SendErrorsStart: INT = -100;
SendInvalidMemory: INT = -101;  -- Message structure or out-of-line data invalid
SendInvalidPort: INT = -102;  -- Reference to inacessible port
SendTimedOut: INT =  -103;  -- Terminated due to timeout
SendWillNotify: INT = -105;  -- Last message accepted until notification sent
SendNotifyInProgress: INT = -106;  -- Already awaiting a notification
SendKernelRefused: INT = -107;  -- Message to the kernel refused
SendInterrupted: INT = -108;  -- Software interrupt during send
SendMsgTooLarge: INT = -109;  -- Message specified was too large
SendMsgTooSmall: INT = -110;  -- Data specified exceeds message size
SendMsgSizeChange: INT = -111;  -- Message size changed while being copied
RcvErrorsStart: INT = -200;
RcvInvalidMemory: INT = -201;
RCVInvalidPort: INT = -202;
RcvTimedOut: INT =  -203;
RcvTooLarge: INT =  -204;  -- Message structure too small to hold data
RcvNotEnoughMemory: INT = -205;  -- Unable to find address space to put out-of-line data
RcvOnlySender: INT =  -206;  -- Receiver/owner are only remaining senders
RcvInterrupted: INT =  -207;
RcvPortChange: INT =  -208;  -- Port receiver changed, or port became enabled
NotifyFirst: INT =   0100B;
NotifyPortDeleted: INT =   NotifyFirst + 001;
NotifyMsgAccepted: INT =  NotifyFirst + 002;
NotifyOwnershipRights: INT =  NotifyFirst + 003;
NotifyReceiveRights: INT =  NotifyFirst + 004;
NotifyLast: INT =   NotifyFirst + 015B;
MigTypeError: INT =  -300;  -- Type check failure
MigReplyMismatch: INT = -301;  -- Wrong return message ID
MigRemoteError: INT = -302;  -- Server detected error
MigBadId: INT =  -303;  -- Bad message ID
MigBadArguments: INT = -304;  -- Server found wrong arguments
MigNoReply: INT =  -305;  -- Server shouldn't reply
MigException: INT =  -306;  -- Server raised exception
MigArrayTooLarge: INT = -307;  -- User specified array not large enough to hold returned array
Common data types
portT: TYPE = RECORD [portNumber: INT32];
portArrayT: TYPE = POINTER TO portT;
ListOfPorts: TYPE = LIST OF portT;
taskT: TYPE = portT;
vmTaskT: TYPE = taskT;
threadT: TYPE = portT;
vmOffsetT: TYPE = CARD32;
vmSizeT: TYPE = CARD32;
vmAddressT: TYPE = vmOffsetT;
pointerT: TYPE = vmOffsetT;
pagingObjectT: TYPE = portT;
caddrT: TYPE = POINTER TO CHAR;
netnameNameT: TYPE = ARRAY[0..80) OF CHAR;
Some port constants
PortNull: portT = [0];
PortEnabled: portT = [-1];
PortDefault: portT = [-1];
PortInvalid: portT = [-2];
MachPortsSlotsUsed: INT = 3;
Tasks
taskSelf: PROC RETURNS [targetTask: taskT];
get my task (task←self and current←task)
taskNotify: PROC RETURNS [notifyPort: portT];
get my notify port (task←notify)
taskData: PROC RETURNS [dataPort: portT];
get my data port (task�ta)
Virtual Memory
vmAllocate: PROC [targetTask: vmTaskT, address: vmAddressT, size: vmSizeT, anywhere: BOOL, raiseSignal: BOOL] RETURNS [mappedAddress: vmAddressT, kernCode: kernReturnT];
Grab some VM.
vmAllocateWithPager: PROC [targetTask: vmTaskT, address: vmAddressT, size: vmSizeT, anywhere: BOOL, pagingObject: pagingObjectT, offset: vmOffsetT, raiseSignal: BOOL] RETURNS [mappedAddress: vmAddressT, kernCode: kernReturnT];
Map some externally backed memory into VM.
vmDeallocate: PROC [targetTask: vmTaskT, address: vmAddressT, size: vmSizeT, raiseSignal: BOOL] RETURNS [kernCode: kernReturnT];
Unmap some externally backed memory into VM, whether externally backed or not.
Messages
msgSend: PROC [header: REF msgHeaderT, option: msgOptionT, timeout: INT, raiseSignal: BOOL] RETURNS [msgCode: msgReturnT];
send a message
msgReceive: PROC [header: REF msgHeaderT, option: msgOptionT, timeout: INT, raiseSignal: BOOL] RETURNS [msgCode: msgReturnT];
Receive a message.
Modifies the header!
msgRPC: PROC [header: REF msgHeaderT, option: msgOptionT, rcvSize: INT, sendTimeout: INT, rcvTimeout: INT, raiseSignal: BOOL] RETURNS [msgCode: msgReturnT];
"Hybrid call which performs a msgSend followed by a msgReceive, using the same message buffer."
Ports
nameServerPort: PROC RETURNS [portT];
get my port to the name server (name←server←port)
environmentPort: PROC RETURNS [portT];
get my port to the environment (environment←port)
servicePort: PROC RETURNS [portT];
get my port to the service port (service←port)
MachPortsLookup: PROC [targetTask: taskT, raiseSignal: BOOL] RETURNS [intPortSet: portArrayT, intPortArrayCount: INT, kernCode: kernReturnT];
Lookup the list of well known ports
portAllocate: PROC [targetTask: taskT, raiseSignal: BOOL] RETURNS [newPort: portT, kernCode: kernReturnT];
"causes a port to be created for the specified taks"
portDeallocate: PROC [targetTask: taskT, localPort: portT, raiseSignal: BOOL] RETURNS [kernCode: kernReturnT];
"requests that the target task's access to a port be relinquished"
portRestrict: PROC [targetTask: taskT, port: portT, raiseSignal: BOOL] RETURNS [kernCode: kernReturnT];
restricts port so that msgReceive must be used the port number, not PortDefault
portUnrestrict: PROC [targetTask: taskT, port: portT, raiseSignal: BOOL] RETURNS [kernCode: kernReturnT];
unrestricts port so that PortDefault to msgReceive can receive from this port
portMessages: PROC [targetTask: taskT, ports: portArrayT, portsCount: POINTER TO INT, raiseSignal: BOOL] RETURNS [kernCode: kernReturnT];
unrestricts port so that PortDefault to msgReceive can receive from this port
portStatus: PROC [targetTask: taskT, myPort: portT, raiseSignal: BOOL] RETURNS [unrestricted: BOOL, numMsgs: INT, backlog: INT, owner: BOOL, receiver: BOOL, kernCode: kernReturnT];
unrestricts port so that PortDefault to msgReceive can receive from this port
portSetBacklog: PROC [targetTask: taskT, myPort: portT, backlog: INT, raiseSignal: BOOL] RETURNS [kernCode: kernReturnT];
unrestricts port so that PortDefault to msgReceive can receive from this port
Netname
netnameCheckIn: PROC [ServPort: portT, portName: Rope.ROPE, signature: portT, portId: portT, raiseSignal: BOOL] RETURNS [kernCode: kernReturnT];
"check in a name into the local name space"
netnameLookUp: PROC [ServPort: portT, hostName: Rope.ROPE, portName: Rope.ROPE, raiseSignal: BOOL] RETURNS [portId: portT, kernCode: kernReturnT];
"check in a name into the local name space"
netnameCheckOut: PROC [ServPort: portT, portName: Rope.ROPE, signature: portT, raiseSignal: BOOL] RETURNS [kernCode: kernReturnT];
"check in a name into the local name space"
END.