[comp.sys.transputer] Software reset on transputers

davidb@inmos.co.uk (David Boreham) (05/04/89)

For those who were intrigued by my previous posting about software reset,
here is some more information which I have gathered from experts within INMOS:

 
A) This is an explanation of the RESTART instruction. As you can see,
   it's not quite all one would desire, and it is not supported.

 
It is OPR #1FF in GUY code or 21 2F FF.
 
    The Transputer is reset to its state before boot, BUT
    the link hardware is not reset. This is fine if there
    are no pending inputs on links - I am not sure about pending
    outputs. To be on the safe side, use the reset channel
    instruction on suspicious input/output links as well.
    
    The timers are not stopped.
    
    As a consequence of this the machine has a bad habit
    of timeslicing after inputting the boot code. This
    means that from 1 to 4 bytes at the end of the bootstrap
    code are trodden on by the IPTR (cos the WPTR is set to
    the first word after the bootstrap code, then the IPTR
    is written beneath it). A simple fix is to pad the bootstrap
    code out by 4 bytes.    
 
 

B) Here is an example program (in OCCAM) which emulates most of
   the reset state:

PROC soft.reboot.T414 ()

  --{{{  memory placement
  [MOSTPOS INT]BYTE memory : -- MUST BE COMPILED IN REDUCED MODE
                             -- OR WITH NO RANGE CHECKING!
  PLACE memory AT 0 :
  --}}} 
  --{{{  PROC make.sure.of.workspace
  PROC make.sure.of.workspace ()
  
    -- Ensure we don't overwrite anything useful:
  
    -- We are going to load code into the bottom 256 bytes of memory,
    -- Because of the way the IMS D700D/D705B compiler allocates space,
    -- this makes sure that at least 256 bytes are never used
  
    [256]BYTE waste.of.space :                   -- max size of first message
    PLACE waste.of.space IN WORKSPACE :
    SKIP
  :
  --}}} 
  --{{{  Processor specific declarations
  -- These are for a T414
  
  -- VAL bpw IS 4 :  -- bytes per word
  -- OR: calculate bytes per word as a compile time constant!
  INT unused.variable :
  VAL []BYTE b.unused.variable RETYPES unused.variable :
  VAL bpw         IS SIZE b.unused.variable :
  
  VAL bpw.shift   IS bpw / 2 : -- Only works when bpw IS 2 or 4!
  
  VAL MemStart    IS #80000048 :
  VAL no.of.links IS 4 :
  --}}} 
  --{{{  links
  [no.of.links]CHAN OF ANY from.links, to.links :
  PLACE to.links   AT 0 :
  PLACE from.links AT no.of.links :
  --}}} 
  --{{{  declarations
  BYTE len :
  INT addr.from.boot :
  VAL peek.byte IS 1(BYTE) :
  VAL poke.byte IS 0(BYTE) :
  --}}} 
  SEQ
    make.sure.of.workspace ()   -- leaves bottom 256 bytes clear!
    --{{{  read the bootstrap
    BOOL looping :
    INT  address :
    SEQ
      looping := TRUE
      WHILE looping
        ALT i = 0 FOR no.of.links
          in.link IS from.links [i] :
          in.link ? len
            IF
              len = peek.byte
                SEQ
                  in.link ? address
                  to.links [i] ! [memory FROM address >< (MOSTNEG INT) FOR bpw]
              len = poke.byte
                SEQ
                  in.link ? address
                  in.link ? address  -- throw the poke value away
              TRUE
                SEQ
                  in.link ? [memory FROM MemStart >< (MOSTNEG INT) FOR (INT len)]
                  addr.from.boot := (MOSTNEG INT) + ((no.of.links + i) * bpw)
                  looping := FALSE
    --}}} 
    --{{{  jump into the code, with registers correctly set as though just analysed
    INT new.Wptr :
    SEQ
      -- Point Wptr at first free word
      new.Wptr := MemStart + ((((INT len) >> bpw.shift) + 1) << bpw.shift)
      GUY
        LDL  addr.from.boot     -- address of the link booted by
        LDL  new.Wptr
        GAJW                    -- puts old Wptr into A reg
        LDC  MemStart           -- new Iptr
    
        -- Now A reg holds new Iptr, which will be swapped with current Iptr
        -- by the GCALL,
        -- B reg holds the old Wptr
        -- C reg holds a pointer to the boot link
    
        GCALL                   -- jump to MemStart
    --}}} 
:


Please note the following :

1) As the program stands, it is for a T414. The values of bpw and MemStart
will need to be modified for other processors.

2) It doesn't worry much about priority, so I think that if you run 
it in high priority, it will re-boot in high priority.

3) It ignores POKEs

4) Compile it with range checking OFF if you want to peek memory above
the half way line in the memory space!
(That's cos 'memory' is defined as MOSTPOS INT bytes)

5) I DON'T GUARANTEE it!


C) Design your hardware with a reset register writable by the
   processor, which resets itself by writing the register. (Note that this can 
   be achieved with TRAMs and so-on by tying subsystem to reset, through
   a gate on the motherboard.
   (To work reliably, this needs some monostable-type circuit
    which can stretch the reset pulse to be longer than the 
    minimum data-sheet value. Short reset pulses can cause 
    all manner of strange behaviour in the processor).




Note that this posting is definitely not INMOS customer support,
it is an informal note on what is possible.
-- 
David Boreham, INMOS Limited | mail(uk): davidb@inmos.co.uk or ukc!inmos!davidb
Bristol,  England            |      (us): uunet!inmos-c!davidb
+44 454 616616 ex 543        | Internet : @col.hp.com:davidb@inmos-c