1 /****^  ***********************************************************
  2         *                                                         *
  3         * Copyright, (C) Honeywell Bull Inc., 1987                *
  4         *                                                         *
  5         * Copyright, (C) Honeywell Information Systems Inc., 1982 *
  6         *                                                         *
  7         *********************************************************** */
  8 
  9 /* format: style1 */
 10 
 11 init_scu: proc (P_tag, P_errtag, P_code);
 12 
 13 /* *      INIT_SCU - Initialize a System Controller.
 14    *
 15    *      History:
 16    *      Modified 4/84, Keith Loepere for collection_1_phase.
 17    *      Modified '82 for early initialization operation
 18    *      Modified 01/09/81, W. Olin Sibert, for scs$scas_page_table.
 19    *      Modified 12/01/79, Mike Grady, to improve mem config size checks.
 20    *      Modified 07/14/79, Mike Grady, to improve config checks.
 21    *      Modified sometime, BSG, for 8 cpu port expander.
 22    *      Coded 03/01/76, Noel I. Morris
 23 */
 24 
 25 
 26 /****^  HISTORY COMMENTS:
 27   1) change(88-07-27,Farley), approve(88-10-05,MCR7968),
 28      audit(88-10-10,Beattie), install(88-10-14,MR12.2-1166):
 29      Added code to check for memory address overlap conditions.  This adds a
 30      call to pmut$check_for_mem_overlap and a new error code,
 31      rcerr_addscu_memoverlap.
 32                                                    END HISTORY COMMENTS */
 33 
 34 
 35           dcl     P_tag                  fixed bin (3) parameter; /* system controller tag */
 36           dcl     P_errtag               fixed bin (3) parameter; /* CPU or mask in error */
 37           dcl     P_code                 fixed bin (35) parameter; /* error code */
 38 
 39           dcl     code                   fixed bin (35);    /* error code */
 40           dcl     tag                    fixed bin (3);     /* tag of SCU we are working on */
 41           dcl     ptp                    pointer;           /* Pointer to current SCAS PTW */
 42           dcl     i                      fixed bin (3);     /* iteration index */
 43           dcl     j                      fixed bin (3);     /* iteration index */
 44           dcl     x                      fixed bin (5);     /* SCAS index */
 45           dcl     low_base               fixed bin;         /* for overlap check */
 46           dcl     high_base              fixed bin;         /* for overlap check */
 47           dcl     mem_size               fixed bin;         /* real mem size */
 48           dcl     found                  bit (1) aligned;   /* used to check mask assignments */
 49           dcl     unfound_mask           (4) bit (1) unal;  /* used to check mask assignments also  */
 50 
 51           dcl     cdp                    ptr;
 52           dcl     pdp                    ptr;
 53           dcl     1 cdata                based (cdp) like scs$controller_data aligned; /* single element of controller data */
 54           dcl     1 pdata                based (pdp) like scs$processor_data aligned; /* single element of processor data */
 55 
 56           dcl     privileged_mode_ut$check_for_mem_overlap
 57                                          entry (fixed bin, fixed bin, fixed bin (35));
 58           dcl     scr_util$read_cfg      entry (fixed bin (3));
 59           dcl     scr_util$set_mask      entry (fixed bin (3), fixed bin (3), fixed bin (71));
 60           dcl     syserr                 entry options (variable);
 61 
 62           dcl     tag_letter             (0:7) char (1) aligned static init ("A", "B", "C", "D", "E", "F", "G", "H"); /* for message */
 63 
 64           dcl     (addr, bit, divide, index, string) builtin;
 65 ^L
 66 
 67           tag = P_tag;                                      /* Copy parameter */
 68 
 69           cdp = addr (scs$controller_data (tag));           /* Get pointer to data for this controller. */
 70           call set_scas_ptw ((tag), (cdata.base));          /* Set scas entry for this controller. */
 71 
 72 /* Read CFG data from the controller and fill in data pertaining to
 73    the configuration of store units connected to the controller.      */
 74 
 75           call scr_util$read_cfg (tag);                     /* Now, do RSCR CFG from controller. */
 76 
 77           mem_size = cdata.lower_store_size + cdata.upper_store_size;
 78 
 79           if cdata.size < mem_size then /* Processor and controller sizes disagree. */
 80                call init_error (rcerr_addscu_size, 0);
 81 
 82           if scs$controller_config_size (tag) > mem_size then
 83                call init_error (rcerr_addscu_bigconfig, 0);
 84 
 85           if ^cdata.program then /* Must be in programmable mode. */
 86                call init_error (rcerr_addscu_manual, 0);
 87 
 88           if (cdata.type < "0010"b) & (string (scs$expanded_ports) ^= ""b) then
 89                call init_error (rcerr_addscu_oldexpand, 0); /* Can't have expanders on old SCU's */
 90 
 91 /* Set up any additional SCAS PTWs */
 92 
 93           if (cdata.store_b_is_lower & cdata.store_a_online) |
 94                (^cdata.store_b_is_lower & cdata.store_b_online) then
 95                call set_scas_ptw (tag + 8, cdata.base + cdata.lower_store_size);
 96 
 97           if (cdata.store_b_is_lower & cdata.store_b1_online) |
 98                (^cdata.store_b_is_lower & cdata.store_a1_online) then
 99                call set_scas_ptw (tag + 16, cdata.base + divide (cdata.lower_store_size, 2, 17, 0));
