// Power.bcpl -- Turn on/off Maxc1 power supplies external [ // Outgoing procedures Block // Incoming procedures InitNovaAlto; InitializeInterrupt; InitializeZone; GetFixed; Zero Ws; Wl; PutTemplate; CallSwat SetupReadParam; ReadParam ExIO; ExSkip SetTimer; TimerHasExpired; Dismiss // Incoming statics dsp ] manifest [ //Nova i/o opcodes nioc = #060200; nios = #060100; niop = #060300 dia = #060400; diac = #060600; dias = #060500; diap = #060700 dib = #061400; dibc = #061600; dibs = #061500; dibp = #061700 dic = #062400; dicc = #062600; dics = #062500; dicp = #062700 doa = #061000; doac = #061200; doas = #061100; doap = #061300 dob = #062000; dobc = #062200; dobs = #062100; dobp = #062300 doc = #063000; docc = #063200; docs = #063100; docp = #063300 skpbn = #063400; skpbz = #063500; skpdn = #063600; skpdz = #063700 //Nova device codes maint = #60 // Maintenance interface mem = #34 // Memory interface mem2 = #35 // Second device code for memory interface // Commands for Maxc memory memRead = #60000 memWrite = #120000 memSetBit = #160000 // Bits controlling power supplies procPlus5 = #1 portPlus5 = #2 memPlus5 = #1 memPlus16 = #2 memPlus4 = #4 memMinus5 = #10 ] static [ procPowerOut; procPowerIn; memPowerOut; memPowerIn zone ] // ---------------------------------------------------------------- let Power() be // ---------------------------------------------------------------- [ // SMI addresses for power control input and output registers // The first entry in each table is the number of following entries procPowerOut = table [ 1; #100 ] //also controls port procPowerIn = table [ 1; #101 ] memPowerOut = table [ 3; #20; #33; #105 ] memPowerIn = table [ 3; #21; #32; #104 ] zone = GetFixed(2000) InitializeZone(zone,2000) InitNovaAlto(zone) // Arm memory interface interrupt InitializeInterrupt(mem,MaxcMemInt) // Read command line to find out what to do let stringVec,switchVec = vec 127,vec 127 SetupReadParam() if ReadParam(0,0,stringVec,switchVec,true) eq -1 then Error() let doProc,doMem = false,false test switchVec!0 eq 0 ifso // No switches means do both processor and memory [ doProc,doMem = true,true ] ifnot for i = 1 to switchVec!0 do switchon switchVec!i into [ case $P: case $p: [ doProc = true; endcase ] case $M: case $m: [ doMem = true; endcase ] default: Error() ] if stringVec!0 eq 2 & stringVec!1 eq $O & stringVec!2 eq $N then [ // "ON" ProcPortOn(doProc? procPlus5+portPlus5, portPlus5) if doMem then MemoriesOn() ResetMemErrors() finish ] if stringVec!0 eq 3 & stringVec!1 eq $O & stringVec!2 eq $F & stringVec!3 eq $F then [ // "OFF" if doProc then ProcPortOff(doMem? procPlus5+portPlus5,procPlus5) if doMem then MemoriesOff() finish ] Error() ] // ---------------------------------------------------------------- and Error() be // ---------------------------------------------------------------- [ Wl("Commands are:") Wl(" POWER ON -- Turns on processor and memories") Wl(" POWER OFF -- Turns off processor and memories") Wl(" POWER ON/P -- Turns on processor only") Wl(" POWER ON/M -- Turns on memories only") Wl(" POWER OFF/P -- Turns off processor only") Wl(" POWER OFF/M -- Turns off memories only") finish ] // ---------------------------------------------------------------- and ProcPortOn(supply) be // ---------------------------------------------------------------- [ let v = vec 1 v!0 = 1; v!1 = supply PowerOn(procPowerOut,procPowerIn,v,ProcPortOnFail) ] // ---------------------------------------------------------------- and MemoriesOn() be // ---------------------------------------------------------------- [ PowerOn(memPowerOut,memPowerIn, table [ 4 memPlus5 // +5v memMinus5 // -5v memPlus4 // +4v memPlus16 // +16v ], MemOnFail) ConfigureMemory() ZeroMemory() ] // ---------------------------------------------------------------- and ProcPortOff(supply) be // ---------------------------------------------------------------- [ OutputSMI(procPowerOut!1,InputSMI(procPowerIn!1) & not supply) ] // ---------------------------------------------------------------- and MemoriesOff() be // ---------------------------------------------------------------- [ for i = 1 to memPowerOut!0 do if InputSMI(memPowerIn!i) ne 0 then OutputSMI(memPowerOut!i,#15) // +16 supply off first, rest on Dismiss(100) // Wait 1 second for i = 1 to memPowerOut!0 do OutputSMI(memPowerOut!i,0) // Now kill remaining supplies ] // ---------------------------------------------------------------- and PowerOn(outputList,inputList,sequence,FailProc) = valof // ---------------------------------------------------------------- // Turn on power supplies. // outputList = number of cabinets followed by list of // output SMI addresses // inputList = number of cabinets followed by list of // input SMI addresses // sequence = number of supplies in cabinet, followed by // list of bit values required to turn on each supply // FailProc(cab,supply) is called upon failure to turn on a // supply (cab and supply are indices into outputList and // sequence respectively). // returns true if all cabinets turned on successfully. [ let timer = nil SetTimer(lv timer,3000) // 30 seconds maximum let allOn,timedOut = false,false until allOn % timedOut do [ timedOut = TimerHasExpired(lv timer) allOn = true for i = 1 to inputList!0 do [ // Look for first turned-off supply in each cabinet let state = InputSMI(inputList!i) // get current state for j = 1 to sequence!0 do if (state & sequence!j) ne sequence!j then [ // Found one, turn it on allOn = false test timedOut ifnot OutputSMI(outputList!i,state % sequence!j) ifso FailProc(i,sequence!j) break ] ] ] resultis allOn ] // ---------------------------------------------------------------- and ProcPortOnFail(nil,supply) be // ---------------------------------------------------------------- [ let badSupply = supply & not InputSMI(procPowerIn!1) if (badSupply&procPlus5) ne 0 then [ Wl("Failed to turn on processor 5v supply.") Wl(" (It might be that the fan is broken.)") ] if (badSupply&portPlus5) ne 0 then [ Wl("Failed to turn on port 5v supply.") ] ] // ---------------------------------------------------------------- and MemOnFail(cab,supply) be // ---------------------------------------------------------------- [ OutputSMI(memPowerOut!cab,0) // turn off all supplies in cabinet let voltage = selecton supply into [ case memPlus5: 5 case memMinus5: -5 case memPlus4: 4 case memPlus16: 16 ] PutTemplate(dsp,"Failed to turn on $Dv supply in memory cab $O.*n", voltage,cab-1) ] // ---------------------------------------------------------------- and ConfigureMemory() be // ---------------------------------------------------------------- [ OutputSMI(#25,0) // Set normal quadrant configuration OutputSMI(#24,0) // Reset all quadrants let moduleTable = table [ // Physical to logical module correspondence table 4 #200 // Physical 0 = logical 4 #004 // Physical 1 = logical 0 #310 // Physical 2 = logical 6 #114 // Physical 3 = logical 2 ] for quad = 0 to 3 do for mod = 1 to moduleTable!0 do OutputSMIPulse(#22,moduleTable!mod+quad) ] // ---------------------------------------------------------------- and ResetMemErrors() be // ---------------------------------------------------------------- [ OutputSMI(#24,#125) ] // ---------------------------------------------------------------- and ZeroMemory() be // ---------------------------------------------------------------- [ let zeroPage = vec 512*3 Zero(zeroPage,512*3) for cab = 1 to memPowerIn!0 do if InputSMI(memPowerIn!cab) eq #17 then // All supplies on? for i = 0 to 255 do // Zero all memory in this cabinet [ let page = 256*(cab-1)+i unless BltMaxcMem(memWrite,page,0,zeroPage,512) do [ PutTemplate(dsp,"Memory cabinet $O not responding*n", cab-1) break ] ] ] // ---------------------------------------------------------------- and BltMaxcMem(command,maxcPage,maxcWord,novaAdr,count) = valof // ---------------------------------------------------------------- [ ExIO(dob+mem,maxcPage) ExIO(doc+mem,maxcWord) ExIO(doa+mem2,novaAdr) ExIO(doas+mem,command+512-count) let timer = nil; SetTimer(lv timer,10) //100 ms plenty long enough while ExSkip(skpbn+mem) do if TimerHasExpired(lv timer) then [ ExIO(nioc+mem); ResetMemErrors(); resultis false ] ExIO(nioc+mem) resultis true ] // ---------------------------------------------------------------- and MaxcMemInt() be // ---------------------------------------------------------------- // Handle interrupt from memory interface [ ExIO(nioc+mem) ] // ---------------------------------------------------------------- and InputSMI(address) = valof // ---------------------------------------------------------------- [ ExIO(dob+maint,address) let res = ExIO(dia+maint) ExIO(dob+maint,0) resultis res ] // ---------------------------------------------------------------- and OutputSMI(address,value) be // ---------------------------------------------------------------- [ ExIO(dob+maint,address) ExIO(doa+maint,value) ExIO(dob+maint,0) ] // ---------------------------------------------------------------- and OutputSMIPulse(address,value) be // ---------------------------------------------------------------- [ ExIO(dob+maint,address) ExIO(doap+maint,value) ExIO(dob+maint,0) ] // ---------------------------------------------------------------- and Block() be [ ] // Dummy since not using context package // ----------------------------------------------------------------