[LMH]%IO instruction and Device Descriptors

Steve Krueger stevelisp@grape-krueger.com
Sun Jul 27 13:35:02 2003


More on the MISCOP %IO.

%IO always returns NIL.  Generally it is called D-IGNORE.

To start with, don't bother with simulating asych I/O, so the I/O will 
run to completion during the execution of %IO.  Later, when you want 
more fidelity, you can use the OS asynch I/O functions to give a better 
approximation of Explorer disk I/O.

The following describes the asynch behavior.

Each SCSI formatter (one per disk brick and one per tape drive, I 
think), can only handle one command at a time.  So the I/O queuing 
involves figuring out which formatter (SCSI unit) is being addressed. 
 If that formatter is busy, insert this request into the queue in 
priority order.

Priorities (from lroy-qdev.lsip):

    (DefEnum IO-RQ-Priorities (Q-CORRESPONDING-VARIABLE-LISTS
                 System-Constant-Lists)
      (%IO-RQ-Priority-Demand-Page
       %IO-RQ-Priority-Local-File
       %IO-RQ-Priority-Pre-Page
       %IO-RQ-Priority-Remote-File
       %IO-RQ-Priority-VM-Background)
      )

So, the asynch IO magic occurs when the NuPI interrupts for a command 
completion.

The NuPI completion interrupt doesn't indicate which unit (formatter) 
completed a command.  So, the interrupt handler needs to check the head 
entry in each queue to see if it has completed.  There is a bit vector 
in the NuPI device descriptor block that contains a set bit for each 
queue that has an active command.  The RQB at the head of each active 
queue is checked for the COMPLETE bit (%%nupi-status-high-complete   
#o1601  ; complete bit).  When a completed command is found, its 
completion is processed as described below, and it is removed from the 
queue.  If the queue is not empty, the next command is started by 
writing a physical address pointer to the RQB into the NuPI.  If the 
queue is empty, the active bit for the queue in the device descriptor is 
cleared.

If the command being completed does not have the 
%%IO-RQ-Suppress-Sequence-Break bit set, set the sequence break flag in 
the Machine Control Register (MCR).  This bit is sampled at certain 
convenient moments when the state is clean enough that saving a process' 
state into a stack group will fully capture the process.  Generally, a 
sequence break is can be taken between macroinstructions, but some long 
running instructions (think MEMQ) check once per loop when a data item 
is read.  Without these additional tests, sequence breaks might be 
inhibited for a very long time or forever (MEMQ on a circular list).

Generally, the process doing an explicit IO with %IO will wait for the 
RQB to be marked done.  RQB done bit is in the IO information word of 
the RQB as  %%IO-RQ-Done (#o0401   ; Ucode done status).  Microcode sets 
this bit and clears busy in the RQB to complete its processing.

If you don't even try to emulate the asynch IO, you can finish the IO 
request before returning NIL and never bother with the queuing.  You'll 
need to clear busy and set done in the RQB before returning as the wait 
code will check these.

Next up, NuPI.

    -Steve