Jun 28, 2002, 10:28:19 PM (19 years ago)
Joel Sherrill <joel.sherrill@…>
4.10, 4.11, 4.8, 4.9, 5, master

2002-06-28 Joel Sherrill <joel@…>

  • intr_NOTIMES.t: Per PR70 incorporate the posting by Zoltan Kocsi <zoltan@…> explaining a m68k vectoring trick.
1 edited


  • doc/supplements/m68k/intr_NOTIMES.t

    rf610f0c5 rbe6073f4  
    144144@end ifset
     146@section CPU Models Without VBR and RAM at 0
     148This is from a post by Zoltan Kocsi <zoltan@bendor.com.au> and is
     149a nice trick in certain situations.  In his words:
     151I think somebody on this list asked about the interupt vector
     152handling w/o VBR and RAM at 0.  The usual trick is
     153to initialise the vector table (except the first 2 two entries, of
     154course) to point to the same location BUT you also add the vector
     155number times 0x1000000 to them. That is, bits 31-24 contain the vector
     156number and 23-0 the address of the common handler.
     157Since the PC is 32 bit wide but the actual address bus is only 24,
     158the top byte will be in the PC but will be ignored when jumping
     159onto your routine.
     161Then your common interrupt routine gets this info by loading the PC
     162into some register and based on that info, you can jump to a vector
     163in a vector table pointed by a virtual VBR:
     167//  Real vector table at 0
     170    .long   initial_sp
     171    .long   initial_pc
     172    .long   myhandler+0x02000000
     173    .long   myhandler+0x03000000
     174    .long   myhandler+0x04000000
     175    ...
     176    .long   myhandler+0xff000000
     180// This handler will jump to the interrupt routine   of which
     181// the address is stored at VBR[ vector_no ]
     182// The registers and stackframe will be intact, the interrupt
     183// routine will see exactly what it would see if it was called
     184// directly from the HW vector table at 0.
     187    .comm    VBR,4,2        // This defines the 'virtual' VBR
     188                            // From C: extern void *VBR;
     190myhandler:                  // At entry, PC contains the full vector
     191    move.l  %d0,-(%sp)      // Save d0
     192    move.l  %a0,-(%sp)      // Save a0
     193    lea     0(%pc),%a0      // Get the value of the PC
     194    move.l  %a0,%d0         // Copy it to a data reg, d0 is VV??????
     195    swap    %d0             // Now d0 is ????VV??
     196    and.w   #0xff00,%d0     // Now d0 is ????VV00 (1)
     197    lsr.w   #6,%d0          // Now d0.w contains the VBR table offset
     198    move.l  VBR,%a0         // Get the address from VBR to a0
     199    move.l  (%a0,%d0.w),%a0 // Fetch the vector
     200    move.l  4(%sp),%d0      // Restore d0
     201    move.l  %a0,4(%sp)      // Place target address to the stack
     202    move.l  (%sp)+,%a0      // Restore a0, target address is on TOS
     203    ret                     // This will jump to the handler and
     204                            // restore the stack
     206(1) If 'myhandler' is guaranteed to be in the first 64K, e.g. just
     207    after the vector table then that insn is not needed.
     209@end example
     211There are probably shorter ways to do this, but it I believe is enough
     212to illustrate the trick. Optimisation is left as an exercise to the
     213reader :-)
    146216@section Interrupt Levels
Note: See TracChangeset for help on using the changeset viewer.