1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 uncp_util:
21 procedure;
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 dcl a_data_ptr ptr;
62 dcl cent fixed bin (15) unsigned init (1);
63 dcl un fixed bin (12) unsigned init (1);
64 dcl a_devx fixed bin;
65 dcl a_fnp_no fixed bin;
66 dcl a_fnp_mem_size fixed bin;
67 dcl a_fnp_type fixed bin;
68 dcl a_ptr ptr;
69 dcl a_count fixed bin;
70 dcl a_code fixed bin (35);
71 dcl a_ev_chan fixed bin (71);
72 dcl a_absadr fixed bin (24);
73 dcl norm_int_cell fixed bin;
74 dcl emergency_int_cell fixed bin;
75 dcl a_ints bit (2) aligned;
76 dcl a_level fixed bin (3);
77 dcl a_fnp_addr fixed bin (15);
78
79
80
81 dcl auto_absadr fixed bin (24);
82 dcl fnp_no fixed bin;
83 dcl fnp_mem_size fixed bin;
84 dcl fnp_type fixed bin;
85 dcl fnp_addr fixed bin (15);
86 dcl opcode bit (6) aligned;
87 dcl temp_fnp_name char (32);
88 dcl segptr ptr;
89 dcl nwords fixed bin;
90 dcl code fixed bin (35);
91 dcl devx fixed bin;
92 dcl abs_addr_string bit (24);
93 dcl i fixed bin;
94 dcl abs_address fixed bin (26);
95 dcl data_ptr ptr;
96 dcl offset fixed bin;
97 dcl fnp_tally fixed bin;
98 dcl start_time fixed bin (71);
99 dcl version char (4);
100 dcl load_info_ptr ptr;
101 dcl locked bit (1) aligned init ("0"b);
102 dcl config_locked bit (1) aligned init ("0"b);
103
104 declare message fixed bin (71);
105 declare 1 auto_fnp_msg aligned like fnp_msg;
106
107
108
109
110
111
112 dcl (addr, addrel, addwordno, baseno, bin, bit, clock, divide, fixed, min,
113 null, segno, string, substr, unspec) builtin;
114
115
116
117
118 dcl config_$find_2 entry (character (4) aligned, character (4) aligned, pointer);
119 dcl uncp_multiplexer$assign entry (fixed binary, fixed binary (35));
120 dcl uncp_multiplexer$unassign entry (fixed binary, fixed binary (35));
121 dcl uncp_multiplexer$fnp_lock entry (pointer, fixed binary (35));
122 dcl uncp_multiplexer$fnp_unlock entry (pointer);
123 dcl get_fnp_name_ entry (fixed bin) returns (char (32));
124 dcl ioam_$assign entry (fixed bin, entry, fixed bin (35));
125 dcl ioam_$unassign entry (fixed bin, fixed bin (35));
126 dcl priv_channel_manager$get_devx entry (char (*), fixed bin, fixed bin (35));
127 dcl dn355_util$compute_parity entry (bit (36)) returns (bit (36));
128 dcl absadr entry (ptr, fixed bin (35)) returns (fixed bin (24));
129 dcl ioi_page_table$get entry (fixed binary (19), fixed binary, fixed binary (35));
130 dcl ioi_page_table$ptx_to_ptp entry (fixed binary) returns (pointer);
131 dcl ioi_page_table$put entry (fixed binary, fixed binary (35));
132 dcl pxss$notify entry (fixed bin);
133 dcl pxss$addevent entry (fixed bin);
134 dcl pxss$delevent entry (fixed bin);
135 dcl pxss$wait entry;
136 dcl pxss$ring_0_wakeup entry (bit (36) aligned, fixed bin (71), fixed bin (71), fixed bin (35));
137 dcl get_ptrs_$given_segno entry (fixed bin) returns (ptr);
138 dcl uncp$interrupt entry;
139 dcl uncp$send_global_wcd entry (ptr, fixed bin (8), fixed bin, bit (*) aligned);
140 dcl syserr entry options (variable);
141 dcl syserr$error_code entry options (variable);
142 dcl lock$wait entry (ptr, char (4) aligned, fixed bin (35));
143 dcl lock$lock_fast entry (pointer);
144 dcl lock$unlock_fast entry (pointer);
145 dcl lock$unlock entry (ptr, char (4) aligned);
146 dcl pc_abs$wire_abs_contig entry (ptr, fixed bin, fixed bin, fixed bin (35));
147 dcl pc_abs$unwire_abs entry (ptr, fixed bin, fixed bin);
148
149
150
151 dcl (
152 error_table_$io_no_permission,
153 error_table_$invalid_state,
154 error_table_$bad_mpx_load_data,
155 error_table_$no_io_interrupt,
156
157 error_table_$io_configured,
158 error_table_$io_not_configured,
159 error_table_$io_not_assigned,
160 error_table_$io_not_defined
161 ) fixed bin (35) ext static;
162
163 dcl pds$processid bit (36) ext static;
164 dcl pds$process_group_id char (32) ext static;
165 dcl tc_data$initializer_id bit (36) aligned external static;
166 dcl tty_buf$fnp_config_flags (1:8) bit (1) unaligned external static;
167 dcl tty_buf$lct_ptr pointer external static;
168 dcl sst$astsize fixed bin external;
169 dcl sys_info$page_size fixed bin external;
170
171
172
173
174 dcl (
175 FNP_DOWN init (2)
176 ) fixed bin int static options (constant);
177 dcl SIZE_1024 fixed bin int static options (constant) init (1024);
178 dcl NORM_CELL fixed bin int static options (constant) init (3);
179 dcl EMER_CELL fixed bin int static options (constant) init (7);
180 dcl SECONDS_30 fixed bin (35) int static options (constant) init (30000000);
181 dcl MIN_TALLY fixed bin int static options (constant) init (308);
182 dcl BIT_75 bit (6) int static options (constant) init ("75"b3);
183 dcl BIT_76 bit (6) int static options (constant) init ("76"b3);
184 dcl SIZE_256 fixed bin int static options (constant) init (256);
185 dcl LOW_MBX_PTW fixed bin int static options (constant) init (1);
186 dcl HIGH_MBX_PTW fixed bin int static options (constant) init (3);
187 dcl fdump_seg_event char (4) aligned init ("fnpd") static options (constant);
188 dcl cleanup condition;
189
190
191
192
193 dcl tally_words (fnp_tally) bit (36) aligned based;
194
195 dcl 1 dump_355_control aligned based (data_ptr),
196 2 address_mode bit (3) unaligned,
197 2 fnp_address bit (15) unaligned,
198 2 tally fixed bin (17) unaligned;
199
200 dcl 1 dump_6670_control aligned based (data_ptr),
201 2 fnp_address fixed bin (18) unsigned unaligned,
202 2 unpaged bit (1) unaligned,
203 2 mbz bit (5) unaligned,
204 2 tally fixed bin (12) unsigned unaligned;
205
206 dcl 1 load_info aligned based (load_info_ptr),
207 2 ev_chan fixed bin (71),
208 2 no_entries fixed bin,
209 2 entries (0 refer (load_info.no_entries)),
210 3 devx fixed bin,
211 3 baud_rate fixed bin,
212 3 line_type fixed bin,
213 2 version char (4),
214 2 pointeur_image_dns ptr,
215 2 image fixed bin (24),
216 2 etape fixed bin;
217
218
219
220
221
222 dcl 1 d7100 aligned based (data_ptr),
223 2 pcw,
224 3 adr_mode bit (3) unaligned init ("001"b),
225 3 fnp_address fixed bin (15) unsigned unaligned,
226 3 poids_fort bit (1) unaligned init ("1"b),
227 3 pad3 bit (5) unaligned init ("00000"b),
228 3 tally fixed bin (12) unsigned unaligned,
229 2 working_location (7) fixed bin (35) unaligned,
230 2 verrou_mot,
231 3 pad bit (35) unaligned,
232 3 verrou bit (1) unaligned,
233 2 control_information unaligned,
234 3 pad1 bit (1) unaligned,
235 3 administrative_header bit (4) unaligned,
236 3 node_type_ofresponder bit (4) unaligned,
237 3 pad2 bit (1) unaligned,
238 3 software_level_of_responder bit (8) unaligned,
239 3 node_ID_of_responder bit (18) unaligned,
240 3 Time_of_response bit (36) unaligned,
241 3 Node_ID_of_originator bit (18) unaligned,
242 3 pad3 bit (1) unaligned,
243 3 Origin_type bit (8) unaligned,
244 3 pad4 bit (1) unaligned,
245 3 Specific_origin bit (8) unaligned,
246 3 pad5 bit (1) unaligned,
247 3 RFU bit (8) unaligned,
248 3 pad6 bit (1) unaligned,
249 3 Type bit (8) unaligned,
250 3 pad7 bit (1) unaligned,
251 3 Class bit (8) unaligned,
252 3 pad8 bit (1) unaligned,
253 3 Code bit (8) unaligned,
254 3 pad8b bit (2) unaligned,
255 3 Length_of_commmand bit (16) unaligned,
256 3 pad9 bit (1) unaligned,
257 3 Format_of_response bit (8) unaligned,
258 3 pad10 bit (1) unaligned,
259 3 Importance_level bit (8) unaligned,
260 3 Length_of_response bit (18) unaligned,
261 3 S2_link_ident bit (18) unaligned;
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294 ^L
295 load:
296 entry (a_fnp_no, a_data_ptr, a_code);
297
298
299
300
301
302 fnp_no = a_fnp_no;
303 load_info_ptr = a_data_ptr;
304 call validate_fnp_ret ("load");
305 call validate_assigned_ret ("load");
306
307 if datanet_info.trace
308 then call syserr (ANNOUNCE, "uncp_util$load: FNP ^d ADDR ^o", fnp_no, auto_absadr);
309
310 call assign_interrupt (uncp$interrupt, code);
311
312 if fnp_info.bootloading
313 then do;
314 code = error_table_$invalid_state;
315 call syserr (ANNOUNCE, "uncp_util$load: FNP load already in progress for FNP ^a.", fnp_info.fnp_tag);
316 go to load_return;
317 end;
318
319
320 if fnp_info.running
321 then do;
322 code = error_table_$invalid_state;
323 if datanet_info.trace
324 then call syserr (ANNOUNCE, "uncp_util$load: FNP ^a is running.", fnp_info.fnp_tag);
325 go to load_return;
326 end;
327
328
329
330
331 if load_info.no_entries ^= fnp_info.no_of_channels
332 then do;
333
334 a_code = error_table_$bad_mpx_load_data;
335 go to load_return;
336 end;
337
338 n_pcbs = fnp_info.no_of_channels;
339
340 do i = 1 to load_info.no_entries;
341 pcbp = addr (fnp_info.pcb_array_ptr -> pcb_array (i));
342 if load_info (i).devx ^= pcb.devx
343 then do;
344 a_code = error_table_$bad_mpx_load_data;
345 go to load_return;
346 end;
347 pcb.baud_rate = load_info (i).baud_rate;
348 pcb.line_type = load_info (i).line_type;
349
350
351 end;
352
353
354
355 version = " ";
356
357 fnp_info.boot_ev_chan = load_info.ev_chan;
358 fnp_info.boot_process_id = pds$processid;
359 fnp_info.version = version;
360 fnp_info.fnp_mem_size = fnp_mem_size * SIZE_1024;
361 fnp_info.bootloading = "1"b;
362
363 datanet_mbx.dia_pcw.command = ""b;
364 datanet_mbx.mailbox_requests = 0;
365 datanet_mbx.term_inpt_mpx_wd = "0"b;
366 datanet_mbx.last_mbx_req_count = 0;
367 string (datanet_mbx.mbx_used_flags) = "0"b;
368
369 datanet_mbx.crash_data.fault_code = 0;
370 datanet_mbx.crash_data.ic = 0;
371 datanet_mbx.crash_data.iom_fault_status = 0;
372 datanet_mbx.crash_data.fault_word = 0;
373
374
375 ttybp = addr (tty_buf$);
376 fnp_dump_ptr = addr (fnp_dump_seg$);
377
378
379 deux_ten:
380 send_wcd:
381
382 call uncp$send_global_wcd (fnpp, init_complete, 0, ""b);
383
384
385
386 code = 0;
387 go to fin;
388
389
390 unwire_load_buffer:
391 call unwire_dump_seg;
392 restore_load_interrupt:
393 call assign_interrupt (uncp$interrupt, code);
394
395 unlock_load_seg:
396 call lock$unlock (addr (fnp_dump_seg.lock), fdump_seg_event);
397 ret_bad_load_code:
398 fin:
399 a_code = code;
400 return;
401
402 load_return:
403 if code ^= 0 & (datanet_info.trace | datanet_info.debug_stop)
404 then do;
405 call syserr$error_code (ANNOUNCE, code, "uncp_util$load: Error loading FNP ^a.", fnp_info.fnp_tag);
406 call STOP_CHECK ("load");
407 end;
408 a_code = code;
409 return;
410 ^L
411
412 info:
413 entry (a_fnp_no, a_absadr, norm_int_cell, emergency_int_cell, a_code);
414
415
416
417 fnp_no = a_fnp_no;
418 call validate_fnp_ret ("info");
419
420 a_absadr = absadr (fnp_info.mbx_pt, code);
421 if code = 0
422 then do;
423 norm_int_cell = NORM_CELL;
424 emergency_int_cell = EMER_CELL;
425 end;
426
427 a_code = code;
428 return;
429 ^L
430 fill_page_table:
431 entry (a_fnp_no, a_code);
432
433 fnp_no = a_fnp_no;
434 call validate_fnp_ret ("fill_page_table");
435 call validate_assigned_ret ("fill_page_table");
436 if fnp_info.ptx ^= -1 | fnp_info.ptp ^= null ()
437 then do;
438 call syserr (ANNOUNCE, "uncp_util$fill_page_table: page table already assigned for FNP ^a.",
439 fnp_info.fnp_tag);
440 call STOP_CHECK ("fill_page_table");
441 end;
442 call get_page_table (code);
443 if code ^= 0 & (datanet_info.trace | datanet_info.debug_stop)
444 then do;
445 call syserr$error_code (ANNOUNCE, code, "uncp_util$fill_page_table: ioi_page_table$get failed for FNP ^a.",
446 fnp_info.fnp_tag);
447 call STOP_CHECK ("fill_page_table");
448 end;
449 a_code = code;
450 return;
451
452 free_page_table:
453 entry (a_fnp_no, a_code);
454
455 fnp_no = a_fnp_no;
456 call validate_fnp_ret ("free_page_table");
457 if fnp_info.ptx = -1
458 then do;
459 call syserr (ANNOUNCE, "uncp_util$free_page_table: no page table assigned for FNP ^a.", fnp_info.fnp_tag);
460 go to ret_bad_code;
461 end;
462 call ioi_page_table$put (fnp_info.ptx, code);
463 fnp_info.ptx = -1;
464 fnp_info.ptp = null ();
465 a_code = code;
466 return;
467 ^L
468
469
470
471
472
473
474
475
476 configure:
477 entry (a_fnp_no, a_code);
478
479 fnp_no = a_fnp_no;
480 call validate_fnp_ret ("configure");
481 call lock_fnp;
482 if fnp_info.available
483 then do;
484 code = error_table_$io_configured;
485 if datanet_info.trace | datanet_info.debug_stop
486 then call syserr (ANNOUNCE, "uncp_util$configure: FNP ^a already configured.", fnp_info.fnp_tag);
487 call STOP_CHECK ("configure");
488 go to configure_return;
489 end;
490 fnp_info.available = "1"b;
491 fnp_info.io_manager_assigned = "0"b;
492 fnp_info.flags = "0"b;
493 configure_return:
494 call unlock_fnp;
495 if code = 0
496 then do;
497 call config_$find_2 ("prph", "fnp" || fnp_info.fnp_tag, prph_fnp_cardp);
498 prph_fnp_card.state = "on";
499 call syserr (ANNOUNCE, "uncp_util: FNP ^a added to configuration^[ by ^a^].", fnp_info.fnp_tag,
500 pds$processid ^= tc_data$initializer_id, pds$process_group_id);
501 end;
502 a_code = code;
503 return;
504
505
506
507
508
509
510
511
512 deconfigure:
513 entry (a_fnp_no, a_code);
514
515 fnp_no = a_fnp_no;
516 call validate_fnp_ret ("deconfigure");
517 call lock_fnp;
518
519 if ^fnp_info.available
520 then do;
521 code = error_table_$io_not_configured;
522 go to deconfigure_return;
523 end;
524
525 fnp_info.available = "0"b;
526
527 if ^fnp_info.io_manager_assigned
528 then go to deconfigure_return;
529
530
531
532 if fnp_info.t_and_d_in_progress
533 then do;
534 call unlock_fnp;
535 call release_t_and_d;
536 go to deconfigure_return_unlocked;
537 end;
538 else do;
539 call mask_dia;
540 call uncp_multiplexer$unassign (fnp_no, (0));
541
542 auto_fnp_msg.fnp_no = fnp_info.fnp_number;
543 auto_fnp_msg.state = FNP_DOWN;
544 auto_fnp_msg.flags = "0"b;
545 auto_fnp_msg.deconfigured = "1"b;
546 unspec (message) = unspec (auto_fnp_msg);
547 call pxss$ring_0_wakeup (fnp_info.boot_process_id, fnp_info.boot_ev_chan, message, (0));
548 end;
549
550
551
552 deconfigure_return:
553 call unlock_fnp;
554 deconfigure_return_unlocked:
555 if code = 0
556 then do;
557 call config_$find_2 ("prph", "fnp" || fnp_info.fnp_tag, prph_fnp_cardp);
558 prph_fnp_card.state = "off";
559 call syserr (ANNOUNCE, "uncp_util: FNP ^a deleted from configuration^[ by ^a^].", fnp_info.fnp_tag,
560 pds$processid ^= tc_data$initializer_id, pds$process_group_id);
561 end;
562 a_code = code;
563 return;
564 ^L
565 abort:
566 entry (a_fnp_no, a_code);
567
568
569 fnp_no = a_fnp_no;
570 call validate_fnp_ret ("abort");
571 fnp_info.bootloading, fnp_info.running = "0"b;
572 a_code = code;
573 return;
574 ^L
575
576 fdump:
577 entry (a_fnp_no, a_fnp_type, a_fnp_mem_size, a_ptr, a_code);
578
579
580
581
582
583
584
585
586
587
588
589
590 fnp_no = a_fnp_no;
591 fnp_type = a_fnp_type;
592 fnp_mem_size = a_fnp_mem_size;
593 segptr = a_ptr;
594
595 call validate_fnp_ret ("fdump");
596
597
598 ttybp = addr (tty_buf$);
599 fnp_dump_ptr = addr (fnp_dump_seg$);
600 on cleanup
601 begin;
602 if fnp_dump_seg.lock = pds$processid
603 then call lock$unlock (addr (fnp_dump_seg.lock), fdump_seg_event);
604 end;
605 go to ret_bad_code;
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682 unlock_dump_seg:
683 call lock$unlock (addr (fnp_dump_seg.lock), fdump_seg_event);
684 ret_bad_code:
685 a_code = code;
686 return;
687
688
689 fdump_seg_io:
690 proc (a_diaop);
691
692 dcl a_diaop bit (6) aligned;
693
694 start_time = clock ();
695 fnp_dump_seg.fdump = "1"b;
696 call pxss$addevent (tty_ev);
697 call connect_to_dia (a_diaop);
698 call pxss$wait;
699
700 do while (fnp_dump_seg.fdump);
701 if clock () - start_time > SECONDS_30
702 then do;
703 code = error_table_$no_io_interrupt;
704 return;
705 end;
706
707 call pxss$addevent (tty_ev);
708 if fnp_info.t_and_d_in_progress
709 then if fnp_info.t_and_d_lev_3_occurred | fnp_info.t_and_d_lev_7_occurred
710 then do;
711 code = 0;
712 return;
713 end;
714 if fnp_dump_seg.fdump
715 then call pxss$wait;
716 else call pxss$delevent (tty_ev);
717 end;
718 code = 0;
719 end fdump_seg_io;
720
721 dump_interrupt:
722 entry (a_fnp_no, a_level, a_dummy);
723
724
725
726 dcl a_dummy bit (36) aligned parameter;
727
728 fnp_dump_ptr = addr (fnp_dump_seg$);
729 infop = addr (dn355_data$);
730 if datanet_info.trace
731 then call syserr (ANNOUNCE,
732 "uncp_util (dump_interrupt): Interrupt for FNP ^d level ^d. fnp_dump_seg.fdump = ""^b""b", a_fnp_no,
733 a_level, fnp_dump_seg.fdump);
734 if fnp_dump_seg.fdump
735 then do;
736 fnp_dump_seg.fdump = "0"b;
737 call pxss$notify (tty_ev);
738 end;
739 return;
740 ^L
741
742 ^L
743
744
745
746
747
748 fnp_tandd_setup:
749 entry (a_fnp_no, a_ev_chan, a_code);
750
751 fnp_no = a_fnp_no;
752 call validate_fnp_ret ("fnp_tandd_setup");
753
754
755
756
757
758 temp_fnp_name = get_fnp_name_ (fnp_no);
759 if fnp_info.lcte_ptr = null
760 then do;
761 call priv_channel_manager$get_devx (temp_fnp_name, devx, code);
762 if code ^= 0
763 then go to ret_bad_code;
764 fnp_info.lcte_ptr = addr (tty_buf$lct_ptr -> lct.lcte_array (devx));
765 end;
766
767 call lock_fnp;
768
769 if fnp_info.bootloading | fnp_info.running | fnp_info.t_and_d_in_progress
770 then do;
771 code = error_table_$invalid_state;
772 go to tandd_setup_loses_unlock;
773 end;
774
775 call uncp_multiplexer$assign (fnp_no, code);
776 if code ^= 0
777 then do;
778 call syserr$error_code (ANNOUNCE, code, "uncp_util: channel assignment failed for FNP ^a.",
779 fnp_info.fnp_tag);
780 go to tandd_setup_loses_unlock;
781 end;
782
783 call ioam_$assign ((fnp_info.io_manager_chx), fnp_tandd_release_handler, code);
784 if code ^= 0
785 then do;
786 call syserr$error_code (ANNOUNCE, code, "uncp_util: ioam_$assign failed for FNP ^a.", fnp_info.fnp_tag);
787 go to tandd_setup_loses_unlock;
788 end;
789 fnp_info.boot_process_id = pds$processid;
790 fnp_info.t_and_d_lev_3_occurred, fnp_info.t_and_d_lev_7_occurred = "0"b;
791 call syserr (ANNOUNCE, "uncp_util: assigned FNP ^a to ^a for T & D.", temp_fnp_name, pds$process_group_id);
792 fnp_info.t_and_d_in_progress = "1"b;
793
794 tandd_setup_loses_unlock:
795 if code = 0
796 then fnp_info.boot_ev_chan = a_ev_chan;
797 call unlock_fnp;
798 a_code = code;
799 return;
800
801
802
803
804 fnp_tandd_release_handler:
805 entry (a_devx, a_code);
806
807 devx = a_devx;
808 infop = addr (dn355_data$);
809 fnp_dump_ptr = addr (fnp_dump_seg$);
810 on cleanup
811 begin;
812 if fnp_dump_seg.lock = pds$processid
813 then call lock$unlock (addr (fnp_dump_seg.lock), fdump_seg_event);
814 end;
815 do fnp_no = 1 to datanet_info.no_of_355s;
816 fnpp = addr (datanet_info.per_datanet (fnp_no));
817 if devx = fnp_info.io_manager_chx
818 then if fnp_info.t_and_d_in_progress
819 then call release_t_and_d;
820 end;
821 return;
822
823
824
825
826
827
828
829
830
831
832 fnp_tandd_detach:
833 entry (a_fnp_no, a_code);
834 fnp_no = a_fnp_no;
835
836 call validate_fnp_tandd_ret ("fnp_tandd_detach");
837 call lock_fnp;
838 call validate_assigned_ret ("fnp_tandd_detach");
839
840 call mask_dia;
841
842 fnp_info.boot_process_id = "000000000000"b3;
843 fnp_info.t_and_d_in_progress = "0"b;
844 fnp_info.t_and_d_lev_3_occurred, fnp_info.t_and_d_lev_7_occurred = "0"b;
845 call ioam_$unassign ((fnp_info.io_manager_chx), (0));
846 call uncp_multiplexer$unassign (fnp_no, code);
847 if code ^= 0
848 then call syserr$error_code (ANNOUNCE, code, "uncp_util: io channel unassignment failed for FNP ^a.",
849 fnp_info.fnp_tag);
850 call syserr (ANNOUNCE, "uncp_util: releasing FNP ^a from ^a", fnp_info.fnp_id.fnp_tag, pds$process_group_id);
851 call unlock_fnp;
852 a_code = 0;
853 return;
854
855
856
857
858 fnp_tandd_mask:
859 entry (a_fnp_no, a_code);
860 fnp_no = a_fnp_no;
861 call validate_fnp_tandd_ret ("fnp_tandd_mask");
862 call lock_fnp;
863 call validate_assigned_ret ("fnp_tandd_mask");
864
865 call mask_dia;
866 call unlock_fnp;
867 a_code = 0;
868 return;
869
870
871
872
873 fnp_tandd_send_int:
874 entry (a_fnp_no, a_level, a_code);
875 fnp_no = a_fnp_no;
876 call validate_fnp_tandd_ret ("fnp_tandd_send_int");
877 call lock_fnp;
878 call validate_assigned_ret ("fnp_tandd_send_int");
879
880 fnp_info.t_and_d_lev_3_occurred, fnp_info.t_and_d_lev_7_occurred = "0"b;
881 call connect_to_dia ("71"b3);
882 call unlock_fnp;
883
884 a_code = 0;
885 return;
886
887
888
889
890 fnp_tandd_get_ints:
891 entry (a_fnp_no, a_ints, a_code);
892 fnp_no = a_fnp_no;
893 call validate_fnp_tandd_ret ("fnp_tandd_get_ints");
894 call lock_fnp;
895 call validate_assigned_ret ("fnp_tandd_get_ints");
896 a_ints = fnp_info.t_and_d_lev_3_occurred || fnp_info.t_and_d_lev_7_occurred;
897 fnp_info.t_and_d_lev_3_occurred, fnp_info.t_and_d_lev_7_occurred = "0"b;
898 call unlock_fnp;
899 a_code = 0;
900 return;
901
902
903
904
905 fnp_tandd_read:
906 entry (a_fnp_no, a_ptr, a_count, a_fnp_addr, a_fnp_type, a_code);
907 opcode = BIT_75;
908 go to fnp_t_and_d_rw_merge;
909
910
911
912
913 fnp_tandd_write:
914 entry (a_fnp_no, a_ptr, a_count, a_fnp_addr, a_fnp_type, a_code);
915 opcode = BIT_76;
916 fnp_t_and_d_rw_merge:
917
918
919 fnp_no = a_fnp_no;
920 segptr = a_ptr;
921 nwords = a_count;
922 fnp_type = a_fnp_type;
923 fnp_addr = a_fnp_addr;
924 fnp_dump_ptr = addr (fnp_dump_seg$);
925 call validate_fnp_tandd_ret ("fnp_tandd_rw");
926
927 on cleanup
928 begin;
929 if fnp_dump_seg.lock = pds$processid
930 then call lock$unlock (addr (fnp_dump_seg.lock), fdump_seg_event);
931 end;
932
933 data_ptr = addr (fnp_dump_seg.data);
934
935 call lock$wait (addr (fnp_dump_seg.lock), fdump_seg_event, code);
936 if code ^= 0
937 then go to ret_bad_code;
938 if fnp_type = DN6670
939 then dump_6670_control.unpaged = "1"b;
940 else dump_355_control.address_mode = "1"b3;
941 offset = 0;
942 do while (nwords > 0);
943 fnp_tally = min (MIN_TALLY, nwords);
944 nwords = nwords - fnp_tally;
945 call setup_dump_ctl_word;
946 if opcode = BIT_76
947 then addr (fnp_dump_seg.data (2)) -> tally_words = addrel (segptr, offset) -> tally_words;
948 call wire_dump_seg;
949 if code ^= 0
950 then go to unlock_dump_seg;
951 fnp_info.t_and_d_lev_3_occurred, fnp_info.t_and_d_lev_7_occurred = "0"b;
952 fnp_info.t_and_d_notify_requested = "1"b;
953
954 call fdump_seg_io (opcode);
955
956 fnp_info.t_and_d_lev_3_occurred, fnp_info.t_and_d_lev_7_occurred = "0"b;
957 call unwire_dump_seg;
958 if code ^= 0
959 then go to unlock_dump_seg;
960 if opcode = BIT_75
961 then addrel (segptr, offset) -> tally_words = addr (fnp_dump_seg.data (2)) -> tally_words;
962
963 offset = offset + fnp_tally;
964 end;
965 code = 0;
966 go to unlock_dump_seg;
967 ^L
968
969 validate_assigned_ret:
970 procedure (caller);
971
972 declare caller char (32);
973
974 if ^fnp_info.io_manager_assigned
975 then do;
976 code = error_table_$io_not_assigned;
977 if datanet_info.trace | datanet_info.debug_stop
978 then call syserr$error_code (ANNOUNCE, code,
979 "uncp_util$validate_assigned_ret (^a): IO manager assignment lacking.", caller);
980 call STOP_CHECK ("validate_assigned_ret");
981 call unlock_fnp;
982 go to ret_bad_code;
983 end;
984 return;
985 end validate_assigned_ret;
986
987
988 validate_fnp_ret:
989 procedure (caller);
990
991 declare caller char (32);
992
993
994
995 infop = addr (dn355_data$);
996
997 if fnp_no <= 0 | fnp_no > max_no_355s
998 then do;
999 code = error_table_$io_not_defined;
1000 ERROR:
1001 if datanet_info.trace | datanet_info.debug_stop
1002 then call syserr$error_code (ANNOUNCE, code, "uncp_util$^a: Invalid call for FNP ^d.", caller, fnp_no);
1003 call STOP_CHECK (caller);
1004 go to ret_bad_code;
1005 end;
1006
1007 if ^tty_buf$fnp_config_flags (fnp_no)
1008 then do;
1009 fnpp = null;
1010 code = error_table_$io_not_defined;
1011 go to ERROR;
1012 end;
1013
1014 code = 0;
1015 fnpp = addr (datanet_info.per_datanet (fnp_no));
1016 mbxp = fnp_info.mbx_pt;
1017 if datanet_info.trace
1018 then call syserr (ANNOUNCE, "uncp_util$^a: Tracing call for fnp ^a.", caller, fnp_info.fnp_tag);
1019
1020 return;
1021
1022 end validate_fnp_ret;
1023 ^L
1024
1025
1026 validate_fnp_tandd_ret:
1027 proc (caller);
1028
1029 declare caller char (32);
1030
1031 call validate_fnp_ret (caller);
1032 if ^fnp_info.t_and_d_in_progress
1033 then code = error_table_$invalid_state;
1034 else if fnp_info.boot_process_id ^= pds$processid
1035 then code = error_table_$io_no_permission;
1036 if code ^= 0
1037 then do;
1038 if (datanet_info.trace | datanet_info.debug_stop)
1039 then call syserr$error_code (ANNOUNCE, code, "uncp_util$^a: Invalid call.", caller);
1040 go to ret_bad_code;
1041 end;
1042 return;
1043 end validate_fnp_tandd_ret;
1044 ^L
1045 setup_dump_ctl_word:
1046 proc;
1047
1048 d7100.pcw.fnp_address = divide (2 * offset, SIZE_256, 14, 0);
1049
1050 d7100.pcw.tally = fixed (fnp_tally, 11);
1051
1052 end;
1053
1054 wire_dump_seg:
1055 proc;
1056
1057 astep = get_ptrs_$given_segno (fixed (baseno (fnp_dump_ptr), 17));
1058 call pc_abs$wire_abs_contig (astep, 0, 1, code);
1059 if code = 0
1060 then abs_address = absadr (fnp_dump_ptr, code);
1061 if code = 0
1062 then abs_addr_string = bit (fixed (abs_address + 2, 24), 24);
1063
1064 end;
1065
1066 unwire_dump_seg:
1067 proc;
1068
1069 astep = get_ptrs_$given_segno (fixed (baseno (fnp_dump_ptr), 17));
1070 call pc_abs$unwire_abs (astep, 0, 1);
1071 return;
1072 end unwire_dump_seg;
1073
1074
1075 assign_interrupt:
1076 proc (handler, code);
1077
1078
1079
1080 dcl handler entry;
1081
1082 dcl iom_code fixed bin (35);
1083 dcl code fixed bin (35);
1084
1085 call lock_fnp;
1086 if ^fnp_info.io_manager_assigned
1087 then if ^fnp_info.available
1088 then do;
1089 code = error_table_$io_not_configured;
1090 return;
1091 end;
1092
1093
1094
1095 if fnp_info.io_manager_assigned
1096 then do;
1097 call io_manager$unassign (fnp_info.io_manager_chx, code);
1098 if code ^= 0
1099 then call syserr$error_code (CRASH, code, "uncp_util: Could not unassign FNP ^a at reassign_interrupt.",
1100 fnp_info.fnp_tag);
1101 fnp_info.io_manager_assigned = "0"b;
1102 end;
1103
1104 call io_manager$assign (fnp_info.io_manager_chx, fnp_info.io_chanid, handler, (fnp_no), (null ()), iom_code);
1105 call unlock_fnp;
1106 if code = 0
1107 then do;
1108 code = iom_code;
1109 fnp_info.io_manager_assigned = "1"b;
1110 end;
1111
1112 return;
1113
1114 end assign_interrupt;
1115
1116
1117
1118
1119
1120
1121
1122
1123 connect_to_dia:
1124 proc (cmd);
1125
1126
1127
1128 dcl cmd bit (6) aligned;
1129 dcl 1 ima aligned like io_manager_arg;
1130
1131 datanet_mbx.dia_pcw.zero = substr (abs_addr_string, 7, 18);
1132
1133 datanet_mbx.dia_pcw.mbx_no = substr (abs_addr_string, 1, 6);
1134
1135 datanet_mbx.dia_pcw.command = cmd;
1136
1137
1138
1139 string (datanet_mbx.dia_pcw) = dn355_util$compute_parity (string (datanet_mbx.dia_pcw));
1140
1141 ima.chx = fnp_info.io_manager_chx;
1142 ima.ptp = null ();
1143 call io_manager$connect_direct (ima);
1144
1145 return;
1146 end ;
1147 mask_dia:
1148 procedure;
1149 call io_manager$mask (fnp_info.io_manager_chx);
1150 end mask_dia;
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178 release_t_and_d:
1179 procedure;
1180
1181 declare unlock_dump_seg bit (1) aligned;
1182
1183 call lock$wait (addr (fnp_dump_seg.lock), fdump_seg_event, code);
1184
1185 unlock_dump_seg = (code = 0);
1186 call syserr (0, "uncp_util: force detaching FNP ^a from process ^w.", fnp_info.fnp_id.fnp_tag,
1187 fnp_info.boot_process_id);
1188 call lock_fnp;
1189 fnp_info.boot_process_id = "000000000000"b3;
1190 fnp_info.boot_ev_chan = 0;
1191 fnp_info.t_and_d_in_progress = "0"b;
1192 fnp_info.t_and_d_lev_3_occurred, fnp_info.t_and_d_lev_7_occurred = "0"b;
1193 call uncp_multiplexer$unassign (fnp_no, code);
1194 if code ^= 0
1195 then call syserr$error_code (ANNOUNCE, code, "uncp_util: io channel unassignment failed for FNP ^a.",
1196 fnp_info.fnp_tag);
1197 call unlock_fnp;
1198 if unlock_dump_seg
1199 then call lock$unlock (addr (fnp_dump_seg.lock), fdump_seg_event);
1200 return;
1201 end release_t_and_d;
1202
1203
1204 lock_fnp:
1205 procedure;
1206
1207 declare code fixed bin (35);
1208
1209 if locked | config_locked
1210 then call syserr (CRASH, "uncp_util: lock_fnp called with lock locked.");
1211 locked, config_locked = "0"b;
1212
1213 call lock$lock_fast (addr (datanet_info.configuration_lock));
1214 config_locked = "1"b;
1215 if fnp_info.lcte_ptr = null ()
1216 then return;
1217 else if ^fnp_info.lcte_ptr -> lcte.initialized
1218 then return;
1219
1220
1221
1222 call uncp_multiplexer$fnp_lock (fnpp, code);
1223 if code = 0
1224 then do;
1225 locked = "1"b;
1226 call lock$unlock_fast (addr (datanet_info.configuration_lock));
1227
1228
1229 config_locked = "0"b;
1230 end;
1231 return;
1232
1233 unlock_fnp:
1234 entry;
1235
1236 if locked
1237 then call uncp_multiplexer$fnp_unlock (fnpp);
1238 locked = "0"b;
1239 if config_locked
1240 then call lock$unlock_fast (addr (datanet_info.configuration_lock));
1241 config_locked = "0"b;
1242 return;
1243 end lock_fnp;
1244
1245
1246 STOP_CHECK:
1247 procedure (Tracer);
1248 declare Tracer char (*);
1249
1250 if datanet_info.debug_stop
1251 then call syserr (CRASH, "uncp_util$^a: Debugging stop (type go to continue).", Tracer);
1252 return;
1253 end STOP_CHECK;
1254 ^L
1255
1256 get_page_table:
1257 procedure (code);
1258
1259 declare pagex fixed bin;
1260 declare px fixed bin;
1261 declare 1 seg_pt (0:255) aligned like l68_core_ptw based (ptp);
1262 declare ptp pointer;
1263 declare code fixed bin (35);
1264
1265 io_page_table_size = SIZE_256;
1266 call ioi_page_table$get (io_page_table_size * sys_info$page_size, fnp_info.ptx, code);
1267
1268 if code ^= 0
1269 then return;
1270 fnp_info.ptp, ioptp = ioi_page_table$ptx_to_ptp (fnp_info.ptx);
1271
1272 unspec (page_table) = ""b;
1273
1274
1275
1276
1277
1278 do px = LOW_MBX_PTW to HIGH_MBX_PTW;
1279 io_ptwp = addr (page_table.ptw (px));
1280 io_ptw.address = px;
1281 io_ptw.write = "1"b;
1282 io_ptw.valid = "1"b;
1283 end;
1284
1285
1286
1287 astep = get_ptrs_$given_segno (segno (addr (tty_buf$)));
1288 pagex = FIRST_TTY_BUF_PAGEX;
1289 ptp = addwordno (astep, sst$astsize);
1290 do px = 0 to bin (aste.csl, 9) - 1;
1291 io_ptwp = addr (page_table.ptw (pagex));
1292 io_ptw.address = seg_pt (px).frame;
1293 io_ptw.write = "1"b;
1294 io_ptw.valid = "1"b;
1295 pagex = pagex + 1;
1296 end;
1297 return;
1298
1299 fill_bootload_page_table:
1300 entry;
1301
1302
1303
1304 pagex = FIRST_BOOTLOAD_PAGEX;
1305 ptp = addwordno (astep, sst$astsize);
1306 auto_absadr = pagex * sys_info$page_size;
1307 ioptp = fnp_info.ptp;
1308
1309 do px = 0 to fnp_info.n_pages_wired - 1;
1310 io_ptwp = addr (page_table.ptw (pagex));
1311 io_ptw.address = seg_pt (px).frame;
1312 io_ptw.write = "0"b;
1313 io_ptw.valid = "1"b;
1314 pagex = pagex + 1;
1315 end;
1316
1317 if datanet_info.trace
1318 then do px = 0 to 255;
1319 if unspec (page_table.ptw (px)) ^= ""b
1320 then call syserr (ANNOUNCE, "uncp_util: ptw at ^4o = ^w", px, unspec (page_table.ptw (px)));
1321 end;
1322
1323 return;
1324
1325 end get_page_table;
1326
1327
1328
1329
1330
1331 %page; %include aste;
1332 %page; %include config_prph_fnp_card;
1333 %page; %include dn355_mailbox;
1334 %page; %include mailbox_ops;
1335 %page; %include lct;
1336 %page; %include dn355_data;
1337 %page; %include pcb;
1338 %page; %include fnp_dump_seg;
1339 %page; %include fnp_types;
1340 %page; %include io_manager_dcls;
1341 %page; %include io_page_tables;
1342 %page; %include io_chnl_util_dcls;
1343 %page; %include "ptw.l68";
1344 declare ptp pointer;
1345 %page; %include syserr_constants;
1346 %page; %include tty_buf;
1347 %include fnp_mpx_msg_;
1348
1349 ^L
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479 end uncp_util;