Wart.mesa
last edited by Levin on December 15, 1983 11:46 am
Last edited by Andrew Birrell on August 24, 1983 7:03 pm
DIRECTORY
BootStartList USING [Base, Initialize],
DebuggerSwap USING [
CallDebugger, Catcher, Initialize, StartSwatWatcher, WorryCallDebugger],
GermSwap USING [GetPStartListHeader, Switch, switches],
KeyboardFace USING [DownUp, keyboard],
Keys USING [KeyBits, KeyName],
MesaRuntimeInit USING [
FrameImpl, InstructionsImpl, ProcessImpl, SignalsImpl, Start, TrapsImpl],
MPCodes USING [
incorrectMachineType, incorrectMicrocode, initializationStarted, mesaRuntimeInitialized],
PrincOps USING [NullFrame, VersionResult],
PrincOpsUtils USING [SetReturnFrame, VERSION, WordsForPages, WriteWDC, WriteXTS],
Process USING [priorityNormal, SetPriority],
ProcessorFace USING [Go, InitializeCleanup, millisecondsPerTick, reservedNakedNotifyMask, SetMP],
RuntimeError USING [RegisterUncaughtSignalHandler],
SystemVersion USING [Date, MachineType, ReleaseNumber];
Wart: PROGRAM
IMPORTS
BootStartList, DebuggerSwap, GermSwap, KeyboardFace, MesaRuntimeInit, PrincOpsUtils, Process, ProcessorFace, RuntimeError
EXPORTS SystemVersion =
BEGIN
Exports to SystemVersion
machineType: PUBLIC SystemVersion.MachineType;
uCodeDate: PUBLIC SystemVersion.Date;
uCodeVersion: PUBLIC CARDINAL;
uCodeFloatingPoint: PUBLIC BOOL;
uCodeCedar: PUBLIC BOOL;
release: PUBLIC SystemVersion.ReleaseNumber;
bootFileDate: PUBLIC SystemVersion.Date;
InitializeBootFile: PROC = {
h: BootStartList.Base;
Let the human know we're here. On a Dorado, this is a no-op, since ProcessorFace.Start hasn't been called yet and the "maintenance panel" is implemented in software in the processor head. On processors with physical maintenance panels (Dolphin, Dandelion), this works because SetMP is an inline, hence the ProcessorFace need not have been started (a cheat, but a useful one).
ProcessorFace.SetMP[MPCodes.initializationStarted];
Initialize the debugger linkage.
DebuggerSwap.Initialize[];
h ← GermSwap.GetPStartListHeader[]; -- get it while it's still valid (i.e., before first world swap)!
We can now get to a local world-swap debugger if someone has told us where it is (i.e., if h.locDebugger and friends have been filled in (by Set Debugger Pointers)). If not, we can get to a remote debugger.
IF GermSwap.switches[zero] THEN DebuggerSwap.WorryCallDebugger["Key Stop 0"L];
Enable the language's START construct.
MesaRuntimeInit.Start[LOOPHOLE[MesaRuntimeInit.TrapsImpl]];
Note: Any module invoked by the code before this point must be specified as "NOTRAP" in the input to MakeBoot and must be coded without any useful main body (including no initialization variable declarations). Furthermore, it must not use any non-microcode instructions, since the processor face has not yet been started. Such modules should be compiled /-m.
START MesaRuntimeInit.InstructionsImpl[]; -- goes away in Trinity
Note: Any module invoked by the code before this point must not use any non-microcode instructions, since the processor face has not yet been started. Such modules should be compiled /-m.
Initialize processor face. The Dorado maintenance panel now works. Other heads are started by control list on the heads configuration.
ProcessorFace.Go[];
ProcessorFace.InitializeCleanup[];
Ensure valid microcode. Since this relies on the VERSION instruction, which may be implemented in software, it can't be invoked until the processor face is working.
CheckVersions[h];
Make FORK, JOIN and the procedures in the Process interface work.
START MesaRuntimeInit.ProcessImpl[
pdaWords: PrincOpsUtils.WordsForPages[h.pdaPages],
svCounts: @h.stateVectorCounts,
wordsPerSV: h.stateVectorSize,
reservedNakedNotifyMask: ProcessorFace.reservedNakedNotifyMask,
millisecondsPerTick: ProcessorFace.millisecondsPerTick
];
DebuggerSwap.StartSwatWatcher[enabled: GermSwap.switches[i]];
If we were booted with the "i" swaitch, we can now get to the remote debugger via the keyboard, or to the local debugger if h.locDebugger and friends have been filled in.
START MesaRuntimeInit.FrameImpl[];
START MesaRuntimeInit.SignalsImpl[];
[] ← RuntimeError.RegisterUncaughtSignalHandler[DebuggerSwap.Catcher];
The Mesa runtime is now fully operational.
Process.SetPriority[Process.priorityNormal];
ProcessorFace.SetMP[MPCodes.mesaRuntimeInitialized];
IF GermSwap.switches[one] THEN DebuggerSwap.CallDebugger["Key Stop 1"L];
BootStartList.Initialize[h];
LookForKeyboardKeys[];
Start the rest of the boot file.
MesaRuntimeInit.Start[h.controlList];
};
LookForKeyboardKeys: PROC =
BEGIN
pKeys: LONG POINTER TO Keys.KeyBits = LOOPHOLE[KeyboardFace.keyboard];
keyNames: ARRAY GermSwap.Switch[a..z] OF Keys.KeyName = [ -- "Space" => ignore
a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: Space, j: J,
k: K, l: L, m: M, n: N, o: O, p: P, q: Q, r: R, s: S, t: T,
u: U, v: V, w: W, x: X, y: Y, z: Z
];
FOR sw: GermSwap.Switch IN GermSwap.Switch[a..z]
DO IF keyNames[sw] # Space AND pKeys[keyNames[sw]] = down
THEN GermSwap.switches[sw] ← TRUE;
ENDLOOP;
END;
CheckVersions: PROC [h: BootStartList.Base] = INLINE {
DaysToSeconds: PROC [d: CARDINAL] RETURNS [SystemVersion.Date] = INLINE {
RETURN [d.LONG*60*60*24]
};
info: PrincOps.VersionResult = PrincOpsUtils.VERSION[];
IF ~(info.machineType IN SystemVersion.MachineType) THEN
{ProcessorFace.SetMP[MPCodes.incorrectMachineType]; DO ENDLOOP};
machineType ← info.machineType;
IF (uCodeDate ← DaysToSeconds[info.releaseDate]) < h.requiredUCode[machineType] THEN
{ProcessorFace.SetMP[MPCodes.incorrectMicrocode]; DO ENDLOOP};
uCodeVersion ← info.majorVersion;
uCodeFloatingPoint ← info.floatingPoint;
uCodeCedar ← info.cedar;
release ← h.release;
bootFileDate ← h.buildDate;
};
Main Body
PrincOpsUtils.WriteWDC[1];
PrincOpsUtils.WriteXTS[off];
PrincOpsUtils.SetReturnFrame[PrincOps.NullFrame]; -- for Detach in MesaRuntime initialization
InitializeBootFile[];
END.