$LARGE /******************************************************************************* MODULE NAME: Test$Rack$Job AUTHOR: A. Measday VERSION 003 16-DEC-1986 A. Measday Added code to set the HP 6034A and 6032A power supplies into remote mode on power-up or after a reset (hard or soft), thereby preventing any idle passers-by from fooling with the front panel and frying the power supply. VERSION 002 24-FEB-1986 A. Measday Added initialization of RPU source and destination mappings. Previously, they were set to N$NUL until the first "UP" command was received. Now, the universal firmware makes an educated guess based on whether or not the SBC is the IEEE-488 system controller or just a talker/listener. The "UP" command functions as before. VERSION 001 05-DEC-1984 A. Measday New routine. CONFIGURATION: iSBC 286/10 in Real-Address Mode, using iRMX Operating System. PURPOSE: The test rack job initialization and download task sets up the universal firmware for processing. The test rack job is created by the first-level user job. This two-job structure simplifies restarting the firmware; the user job needs only to delete the test rack job in order to deallocate all the test rack job's resources (semaphores, mailboxes, memory segments, etc.). The initialization and download task is the first task executed when the test rack job is created. This task is responsible for creating some semaphores and mailboxes, starting up the interface tasks, and, if requested, downloading the applications firmware. The main applications task is then created and control is passed to it. During the download, the initialization and download task appears to the interface tasks as a pseudo-main applications task (thus using the same semaphores and mailboxes as the real main applications task). The download task recognizes the following commands from the RPU: "UP" - If the universal firmware is up and running, then send the version number of the firmware back to the RPU. "DL" - Begin applications firmware download. "GO" - Start the applications firmware running. Usually, the following communications will take place between the RPU and the SBC: (1) The RPU repeatedly sends "UP" to the SBC until it receives a response from the SBC. (2) After booting up, the SBC waits for an "UP" message from the RPU. Upon receiving the "UP" message, the SBC returns a status and version number message to the RPU. (3) The RPU then sends a "DL" message to inform the SBC to set up for applications firmware download. (4) Upon receiving the "DL" command, the SBC resets its download parameters. NOTE: Sending a new "DL" command aborts the download currently in progress and begins a new download. (5) The RPU sends each record of the INTEL hexadecimal object file to the SBC. These INTEL-generated records all have a colon (":") at the beginning of the record. (6) The SBC processes each download record. (7) After download is complete, the RPU sends a "GO" command to the SBC. (8) Upon receiving a "GO" command from the RPU, the SBC starts up the applications firmware at the address specified in the download. The "UP" command sets up new source and destination mappings for the RPU (i.e., who is the RPU). By default, the RS-232C interface is the RPU interface for the panel test set and the IEEE-488 interface is the RPU interface for all the other test sets. You can also use the console as the RPU interface! The version message returned to the RPU includes the statuses of the memory tests performed upon power-up of the test rack. These are stored in a variable, MEMORY$TEST$STATUS, which is declared in the MILSTAR power-up firmware (see MSURST.A86). If a memory test passed, then a "P" is inserted in the version message; if the test failed, an "F" is inserted, instead. INPUT: The parameter object passed from the user job to the test rack job is the token for the user job. It is not currently used for anything. DATA STRUCTURES: Semaphore TIR_EXCHANGE - Set to indicate that an event has occurred to which the test rack job initialization task must respond. Mailbox RPU_MESSAGE - Input message mailbox for the RPU interface task. TIR_MESSAGE - Input message mailbox for the test rack job initialization task. Common 488_IS_CONTROLLER - True if the SBC is the IEEE-488 system controller. APPLICATION_START_ADDRESS - Start address for the downloaded applications software. It is set whenever the software is downloaded. By being global to the test rack job, this variable is available whenever the test rack job is restarted and re-download is not desired. DESTINATION_MAPPING - Destination mapping table. MEMORY$TEST$STATUS - Results of the memory tests performed at power-up. SOURCE_SUBSTITUTION - Source substitution table. *******************************************************************************/ $EJECT tirjob_module: DO ; /* Non-local declarations. */ /* iRMX definitions. */ $ INCLUDE (:F1:RMXDEF.EXT) /* iRMX nucleus routines. */ $ INCLUDE (:F1:RMXNCL.EXT) /* Miscellaneous definitions. */ $ INCLUDE (:F1:MSUNIV.EXT) /* External procedures. */ $ INCLUDE (:F1:MSUPRC.EXT) DECLARE version_text(*) BYTE /* Version message. */ DATA ('0XXXXX MILSTAR Universal Firmware, Version 3.0, 16-DEC-1986', 0) ; /* Declared in the parent user job. */ DECLARE application_start_address POINTER EXTERNAL ; /* Declared in the MILSTAR power-up firmware. */ DECLARE Memory$Test$Status(*) WORD EXTERNAL ; /* Declared in the RPU interface task. */ DECLARE source_substitution(7) BYTE EXTERNAL ; DECLARE destination_mapping(7) BYTE EXTERNAL ; /* Semaphores and mailboxes. */ DECLARE tir_exchange TOKEN PUBLIC, tir_message TOKEN PUBLIC ; DECLARE rpu_exchange TOKEN EXTERNAL, rpu_message TOKEN EXTERNAL ; /* IEEE-488 interface data structures. */ DECLARE i488_is_controller BYTE EXTERNAL ; /* Download firmware from RPU. */ download_firmware: PROCEDURE (record_ptr, record_length, load_segment_ptr, start_address_ptr, status_ptr) EXTERNAL ; DECLARE record_ptr POINTER, record_length WORD, load_segment_ptr POINTER, start_address_ptr POINTER, status_ptr POINTER ; END download_firmware ; /* Task start address. */ RPU$Interface$Task: PROCEDURE EXTERNAL ; END RPU$Interface$Task ; $EJECT Test$Rack$Job: PROCEDURE REENTRANT PUBLIC ; /* Local declarations. */ DECLARE command WORD, i WORD, length WORD, load_segment SELECTOR, packet_token TOKEN, response_token TOKEN, segment_token TOKEN, status WORD, task_token TOKEN ; DECLARE packet_ptr POINTER, packet BASED packet_ptr MESSAGE ; DECLARE buffer_ptr POINTER, (buffer BASED buffer_ptr)(*) BYTE ; $EJECT CALL console_out (@(cr$lf, ring$bell, ring$bell, ring$bell, '*** MILSTAR Universal Firmware ***', cr$lf, ring$bell, ring$bell, ring$bell, 0), 0) ; /* Initialize the CREATE_SEGMENT routine. */ segment_token = create_segment (0) ; /* Create/catalog the TIR_EXCHANGE semaphore and the TIR_MESSAGE mailbox. */ tir_exchange = create_semaphore (@('TIR_EXCHANGE', 0), 0) ; tir_message = create_mailbox (@('TIR_MESSAGE', 0)) ; /* Create the RPU interface task and wait for it to initialize itself. */ task_token = create_task (@RPU$Interface$Task, 384) ; CALL wait_and_read (tir_exchange, wait$forever, 0, 0, NIL, @status) ; IF status <> E$OK THEN CALL console_out (@('TIRJOB: Error waiting on TIR_EXCHANGE semaphore.', cr$lf, 0), 0) ; /* Assume a default source/destination for the RPU. When the SBC is the IEEE-488 system controller (panel STE test set only), the RPU is the VAX computer, connected to the SBC via the RS-232C link. When the SBC is just a talker/listener on the IEEE-488 bus (all other test sets), the RPU is the HP-1000 computer, connected to the SBC via the IEEE-488 interface. */ IF i488_is_controller THEN DO ; /* Panel STE test set. */ source_substitution(N$232) = N$RPU ; destination_mapping(N$RPU) = N$232 ; END ; ELSE DO ; /* Other test sets. */ source_substitution(N$488) = N$RPU ; destination_mapping(N$RPU) = N$488 ; END ; /* Set the HP 6034A (address 13H) and 6032A (address 17H) power supplies into remote mode (panel STE test set only); this will prevent accidental front-panel access to the power supplies. Activate the Remote Enable signal on the IEEE-488 bus, command devices 13H and 17H to listen, and output a carriage return and line feed to ensure that they go into remote mode. */ IF i488_is_controller THEN DO ; /* Panel STE test set. */ packet_token = build_message (N$TIR, N$488, N$SPECIAL, N$NONE, 0, @('RMT', 0)) ; CALL send_and_signal (rpu_message, packet_token, rpu_exchange, @status) ; packet_token = build_message (N$TIR, N$488, N$SPECIAL, N$NONE, 0, @('LIS 1317', 0)) ; CALL send_and_signal (rpu_message, packet_token, rpu_exchange, @status) ; packet_token = build_message (N$TIR, N$488, N$OUTPUT, N$NONE, 0, @(cr$lf, 0)) ; CALL send_and_signal (rpu_message, packet_token, rpu_exchange, @status) ; END ; $EJECT /* Read and process messages from the RPU until a "GO" command is received. */ command = ' ' ; DO WHILE command <> 'GO' ; /* Read a message from the RPU. */ CALL wait_and_read (tir_exchange, wait$forever, tir_message, no$wait, @packet_token, @status) ; packet_ptr = BUILD$PTR (packet_token, 0) ; CALL MOVW (packet.location, @command, 1) ; command = ROL (command, 8) ; /* "UP" command - return a status and version number message to the RPU. Set up the RPU mappings (overriding the default mappings set up initially). */ IF command = 'UP' THEN DO ; IF packet.source <> N$RPU THEN DO ; i = destination_mapping(N$RPU) ; /* Reset the old RPU mapping. */ source_substitution(i) = i ; source_substitution(packet.source) = N$RPU ; /* Set up the new RPU mapping. */ destination_mapping(N$RPU) = packet.source ; END ; length = FINDB (@version_text, 0, 0FFFFH) ; segment_token = create_segment (length) ; buffer_ptr = BUILD$PTR (segment_token, 0) ; CALL MOVB (@version_text, buffer_ptr, length) ; DO i = 0 TO 4 ; IF Memory$Test$Status(i) = E$OK THEN buffer(i+1) = 'P' ; ELSE buffer(i+1) = 'F' ; END ; response_token = build_message (N$TIR, N$RPU, N$OUTPUT, N$DELETE, length, buffer_ptr) ; END ; /* "DL" command - prepare for downloading the applications firmware. */ ELSE IF command = 'DL' THEN DO ; application_start_address = NIL ; load_segment = SELECTOR$OF (NIL) ; response_token = build_message (N$TIR, packet.source, N$OUTPUT, N$NONE, 1, @('0')) ; END ; /* "GO" command - start the applications firmware. */ ELSE IF command = 'GO' THEN DO ; IF application_start_address = NIL THEN DO ; /* No start address specified yet. */ response_token = build_message (N$TIR, packet.source, N$OUTPUT, N$NONE, 1, @('1')) ; command = ' ' ; END ; ELSE DO ; /* OK! */ response_token = build_message (N$TIR, packet.source, N$OUTPUT, N$NONE, 1, @('0')) ; END ; END ; /* ":" download record - process it. */ ELSE IF HIGH (command) = ':' THEN DO ; CALL download_firmware (packet.location, packet.length, @load_segment, @application_start_address, @status) ; IF status = E$OK THEN DO ; /* No error. */ response_token = build_message (N$TIR, packet.source, N$OUTPUT, N$NONE, 1, @('0')) ; END ; ELSE IF status = E$CONTEXT THEN DO ; /* Invalid record type. */ CALL print_message (@('TIRJOB: Invalid Record Type', 0), packet_token, 'Y') ; response_token = build_message (N$TIR, packet.source, N$OUTPUT, N$NONE, 1, @('1')) ; END ; ELSE IF status = E$MEM THEN DO ; /* Checksum error. */ CALL print_message (@('TIRJOB: Download Checksum Error', 0), packet_token, 'Y') ; response_token = build_message (N$TIR, packet.source, N$OUTPUT, N$NONE, 1, @('2')) ; END ; END ; /* Serial poll complete ("SPC") message from the IEEE-488 interface - ignore these; they are probably power-up SRQ's from the devices on the bus). */ ELSE IF command = 'SP' THEN DO ; CALL console_out (@('TIRJOB: SRQ''s - "', 0), 0) ; CALL console_out (packet.location, packet.length) ; CALL console_out (@('".', cr$lf, 0), 0) ; response_token = 0 ; /* No response. */ END ; /* Invalid command. */ ELSE DO ; CALL print_message (@('TIRJOB: Invalid Command', 0), packet_token, 'Y') ; response_token = build_message (N$TIR, packet.source, N$OUTPUT, N$NONE, 1, @('1')) ; END ; /* Return the message processing status back to the RPU. */ IF response_token <> 0 THEN DO ; CALL send_and_signal (rpu_message, response_token, rpu_exchange, @status) ; IF status <> E$OK THEN CALL console_out (@('TIRJOB: Error sending message to RPU interface task.', cr$lf, 0), 0) ; END ; /* Delete the message input from the RPU. */ CALL delete_message (packet_token) ; END ; /* Until "GO" command received. */ /* Create the test rack main applications task. */ IF application_start_address <> NIL THEN task_token = create_task (application_start_address, 384) ; /* Help! I'm being deleted! */ CALL RQ$DELETE$TASK (0, @status) ; END Test$Rack$Job ; END tirjob_module ;