" *********************************************************** " * * " * Copyright, (C) Honeywell Bull Inc., 1987 * " * * " * Copyright, (C) Honeywell Information Systems Inc., 1982 * " * * " * Copyright (c) 1972 by Massachusetts Institute of * " * Technology and Honeywell Information Systems, Inc. * " * * " *********************************************************** " SIGNALLER - Ring 0 Module to Perform Signalling Operation. " Modification record: (Date and Reason) " 83-12-12 by BIM to unmask before -2 terminates " 7/81 by J. Bongiovanni for prev stack frame bug " 8/80 by J. A. Bush for DPS8/70M " 5/79 by M. Grady to implement stack 0 sharing. " 10/78 by B. Greenberg to set support bit in frame. " 10/75 by R. Bratt to signal on primary stack if prr ^= sp.ring_no " 7/75 by B. Greenberg, to limit MC saving " 3/75 by S. Webber to use new (safe) RCU conventions " 2/74 by Steve Webber to trace signallings in pds trace data " 10/73 by Steve Webber to separate out restart_fault code into different segment " 9/73 by M. Weaver to move fim_frame_flag and fill in entry ptr " 29 Aug 72 by R F Mabee to remove numerous followon conversion bugs. " 8/8/72 by Steve Webber to fix the 4 signaller bugs. " 6/26/72 by Bill Silver for 645F. " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " SIGNALLER -- This program must by called (transferred to) in ring " 0 when a fault or condition is to be signalled. It " expects the machine conditions to be in pds$signal_data " and the condition name to be in pds$condition_name. " " A dummy (signaller) stack frame is created on the stack " being signalled on and the machine conditions and name " are copied into this frame. The signal_ procedure defined " by the signal_ptr in the stack header of the stack being " signalled on is then called. " " The procedure shares the stack frame with "restart_fault" " and hence any changes to stack variables in either program " must be reflected in the other. " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " name signaller inhibit on <+><+><+><+><+><+><+><+><+><+><+><+> link signaller_link,<*text>|0 link restart_fault_link,restart_fault$ link pds_link,pds$ include signaller_stack include mc include apte include stack_header include stack_frame " entry signaller entry no_save no_save: "entry to signal illegal_return data tsplb page_fault$trace_signaller eax7 2 no save, but leave scux in fim_temp. tra merge signaller: tsplb page_fault$trace_signaller eax7 0 set to save mc merge: epaq * lprplp sb|stack_header.lot_ptr,*au eppbp pds$signal_data bp -> m.c. data in PDS. " Now we must unmask to open level. All interrupts are " allowed after we signal. We unmask here so that the " following termination happens in an unmasked environment. ldaq scs$open_level open up mask lxl1 prds$processor_tag CPU tag in X1 lprpab scs$mask_ptr,1 get pointer for masking xec scs$set_mask,1 " Terminate process if fault occurred during signalling. ldx0 bp|mc.scu.ppr.psr_word Pick up PPR.PRR and PPR.PSR anx0 scu.ppr.psr_mask,du from m.c. and zero PPR.PRR. cmpx0 lp|signaller_link were we in signaller? tze term4,* cmpx0 lp|restart_fault_link what about restart_fault? tze term4,* if so, bye-bye! " Now we must save the stack pointer we are currently using. This " will be used to reset the stack end pointer if we are signalling " on a different stack. sprisp bp|mc.mask eppsp bp|mc.prs+6*2,* set sp to stack to signal on eppap sp|0 save for prev frame pointer lda bp|mc.scu.indicators_word see if we were in bar mode cana scu.ir.bm,dl .. tze bar_mode lda bp|mc.prs+6*2 get ring of sp als 18 era bp|mc.scu.ppr.psr_word compare to prr cana =o700000,du tze set_sb equal - signal on sp lda bp|mc.scu.ppr.psr_word arl 36-3 als 1 epbpsp pds$stacks,al* eppsp sp|stack_header.stack_end_ptr,* tra set_sb not equal - signal on pds$stacks (prr) bar_mode: epbpsb sp|0 make sb point to base of stack lda sb|stack_header.bar_mode_sp+1 get word offset of saved sp " (saved before entering BAR mode) eawpsp 0,au use this value since BAR mode pgm could clobber ADR6 eppap sp|0 and save as prev pointer " which is also word offset of sp ldaq sp|stack_frame.next_sp get next sp from current frame cmpaq sb|stack_header.stack_end_ptr better be equal to stack end ptr tnz term8,* it isn't...we can't trust sp so wipe the guy out set_sb: epbpsb sp|0 Make sb point to base of validated stack segment. " Get offset of next frame. ldq fim_frame_flag,dl turn ON fim frame flag orsq sp|stack_frame.flag_word ldq sb|stack_header.stack_end_ptr+1 " Add default frame size to frame offset in case fault occurred when adding a new frame " but before all pointers were set - for example, in the middle of a "push". adlq stack_frame.min_length,du orq fim_frame_flag,dl OR in old fim frame flag bit. " Update the pointer in the old frame. stq sp|stack_frame.next_sp+1 " Setup "sp" to point to the new frame. We can't trust the segment number in " the stack_header.stack_end_ptr nor in the next_sp pointer in the previous " frame. We will use the validated "sb" as the segment number. The offset " we trust. eppsp sb|0,qu Offset still in QU. " Now "sp" points to the new frame. spriap sp|stack_frame.prev_sp Store ptr to old frame. ldx0 push get size of signaller frame eppap sp|0,0 get pointer to end of frame spriap sp|stack_frame.next_sp Store ptr to next frame. spriap sb|stack_header.stack_end_ptr Update header. sprilp sp|stack_frame.lp_ptr lda 4,du fill in translator ID sta sp|stack_frame.translator_id lda stack_frame.support_bit,dl orsa sp|stack_frame.prev_sp turn on support bit. eppap return_to_ring_0_$return_to_ring_0_ spriap sp|stack_frame.entry_ptr epaq sp|0 now check to see if we're abandoning a stack eax0 0,au segno of new stack in x0 cmpx0 bp|mc.mask same as old stack ? tze old_stack we're still using this stack, don't reset epbplb bp|mc.mask,* get pointer to base of old stack ldaq lb|stack_header.stack_begin_ptr reset end pointer to begin pointer staq lb|stack_header.stack_end_ptr old_stack: " " Save the machine conditions in the pds. We will only save the SCU data " and the pointers and lengths. " tsx1 copy_and_save_mc save mc in pds and copy into stack frame eppap mach_cond get pointer to machine conditions spriap mc_ptr save mc pointer in stack ldq 0,dl set up for no hregs (zero length) szn pds$hregs_saved do history regs exist? tze *+2 xfer if no, pad hreg blk with 0's ldq 128*4,dl yes, set length mlr (pr,rl),(pr),fill(0) desc9a bp|48,ql desc9a history_registers,128*4 " Copy the condition name into stack frame. eppbp pds$condition_name bp -> condition name in wired storage eppap signal_string ap -> condition name in stack mlr (pr),(pr) desc9a bp|0,32 desc9a ap|0,32 " " Make descriptors for call to signal. lda signal_string pick up first word of string arl 27 right-justify character count ora char_desc_mask,du Insert bits for desc_mask sta string_descriptor save the descriptor lda ptr_desc_mask,du Make a descriptor for pointer. sta ptr_descriptor save the descriptor " Now set up the cleanup handler to discard the MC if necessary " tsx1 set_up_cleanup set up cleanup condition handler " Create argument list for call to signal. ldaq arg_list_header Setup argument list header. staq arglist eppap null,* ap contains null pointer spriap null_ptr set up null pointer for call eppap signal_string set up argument list spriap arglist+2 lda 9*512,dl don't forget the bit offset orsa arglist+3 for character string eppap mc_ptr call signal_ (condition_name, mc_ptr, null, null) eppbp null_ptr ap -> m.c. pointer, bp -> null pointer. spriap arglist+4 set arguments eppap null_ptr spriap arglist+6 spribp arglist+8 eppap string_descriptor set pointers to descriptors spriap arglist+10 eppap ptr_descriptor spriap arglist+12 spriap arglist+14 spriap arglist+16 eppbb sb|stack_header.signal_ptr,* we want to call signal_ eppap arglist set up ap for call join: " get pointer which gets us to ring 0 eppbp return_to_ring_0_$return_to_ring_0_ spribp sp|stack_frame.return_ptr save in normal return loc spribp sp|stack_frame.entry_ptr for debuggers " " Before calling signal_, we return to system code in return_to_ring_0_ which " will execute in the user ring so that any pending ring alarm faults can be handled. " This is done by first returning to return_to_ring_0_ (which really returns to ring N) " which will then call signal_. " eppab pds$signal_data+mc.mask return from this place sprisb ab|0 save this for ring number only epaq return_to_ring_0_$return_to_ring_n stca ab|0,70 stcq ab|1,70 rtcd ab|0 return to return_to_ring_n " " for_linker " " This entry is used by the linker to complete the work of calling the trap_caller " for a trap-before-link or trap-at-first-reference. " " Call is: call signaller$for_linker (stack_ptr, entry_ptr) " entry for_linker for_linker: epbplb sp|0 save pointer to stack we're on eppbp lb|stack_header.stack_begin_ptr,* reset stack spribp lb|stack_header.stack_end_ptr .. eppbb ap|2,* get target stack pointer eppsp bb|0,* into sp register epbpsb sp|0 generate pointer to stack base eppbb ap|4,* get entry to call eppbb bb|0,* ,, eax7 0 hopefully save machine conditions eppbp pds$signal_data get ptr to place to stash data tsx1 copy_and_save_mc do the work tsx1 set_up_cleanup and set up a cleanup handler in outer ring eppap sp|stack_frame.operator_ptr,* (left here by trap_caller_caller_) tra join " " Subroutines " copy_and_save_mc: ldx0 bp|mc.scu.ppr.psr_word what is ring? canx0 =o700000,du pds ? tnz *+2 if not, don't inhibit saving. eax7 1 Was the PDS, can't restart, so don't save. eax0 0 set for 0 SCU index if not saved. eax7 0,7 Is state of mc rotten already? tnz dont_save yes, don't save MC. eppap pds$mc_save_ptr,* get place to put data eax0 ap|16 where will that put us? cmpx0 pds$mc_save_limit too many? tpl too_many signal new problem if too many stx0 pds$mc_save_ptr save new next ptr mlr (pr),(pr) desc9a bp|mc.scu,8*4 desc9a ap|0,8*4 mlr (pr),(pr) desc9a bp|mc.eis_info,8*4 desc9a ap|8,8*4 aos pds$unique_scu_index lxl0 pds$unique_scu_index stx0 ap|scu.tsr_stat_word save unique index in ring 0 copy " Copy the machine conditions into stack frame. dont_save: mlr (pr),(pr) desc9a bp|0,48*4 desc9a mach_cond,48*4 cmpx7 2,du is this illegal return signal? tze *+2 if so, leave original scux stx0 mach_cond+mc.fim_temp save the unique index tra 0,1 set_up_cleanup: " Generate condition unit for cleanup lda =o100,dl set condition flag orsa sp|stack_frame.prev_sp equ on_unit_offset,on_unit eax0 on_unit_offset get offset of on-unit structure in new stack frame stx0 sp|stack_frame.on_unit_rel_ptrs eppbp on_unit+8 get pointer to place to store string spribp on_unit save it in the real on unit lda 7,dl set length of the name sta on_unit+4 stz on_unit+5 clear flags word eppbp |1 spribp on_unit+2 mlr (),(pr),fill(040) move the string into the stack desc9a cname,7 desc9a on_unit+8,32 tra 0,1 " " User has willingly prevented mc cleanup. Flag the mc identifiably, " and don't save them. " too_many: eax0 -1 make identifiable flag in mc tra dont_save merge " " storage and constants even term4: its -2,-4 term8: its -2,-8 null: its -1,1 arg_list_header: vfd 18/8,18/4 vfd 18/8,18/0 bool ptr_desc_mask,464000 bool char_desc_mask,524000 push: push cname: aci "cleanup" end " " " ----------------------------------------------------------- " " " " Historical Background " " This edition of the Multics software materials and documentation is provided and donated " to Massachusetts Institute of Technology by Group Bull including Bull HN Information Systems Inc. " as a contribution to computer science knowledge. " This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, " Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell Bull Inc., Groupe Bull " and Bull HN Information Systems Inc. to the development of this operating system. " Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), " renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership " of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture for " managing computer hardware properly and for executing programs. Many subsequent operating systems " incorporated Multics principles. " Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., " as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . " " ----------------------------------------------------------- " " Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without " fee is hereby granted,provided that the below copyright notice and historical background appear in all copies " and that both the copyright notice and historical background and this permission notice appear in supporting " documentation, and that the names of MIT, HIS, Bull or Bull HN not be used in advertising or publicity pertaining " to distribution of the programs without specific prior written permission. " Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. " Copyright 2006 by Bull HN Information Systems Inc. " Copyright 2006 by Bull SAS " All Rights Reserved " "