COMPILATION LISTING OF SEGMENT patch_firmware Compiled by: Multics PL/I Compiler, Release 28e, of February 14, 1985 Compiled at: Honeywell Multics Op. - System M Compiled on: 04/02/85 1042.1 mst Tue Options: optimize map 1 /* *********************************************************** 2* * * 3* * Copyright, (C) Honeywell Information Systems Inc., 1982 * 4* * * 5* * Copyright (c) 1972 by Massachusetts Institute of * 6* * Technology and Honeywell Information Systems, Inc. * 7* * * 8* *********************************************************** */ 9 10 /* format: style4,delnl,insnl,^ifthendo */ 11 12 /* 13* PATCH_FIRMWARE: Implements the patch_firmware and dump_firmware commands. 14* These commands patch and dump the contents of segments containing firmware 15* modules. 16* 17* Written July 1976 by Larry Johnson. 18* Modified 84June by Art Beattie to deal with DAU firmware. 19* Modified March 1985 by Paul Farley to fix minor bug with DAU checking (PBF). 20**/ 21 22 patch_firmware: 23 proc; 24 25 /* Start here for patch_firmware command */ 26 27 name = "patch_firmware"; 28 patch = "1"b; 29 go to start; 30 31 /* Start here for dump_firmware command */ 32 33 dump_firmware: 34 entry; 35 36 name = "dump_firmware"; 37 patch = "0"b; 38 39 /* Command starts here */ 40 41 start: 42 call cu_$arg_list_ptr (arg_list_ptr); 43 call cu_$arg_count (nargs); 44 if nargs = 0 45 then do; 46 if patch 47 then call ioa_ ("Usage: ^a path cs/rw addr(hex) word1(hex) ... wordn(hex)", name); 48 else call ioa_ ("Usage: ^a path cs/rw/size addr(hex) count(hex)", name); 49 return; 50 end; 51 52 on cleanup call clean_up; 53 54 call scan_args; 55 56 call find_fw; 57 58 if size_sw 59 then call print_size; 60 else if patch 61 then call patch_fw; 62 else call dump_fw; 63 64 done: 65 call clean_up; 66 if patch_worked 67 then call ioa_ ("Patch complete."); 68 return; 69 70 /* Procedure to scan argument list */ 71 72 scan_args: 73 proc; 74 75 arg_name = "Pathname"; /* Need path first */ 76 call get_arg; 77 call expand_path_ (arg_ptr, arg_len, addr (dir), addr (ename), code); 78 if code ^= 0 79 then do; 80 call com_err_ (code, name, "^a", arg); 81 go to done; 82 end; 83 84 arg_name = "Memory type"; 85 call get_arg; 86 if arg = "cs" 87 then cs_sw = "1"b; 88 else if arg = "rw" 89 then cs_sw = "0"b; 90 else if ^patch & arg = "size" 91 then do; 92 size_sw = "1"b; 93 return; 94 end; 95 else do; 96 if patch 97 then call com_err_ (0, name, "Second arg must be cs or rw, not ^a.", arg); 98 else call com_err_ (0, name, "Second arg must be cs, rw, or size, not ^a.", arg); 99 go to done; 100 end; 101 102 arg_name = "Address"; 103 address = get_hex_arg (); 104 105 if ^patch 106 then do; 107 arg_name = "Word count"; 108 count = get_hex_arg (); 109 if count < 1 110 then do; 111 call com_err_ (0, name, "Invalid word count: ^a", arg); 112 go to done; 113 end; 114 end; 115 else do; 116 count = nargs - arg_no + 1; 117 if count = 0 118 then do; 119 call com_err_ (error_table_$noarg, name, "Patch data."); 120 go to done; 121 end; 122 if count > 16 123 then do; 124 call com_err_ (error_table_$too_many_args, name, "Patch data."); 125 go to done; 126 end; 127 do i = 1 to count; 128 data (i) = get_hex_arg (); 129 end; 130 end; 131 132 return; 133 end scan_args; 134 135 /* Get next argument */ 136 137 get_arg: 138 proc; 139 140 call cu_$arg_ptr_rel (arg_no, arg_ptr, arg_len, code, arg_list_ptr); 141 if code ^= 0 142 then do; 143 call com_err_ (code, name, "^a", arg_name); 144 go to done; 145 end; 146 arg_no = arg_no + 1; 147 return; 148 149 end get_arg; 150 151 get_hex_arg: 152 proc returns (fixed bin (35)); /* Get next argument in hex */ 153 154 dcl (i, j) fixed bin; 155 dcl v fixed bin (35); 156 157 call get_arg; 158 v = 0; 159 do i = 1 to length (arg); 160 j = index ("0123456789abcdef", substr (arg, i, 1)); 161 if j = 0 162 then do; /* Try caps */ 163 j = index ("ABCDEF", substr (arg, i, 1)); 164 if j = 0 165 then do; /* Still not found */ 166 call com_err_ (0, name, "Invalid hexadecimal number: ^a", arg); 167 go to done; 168 end; 169 j = j + 10; 170 end; 171 v = 16 * v + j - 1; 172 if v > 1111111111111111b 173 then do; /* Too big */ 174 call com_err_ (0, name, "Hexadecimal number not in range 0-FFFF: ^a", arg); 175 go to done; 176 end; 177 end; 178 return (v); 179 180 end get_hex_arg; 181 182 /* Procedure to initiate the firmware segment and decode it */ 183 184 find_fw: 185 proc; 186 187 call hcs_$initiate_count (dir, ename, "", bit_count, 0, seg_ptr, code); 188 if seg_ptr = null 189 then do; 190 call com_err_ (code, name, "^a>^a", dir, ename); 191 go to done; 192 end; 193 194 word_count = divide (bit_count, 36, 17, 0); 195 196 if word_count ^> 10 197 then do; 198 call com_err_ (0, name, "Segment too small to be firmware segment."); 199 go to done; 200 end; 201 if seg (word_count) ^= mpcbot 202 then do; /* Check magic word */ 203 call com_err_ (0, name, "Last word of segment does not contain ^12.3b, which is is BCD for 'MPCBOT'.", 204 mpcbot); 205 go to done; 206 end; 207 208 call gcos_cv_gebcd_ascii_ (addr (seg (word_count - 7)), 6, addr (fw_type)); 209 call gcos_cv_gebcd_ascii_ (addr (seg (word_count - 9)), 6, addr (fw_ident)); 210 call gcos_cv_gebcd_ascii_ (addr (seg (word_count - 6)), 4, addr (fw_name)); 211 call gcos_cv_gebcd_ascii_ (addr (seg (word_count - 8)), 6, addr (fw_rev)); 212 213 if fw_ident = "msp800" 214 then do; /* DAU firmware has to be handled differently. */ 215 dau_sw = "1"b; 216 dau_factor = 2; 217 word_length = 8; 218 words_per_line = 16; 219 end; 220 else do; /* Normal stuff */ 221 dau_sw = "0"b; 222 dau_factor = 1; 223 word_length = 16; 224 words_per_line = 8; 225 end; 226 227 /* Even if DAU firmware, need to have the following. */ 228 229 cs_start = 1; /* Control store starts in beginning */ 230 rw_start = bin (substr (seg (word_count - 5), 1, 18), 18); 231 /* RW start is hidden here */ 232 if rw_start = 0 233 then do; /* No rw overlay, probably itr */ 234 cs_length = word_count - 10; /* Whole seg is control store */ 235 rw_length = 0; /* This says no read write overlay */ 236 end; 237 else do; 238 cs_length = rw_start; /* Control store is everything before read/write */ 239 rw_length = word_count - rw_start - 10; 240 rw_start = rw_start + 1; /* Because array starts at 1 */ 241 end; 242 243 if ((rw_length > 0) | substr (fw_type, 4) = "itr") & fw_type ^= "msp800" 244 then /* If itr, or common firmware but not DAU */ 245 cs_low = 512; /* Adjust control store start */ 246 else cs_low = 0; 247 cs_high = cs_low + 2 * cs_length * dau_factor - 1; 248 rw_low = 0; 249 if rw_length > 0 250 then rw_high = rw_low + 2 * rw_length * dau_factor - 1; 251 else rw_high = 0; 252 253 if size_sw 254 then return; /* If just printing size, no more analysis needed */ 255 256 /* Now that memory overlays are isolated, be sure request is consistent */ 257 258 if dau_sw 259 then do; 260 fw_low = cs_low; 261 fw_high = cs_high + rw_high + 1; 262 mem_name = "dau"; 263 end; 264 265 else if cs_sw 266 then do; /* Working with control store */ 267 fwp = addr (seg (cs_start)); 268 fw_low = cs_low; 269 fw_high = cs_high; 270 mem_name = "control store"; /* In case error printed */ 271 end; 272 else do; 273 if rw_start = 0 274 then do; /* R/W overlay non-existant */ 275 call com_err_ (0, name, "No read/write overlay in segment."); 276 go to done; 277 end; 278 fwp = addr (seg (rw_start)); 279 fw_low = rw_low; 280 fw_high = rw_high; 281 mem_name = "read/write"; 282 end; 283 284 if ^patch 285 then addr_limit = fw_high; /* Allow dump of entire module */ 286 else addr_limit = fw_high - 2 * dau_factor; /* But don't allow patch of checksum word */ 287 288 if address < fw_low | address > addr_limit 289 then do; /* Bad addr */ 290 call com_err_ (0, name, "Starting address not in ^a memory. Range is ^.4b:^.4b", mem_name, 291 bit (bin (fw_low, 16), 16), bit (bin (addr_limit, 16), 16)); 292 go to done; 293 end; 294 if address + count - 1 > addr_limit 295 then do; 296 call com_err_ (0, name, "Ending address not in ^a memory. Range is ^.4b:^.4b", mem_name, 297 bit (bin (fw_low, 16), 16), bit (bin (addr_limit, 16), 16)); 298 go to done; 299 end; 300 301 if dau_sw 302 then do; 303 304 rw_low = cs_high + 1; 305 rw_high = rw_low + rw_high; 306 daup = addr (seg (1)); 307 dau_low = 0; 308 dau_high = rw_high; 309 310 if patch 311 then do i = cs_high - 3 to cs_high; 312 if i >= address & i <= address + count - 1 313 then do; 314 call com_err_ (0, name, "Cannot patch checksum for part one of the DAU firmware; ^.4b:^.4b", 315 bit (bin (cs_high - 3, 16), 16), bit (bin (cs_high, 16), 16)); 316 go to done; 317 end; 318 end; /* check for patching checksum for lower part */ 319 /* This has to be done on both parts of DAU firmware. */ 320 fw_low = 0; 321 fw_high = 2 * cs_length - 1; /* Checksum is done using MPC word length (16 bits) */ 322 fwp = addr (seg (1)); 323 call compute_checksum; 324 325 if get_word (fw_high - 1) ^= checksum 326 then do; 327 call com_err_ (0, name, "Checksum for lower part of DAU firmware is not correct."); 328 go to done; 329 end; 330 331 fwp = addr (seg (rw_start)); 332 fw_high = 2 * rw_length - 1; 333 call compute_checksum; 334 335 if get_word (fw_high - 1) ^= checksum 336 then do; 337 call com_err_ (0, name, "Checksum for upper part of DAU firmware is not correct."); 338 go to done; 339 end; 340 end; /* dau firmware checksum check */ 341 342 else do; 343 call compute_checksum; /* Be sure checksum starts correct */ 344 if get_word (fw_high - 1) ^= checksum 345 then do; 346 call com_err_ (0, name, "Checksum for ^a is not correct.", mem_name); 347 go to done; 348 end; 349 end; /* normal firmware checksum check */ 350 351 return; 352 353 end find_fw; 354 355 /* Procedure that can get a DAU firmware word */ 356 357 get_dau_word: 358 proc (get_address) returns (bit (16)); 359 360 dcl get_address fixed bin; 361 362 return (dau.byte (get_address) || "00"b4); 363 364 end get_dau_word; 365 366 367 /* Procedure that can reconstruct a firmware word */ 368 369 get_mpc_word: 370 proc (get_address) returns (bit (16)); 371 372 dcl get_address fixed bin; 373 374 return (fw.byte1 (get_address) || fw.byte2 (get_address)); 375 376 end get_mpc_word; 377 378 379 /* Procedure which can store a DAU firmware word */ 380 381 put_dau_word: 382 proc (address, new_word); 383 384 dcl (address) fixed bin; 385 dcl new_word bit (16); 386 387 dau.byte (address) = substr (new_word, 1, 8); 388 389 end put_dau_word; 390 391 392 /* Procedure which can store a mpc firmware word */ 393 394 put_mpc_word: 395 proc (address, new_word); 396 397 dcl address fixed bin; 398 dcl new_word bit (16); 399 400 fw.byte1 (address) = substr (new_word, 1, 8); 401 fw.byte2 (address) = substr (new_word, 9, 8); 402 403 end put_mpc_word; 404 405 406 /* Procedure that can compute a checksum from a mpc memory image */ 407 408 compute_checksum: 409 proc; 410 411 dcl sum fixed bin (35); 412 dcl i fixed bin; 413 414 get_word = get_mpc_word; 415 sum = 0; 416 do i = 0 to fw_high - 2; 417 sum = sum + bin (get_word (i), 16); 418 do while (sum > 1111111111111111b); 419 sum = sum - 10000000000000000b; 420 sum = sum + 1; 421 end; 422 end; 423 sum = -sum; 424 checksum = substr (unspec (sum), 21); /* Get last 16 bits */ 425 return; 426 427 end compute_checksum; 428 429 /* Procedure to copy a firmware overlay as a character string for efficiency */ 430 431 copy_fw: 432 proc (from_ptr, to_ptr); 433 434 dcl (from_ptr, to_ptr) ptr; 435 dcl char_len fixed bin; 436 dcl char_overlay char (char_len) based; 437 438 char_len = 2 * (fw_high - fw_low + 1); 439 to_ptr -> char_overlay = from_ptr -> char_overlay; 440 return; 441 442 end copy_fw; 443 444 /* Procedure that can dump firmware words */ 445 446 dump_fw: 447 proc; 448 449 dcl buffer (words_per_line) bit (word_length) aligned; 450 dcl nwords fixed bin; 451 dcl based_buffer (nwords) bit (word_length) aligned based (addr (buffer)); 452 dcl i fixed bin; 453 dcl dump_fw_display char (64); 454 455 if dau_sw 456 then do; 457 get_word = get_dau_word; 458 dump_fw_display = "^4.4b ^(^2.4b ^)"; 459 end; 460 else do; 461 get_word = get_mpc_word; 462 dump_fw_display = "^4.4b ^(^4.4b ^)"; 463 end; 464 465 do while (count > 0); 466 nwords = min (words_per_line, count); /* Words this line */ 467 do i = 1 to nwords; 468 buffer (i) = get_word (address + i - 1); 469 end; 470 call ioa_ (dump_fw_display, bit (bin (address, 16), 16), based_buffer); 471 count = count - nwords; 472 address = address + nwords; 473 end; 474 return; 475 476 end dump_fw; 477 478 /* Procedure to patch firmware */ 479 480 patch_fw: 481 proc; 482 483 dcl (real_fwp, temp_fwp) ptr; 484 dcl (i, patch_address) fixed bin; 485 dcl new_dat bit (16); 486 dcl answer char (3) var; 487 dcl patch_data_display char (64); 488 dcl dau_base fixed bin; 489 dcl patch_checksum_display char (64); 490 dcl ctrl_checksum_display fixed bin; 491 492 dcl 1 query_info aligned, 493 2 version fixed bin init (2), 494 2 yes_or_no bit (1) unal init ("1"b), 495 2 suppress_name bit (1) unal init ("0"b), 496 2 status_code fixed bin (35) init (0), 497 2 query_code fixed bin (35) init (0); 498 499 if dau_sw 500 then do; 501 patch_data_display = "^4.4b ^2.4b to ^2.4b"; 502 get_word = get_dau_word; 503 put_word = put_dau_word; 504 if address < rw_low /* patching either lower or upper but not both */ 505 then do; 506 fwp = addr (seg (1)); 507 fw_high = 2 * cs_length - 1; 508 ctrl_checksum_display = 2; 509 dau_base = 0; 510 end; 511 else do; 512 fwp = addr (seg (rw_start)); 513 fw_high = 2 * rw_length - 3; 514 ctrl_checksum_display = 3; 515 dau_base = rw_low; 516 address = address - dau_base; 517 end; 518 end; 519 else do; 520 patch_data_display = "^4.4b ^4.4b to ^4.4b"; 521 get_word = get_mpc_word; 522 put_word = put_mpc_word; 523 ctrl_checksum_display = 1; 524 end; 525 526 call get_temp_segments_ (name, ptr_array, code); /* Get seg for temp copy */ 527 if code ^= 0 528 then do; 529 call com_err_ (code, name, "Unable to allocate temp segment."); 530 go to done; 531 end; 532 temp_fwp = ptr_array (1); 533 call copy_fw (fwp, temp_fwp); /* Copy only the section of */ 534 /* firmware that will be changed */ 535 real_fwp = fwp; /* Save pointer to old data */ 536 fwp = temp_fwp; /* The "fw" structure now defines temp copy */ 537 daup = temp_fwp; 538 patch_checksum_display = "^4.4b ^4.4b to ^4.4b (^[^;lower ^;upper ^]checksum)"; 539 540 do i = 1 to count; /* Print changes */ 541 patch_address = address + i - 1; 542 if dau_sw 543 then new_dat = bit (bin (data (i), 8), 16); 544 else new_dat = bit (bin (data (i), 16), 16); 545 call ioa_ (patch_data_display, bit (bin (patch_address + dau_base, 16), 16), get_word (patch_address), 546 new_dat); 547 call put_word (patch_address, new_dat); /* This makes the patch */ 548 end; 549 550 check_addr = fw_high - 1; 551 call compute_checksum; /* Get checksum for patched module */ 552 call ioa_ (patch_checksum_display, bit (bin (check_addr * dau_factor + dau_base, 16), 16), 553 get_mpc_word (check_addr), checksum, ctrl_checksum_display); 554 call put_mpc_word (check_addr, checksum); 555 556 call command_query_ (addr (query_info), answer, name, "Type yes if patches are correct -- "); 557 if answer ^= "yes" 558 then return; /* Bad patch */ 559 call copy_fw (temp_fwp, real_fwp); /* Replace firmware */ 560 fwp = real_fwp; 561 call compute_checksum; /* Recalculate checksum, just to be sure */ 562 if get_word (check_addr) ^= checksum 563 then do; /* Logically, this can't fail, but... */ 564 call com_err_ (0, name, "Firmware patched incorrectly. ^a now has a bad checksum.", ename); 565 go to done; 566 end; 567 patch_worked = "1"b; 568 return; 569 570 end patch_fw; 571 572 /* Procedure to print sizes of memory overlays */ 573 574 print_size: 575 proc; 576 577 call ioa_ ("Firmware type: ^a,^a ^a (^a)", fw_type, fw_ident, fw_name, fw_rev); 578 if dau_sw /* There are four bytes that cannot be used in the middle */ 579 then call print_size_subr ("DAU", cs_start, cs_length + rw_length, cs_low, cs_high + rw_high + 1 - 4); 580 else do; 581 call print_size_subr ("Control store", cs_start, cs_length, cs_low, cs_high - 2); 582 call print_size_subr ("Read/write", rw_start, rw_length, rw_low, rw_high - 2); 583 end; 584 return; 585 586 end print_size; 587 588 print_size_subr: 589 proc (mem_nm, start, len, low_adr, up_adr); 590 591 dcl mem_nm char (*); 592 dcl (start, len, low_adr, up_adr) fixed bin; 593 594 if len = 0 595 then do; 596 call ioa_ ("No ^a overlay.", mem_nm); 597 return; 598 end; 599 600 call ioa_ ("^a overlay at ^a|^o for ^d Multics words, ^.4b MPC(hex) words (addresses ^.4b:^.4b).", mem_nm, 601 ename, start - 1, len, bit (bin (up_adr - low_adr + 1, 16), 16), bit (bin (low_adr, 16), 16), 602 bit (bin (up_adr, 16), 16)); 603 return; 604 605 end print_size_subr; 606 607 608 609 /* Cleanup handler */ 610 611 clean_up: 612 proc; 613 614 if seg_ptr ^= null 615 then call hcs_$terminate_noname (seg_ptr, code); 616 if ptr_array (1) ^= null 617 then call release_temp_segments_ (name, ptr_array, code); 618 return; 619 620 end clean_up; 621 622 623 dcl get_word entry (fixed bin) returns (bit (16)) variable; 624 dcl put_word entry (fixed bin, bit (16)) variable; 625 dcl name char (16); /* Name called by */ 626 dcl code fixed bin (35); 627 dcl arg_ptr ptr; 628 dcl arg_len fixed bin; 629 dcl arg char (arg_len) based (arg_ptr); 630 dcl arg_list_ptr ptr; 631 dcl nargs fixed bin; 632 dcl patch bit (1); /* 1 for patch, 0 for dump */ 633 dcl arg_no fixed bin init (1); 634 dcl arg_name char (16); 635 dcl data (16) fixed bin; 636 dcl dau_factor fixed bin; /* DAU addresses twice that of normal firmware */ 637 dcl word_length fixed bin; 638 dcl words_per_line fixed bin; /* for displaying memory */ 639 dcl cs_sw bit (1); /* 1 for control store, 0 for read/write */ 640 dcl dau_sw bit (1) init ("0"b); /* 1 for DAU firmware, 0 for everthing else */ 641 dcl address fixed bin; 642 dcl dir char (168); 643 dcl ename char (32); 644 dcl i fixed bin; 645 dcl count fixed bin; 646 dcl cs_start fixed bin; /* offset of cs in fw module in Multics words */ 647 dcl cs_length fixed bin; /* length of cs in Multics words */ 648 dcl rw_start fixed bin; /* offset of rw in fw module in Multics words */ 649 dcl rw_length fixed bin; /* length of rw in Multics words */ 650 dcl word_count fixed bin; 651 dcl bit_count fixed bin (24); 652 dcl mem_name char (16); 653 dcl seg_ptr ptr init (null); 654 dcl (cs_low, cs_high) fixed bin; /* Range of valid control store addresses */ 655 dcl (rw_low, rw_high) fixed bin; /* Range of valid read/write addresses */ 656 dcl (dau_low, dau_high) fixed bin; /* Range for current overlay in DAU words */ 657 dcl (fw_low, fw_high) fixed bin; /* Range for current overlay in MPC words */ 658 dcl fw_type char (6); /* Type of firmware, decoded from bcd */ 659 dcl fw_ident char (6); /* Firmware ident field, decoded from bcd */ 660 dcl fw_name char (4); 661 dcl fw_rev char (6); 662 dcl daup ptr; 663 dcl fwp ptr; 664 dcl checksum bit (16); 665 dcl check_addr fixed bin; /* Address of the checksum word */ 666 dcl ptr_array (1) ptr init (null); 667 dcl patch_worked bit (1) init ("0"b); 668 dcl size_sw bit (1) init ("0"b); 669 dcl addr_limit fixed bin; 670 671 dcl mpcbot bit (36) aligned int static options (constant) init ("100100100111010011010010100110110011"b); 672 /* Bcd for MPCBOT */ 673 674 dcl seg (word_count) bit (36) aligned based (seg_ptr); /* Entire segment */ 675 676 dcl 1 dau based (daup), 677 2 dau_word (dau_low:dau_high) unal, 678 3 fill bit (1), 679 3 byte bit (8); 680 681 dcl 1 fw based (fwp), /* A memory overlay */ 682 2 fw_word (fw_low:fw_high) unal, 683 3 fill1 bit (1) unal, 684 3 byte1 bit (8) unal, 685 3 fill2 bit (1) unal, 686 3 byte2 bit (8) unal; 687 688 dcl cu_$arg_list_ptr entry (ptr); 689 dcl cu_$arg_count entry (fixed bin); 690 dcl cu_$arg_ptr_rel entry (fixed bin, ptr, fixed bin, fixed bin (35), ptr); 691 dcl ioa_ entry options (variable); 692 dcl com_err_ entry options (variable); 693 dcl expand_path_ entry (ptr, fixed bin, ptr, ptr, fixed bin (35)); 694 dcl hcs_$initiate_count entry (char (*), char (*), char (*), fixed bin (24), fixed bin (2), ptr, fixed bin (35)); 695 dcl hcs_$terminate_noname entry (ptr, fixed bin (35)); 696 dcl get_temp_segments_ entry (char (*), dim (*) ptr, fixed bin (35)); 697 dcl release_temp_segments_ entry (char (*), dim (*) ptr, fixed bin (35)); 698 dcl command_query_ entry options (variable); 699 dcl gcos_cv_gebcd_ascii_ entry (ptr, fixed bin, ptr); 700 701 dcl error_table_$noarg ext fixed bin (35); 702 dcl error_table_$too_many_args ext fixed bin (35); 703 704 dcl cleanup condition; 705 706 dcl (addr, bin, bit, divide, index, length, min, null, substr, unspec) builtin; 707 708 end patch_firmware; SOURCE FILES USED IN THIS COMPILATION. LINE NUMBER DATE MODIFIED NAME PATHNAME 0 04/02/85 1035.3 patch_firmware.pl1 >spec>on>6953_pbf-04/02/85>patch_firmware.pl1 NAMES DECLARED IN THIS COMPILATION. IDENTIFIER OFFSET LOC STORAGE CLASS DATA TYPE ATTRIBUTES AND REFERENCES (* indicates a set context) NAMES DECLARED BY DECLARE STATEMENT. addr builtin function dcl 706 ref 77 77 77 77 208 208 208 208 209 209 209 209 210 210 210 210 211 211 211 211 267 278 306 322 331 470 506 512 556 556 addr_limit 000314 automatic fixed bin(17,0) dcl 669 set ref 284* 286* 288 290 290 294 296 296 address parameter fixed bin(17,0) dcl 384 in procedure "put_dau_word" ref 381 387 address parameter fixed bin(17,0) dcl 397 in procedure "put_mpc_word" ref 394 400 401 address 000160 automatic fixed bin(17,0) dcl 641 in procedure "patch_firmware" set ref 103* 288 288 294 312 312 468 470 470 472* 472 504 516* 516 541 answer 000426 automatic varying char(3) dcl 486 set ref 556* 557 arg based char unaligned dcl 629 set ref 80* 86 88 90 96* 98* 111* 159 160 163 166* 174* arg_len 000120 automatic fixed bin(17,0) dcl 628 set ref 77* 80 80 86 88 90 96 96 98 98 111 111 140* 159 160 163 166 166 174 174 arg_list_ptr 000122 automatic pointer dcl 630 set ref 41* 140* arg_name 000127 automatic char(16) unaligned dcl 634 set ref 75* 84* 102* 107* 143* arg_no 000126 automatic fixed bin(17,0) initial dcl 633 set ref 116 140* 146* 146 633* arg_ptr 000116 automatic pointer dcl 627 set ref 77* 80 86 88 90 96 98 111 140* 159 160 163 166 174 based_buffer based bit array dcl 451 set ref 470* bin builtin function dcl 706 ref 230 290 290 290 290 296 296 296 296 314 314 314 314 417 470 470 542 544 545 545 552 552 600 600 600 600 600 600 bit builtin function dcl 706 ref 290 290 290 290 296 296 296 296 314 314 314 314 470 470 542 544 545 545 552 552 600 600 600 600 600 600 bit_count 000252 automatic fixed bin(24,0) dcl 651 set ref 187* 194 buffer 000100 automatic bit array dcl 449 set ref 468* 470 byte 0(01) based bit(8) array level 3 packed unaligned dcl 676 set ref 362 387* byte1 0(01) based bit(8) array level 3 packed unaligned dcl 681 set ref 374 400* byte2 0(10) based bit(8) array level 3 packed unaligned dcl 681 set ref 374 401* char_len 000406 automatic fixed bin(17,0) dcl 435 set ref 438* 439 439 char_overlay based char unaligned dcl 436 set ref 439* 439 check_addr 000307 automatic fixed bin(17,0) dcl 665 set ref 550* 552 552 552* 552* 554* 562* checksum 000306 automatic bit(16) unaligned dcl 664 set ref 325 335 344 424* 552* 554* 562 cleanup 000316 stack reference condition dcl 704 ref 52 code 000114 automatic fixed bin(35,0) dcl 626 set ref 77* 78 80* 140* 141 143* 187* 190* 526* 527 529* 614* 616* com_err_ 000020 constant entry external dcl 692 ref 80 96 98 111 119 124 143 166 174 190 198 203 275 290 296 314 327 337 346 529 564 command_query_ 000034 constant entry external dcl 698 ref 556 count 000244 automatic fixed bin(17,0) dcl 645 set ref 108* 109 116* 117 122 127 294 312 465 466 471* 471 540 cs_high 000263 automatic fixed bin(17,0) dcl 654 set ref 247* 261 269 304 310 310 314 314 314 314 578 581 cs_length 000246 automatic fixed bin(17,0) dcl 647 set ref 234* 238* 247 321 507 578 581* cs_low 000262 automatic fixed bin(17,0) dcl 654 set ref 243* 246* 247 260 268 578* 581* cs_start 000245 automatic fixed bin(17,0) dcl 646 set ref 229* 267 578* 581* cs_sw 000156 automatic bit(1) unaligned dcl 639 set ref 86* 88* 265 ctrl_checksum_display 000471 automatic fixed bin(17,0) dcl 490 set ref 508* 514* 523* 552* cu_$arg_count 000012 constant entry external dcl 689 ref 43 cu_$arg_list_ptr 000010 constant entry external dcl 688 ref 41 cu_$arg_ptr_rel 000014 constant entry external dcl 690 ref 140 data 000133 automatic fixed bin(17,0) array dcl 635 set ref 128* 542 544 dau based structure level 1 packed unaligned dcl 676 dau_base 000450 automatic fixed bin(17,0) dcl 488 set ref 509* 515* 516 545 545 552 552 dau_factor 000153 automatic fixed bin(17,0) dcl 636 set ref 216* 222* 247 249 286 552 552 dau_high 000267 automatic fixed bin(17,0) dcl 656 set ref 308* dau_low 000266 automatic fixed bin(17,0) dcl 656 set ref 307* 362 387 dau_sw 000157 automatic bit(1) initial unaligned dcl 640 set ref 215* 221* 258 301 455 499 542 578 640* dau_word based structure array level 2 packed unaligned dcl 676 daup 000302 automatic pointer dcl 662 set ref 306* 362 387 537* dir 000161 automatic char(168) unaligned dcl 642 set ref 77 77 187* 190* divide builtin function dcl 706 ref 194 dump_fw_display 000102 automatic char(64) unaligned dcl 453 set ref 458* 462* 470* ename 000233 automatic char(32) unaligned dcl 643 set ref 77 77 187* 190* 564* 600* error_table_$noarg 000040 external static fixed bin(35,0) dcl 701 set ref 119* error_table_$too_many_args 000042 external static fixed bin(35,0) dcl 702 set ref 124* expand_path_ 000022 constant entry external dcl 693 ref 77 from_ptr parameter pointer dcl 434 ref 431 439 fw based structure level 1 packed unaligned dcl 681 fw_high 000271 automatic fixed bin(17,0) dcl 657 set ref 261* 269* 280* 284 286 321* 325 332* 335 344 416 438 507* 513* 550 fw_ident 000274 automatic char(6) unaligned dcl 659 set ref 209 209 213 577* fw_low 000270 automatic fixed bin(17,0) dcl 657 set ref 260* 268* 279* 288 290 290 296 296 320* 374 374 400 401 438 fw_name 000276 automatic char(4) unaligned dcl 660 set ref 210 210 577* fw_rev 000300 automatic char(6) unaligned dcl 661 set ref 211 211 577* fw_type 000272 automatic char(6) unaligned dcl 658 set ref 208 208 243 243 577* fw_word based structure array level 2 packed unaligned dcl 681 fwp 000304 automatic pointer dcl 663 set ref 267* 278* 322* 331* 374 374 400 401 506* 512* 533* 535 536* 560* gcos_cv_gebcd_ascii_ 000036 constant entry external dcl 699 ref 208 209 210 211 get_address parameter fixed bin(17,0) dcl 360 in procedure "get_dau_word" ref 357 362 get_address parameter fixed bin(17,0) dcl 372 in procedure "get_mpc_word" ref 369 374 374 get_temp_segments_ 000030 constant entry external dcl 696 ref 526 get_word 000100 automatic entry variable dcl 623 set ref 325 335 344 414* 417 457* 461* 468 502* 521* 545 545 562 hcs_$initiate_count 000024 constant entry external dcl 694 ref 187 hcs_$terminate_noname 000026 constant entry external dcl 695 ref 614 i 000375 automatic fixed bin(17,0) dcl 412 in procedure "compute_checksum" set ref 416* 417* i 000101 automatic fixed bin(17,0) dcl 452 in procedure "dump_fw" set ref 467* 468 468* i 000352 automatic fixed bin(17,0) dcl 154 in procedure "get_hex_arg" set ref 159* 160 163* i 000243 automatic fixed bin(17,0) dcl 644 in procedure "patch_firmware" set ref 127* 128* 310* 312 312* i 000422 automatic fixed bin(17,0) dcl 484 in procedure "patch_fw" set ref 540* 541 542 544* index builtin function dcl 706 ref 160 163 ioa_ 000016 constant entry external dcl 691 ref 46 48 66 470 545 552 577 596 600 j 000353 automatic fixed bin(17,0) dcl 154 set ref 160* 161 163* 164 169* 169 171 len parameter fixed bin(17,0) dcl 592 set ref 588 594 600* length builtin function dcl 706 ref 159 low_adr parameter fixed bin(17,0) dcl 592 ref 588 600 600 600 600 mem_name 000253 automatic char(16) unaligned dcl 652 set ref 262* 270* 281* 290* 296* 346* mem_nm parameter char unaligned dcl 591 set ref 588 596* 600* min builtin function dcl 706 ref 466 mpcbot 000000 constant bit(36) initial dcl 671 set ref 201 203* name 000110 automatic char(16) unaligned dcl 625 set ref 27* 36* 46* 48* 80* 96* 98* 111* 119* 124* 143* 166* 174* 190* 198* 203* 275* 290* 296* 314* 327* 337* 346* 526* 529* 556* 564* 616* nargs 000124 automatic fixed bin(17,0) dcl 631 set ref 43* 44 116 new_dat 000424 automatic bit(16) unaligned dcl 485 set ref 542* 544* 545* 547* new_word parameter bit(16) unaligned dcl 398 in procedure "put_mpc_word" ref 394 400 401 new_word parameter bit(16) unaligned dcl 385 in procedure "put_dau_word" ref 381 387 null builtin function dcl 706 ref 188 614 616 653 666 nwords 000100 automatic fixed bin(17,0) dcl 450 set ref 466* 467 470 471 472 patch 000125 automatic bit(1) unaligned dcl 632 set ref 28* 37* 46 60 90 96 105 284 310 patch_address 000423 automatic fixed bin(17,0) dcl 484 set ref 541* 545 545 545* 545* 547* patch_checksum_display 000451 automatic char(64) unaligned dcl 489 set ref 538* 552* patch_data_display 000430 automatic char(64) unaligned dcl 487 set ref 501* 520* 545* patch_worked 000312 automatic bit(1) initial unaligned dcl 667 set ref 66 567* 667* ptr_array 000310 automatic pointer initial array dcl 666 set ref 526* 532 616 616* 666* put_word 000104 automatic entry variable dcl 624 set ref 503* 522* 547 query_code 3 000472 automatic fixed bin(35,0) initial level 2 dcl 492 set ref 492* query_info 000472 automatic structure level 1 dcl 492 set ref 556 556 real_fwp 000416 automatic pointer dcl 483 set ref 535* 559* 560 release_temp_segments_ 000032 constant entry external dcl 697 ref 616 rw_high 000265 automatic fixed bin(17,0) dcl 655 set ref 249* 251* 261 280 305* 305 308 578 582 rw_length 000250 automatic fixed bin(17,0) dcl 649 set ref 235* 239* 243 249 249 332 513 578 582* rw_low 000264 automatic fixed bin(17,0) dcl 655 set ref 248* 249 279 304* 305 504 515 582* rw_start 000247 automatic fixed bin(17,0) dcl 648 set ref 230* 232 238 239 240* 240 273 278 331 512 582* seg based bit(36) array dcl 674 set ref 201 208 208 209 209 210 210 211 211 230 267 278 306 322 331 506 512 seg_ptr 000260 automatic pointer initial dcl 653 set ref 187* 188 201 208 208 209 209 210 210 211 211 230 267 278 306 322 331 506 512 614 614* 653* size_sw 000313 automatic bit(1) initial unaligned dcl 668 set ref 58 92* 253 668* start parameter fixed bin(17,0) dcl 592 ref 588 600 status_code 2 000472 automatic fixed bin(35,0) initial level 2 dcl 492 set ref 492* substr builtin function dcl 706 ref 160 163 230 243 387 400 401 424 sum 000374 automatic fixed bin(35,0) dcl 411 set ref 415* 417* 417 418 419* 419 420* 420 423* 423 424 suppress_name 1(01) 000472 automatic bit(1) initial level 2 packed unaligned dcl 492 set ref 492* temp_fwp 000420 automatic pointer dcl 483 set ref 532* 533* 536 537 559* to_ptr parameter pointer dcl 434 ref 431 439 unspec builtin function dcl 706 ref 424 up_adr parameter fixed bin(17,0) dcl 592 ref 588 600 600 600 600 v 000354 automatic fixed bin(35,0) dcl 155 set ref 158* 171* 171 172 178 version 000472 automatic fixed bin(17,0) initial level 2 dcl 492 set ref 492* word_count 000251 automatic fixed bin(17,0) dcl 650 set ref 194* 196 201 208 208 209 209 210 210 211 211 230 234 239 word_length 000154 automatic fixed bin(17,0) dcl 637 set ref 217* 223* 449 470 470 470 words_per_line 000155 automatic fixed bin(17,0) dcl 638 set ref 218* 224* 449 466 yes_or_no 1 000472 automatic bit(1) initial level 2 packed unaligned dcl 492 set ref 492* NAMES DECLARED BY EXPLICIT CONTEXT. clean_up 004474 constant entry internal dcl 611 ref 52 64 compute_checksum 003245 constant entry internal dcl 408 ref 323 333 343 551 561 copy_fw 003330 constant entry internal dcl 431 ref 533 559 done 001014 constant label dcl 64 ref 81 99 112 120 125 144 167 175 191 199 205 276 292 298 316 328 338 347 530 565 dump_firmware 000656 constant entry external dcl 33 dump_fw 003350 constant entry internal dcl 446 ref 62 find_fw 001670 constant entry internal dcl 184 ref 56 get_arg 001441 constant entry internal dcl 137 ref 76 85 157 get_dau_word 003103 constant entry internal dcl 357 ref 457 502 get_hex_arg 001514 constant entry internal dcl 151 ref 103 108 128 get_mpc_word 003135 constant entry internal dcl 369 ref 414 461 521 552 552 patch_firmware 000641 constant entry external dcl 22 patch_fw 003537 constant entry internal dcl 480 ref 60 print_size 004234 constant entry internal dcl 574 ref 58 print_size_subr 004335 constant entry internal dcl 588 ref 578 581 582 put_dau_word 003173 constant entry internal dcl 381 ref 503 put_mpc_word 003217 constant entry internal dcl 394 ref 522 554 scan_args 001042 constant entry internal dcl 72 ref 54 start 000670 constant label dcl 41 ref 29 THERE WERE NO NAMES DECLARED BY CONTEXT OR IMPLICATION. STORAGE REQUIREMENTS FOR THIS PROGRAM. Object Text Link Symbol Defs Static Start 0 0 5156 5222 4674 5166 Length 5456 4674 44 217 261 0 BLOCK NAME STACK SIZE TYPE WHY NONQUICK/WHO SHARES STACK FRAME patch_firmware 732 external procedure is an external procedure. on unit on line 52 64 on unit scan_args internal procedure shares stack frame of external procedure patch_firmware. get_arg internal procedure shares stack frame of external procedure patch_firmware. get_hex_arg internal procedure shares stack frame of external procedure patch_firmware. find_fw internal procedure shares stack frame of external procedure patch_firmware. get_dau_word 65 internal procedure is assigned to an entry variable. get_mpc_word 65 internal procedure is assigned to an entry variable. put_dau_word 65 internal procedure is assigned to an entry variable. put_mpc_word 65 internal procedure is assigned to an entry variable. compute_checksum internal procedure shares stack frame of external procedure patch_firmware. copy_fw internal procedure shares stack frame of external procedure patch_firmware. dump_fw 114 internal procedure uses auto adjustable storage. patch_fw internal procedure shares stack frame of external procedure patch_firmware. print_size internal procedure shares stack frame of external procedure patch_firmware. print_size_subr internal procedure shares stack frame of external procedure patch_firmware. clean_up 84 internal procedure is called by several nonquick procedures. STORAGE FOR AUTOMATIC VARIABLES. STACK FRAME LOC IDENTIFIER BLOCK NAME dump_fw 000100 buffer dump_fw 000100 nwords dump_fw 000101 i dump_fw 000102 dump_fw_display dump_fw patch_firmware 000100 get_word patch_firmware 000104 put_word patch_firmware 000110 name patch_firmware 000114 code patch_firmware 000116 arg_ptr patch_firmware 000120 arg_len patch_firmware 000122 arg_list_ptr patch_firmware 000124 nargs patch_firmware 000125 patch patch_firmware 000126 arg_no patch_firmware 000127 arg_name patch_firmware 000133 data patch_firmware 000153 dau_factor patch_firmware 000154 word_length patch_firmware 000155 words_per_line patch_firmware 000156 cs_sw patch_firmware 000157 dau_sw patch_firmware 000160 address patch_firmware 000161 dir patch_firmware 000233 ename patch_firmware 000243 i patch_firmware 000244 count patch_firmware 000245 cs_start patch_firmware 000246 cs_length patch_firmware 000247 rw_start patch_firmware 000250 rw_length patch_firmware 000251 word_count patch_firmware 000252 bit_count patch_firmware 000253 mem_name patch_firmware 000260 seg_ptr patch_firmware 000262 cs_low patch_firmware 000263 cs_high patch_firmware 000264 rw_low patch_firmware 000265 rw_high patch_firmware 000266 dau_low patch_firmware 000267 dau_high patch_firmware 000270 fw_low patch_firmware 000271 fw_high patch_firmware 000272 fw_type patch_firmware 000274 fw_ident patch_firmware 000276 fw_name patch_firmware 000300 fw_rev patch_firmware 000302 daup patch_firmware 000304 fwp patch_firmware 000306 checksum patch_firmware 000307 check_addr patch_firmware 000310 ptr_array patch_firmware 000312 patch_worked patch_firmware 000313 size_sw patch_firmware 000314 addr_limit patch_firmware 000352 i get_hex_arg 000353 j get_hex_arg 000354 v get_hex_arg 000374 sum compute_checksum 000375 i compute_checksum 000406 char_len copy_fw 000416 real_fwp patch_fw 000420 temp_fwp patch_fw 000422 i patch_fw 000423 patch_address patch_fw 000424 new_dat patch_fw 000426 answer patch_fw 000430 patch_data_display patch_fw 000450 dau_base patch_fw 000451 patch_checksum_display patch_fw 000471 ctrl_checksum_display patch_fw 000472 query_info patch_fw THE FOLLOWING EXTERNAL OPERATORS ARE USED BY THIS PROGRAM. call_var call_ext_out_desc call_ext_out call_int_this call_int_other return move_label_var make_label_var alloc_auto_adj enable ext_entry int_entry THE FOLLOWING EXTERNAL ENTRIES ARE CALLED BY THIS PROGRAM. com_err_ command_query_ cu_$arg_count cu_$arg_list_ptr cu_$arg_ptr_rel expand_path_ gcos_cv_gebcd_ascii_ get_temp_segments_ hcs_$initiate_count hcs_$terminate_noname ioa_ release_temp_segments_ THE FOLLOWING EXTERNAL VARIABLES ARE USED BY THIS PROGRAM. error_table_$noarg error_table_$too_many_args LINE LOC LINE LOC LINE LOC LINE LOC LINE LOC LINE LOC LINE LOC 633 000620 640 000622 653 000623 666 000625 667 000634 668 000635 22 000640 27 000647 28 000652 29 000654 33 000655 36 000664 37 000667 41 000670 43 000677 44 000706 46 000710 48 000733 49 000753 52 000754 54 000776 56 000777 58 001000 60 001004 62 001010 64 001014 66 001020 68 001041 72 001042 75 001043 76 001046 77 001047 78 001072 80 001074 81 001126 84 001127 85 001132 86 001133 88 001144 90 001152 92 001160 93 001162 96 001163 98 001222 99 001256 102 001257 103 001262 105 001266 107 001270 108 001273 109 001277 111 001301 112 001335 114 001336 116 001337 117 001343 119 001344 120 001371 122 001372 124 001374 125 001421 127 001422 128 001431 129 001436 132 001440 137 001441 140 001442 141 001461 143 001463 144 001511 146 001512 147 001513 151 001514 157 001516 158 001517 159 001520 160 001527 161 001541 163 001542 164 001554 166 001555 167 001611 169 001612 171 001614 172 001623 174 001625 175 001661 177 001662 178 001664 184 001670 187 001671 188 001733 190 001737 191 001772 194 001773 196 001776 198 002000 199 002025 201 002026 203 002032 205 002063 208 002064 209 002105 210 002130 211 002153 213 002176 215 002202 216 002204 217 002206 218 002210 219 002212 221 002213 222 002214 223 002216 224 002220 229 002222 230 002224 232 002231 234 002233 235 002236 236 002237 238 002240 239 002241 240 002245 243 002246 246 002264 247 002265 248 002275 249 002276 251 002310 253 002311 258 002314 260 002316 261 002320 262 002324 263 002327 265 002330 267 002332 268 002335 269 002337 270 002341 271 002344 273 002345 275 002347 276 002374 278 002375 279 002377 280 002401 281 002403 284 002406 286 002412 288 002420 290 002425 292 002476 294 002477 296 002503 298 002554 301 002555 304 002557 305 002562 306 002563 307 002565 308 002566 310 002570 312 002601 314 002610 316 002660 318 002661 320 002663 321 002664 322 002670 323 002672 325 002673 327 002715 328 002742 331 002743 332 002747 333 002753 335 002754 337 002776 338 003023 340 003024 343 003025 344 003026 346 003050 347 003100 351 003101 357 003102 362 003110 369 003134 374 003142 381 003172 387 003200 389 003215 394 003216 400 003224 401 003241 403 003244 408 003245 414 003246 415 003251 416 003252 417 003261 418 003277 419 003303 420 003311 421 003315 422 003316 423 003320 424 003322 425 003327 431 003330 438 003332 439 003337 440 003346 446 003347 449 003355 455 003372 457 003374 458 003401 459 003404 461 003405 462 003412 465 003415 466 003421 467 003425 468 003433 469 003464 470 003466 471 003530 472 003533 473 003535 474 003536 480 003537 492 003540 499 003550 501 003552 502 003555 503 003560 504 003563 506 003566 507 003570 508 003574 509 003576 510 003577 512 003600 513 003604 514 003610 515 003612 516 003614 518 003616 520 003617 521 003622 522 003625 523 003630 526 003632 527 003653 529 003655 530 003701 532 003702 533 003704 535 003706 536 003710 537 003712 538 003713 540 003716 541 003725 542 003730 544 003741 545 003751 547 004013 548 004023 550 004025 551 004030 552 004031 554 004103 556 004113 557 004145 559 004153 560 004155 561 004157 562 004160 564 004177 565 004230 567 004231 568 004233 574 004234 577 004235 578 004267 581 004306 582 004322 584 004334 588 004335 594 004346 596 004351 597 004375 600 004376 603 004472 611 004473 614 004501 616 004516 618 004544 ----------------------------------------------------------- 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