TeledebugImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
This is an initial, ugly, ugly, implementation.
Forrest September 17, 1980 2:27 PM
Birrell, October 31, 1983 12:13 pm
Russ Atkinson, February 20, 1985 6:32:33 pm PST
DIRECTORY
Basics USING [ LongDivMod ],
BootFile USING [GetPageValue, IsVacant, SetPageValue],
GermPrivate USING[ Error ],
MiniEthernetDefs USING [ActivateDriver, KillDriver, RecvPacket, ReturnPacket],
MPCodes USING [germDeviceError, germTeledebugServer],
PrincOps USING [flagsVacant, PageNumber, PageValue, wordsPerPage],
PrincOpsUtils USING [AddressForPageNumber, BITAND, LongCopy, LowHalf],
ProcessorFace USING [SetMP],
PupTypes USING [Pair, PupAddress, PupType],
SA4000Face USING [Command, GetDeviceAttributes, GetNextDevice, globalStateSize, Initialize, Initiate, nullDeviceHandle, Operation, operationSize, Poll],
TeledebugProtocol USING [acknowledgement, CoreFetchAcknowledgement, coreFetchAcknowledgementSize, CoreFetchRequest, coreFetchRequest, CoreStoreAcknowledgement, coreStoreAcknowledgementSize, CoreStoreRequest, coreStoreRequest, DiskAddressSetAcknowledgement, DiskAddressSetRequest, diskAddressSetRequest, DiskFetchAcknowledgement, diskFetchAcknowledgementSize, diskFetchRequest, DiskStoreAcknowledgement, diskStoreAcknowledgementSize, DiskStoreRequest, diskStoreRequest, go, goReply, Label, teleSwatSocket];
TeledebugImpl: PROGRAM
IMPORTS Basics, BootFile, GermPrivate, MiniEthernetDefs, PrincOpsUtils, ProcessorFace, SA4000Face
EXPORTS GermPrivate--TeleDebug-- = {
Ethernet buffer. This is merely storage for MiniDriver
bufSize: CARDINAL = 300;
fudge: CARDINAL = 30;
eBuff: ARRAY [0..bufSize + fudge + 3) OF WORD;
eBuffer: POINTER = LOOPHOLE[PrincOpsUtils.BITAND[LOOPHOLE[@eBuff + 3], 177774B]];
etherIOCBSize: CARDINAL = 30;
"Locals" to Debug and RunDisk
MyPup: TYPE = RECORD [
SELECT OVERLAID * FROM
a => [coreStoreRequest: TeledebugProtocol.CoreStoreRequest],
b => [coreStoreAcknowledgement: TeledebugProtocol.CoreStoreAcknowledgement],
c => [coreFetchRequest: TeledebugProtocol.CoreFetchRequest],
d => [coreFetchAcknowledgement: TeledebugProtocol.CoreFetchAcknowledgement],
e => [diskStoreRequest: TeledebugProtocol.DiskStoreRequest],
f => [diskStoreAcknowledgement: TeledebugProtocol.DiskStoreAcknowledgement],
g => [diskFetchAcknowledgement: TeledebugProtocol.DiskFetchAcknowledgement],
h => [diskAddressSetRequest: TeledebugProtocol.DiskAddressSetRequest],
i => [diskAddressSetAcknowledgement:
TeledebugProtocol.DiskAddressSetAcknowledgement],
ENDCASE];
diskAddressPup: TeledebugProtocol.DiskAddressSetRequest;
bytes: INTEGER;
id: PupTypes.Pair;
pAllocateNext: LONG POINTER; -- iocb's and stuff in first 64K
pup: MyPup;
sa4000IOCB: LONG POINTER TO SA4000Face.Operation;
sender: PupTypes.PupAddress;
temp: CARDINAL;
type: PupTypes.PupType;
TeleDebug: PUBLIC PROC [scratchPage: PrincOps.PageNumber, dFirst64KStorage: LONG DESCRIPTOR FOR ARRAY OF WORD] = {
Allocate: PROC [size: CARDINAL] RETURNS [lp: LONG POINTER] = {
pAllocateNext ← (lp ← pAllocateNext) + LONG[((size + 15)/16)*16];
};
LongTime: PROC RETURNS [BOOL] = {RETURN[FALSE]};
SetNoLabel: PROC [p: LONG POINTER] = {
p^ ← -1;
PrincOpsUtils.LongCopy[from: p, to: p + 1, nwords: SIZE[TeledebugProtocol.Label] - 1];
};
pAllocateNext ← BASE[dFirst64KStorage]; -- reset first 64K allocator
SA4000Face.Initialize[0,
LOOPHOLE[PrincOpsUtils.LowHalf[Allocate[SA4000Face.globalStateSize]]]];
sa4000IOCB ← Allocate[SA4000Face.operationSize];
IF ~MiniEthernetDefs.ActivateDriver[
eBuffer, bufSize, Allocate[etherIOCBSize], TRUE] THEN
GermPrivate.Error[MPCodes.germDeviceError];
ProcessorFace.SetMP[MPCodes.germTeledebugServer];
DO
sender ← [[0], [0], [0, 0]]; -- talk to anybody
[bytes, id, type] ← MiniEthernetDefs.RecvPacket[
@sender, TeledebugProtocol.teleSwatSocket, @pup, SIZE[MyPup], LongTime];
SELECT type FROM
TeledebugProtocol.coreFetchRequest => {
OPEN p: pup.coreFetchAcknowledgement;
pPage: PrincOps.PageNumber = p.page;
IF bytes # (2*SIZE[TeledebugProtocol.CoreFetchRequest]) THEN LOOP;
IF ~BootFile.IsVacant[pPage] THEN {
pv: PrincOps.PageValue ← BootFile.GetPageValue[pPage];
p.flags ← LOOPHOLE[pv.state.flags];
PrincOpsUtils.LongCopy[
from: PrincOpsUtils.AddressForPageNumber[pPage], to: @p.data, nwords: PrincOps.wordsPerPage];
BootFile.SetPageValue[pPage, pv];
}
ELSE p.flags ← LOOPHOLE[PrincOps.flagsVacant];
bytes ← 2*TeledebugProtocol.coreFetchAcknowledgementSize;
};
TeledebugProtocol.coreStoreRequest => {
OPEN p: pup.coreStoreRequest;
pPage: PrincOps.PageNumber = p.page;
IF bytes # (2*SIZE[TeledebugProtocol.CoreStoreRequest]) THEN LOOP;
IF ~BootFile.IsVacant[pPage] THEN {
v: PrincOps.PageValue ← BootFile.GetPageValue[pPage];
v.state.flags.readonly ← FALSE;
BootFile.SetPageValue[pPage, v];
PrincOpsUtils.LongCopy[
to: PrincOpsUtils.AddressForPageNumber[pPage], from: @p.data, nwords: PrincOps.wordsPerPage];
v.state.flags ← LOOPHOLE[p.flags];
BootFile.SetPageValue[pPage, v];
}
ELSE p.flags ← LOOPHOLE[PrincOps.flagsVacant];
bytes ← 2*TeledebugProtocol.coreStoreAcknowledgementSize;
};
TeledebugProtocol.diskAddressSetRequest => {
IF bytes # (2*SIZE[TeledebugProtocol.DiskAddressSetRequest]) THEN LOOP;
PrincOpsUtils.LongCopy[ -- just save it.
to: @diskAddressPup, from: @pup.diskAddressSetRequest,
nwords: SIZE[TeledebugProtocol.DiskAddressSetRequest]];
};
TeledebugProtocol.diskFetchRequest => {
OPEN p: pup.diskFetchAcknowledgement;
SELECT bytes FROM
0 => NULL;
2*SIZE[TeledebugProtocol.DiskAddressSetRequest] =>
PrincOpsUtils.LongCopy[ -- save disk address request.
to: @diskAddressPup, from: @pup.diskAddressSetRequest,
nwords: SIZE[TeledebugProtocol.DiskAddressSetRequest]];
ENDCASE => LOOP; -- illegal request
IF ~RunDisk[vrr, scratchPage, @p.label, @p.data] THEN SetNoLabel[@p.label];
bytes ← 2*TeledebugProtocol.diskFetchAcknowledgementSize;
};
TeledebugProtocol.diskStoreRequest => {
OPEN p: pup.diskStoreRequest;
IF bytes # (2*SIZE[TeledebugProtocol.DiskStoreRequest]) THEN LOOP;
IF ~RunDisk[vvw, scratchPage, @p.label, @p.data] THEN
SetNoLabel[@pup.diskStoreAcknowledgement.label];
bytes ← 2*TeledebugProtocol.diskStoreAcknowledgementSize;
};
TeledebugProtocol.go => {
GoConfirm: PROC RETURNS [BOOL] = INLINE {
tenSecondsCount: CARDINAL = LAST[CARDINAL];
MiniEthernetDefs.ReturnPacket[TeledebugProtocol.acknowledgement, @pup, 0];
temp ← tenSecondsCount;
[bytes, id, type] ← MiniEthernetDefs.RecvPacket[
@sender, TeledebugProtocol.teleSwatSocket, @pup, SIZE[MyPup], TenSeconds];
also check id??? (what to do if wrong)
RETURN[bytes = -1 OR type = TeledebugProtocol.goReply];
};
TenSeconds: PROC RETURNS [BOOL] = {RETURN[(temp ← temp - 1) = 0]};
IF bytes = 0 AND GoConfirm[] THEN {MiniEthernetDefs.KillDriver[]; RETURN}
ELSE LOOP; -- unexpected respose; ignore
};
ENDCASE => LOOP;
Send ack
MiniEthernetDefs.ReturnPacket[TeledebugProtocol.acknowledgement, @pup, bytes];
ENDLOOP;
};
RunDisk: PROC [c: SA4000Face.Command, scratchPage: PrincOps.PageNumber, labelP, dataP: POINTER] RETURNS [BOOL] = {
OPEN o: sa4000IOCB, SA4000Face;
IF diskAddressPup.device # sa4000 THEN RETURN[FALSE];
o.device ← nullDeviceHandle;
THROUGH [0..diskAddressPup.deviceOrdinal] DO
IF (o.device ← GetNextDevice[o.device]) = nullDeviceHandle THEN RETURN[FALSE];
ENDLOOP;
[quotient: temp, remainder: o.clientHeader.sector] ← Basics.LongDivMod[
num: diskAddressPup.page, den: GetDeviceAttributes[o.device].sectorsPerTrack];
o.clientHeader.head ← temp MOD GetDeviceAttributes[o.device].movingHeads;
o.clientHeader.cylinder ← temp/GetDeviceAttributes[o.device].movingHeads;
o.labelPtr ← labelP; o.dataPtr ← PrincOpsUtils.AddressForPageNumber[scratchPage];
o.incrementDataPtr ← FALSE; o.command ← c; o.pageCount ← 1;
IF c = vvw THEN
PrincOpsUtils.LongCopy[from: LONG[dataP], to: o.dataPtr, nwords: PrincOps.wordsPerPage];
THROUGH [0..8) DO
SA4000Face.Initiate[sa4000IOCB];
DO
SELECT SA4000Face.Poll[sa4000IOCB] FROM
inProgress => LOOP;
goodCompletion => {
IF c = vrr THEN PrincOpsUtils.LongCopy[
to: LONG[dataP], from: o.dataPtr, nwords: PrincOps.wordsPerPage];
RETURN[TRUE];
};
ENDCASE --ERROR-- => EXIT;
ENDLOOP;
ENDLOOP;
RETURN[FALSE];
};
}.
LOG
Time: March 21, 1980 6:58 PM By: Forrest Action: Create file
Time: March 24, 1980 11:45 AM By: Forrest Action: initialize sender, fix maxVirtualPages
Time: April 1, 1980 2:53 PM By: Forrest Action: Add Disk Implementation
Time: April 7, 1980 7:11 PM By: Forrest Action: Added SetDiskAddress+Fetch enhancement
Time: April 10, 1980 12:19 PM By: Forrest Action: RCPProtocol => TeledebugProtocol
Time: April 22, 1980 5:41 PM By: McJones Action: Add avoidCleanup: TRUE to ActivateDriver call
Time: June 25, 1980 4:21 PM By: McJones Action: OISDisk=>PilotDisk; OISProcessorFace=>ProcessorFace; SA4000Face.Operation: clientLabel+diskLabel=>labelPtr
Time: September 17, 1980 12:45 PM By: Forrest Action: change to use returnPacket; zero socket each trip around loop; use GetF, Utilities.LongPointerFromPage
Time: May 24, 1983 12:06 pm By: Andrew Birrell Action: Fixed IsVacant for out-of-bounds pages