100 
101           if (cdata.store_b_is_lower & cdata.store_a1_online) |
102                (^cdata.store_b_is_lower & cdata.store_b1_online) then
103                call set_scas_ptw (tag + 24, cdata.base + cdata.lower_store_size + divide (cdata.lower_store_size, 2, 17, 0));
104 
105 /**** Check for possible memory address overlap, which can occur when
106       stores A & A1 (and/or B & B1) should be enabled, but only A (and/or B)
107       is actually enabled. */
108 
109                                                             /** first check for overlap in lower store */
110 
111           if (cdata.store_b_is_lower & cdata.store_b_online & ^cdata.store_b1_online) |
112                (^cdata.store_b_is_lower & cdata.store_a_online & ^cdata.store_a1_online) then do;
113                     low_base = cdata.base;
114                     high_base = cdata.base + divide (cdata.lower_store_size, 2, 17, 0);
115                     call privileged_mode_ut$check_for_mem_overlap
116                          (low_base, high_base, code);
117 
118                     if code ^= 0 then
119                          call init_error (rcerr_addscu_memoverlap, 0);
120                end;
121 
122                                                             /** now check for overlap in lower store */
123 
124           if (cdata.lower_store_size = cdata.upper_store_size) then
125                if (cdata.store_b_is_lower & cdata.store_b_online & cdata.store_a_online & ^cdata.store_a1_online) |
126                     (^cdata.store_b_is_lower & cdata.store_a_online & cdata.store_b_online & ^cdata.store_b1_online) then do;
127                          low_base = cdata.base + cdata.lower_store_size;
128                          high_base = cdata.base + cdata.lower_store_size +
129                               divide (cdata.lower_store_size, 2, 17, 0);
130                          call privileged_mode_ut$check_for_mem_overlap
131                               (low_base, high_base, code);
132 
133                          if code ^= 0 then
134                               call init_error (rcerr_addscu_memoverlap, 0);
135                     end;
136 ^L
137 
138 /* Make sure that each assigned controller mask is assigned to
139    a processor, and that at most one controller mask is assigned
140    to each processor.                                                 */
141 
142           string (unfound_mask) = "1111"b;                  /* Mark all masks as not yet found. */
143 
144           do i = 0 to 7;                                    /* Look at all CPU's. */
145                pdp = addr (scs$processor_data (i));         /* Get pointer to data for this CPU. */
146                if ^(pdata.offline | pdata.online) then /* Is CPU in the configuration ? */
147                     goto NEXT_CPU_LOOP;
148 
149                found = "0"b;                                /* Have not yet found mask for this processor. */
150                do j = 1 to 4;                               /* Look at all mask assignments. */
151                     if cdata.eima_data (j).mask_assigned then do;
152                               if pdata.controller_port = cdata.eima_data (j).mask_assignment then do;
153                                         if ^found then do;  /* Make sure neither mask nor port duplicates */
154                                                   unfound_mask (j) = "0"b; /* Found a mask for this CPU. */
155                                                   found = "1"b;
156                                                   call scr_util$set_mask (tag, (pdata.controller_port), 0);
157                                              end;
158 
159                                         else call init_error (rcerr_addscu_dup_mask, i); /* Found more than one mask. */
160                                    end;                     /* Two masks are assigned to one port. */
161                          end;                               /* Of case for assigned mask */
162 
163                     else unfound_mask (j) = "0"b;           /* No assignment for this mask. */
164                end;                                         /* Of loop through possible masks */
165 
166                if (cdata.type < "0010"b) & ^found then /* If not 4MW SCU ... */
167                     call init_error (rcerr_addscu_no_mask, i); /* Every processor must have an assigned mask. */
168 
169 NEXT_CPU_LOOP:
170           end;                                              /* Of loop through processors */
171 
172           if string (unfound_mask) ^= ""b then /* If some mask not accounted for ... */
173                call init_error (rcerr_addscu_bad_mask, (index (string (unfound_mask), "1"b) - 1));
174                                                             /* Mask not assigned to a processor port. */
175 
176           if ^(sys_info$collection_1_phase = EARLY_INITIALIZATION | sys_info$collection_1_phase > SERVICE_INITIALIZATION)
177           then if scs$controller_config_size (tag) < mem_size then
178                     call syserr (0, "init_scu: Warning - Not all of MEM ^a will be used.", tag_letter (tag));
179 
180           P_code = 0;                                       /* Indicate success */
181           P_errtag = 0;
182 
183 ERROR_RETURN:
184           return;                                           /* End of code for init_scu */
185 ^L
186 
187 final_scu: entry (P_tag);
188 
189           tag = P_tag;                                      /* Copy parameter */
190 
191           do x = tag by 8 while (x < 32);                   /* Fault out all entries in SCAS for this controller. */
192                call reset_scas_ptw (x);
193           end;
194 
195           return;                                           /* End of code for init_scu$final_scu */
196 ^L
197 
198 init_error: proc (return_code, error_tag);
199 
200           dcl     return_code            fixed bin parameter;
201           dcl     error_tag              fixed bin (3) parameter;
202 
203 
204           call final_scu (tag);                             /* Finish this SCU */
205 
206           P_code = return_code;                             /* and return error parameters */
207           P_errtag = error_tag;
208 
209           goto ERROR_RETURN;
210      end init_error;
211 
212 
213 
214 set_scas_ptw: proc (scasx, base);                           /* procedure to set PTW in scas. */
215 
216           dcl     scasx                  fixed bin (5) parameter; /* index into the scas */
217           dcl     base                   fixed bin (14) parameter; /* absolute address (in 1024 word blocks) for PTW */
218 
219 
220           ptp = addr (scs$scas_page_table (scasx));         /* Find our PTW */
221 
222           ptp -> l68_ptw.add = bit (base);                  /* Insert base address in PTW. */
223           ptp -> l68_ptw.phu = "1"b;                        /* Turn on used bit in PTW. */
224           ptp -> l68_ptw.valid = "1"b;                      /* Turn off directed fault in PTW. */
225 
226           return;
227      end set_scas_ptw;
228 
229 
230 
231 reset_scas_ptw: proc (scasx);                               /* proc to reset PTW in scas. */
232 
233           dcl     scasx                  fixed bin (5) parameter; /* index into the scas */
234 
235 
236           ptp = addr (scs$scas_page_table (scasx));         /* Find our PTW */
237 
238           ptp -> l68_ptw.valid = "0"b;                      /* Turn on directed fault in PTW. */
239 
240           return;
241      end reset_scas_ptw;
242 
243 %page; %include collection_1_phases;
244 %page; %include scs;
245 %page; %include "ptw.l68";
246 %page; %include rcerr;
247 ^L
248 
249 /* BEGIN MESSAGE DOCUMENTATION
250 
251    Message:
252    init_scu: Warning - Not all of MEM Y will be used.
253 
254    S:     $info
255 
256    T:     $init
257 
258    M:     The actual amount of memory present in MEM Y does
259    not agree with the config deck. Only as much as the configuration deck
260    specifies will be used.
261 
262    A:     If this is an unintentional error,
263    correct the configuration deck before the next bootload.
264 
265 
266    END MESSAGE DOCUMENTATION */
267 
268      end init_scu;