baum@Apple.COM (Allen J. Baum) (09/09/89)
[] There seems to be a problem with instruction restart and memory mapped I/O., for example, in article <blahblahblah> deraadt@enme3.UUCP(Theo Deraadt) writes: >Gad. How about a hardware FIFO? How about a serial receive buffer on >your generic serial chip? If you re-execute, then you might dump something into the FIFO twice. Or, (more likely), you'll take something out twice. This is only because of a design practice that should be abolished, which is side-effects upon reading. Without this mis-feature, extraneous reads do not change state, and the problems don't occur. Writes generally will not get re-executed anyway, since if you execute the write, then you've sucessfully completed the instruction and you don't have to do it again. -- baum@apple.com (408)974-3385 {decwrl,hplabs}!amdahl!apple!baum
jonah@db.toronto.edu (Jeffrey Lee) (09/11/89)
baum@Apple.COM (Allen J. Baum) writes: >There seems to be a problem with instruction restart and memory mapped I/O., >for example, in article <blahblahblah> deraadt@enme3.UUCP(Theo Deraadt) writes: >>Gad. How about a hardware FIFO? How about a serial receive buffer on >>your generic serial chip? >If you re-execute, then you might dump something into the FIFO twice. >Or, (more likely), you'll take something out twice. >This is only because of a design practice that should be abolished, which is >side-effects upon reading. Without this mis-feature, extraneous reads do not >change state, and the problems don't occur. It is probably worth noting that the situation gets much worse when there are 2 or more memory arguments to an instruction (CISC) or when there is an instruction pipeline (RISC/CISC). Ideally you would like to ensure that an instruction restart or continuation will not cause any data to be read or written for a second time. [Note: an instruction may be fetched twice, but no data should be read or written twice.] This may be easier to accomplish on a RISC processor where there is at most one memory argument per instruction (as in most load/store RISC processors). I believe that the following constraints may be sufficient (although not all necessary) to ensure deterministic exception handling with no double reads or writes: Instructions in the pipeline must be allowed to commit, be check-pointed (for continuation), or be aborted (for restart) in the order that they were fetched. An instruction must NOT be committed unless all instructions fetched before it have been committed. An instruction that commits need not be restarted. An instruction that aborts must have no net-effect on the processor state or on the external memory state. [Corollary: An instruction cannot be aborted if it may have had an effect on the external memory state.] An instruction must not be aborted unless all instructions fetched after it can be aborted. An instruction must be check-pointed (for continuation) if it can neither be committed nor aborted for any reason. If an external memory read, write, or read-modify-write cycle is begun on behalf of an instruction, that cycle should be allowed to complete BEFORE handling any interrupts or exceptions. If the cycle completes successfully, the associated instruction must be allowed to commit or else it must be check-pointed BEFORE handling the interrupt or exception. If the cycle fails to complete successfully, the associated instruction shall be deemed to have triggered (and raised) the exception (if any) associated with the failure. If an instruction generates an exception (as opposed to an external interrupt), all instructions prior to it should be allowed to COMPLETE and all instructions after it must be allowed to abort (or be check-pointed) BEFORE beginning the exception processing. If two instructions in a pipeline cause an exception, the exception(s) from the instruction fetched first must be handled first. No new memory cycles should be begun after an exception is raised except to sevice the exception. Hence, any pending instructions that require external memory access to complete must be aborted (if possible) or check-pointed. This means that an instruction MUST NOT begin any memory accesses or raise an exception until ALL prior instructions have finished their memory accesses and/or exception processing (at which point they are free to execute to completion). If an external interrupt occurs after an exception is raised, the processor should finish preparing for the exception handler to execute (completing, aborting or check-pointing instructions) before raising the interrupt exception. Otherwise, an external interrupt should cause all pending instructions to be committed, check-pointed, or aborted as appropriate. Once again, completion of pending instructions must not require any NEW memory accesses to be begun. If the processor cannot guarantee that the execution is continuable according to these constraints, it must save a status flag to indicate that fact. Further more, the status flag should be saved in such a way that it will trigger an exception iff an attempt is made to resume execution in that state. [Ideally a processor should be designed to preclude the need for this flag bit.] These constraints are likely much easier to implement and verify in the design of a RISC processor than in a CISC processor. In particular, it may be possible to avoid the need for instruction check-pointing and continuation through careful design of the pipeline. On the other hand, a CISC processor with multiple memory operands MUST support instruction continuation in order to satisfy these constraints. j.
eifert@oakhill.UUCP (Jim Eifert) (09/14/89)
The MC68332 uses "instruction restart." Most instructions are considered completed when the write is received by the bus controller. When a fault occurs, both the PC of the instruction to execute upon restarting and the "released" write are stacked (in addition to some other information -- see the manual). Because of this: on a move memory to memory, a write which is faulted will not cause the read to be rerun. When the process is continued, the write will be queued up, and the next instruction started (or restarted). Some instructions such as move multiple are continued from a midpoint, though a larger stack frame is not required. Note the the CPU of the MC68332 is a new design and the "virtual memory" implementation is not necessarily similiar to any other present or future products. For those unfamiliar with the MC68332, see "The MC68332 Microcontroller" in the August 1989 issue of IEEE Micro. Or refer to the May and June issues of Microprocessor Report. Jim Eifert