DIRECTORY
BootStartList USING [Base, Initialize],
DebuggerSwap
USING [
CallDebugger, Catcher, Initialize, StartSwatWatcher, WorryCallDebugger],
GermSwap USING [GetPStartListHeader, switches],
MesaRuntimeInit
USING [
FrameImpl, InstructionsImpl, ProcessImpl, SignalsImpl, Start, TrapsImpl],
MPCodes
USING [
incorrectMachineType, incorrectMicrocode, initializationStarted, mesaRuntimeInitialized],
PrincOps USING [NullFrame, VersionResult],
PrincOpsUtils USING [PagesToWords, SetReturnFrame, VERSION, WriteWDC, WriteXTS],
Process USING [priorityNormal, SetPriority],
ProcessorFace USING [Go, millisecondsPerTick, reservedNakedNotifyMask, SetMP],
RuntimeError USING [RegisterUncaughtSignalHandler],
SystemVersion USING [Date, MachineType, ReleaseNumber];
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[];
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.PagesToWords[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];
Start the rest of the boot file.
BootStartList.Initialize[h];
MesaRuntimeInit.Start[h.controlList];
};
CheckVersions:
PROC [h: BootStartList.Base] =
INLINE {
SecondsToDays:
PROC [s: SystemVersion.Date]
RETURNS [
CARDINAL] =
INLINE {
RETURN [s/(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 SecondsToDays[uCodeDate ← h.requiredUCode[machineType]] > info.releaseDate
THEN
{ProcessorFace.SetMP[MPCodes.incorrectMicrocode]; DO ENDLOOP};
uCodeVersion ← info.majorVersion;
uCodeFloatingPoint ← info.floatingPoint;
uCodeCedar ← info.cedar;
release ← h.release;
bootFileDate ← h.buildDate;
};