Annotation of researchv9/sys/sun3/locore.s, revision 1.1.1.1

1.1       root        1:        .data
                      2:        .asciz  "@(#)locore.s 1.1 86/02/03 Copyr 1985 Sun Micro"
                      3:        .even
                      4:        .text
                      5: /*
                      6:  *     Copyright (c) 1985 by Sun Microsystems, Inc.
                      7:  */
                      8: 
                      9: #include "../h/param.h"
                     10: #include "../h/vmparam.h"
                     11: #include "../h/errno.h"
                     12: /*
                     13: #include "../netinet/in_systm.h"
                     14: 
                     15: #include "../sundev/mbvar.h"
                     16: */
                     17: 
                     18: #include "../machine/asm_linkage.h"
                     19: #include "../machine/buserr.h"
                     20: #include "../machine/clock.h"
                     21: #include "../machine/cpu.h"
                     22: #include "../machine/diag.h"
                     23: #include "../machine/enable.h"
                     24: #include "../machine/interreg.h"
                     25: #include "../machine/memerr.h"
                     26: #include "../machine/mmu.h"
                     27: #include "../machine/pcb.h"
                     28: #include "../machine/psl.h"
                     29: #include "../machine/pte.h"
                     30: #include "../machine/reg.h"
                     31: #include "../machine/trap.h"
                     32: 
                     33: #include "assym.s"
                     34: 
                     35: /* 
                     36:  * Absolute external symbols
                     37:  */
                     38:        .globl  _u, _DVMA
                     39: _u     = UADDR         | 32 bit virtual address for u-area
                     40: _DVMA  = 0x0FF00000    | 28 bit virtual address for system DVMA
                     41: 
                     42: /*
                     43:  * The interrupt stack.  This must be the first thing in the data
                     44:  * segment (other than an sccs string) so that we don't stomp
                     45:  * on anything important during interrupt handling.  We get a
                     46:  * red zone below this stack for free when the kernel text is
                     47:  * write protected.  Since the kernel is loaded with the "-N"
                     48:  * flag, we pad this stack by a page because when the page
                     49:  * level protection is done, we will lose part of this interrupt
                     50:  * stack.  Thus the true interrupt stack will be at least MIN_INTSTACK_SZ
                     51:  * bytes and at most MIN_INTSTACK_SZ+NBPG bytes.  The interrupt entry
                     52:  * code assumes that the interrupt stack is at a lower address than
                     53:  * both eintstack and the kernel stack in the u area.
                     54:  */
                     55: #define        MIN_INTSTACK_SZ 0x800
                     56:        .data
                     57:        .globl _intstack, eintstack
                     58: _intstack:                             | bottom of interrupt stack
                     59:        . = . + NBPG + MIN_INTSTACK_SZ
                     60: eintstack:                             | end (top) of interrupt stack
                     61: 
                     62: /*
                     63:  * System software page tables
                     64:  */
                     65: #define vaddr(x)       ((((x)-_Sysmap)/4)*NBPG + KERNELBASE)
                     66: #define SYSMAP(mname, vname, npte)     \
                     67:        .globl  mname;                  \
                     68: mname: .=.+(4*npte);                   \
                     69:        .globl  vname;                  \
                     70: vname = vaddr(mname);
                     71:        SYSMAP(_Sysmap   ,_Sysbase      ,SYSPTSIZE      )
                     72:        SYSMAP(_Usrptmap ,_usrpt        ,USRPTSIZE      )
                     73:        SYSMAP(_Forkmap  ,_forkutl      ,UPAGES         )
                     74:        SYSMAP(_Xswapmap ,_xswaputl     ,UPAGES         )
                     75:        SYSMAP(_Xswap2map,_xswap2utl    ,UPAGES         )
                     76:        SYSMAP(_Swapmap  ,_swaputl      ,UPAGES         )
                     77:        SYSMAP(_Pushmap  ,_pushutl      ,UPAGES         )
                     78:        SYSMAP(_Vfmap    ,_vfutl        ,UPAGES         )
                     79:        SYSMAP(_CMAP1    ,_CADDR1       ,1              ) | local tmp
                     80:        SYSMAP(_CMAP2    ,_CADDR2       ,1              ) | local tmp
                     81:        SYSMAP(_mmap     ,_vmmap        ,1              )
                     82:        SYSMAP(_msgbufmap,_msgbuf       ,MSGBUFPTECNT   )
                     83: /*
                     84:        SYSMAP(_Mbmap    ,_mbutl        ,NMBCLUSTERS*CLSIZE)
                     85: */
                     86:        SYSMAP(_ESysmap  ,_Syslimit     ,0              ) | must be last
                     87: 
                     88:        .globl  _Syssize
                     89: _Syssize = (_ESysmap-_Sysmap)/4
                     90: 
                     91: /*
                     92:  * Software copy of system enable register
                     93:  * This is always atomically updated
                     94:  */
                     95:        .data
                     96:        .globl  _enablereg
                     97: _enablereg:    .byte   0                       | UNIX's system enable register
                     98:        .even
                     99:        .text
                    100: 
                    101: /*
                    102:  * Macro to save all registers and switch to kernel context
                    103:  * 1: Save and switch context
                    104:  * 2: Save all registers
                    105:  * 3: Save user stack pointer
                    106:  */
                    107: #define SAVEALL() \
                    108:        clrw    sp@-;\
                    109:        moveml  #0xFFFF,sp@-;\
                    110:        movl    usp,a0;\
                    111:        movl    a0,sp@(R_SP)
                    112: 
                    113: /* Normal trap sequence */
                    114: #define TRAP(type) \
                    115:        SAVEALL();\
                    116:        movl    #type,sp@-;\
                    117:        jra     trap
                    118: 
                    119: /*
                    120:  * System initialization
                    121:  * UNIX receives control at the label `_start' which
                    122:  * must be at offset zero in this file; this file must
                    123:  * be the first thing in the boot image.
                    124:  */
                    125:        .text
                    126:        .globl  _start
                    127: _start:
                    128: /*
                    129:  * We should reset the world here, but it screws the UART settings.
                    130:  *
                    131:  * Do a halfhearted job of setting up the mmu so that we can run out
                    132:  * of the high address space.  We do this by reading the current pmegs
                    133:  * for the `real' locations and using them for the virtual relocation.
                    134:  * NOTE - Assumes that the real and virtual locations have the same
                    135:  * segment offsets from 0 and KERNELBASE!!!
                    136:  *
                    137:  * We make the following assumptions about our environment
                    138:  * as set up by the monitor:
                    139:  *
                    140:  *     - we have enough memory mapped for the entire kernel + some more
                    141:  *     - all pages are writable
                    142:  *     - the last pmeg [SEGINV] has no valid pme's
                    143:  *     - the highest virtual segment has a pmeg allocated to it
                    144:  *     - when the monitor's romp->v_memorybitmap points to a zero
                    145:  *         - each low segment i is mapped to use pmeg i
                    146:  *         - each page map entry i maps physical page i
                    147:  *     - the monitor's scb is NOT in low memory
                    148:  *     - on systems w/ ecc memory, that the monitor has set the base
                    149:  *         addresses and enabled all the memory cards correctly
                    150:  *
                    151:  * We will set the protection properly in startup().
                    152:  */
                    153: 
                    154: /*
                    155:  * Before we set up the new mapping and start running with the correct
                    156:  * addresses, all of the code must be carefully written to be position
                    157:  * independent code, since we are linked for running out of high addresses,
                    158:  * but we get control running in low addresses.  We continue to run
                    159:  * off the stack set up by the monitor until after we set up the u area.
                    160:  */
                    161:        movw    #SR_HIGH,sr             | lock out interrupts
                    162:        moveq   #FC_MAP,d0
                    163:        movc    d0,sfc                  | set default sfc to FC_MAP
                    164:        movc    d0,dfc                  | set default dfc to FC_MAP
                    165:        moveq   #KCONTEXT,d0    
                    166:        movsb   d0,CONTEXTBASE          | now running in KCONTEXT
                    167: 
                    168: leax:  lea     pc@(_start-(leax+2)),a2 | a2 = true current location of _start
                    169:        movl    a2,d2                   | real start address
                    170:        andl    #SEGMENTADDRBITS,d2     | clear extraneous bits
                    171:        orl     #SEGMENTBASE,d2         | set to segment map offset
                    172:        movl    d2,a2                   | a2 = real adddress map pointer
                    173: 
                    174:        movl    #_start,d3              | virtual start address
                    175:        andl    #SEGMENTADDRBITS,d3     | clear extraneous bits
                    176:        orl     #SEGMENTBASE,d3         | set to segment map offset
                    177:        movl    d3,a3                   | a3 = virtual address map pointer
                    178: 
                    179: /*
                    180:  * Compute the number used to control the dbra loop.
                    181:  * By doing ((end - 1) - KERNELBASE) >> SGSHIFT we
                    182:  * essentially get ctos(btoc(end - KERNELBASE)) - 1
                    183:  * where the - 1 is adjustment for the dbra loop.
                    184:  */
                    185:        movl    #_end-1,d1              | get virtual end
                    186:        subl    #KERNELBASE,d1          | subtract off base address
                    187:        movl    #SGSHIFT,d0             | load up segment shift value
                    188:        lsrl    d0,d1                   | d1 = # of segments to map - 1
                    189: 
                    190: /*
                    191:  * Now loop through the real addresses where we are loaded and set
                    192:  * up the virtual segments for where we want to be virtually to be the same.
                    193:  */
                    194: 0:
                    195:        movsb   a2@,d0                  | get real segno value
                    196:        movsb   d0,a3@                  | set virtual segno value
                    197:        addl    #NBSG,a2                | bump real address map pointer
                    198:        addl    #NBSG,a3                | bump virtual address map pointer
                    199:        dbra    d1,0b                   | decrement count and loop
                    200: 
                    201:        movl    #CACHE_CLEAR+CACHE_ENABLE,d0
                    202:        movc    d0,cacr                 | clear (and enable) the cache
                    203: 
                    204:        jmp     cont:l                  | force non-PC rel branch
                    205: cont:
                    206: 
                    207: /*
                    208:  * PHEW!  Now we are running with correct addresses
                    209:  * and can use non-position independent code.
                    210:  */
                    211: 
                    212: /*
                    213:  * Now map in our own copies of the eeprom, clock, memory error
                    214:  * register, interrupt control register, and ecc regs into the
                    215:  * last virtual segment which already has a pmeg allocated to it
                    216:  * when we get control from the monitor.
                    217:  */
                    218:        lea     EEPROM_ADDR_MAPVAL,a0   | map in eeprom
                    219:        movl    #EEPROM_ADDR_PTE,d0
                    220:        movsl   d0,a0@
                    221: 
                    222:        lea     CLKADDR_MAPVAL,a0       | map in clock
                    223:        movl    #CLKADDR_PTE,d0
                    224:        movsl   d0,a0@
                    225: 
                    226:        lea     MEMREG_MAPVAL,a0        | map in memory error register
                    227:        movl    #MEMREG_PTE,d0
                    228:        movsl   d0,a0@
                    229: 
                    230:        lea     INTERREG_MAPVAL,a0      | map in interrupt control reg
                    231:        movl    #INTERREG_PTE,d0
                    232:        movsl   d0,a0@
                    233: 
                    234:        lea     ECCREG_MAPVAL,a0        | map in ecc regs
                    235:        movl    #ECCREG_PTE,d0
                    236:        movsl   d0,a0@
                    237: 
                    238: /*
                    239:  * Check to see if memory was all mapped in correctly.  On versions >= 'N',
                    240:  * if ROMP_ROMVEC_VERSION is greater than zero, then ROMP_MEMORYBITMAP
                    241:  * contains the address of a pointer to an array of bits
                    242:  * If this pointer is non-zero, then we had some bad pages
                    243:  * Until we get smarter, we give up if we find this condition.
                    244:  */
                    245:        tstl    ROMP_ROMVEC_VERSION
                    246:        ble     1f                      | field is <= zero, don't do next test
                    247:        movl    ROMP_MEMORYBITMAP,a0
                    248:        tstl    a0@
                    249:        jeq     1f                      | pointer is zero, all ok
                    250:        pea     0f
                    251:        jsr     _halt
                    252:        addqw   #4,sp                   | in case they really want to try this
                    253:        .data
                    254: 0:     .asciz "Memory bad"
                    255:        .even
                    256:        .text
                    257: 1:
                    258: 
                    259: /*
                    260:  * Set up mapping for the u page(s) now, using the physical page(s)
                    261:  * after _end.  This code and uinit() are closely related.
                    262:  */
                    263:        movl    #(UPAGES-1),d1          | dbra loop counter
                    264:        pea     _end-KERNELBASE+NBPG-1  | phys addr of starting page past end
                    265:        jsr     _getpgmap               | getpgmap(end - KERNELBASE + NBPG - 1)
                    266:        addqw   #4,sp                   | pop argument
                    267:        orl     #(PG_S+PG_W),d0         | make a system writable page
                    268:        lea     _u,a0                   | get addr of u area
                    269: 0:
                    270:        movl    d0,sp@-                 | push pte
                    271:        pea     a0@                     | push addr
                    272:        jsr     _setpgmap               | setpgmap(u + i*NBPG, pte + i)
                    273:        addqw   #8,sp                   | pop arguments
                    274:        addql   #1,d0                   | bump pte to next phys page
                    275:        addl    #NBPG,a0                | bump addr
                    276:        dbra    d1,0b
                    277: 
                    278: | zero first page which will be scb/usrpt page
                    279:        movl    #((NBPG-1)/4),d0        | dbra byte count
                    280:        lea     0,a0                    | start at zero
                    281: 0:     clrl    a0@+                    | clear long word and increment
                    282:        dbra    d0,0b                   | decrement count and loop
                    283: 
                    284: | zero bss + u page(s) (using low addresses)
                    285:        movl    #_end-KERNELBASE+(NBPG*(UPAGES+1))-1,d0
                    286:        andl    #~(NBPG-1),d0           | mask off to page boundary
                    287:        lea     _edata-KERNELBASE,a0    | get bss start
                    288:        subl    a0,d0                   | get bss length
                    289:        lsrl    #2,d0                   | shift for long count
                    290: 0:     clrl    a0@+                    | clear long word and increment
                    291:        subql   #1,d0
                    292:        jne     0b                      | decrement count and loop
                    293: 
                    294: /*
                    295:  * Set up the stack.  From now we continue to use the 68020 ISP
                    296:  * (interrupt stack pointer).  This is because the MSP (master
                    297:  * stack pointer) as implemented by Motorola is too painful to
                    298:  * use since we have to play lots of games and add extra tests
                    299:  * to set something in the master stack if we running on the
                    300:  * interrupt stack and we are about to pop off a throw away
                    301:  * stack frame.
                    302:  *
                    303:  * Thus it is possible to having naming conflicts.  In general,
                    304:  * when the term "interrupt stack" (no pointer) is used, it
                    305:  * is referring to the software implemented interrupt stack
                    306:  * and the "kernel stack" is the per user kernel stack in the
                    307:  * user area.  We handling switching between the two different
                    308:  * address ranges upon interrupt entry/exit.  We will use ISP
                    309:  * and MSP if we are referring to the hardstack stack pointers.
                    310:  */
                    311:        lea     _u+U_STACK+KERNSTACK,sp | set to top of kernel stack
                    312: 
                    313:        /*
                    314:         * See if we have a 68881 attached.
                    315:         * _fppstate is 0 if no fpp,
                    316:         * 1 if fpp is present and enabled,
                    317:         * and -1 if fpp is present but disabled
                    318:         * (not currently used).
                    319:         */
                    320:        .data
                    321:        .globl  _fppstate
                    322: _fppstate:     .word 1         | mark as present until we find out otherwise
                    323:        .text
                    324: 
                    325: flinevec = 0x2c
                    326:        movsb   ENABLEREG,d0            | get the current enable register
                    327:        orb     #ENA_FPP,d0             | or in FPP enable bit
                    328:        movsb   d0,ENABLEREG            | set in the enable register
                    329:        movl    sp,a1                   | save sp in case of fline fault
                    330:        movc    vbr,a0                  | get vbr
                    331:        movl    a0@(flinevec),d1        | save old f line trap handler
                    332:        movl    #ffault,a0@(flinevec)   | set up f line handler
                    333:        frestore fnull
                    334:        jra     1f
                    335: 
                    336: fnull: .long   0                       | null fpp internal state
                    337: 
                    338: ffault:                                        | handler for no fpp present
                    339:        movw    #0,_fppstate            | set global to say no fpp
                    340:        andb    #~ENA_FPP,d0            | clear ENA_FPP enable bit
                    341:        movl    a1,sp                   | clean up stack
                    342: 
                    343: 1:
                    344:        movl    d1,a0@(flinevec)        | restore old f line trap handler
                    345:        movsb   d0,ENABLEREG            | set up enable reg
                    346:        movb    d0,_enablereg           | save soft copy of enable register
                    347: 
                    348: | dummy up a stack so process 1 can find saved registers
                    349:        movl    #USRSTACK,a0            | init user stack pointer
                    350:        movl    a0,usp
                    351:        clrw    sp@-                    | dummy fmt & vor
                    352:        movl    #USRTEXT,sp@-           | push pc
                    353:        movw    #SR_USER,sp@-           | push sr
                    354:        lea     0,a6                    | stack frame link 0 in main
                    355: | invoke main, we will return as process 1 (init)
                    356:        SAVEALL()
                    357:        jsr     _main                   | simulate interrupt -> main
                    358:        clrl    d0                      | fake return value from trap
                    359:        jra     rei
                    360: 
                    361: /*
                    362:  * Entry points for interrupt and trap vectors
                    363:  */
                    364:        .globl  buserr, addrerr, coprocerr, fmterr, illinst, zerodiv, chkinst
                    365:        .globl  trapv, privvio, trace, emu1010, emu1111, spurious
                    366:        .globl  badtrap, brkpt, floaterr, level2, level3, level4, level5
                    367:        .globl  _level7, errorvec
                    368: 
                    369: buserr:
                    370:        TRAP(T_BUSERR)
                    371: 
                    372: addrerr:
                    373:        TRAP(T_ADDRERR)
                    374: 
                    375: coprocerr:
                    376:        TRAP(T_COPROCERR)
                    377: 
                    378: fmterr:
                    379:        TRAP(T_FMTERR)
                    380: 
                    381: illinst:
                    382:        TRAP(T_ILLINST)
                    383: 
                    384: zerodiv:
                    385:        TRAP(T_ZERODIV)
                    386: 
                    387: chkinst:
                    388:        TRAP(T_CHKINST)
                    389: 
                    390: trapv:
                    391:        TRAP(T_TRAPV)
                    392: 
                    393: privvio:
                    394:        TRAP(T_PRIVVIO)
                    395: 
                    396: trace:
                    397:        TRAP(T_TRACE)
                    398: 
                    399: emu1010:
                    400:        TRAP(T_EMU1010)
                    401: 
                    402: emu1111:
                    403:        TRAP(T_EMU1111)
                    404: 
                    405: spurious:
                    406:        TRAP(T_SPURIOUS)
                    407: 
                    408: badtrap:
                    409:        TRAP(T_M_BADTRAP)
                    410: 
                    411: brkpt:
                    412:        TRAP(T_BRKPT)
                    413: 
                    414: floaterr:
                    415:        TRAP(T_M_FLOATERR)
                    416: 
                    417: errorvec:
                    418:        TRAP(T_M_ERRORVEC)
                    419: 
                    420: level2:
                    421:        IOINTR(2)
                    422: 
                    423: level3:
                    424:        IOINTR(3)
                    425: 
                    426: level4:
                    427:        IOINTR(4)
                    428: 
                    429:        .data
                    430:        .globl  _ledcnt
                    431: ledpat:
                    432:        .byte   ~0x80
                    433:        .byte   ~0x40
                    434:        .byte   ~0x20
                    435:        .byte   ~0x10
                    436:        .byte   ~0x08
                    437:        .byte   ~0x04
                    438:        .byte   ~0x02
                    439:        .byte   ~0x01
                    440:        .byte   ~0x02
                    441:        .byte   ~0x04
                    442:        .byte   ~0x08
                    443:        .byte   ~0x10
                    444:        .byte   ~0x20
                    445:        .byte   ~0x40
                    446: endpat:
                    447:        .even
                    448: ledptr:                .long   ledpat
                    449: flag5:         .word   0
                    450: flag7:         .word   0
                    451: _ledcnt:       .word   50              | once per second min LED update rate
                    452: ledcnt:                .word   0
                    453:        .text
                    454: 
                    455: /*
                    456:  * This code assumes that the real time clock interrupts 100 times
                    457:  * a second and that we want to only call hardclock 50 times/sec
                    458:  * We update the LEDs with new values so at least a user can tell
                    459:  * that something it still running before calling hardclock().
                    460:  */
                    461: level5:                                        | default clock interrupt
                    462:        tstb    CLKADDR+CLK_INTRREG     | read CLKADDR->clk_intrreg to clear
                    463:        andb    #~IR_ENA_CLK5,INTERREG  | clear interrupt request
                    464:        orb     #IR_ENA_CLK5,INTERREG   | and re-enable
                    465:        tstb    CLKADDR+CLK_INTRREG     | clear interrupt register again,
                    466:                                        | if we lost interrupt we will
                    467:                                        | resync later anyway.
                    468: | for 100 hz operation, comment out from here ...
                    469:        notw    flag5                   | toggle flag
                    470:        jeq     0f                      | if result zero skip ahead
                    471:        rte
                    472: 0:
                    473: | ... to here
                    474:        moveml  #0xC0E0,sp@-            | save d0,d1,a0,a1,a2
                    475: 
                    476:        movl    sp,a2                   | save copy of previous sp
                    477:        cmpl    #eintstack,sp           | on interrupt stack?
                    478:        jls     1f                      | yes, skip
                    479:        lea     eintstack,sp            | no, switch to interrupt stack
                    480: 1:
                    481: 
                    482:                        /* check for LED update */
                    483:        movl    a2@(5*4+2),a1           | get saved pc
                    484:        cmpl    #idle,a1                | were we idle?
                    485:        beq     0f                      | yes, do LED update
                    486:        subqw   #1,ledcnt
                    487:        bge     2f                      | if positive skip LED update
                    488: 0:
                    489:        movw    _ledcnt,ledcnt          | reset counter
                    490:        movl    ledptr,a0               | get pointer
                    491:        movb    a0@+,d0                 | get next byte
                    492:        cmpl    #endpat,a0              | are we at the end?
                    493:        bne     1f                      | if not, skip
                    494:        lea     ledpat,a0               | reset pointer
                    495: 1:
                    496:        movl    a0,ledptr               | save pointer
                    497:        movsb   d0,DIAGREG              | d0 to diagnostic LEDs
                    498: 
                    499: 2:                                     | call hardclock
                    500:        movw    a2@(5*4),d0             | get saved sr
                    501:        movl    d0,sp@-                 | push it as a long
                    502:        movl    a1,sp@-                 | push saved pc
                    503:        jsr     _hardclock              | call UNIX routine
                    504:        movl    a2,sp                   | restore old sp
                    505:        moveml  sp@+,#0x0703            | restore all saved regs
                    506:        jra     rei_io                  | all done
                    507: 
                    508: /*
                    509:  * Level 7 interrupts can be caused by parity/ECC errors or the
                    510:  * clock chip.  The clock chip is tied to level 7 interrupts
                    511:  * only if we are profiling.  Because of the way nmi's work,
                    512:  * we clear the any level 7 clock interrupts first before
                    513:  * checking the memory error register.
                    514:  */
                    515: _level7:
                    516: #ifdef GPROF
                    517:        tstb    CLKADDR+CLK_INTRREG     | read CLKADDR->clk_intrreg to clear
                    518:        andb    #~IR_ENA_CLK7,INTERREG  | clear interrupt request
                    519:        orb     #IR_ENA_CLK7,INTERREG   | and re-enable
                    520: #endif GPROF
                    521: 
                    522:        moveml  #0xC0C0,sp@-            | save C regs
                    523:        movb    MEMREG,d0               | read memory error register
                    524:        andb    #ER_INTR,d0             | a parity/ECC interrupt pending?
                    525:        jeq     0f                      | if not, jmp
                    526:        jsr     _memerr                 | dump memory error info
                    527:        /*MAYBE REACHED*/               | if we do return to here, then
                    528:        jra     1f                      | we had a non-fatal memory problem
                    529: 0:
                    530: 
                    531: #ifdef GPROF
                    532: | for 100 hz profiling, comment out from here ...
                    533:        notw    flag7                   | toggle flag
                    534:        jne     1f                      | if result non-zero return
                    535: | ... to here
                    536:        jsr     kprof                   | do the profiling
                    537: #else GPROF
                    538:        pea     0f                      | push message printf
                    539:        jsr     _printf                 | print the message
                    540:        addqw   #4,sp                   | pop argument
                    541:        .data
                    542: 0:     .asciz  "stray level 7 interrupt\012"
                    543:        .even
                    544:        .text
                    545: #endif GPROF
                    546: 1:
                    547:        moveml  sp@+,#0x0303            | restore regs
                    548:        rte
                    549: 
                    550: /*
                    551:  * Called by trap #2 to do an instruction cache flush operation
                    552:  */
                    553:        .globl  flush
                    554: flush:
                    555:        movl    #CACHE_CLEAR+CACHE_ENABLE,d0
                    556:        movc    d0,cacr                 | clear (and enable) the cache
                    557:        rte
                    558: 
                    559:        .globl  syscall, trap, rei
                    560: /*
                    561:  * Special case for syscall.
                    562:  * Everything in line because this is by far the most
                    563:  * common interrupt.
                    564:  */
                    565: syscall:
                    566:        subqw   #2,sp                   | empty space
                    567:        moveml  #0xFFFF,sp@-            | save all regs
                    568:        movl    usp,a0                  | get usp
                    569:        movl    a0,sp@(R_SP)            | save usp
                    570:        movl    #syserr,_u+U_LOFAULT    | catch a fault if and when
                    571:        movl    a0@,d0                  | get the syscall code
                    572: syscont:
                    573:        clrl    _u+U_LOFAULT            | clear lofault
                    574:        movl    d0,sp@-                 | push syscall code
                    575:        jsr     _syscall                | go to C routine
                    576:        addqw   #4,sp                   | pop arg
                    577:        orw     #SR_INTPRI,sr           | need to test atomicly, rte will lower
                    578:        bclr    #AST_STEP_BIT-24,_u+PCB_P0LR | need to single step?
                    579:        jne     4f
                    580:        bclr    #AST_SCHED_BIT-24,_u+PCB_P0LR | need to reschedule?
                    581:        jeq     3f                      | no, get out
                    582: 4:     bset    #TRACE_AST_BIT-24,_u+PCB_P0LR | say that we're tracing for AST
                    583:        jne     3f                      | if already doing it, skip
                    584:        bset    #SR_TRACE_BIT-8,sp@(R_SR) | set trace mode
                    585:        jeq     3f                      | if wasn't set, continue
                    586:        bset    #TRACE_USER_BIT-24,_u+PCB_P0LR | save fact that trace was set
                    587: 3:     movl    sp@(R_SP),a0            | restore user SP
                    588:        movl    a0,usp
                    589:        movl    #CACHE_CLEAR+CACHE_ENABLE,d0
                    590:        movc    d0,cacr                 | clear (and enable) the cache
                    591: 1:
                    592:        moveml  sp@,#0x7FFF             | restore all but SP
                    593:        addw    #R_SR,sp                | pop all saved regs
                    594:        rte                             | and return!
                    595: 
                    596: syserr:
                    597:        movl    #-1,d0                  | set err code
                    598:        jra     syscont                 | back to mainline
                    599: 
                    600: /*
                    601:  * We reset the sfc and dfc to FC_MAP in case we came in from
                    602:  * a trap while in the monitor since the monitor uses movs
                    603:  * instructions after dorking w/ sfc and dfc during its operation.
                    604:  */
                    605: trap:
                    606:        moveq   #FC_MAP,d0
                    607:        movc    d0,sfc  
                    608:        movc    d0,dfc
                    609:        jsr     _trap                   | Enter C trap routine
                    610:        addqw   #4,sp                   | Pop trap type
                    611: 
                    612: /*
                    613:  * Return from interrupt or trap, check for AST's.
                    614:  * d0 contains the size of info to pop (if any)
                    615:  */
                    616: rei:
                    617:        btst    #SR_SMODE_BIT-8,sp@(R_SR) | SR_SMODE ?
                    618:        bne     1f                      | skip if system
                    619:        orw     #SR_INTPRI,sr           | need to test atomicly, rte will lower
                    620:        bclr    #AST_STEP_BIT-24,_u+PCB_P0LR | need to single step?
                    621:        jne     4f
                    622:        bclr    #AST_SCHED_BIT-24,_u+PCB_P0LR | need to reschedule?
                    623:        jeq     3f                      | no, get out
                    624: 4:     bset    #TRACE_AST_BIT-24,_u+PCB_P0LR | say that we're tracing for AST
                    625:        bne     3f                      | if already doing it, skip
                    626:        bset    #SR_TRACE_BIT-8,sp@(R_SR) | set trace mode
                    627:        jeq     3f                      | if wasn't set, continue
                    628:        bset    #TRACE_USER_BIT-24,_u+PCB_P0LR | save fact that trace was set
                    629: 3:     movl    sp@(R_SP),a0            | restore user SP
                    630:        movl    a0,usp
                    631:        movl    #CACHE_CLEAR+CACHE_ENABLE,a0
                    632:        movc    a0,cacr                 | clear (and enable) the cache
                    633: 1:
                    634:        tstl    d0                      | any cleanup needed?
                    635:        beq     2f                      | no, skip
                    636:        movl    sp,a0                   | get current sp
                    637:        addw    d0,a0                   | pop off d0 bytes of crud
                    638:        clrw    a0@(R_VOR)              | dummy VOR
                    639:        movl    sp@(R_PC),a0@(R_PC)     | move PC
                    640:        movw    sp@(R_SR),a0@(R_SR)     | move SR
                    641:        movl    a0,sp@(R_SP)            | stash new sp value
                    642:        moveml  sp@,#0xFFFF             | restore all including SP
                    643:        addw    #R_SR,sp                | pop all saved regs
                    644:        rte                             | and return!
                    645: 2:
                    646:        moveml  sp@,#0x7FFF             | restore all but SP
                    647:        addw    #R_SR,sp                | pop all saved regs
                    648:        rte                             | and return!
                    649: 
                    650: /*
                    651:  * Return from I/O interrupt, check for AST's.
                    652:  */
                    653:        .globl  rei_io
                    654: rei_iop:
                    655:        moveml  sp@+,#0x0707            | pop regs <a2,a1,a0,d2,d1,d0>
                    656: rei_io:
                    657:        addql   #1,_cnt+V_INTR          | increment io interrupt count
                    658: rei_si:
                    659:        btst    #SR_SMODE_BIT-8,sp@     | SR_SMODE?  (SR is atop stack)
                    660:        jne     3f                      | skip if system
                    661:        orw     #SR_INTPRI,sr           | need to test atomicly, rte will lower
                    662:        bclr    #AST_STEP_BIT-24,_u+PCB_P0LR | need to single step?
                    663:        jne     4f
                    664:        bclr    #AST_SCHED_BIT-24,_u+PCB_P0LR | need to reschedule?
                    665:        jeq     3f                      | no, get out
                    666: 4:     bset    #TRACE_AST_BIT-24,_u+PCB_P0LR | say that we're tracing for AST
                    667:        jne     3f                      | if already doing it, skip
                    668:        bset    #SR_TRACE_BIT-8,sp@     | set trace mode in SR atop stack
                    669:        jeq     3f                      | if wasn't set, continue
                    670:        bset    #TRACE_USER_BIT-24,_u+PCB_P0LR | save fact that trace was set
                    671: 3:
                    672:        rte                             | and return!
                    673: 
                    674: /*
                    675:  * Handle software interrupts
                    676:  * Just call C routine
                    677:  */
                    678:        .globl  softint
                    679: softint:
                    680:        moveml  #0xC0E0,sp@-            | save regs we trash <d0,d1,a0,a1,a2>
                    681:        movl    sp,a2                   | save copy of previous sp
                    682:        cmpl    #eintstack,sp           | on interrupt stack?
                    683:        jls     0f                      | yes, skip
                    684:        lea     eintstack,sp            | no, switch to interrupt stack
                    685: 0:
                    686:        bclr    #IR_SOFT_INT1_BIT,INTERREG| clear interrupt request
                    687:        jsr     _softint                | Call C
                    688:        movl    a2,sp                   | restore old sp
                    689:        moveml  sp@+,#0x0703            | restore saved regs <a2,a1,a0,d1,d0>
                    690:        jra     rei_si
                    691: 
                    692: /*
                    693:  * Turn on a software interrupt (H/W level 1).
                    694:  */
                    695:        ENTRY(siron)
                    696:        bset    #IR_SOFT_INT1_BIT,INTERREG | trigger level 1 intr
                    697:        rts
                    698: 
                    699: /*
                    700:  * return 1 if an interrupt is being serviced (on interrupt stack),
                    701:  * otherwise return 0.
                    702:  */
                    703:        ENTRY(intsvc)
                    704:        clrl    d0                      | assume false
                    705:        cmpl    #eintstack,sp           | on interrupt stack?
                    706:        bhi     1f                      | no, skip
                    707:        movl    #1,d0                   | return true
                    708: 1:
                    709:        rts
                    710: 
                    711: /*
                    712:  * Enable and disable DVMA.
                    713:  */
                    714:        ENTRY(enable_dvma)
                    715: 1:
                    716:        orb     #ENA_SDVMA,_enablereg   | enable System DVMA
                    717:        movb    _enablereg,d0           | get it in a register
                    718:        movsb   d0,ENABLEREG            | put enable register back
                    719:        cmpb    _enablereg,d0           | see if someone higher changed it
                    720:        bne     1b                      | if so, try again
                    721:        rts
                    722:        
                    723:        ENTRY(disable_dvma)
                    724: 1:
                    725:        andb    #~ENA_SDVMA,_enablereg  | disable System DVMA
                    726:        movb    _enablereg,d0           | get it in a register
                    727:        movsb   d0,ENABLEREG            | put enable register back
                    728:        cmpb    _enablereg,d0           | see if someone higher changed it
                    729:        bne     1b                      | if so, try again
                    730:        rts
                    731: 
                    732: /*
                    733:  * Transfer data to and from user space -
                    734:  * Note that these routines can cause faults
                    735:  * It is assumed that the kernel has nothing at
                    736:  * less than KERNELBASE in the virtual address space.
                    737:  */
                    738: | Return length of user string         _fustrlen(address)
                    739:        ENTRY(fustrlen)
                    740:        movl    #fsuerr,_u+U_LOFAULT    | catch a fault if and when
                    741:        movl    sp@(4),a0               | get address
                    742:        movl    #KERNELBASE-1,a1
                    743: 1:
                    744:        cmpl    a1,a0                   | check address range
                    745:        jhi     fsuerr                  | jmp if greater than
                    746:        tstb    a0@+                    | is it 0
                    747:        jne     1b
                    748:        movl    a0,d0
                    749:        subl    sp@(4),d0               | compute difference
                    750:        clrl    _u+U_LOFAULT            | clear lofault
                    751:        rts
                    752: 
                    753: | Fetch user byte              _fubyte(address)
                    754:        ENTRY2(fubyte,fuibyte)
                    755:        movl    #fsuerr,_u+U_LOFAULT    | catch a fault if and when
                    756:        movl    sp@(4),a0               | get address
                    757:        cmpl    #KERNELBASE-1,a0        | check address range
                    758:        jhi     fsuerr                  | jmp if greater than
                    759:        movb    a0@,d0                  | get the byte
                    760:        andl    #0xFF,d0
                    761:        clrl    _u+U_LOFAULT            | clear lofault
                    762:        rts
                    763: 
                    764: 
                    765: | Fetch user (short) word:      _fusword(address)
                    766:        ENTRY(fusword)
                    767:        movl    #fsuerr,_u+U_LOFAULT    | catch a fault if and when
                    768:        movl    sp@(4),a0               | get address
                    769:        cmpl    #KERNELBASE-2,a0        | check address range
                    770:        jhi     fsuerr                  | jmp if greater than
                    771:        movw    a0@,d0                  | get the word
                    772:        andl    #0xFFFF,d0
                    773:        clrl    _u+U_LOFAULT            | clear lofault
                    774:        rts
                    775: 
                    776: | Fetch user (long) word:      _fuword(address)
                    777:        ENTRY2(fuword,fuiword)
                    778:        movl    #fsuerr,_u+U_LOFAULT    | catch a fault if and when
                    779:        movl    sp@(4),a0               | get address
                    780:        cmpl    #KERNELBASE-4,a0        | check address range
                    781:        jhi     fsuerr                  | jmp if greater than
                    782:        movl    a0@,d0                  | get the long word
                    783:        clrl    _u+U_LOFAULT            | clear lofault
                    784:        rts
                    785: 
                    786: | Set user byte:               _subyte(address, value)
                    787:        ENTRY2(subyte,suibyte)
                    788:        movl    #fsuerr,_u+U_LOFAULT    | catch a fault if and when
                    789:        movl    sp@(4),a0               | get address
                    790:        cmpl    #KERNELBASE-1,a0        | check address range
                    791:        jhi     fsuerr                  | jmp if greater than
                    792:        movb    sp@(8+3),a0@            | set the byte
                    793:        clrl    d0                      | indicate success
                    794:        clrl    _u+U_LOFAULT            | clear lofault
                    795:        rts
                    796: 
                    797: | Set user short word:         _susword(address, value)
                    798:        ENTRY(susword)
                    799:        movl    #fsuerr,_u+U_LOFAULT    | catch a fault if and when
                    800:        movl    sp@(4),a0               | get address
                    801:        cmpl    #KERNELBASE-2,a0        | check address range
                    802:        jhi     fsuerr                  | jmp if greater than
                    803:        movw    sp@(8+2),a0@            | set the word
                    804:        clrl    d0                      | indicate success
                    805:        clrl    _u+U_LOFAULT            | clear lofault
                    806:        rts
                    807: 
                    808: | Set user (long) word:                _suword(address, value)
                    809:        ENTRY2(suword,suiword)
                    810:        movl    #fsuerr,_u+U_LOFAULT    | catch a fault if and when
                    811:        movl    sp@(4),a0               | get address
                    812:        cmpl    #KERNELBASE-4,a0        | check address range
                    813:        jhi     fsuerr                  | jmp if greater than
                    814:        movl    sp@(8+0),a0@            | set the long word
                    815:        clrl    d0                      | indicate success
                    816:        clrl    _u+U_LOFAULT            | clear lofault
                    817:        rts
                    818: 
                    819: fsuerr:
                    820:        movl    #-1,d0                  | return error
                    821:        clrl    _u+U_LOFAULT            | clear lofault
                    822:        rts
                    823: 
                    824: /*
                    825:  * copyout() - except for _u+U_LOFAULT and address
                    826:  * checking this is just bcopy().
                    827:  */
                    828:        ENTRY(copyout)
                    829:        movl    #cpctxerr,_u+U_LOFAULT  | catch faults
                    830:        movl    sp@(4),a0
                    831:        movl    sp@(8),a1
                    832:        movl    sp@(12),d0
                    833:        jle     7f                      | leave if ridiculous count
                    834: copyoutcheck:
                    835:        movl    a1,d1                   | get starting address
                    836:        cmpl    #KERNELBASE,d1          | check starting address
                    837:        jpl     cpctxerr                | jmp on error
                    838:        addl    d0,d1                   | compute ending address
                    839:        cmpl    #KERNELBASE,d1          | check ending address
                    840:        jhi     cpctxerr                | jmp on error
                    841:        cmpl    d1,a1                   | check for wrap around
                    842:        jhi     cpctxerr                | jmp on error
                    843: /* If from address is odd, move one byte to make it even */
                    844:        movl    a0,d1
                    845:        btst    #0,d1
                    846:        jeq     1f                      | even, skip
                    847:        movb    a0@+,a1@+               | move the byte
                    848:        subql   #1,d0                   | decrement count
                    849: /* Now if to address is odd, we have to do byte-by-byte moves */
                    850: 1:     movl    a1,d1
                    851:        btst    #0,d1
                    852:        jne     2f                      | if odd go do bytes
                    853: /* Now both addresses are even and we can do long moves */
                    854:        rorl    #2,d0                   | get count as longs
                    855:        jra     5f                      | enter loop at bottom
                    856: 4:     movl    a0@+,a1@+               | move a long
                    857: 5:     dbra    d0,4b                   | do until --longcount < 0
                    858:        roll    #2,d0
                    859:        andl    #3,d0                   | count %= sizeof (long)
                    860:        jra     2f
                    861: /*
                    862:  * Here for the last 3 bytes or if we have to do byte-by-byte moves
                    863:  * because the pointers were relatively odd
                    864:  */
                    865: 3:     movb    a0@+,a1@+               | move a byte
                    866: 2:     dbra    d0,3b                   | until --count < 0
                    867: 7:     clrl    d0                      | indicate success
                    868:        clrl    _u+U_LOFAULT
                    869:        rts                             | and return
                    870: 
                    871: /*
                    872:  * copyin() - except for _u+U_LOFAULT and address
                    873:  * checking this is just bcopy().
                    874:  */
                    875:        ENTRY(copyin)
                    876:        movl    #cpctxerr,_u+U_LOFAULT  | catch faults
                    877:        movl    sp@(4),a0
                    878:        movl    sp@(8),a1
                    879:        movl    sp@(12),d0
                    880:        jle     7f                      | leave if ridiculous count
                    881: copyincheck:
                    882:        movl    a0,d1                   | get starting address
                    883:        cmpl    #KERNELBASE,d1          | check starting address
                    884:        jpl     cpctxerr                | jmp on error
                    885:        addl    d0,d1                   | compute ending address
                    886:        cmpl    #KERNELBASE,d1          | check ending address
                    887:        jhi     cpctxerr                | jmp on error
                    888:        cmpl    d1,a0                   | check for wrap around
                    889:        jhi     cpctxerr                | jmp on error
                    890: /* If from address is odd, move one byte to make it even */
                    891:        movl    a0,d1
                    892:        btst    #0,d1
                    893:        jeq     1f                      | even, skip
                    894:        movb    a0@+,a1@+               | move the byte
                    895:        subql   #1,d0                   | decrement count
                    896: /* Now if to address is odd, we have to do byte-by-byte moves */
                    897: 1:     movl    a1,d1
                    898:        btst    #0,d1
                    899:        jne     2f                      | if odd go do bytes
                    900: /* Now both addresses are even and we can do long moves */
                    901:        rorl    #2,d0                   | get count as longs
                    902:        jra     5f                      | enter loop at bottom
                    903: 4:     movl    a0@+,a1@+               | move a long
                    904: 5:     dbra    d0,4b                   | do until --longcount < 0
                    905:        roll    #2,d0
                    906:        andl    #3,d0                   | count %= sizeof (long)
                    907:        jra     2f
                    908: /*
                    909:  * Here for the last 3 bytes or if we have to do byte-by-byte moves
                    910:  * because the pointers were relatively odd
                    911:  */
                    912: 3:     movb    a0@+,a1@+               | move a byte
                    913: 2:     dbra    d0,3b                   | until --count < 0
                    914: 7:     clrl    d0                      | indicate success
                    915:        clrl    _u+U_LOFAULT
                    916:        rts                             | and return
                    917: 
                    918: cpctxerr:
                    919:        movl    #EFAULT,d0              | return error
                    920:        clrl    _u+U_LOFAULT            | clear lofault
                    921:        rts
                    922: 
                    923: /*
                    924:  * fetch user longwords  -- used by syscall -- faster than copyin
                    925:  * Doesn't worry about alignment of transfer, let the 68020 worry
                    926:  * about that - we won't be doing more than 8 long words anyways.
                    927:  * Use copyin to do more careful checking if we are real close.
                    928:  * fulwds(uadd, sadd, nlwds)
                    929:  */
                    930:        ENTRY(fulwds)
                    931:        movl    #cpctxerr,_u+U_LOFAULT  | catch a fault if and when
                    932:        movl    sp@(4),a0               | user address
                    933:        movl    sp@(8),a1               | system address
                    934:        movl    sp@(12),d0              | number of words
                    935:        cmpl    #KERNELBASE-8*4,a0      | check starting address
                    936:        jls     1f                      | enter loop at bottom if ok
                    937:        lsll    #2,d0                   | convert to byte count
                    938:        jra     copyincheck             | let copyin code handle
                    939: 2:     movl    a0@+,a1@+               | get longword
                    940: 1:     dbra    d0,2b                   | loop on count
                    941:        clrl    d0                      | indicate success
                    942:        clrl    _u+U_LOFAULT            | clear lofault
                    943:        rts
                    944: 
                    945: /*
                    946:  * Get/Set vector base register
                    947:  */
                    948:        ENTRY(getvbr)
                    949:        movc    vbr,d0
                    950:        rts
                    951: 
                    952:        ENTRY(setvbr)
                    953:        movl    sp@(4),d0
                    954:        movc    d0,vbr
                    955:        rts
                    956: 
                    957: /*
                    958:  * Enter the monitor -- called for console abort
                    959:  */
                    960:        ENTRY(montrap)
                    961:        jsr     _startnmi               | enable monitor nmi routine
                    962:        movl    sp@(4),a0               | address to trap to
                    963:        clrw    sp@-                    | dummy VOR
                    964:        pea     0f                      | return address
                    965:        movw    sr,sp@-                 | current sr
                    966:        jra     a0@                     | trap to monitor
                    967: 0:
                    968:        jsr     _stopnmi                | disable monitor nmi routine
                    969:        rts
                    970: 
                    971: /*
                    972:  * Read the ID prom.  This is mapped from IDPROMBASE for IDPROMSIZE
                    973:  * bytes in the FC_MAP address space for byte access only.  Assumes
                    974:  * that the sfc has already been set to FC_MAP.
                    975:  */
                    976:        ENTRY(getidprom)
                    977:        movl    sp@(4),a0               | address to copy bytes to
                    978:        lea     IDPROMBASE,a1           | select id prom
                    979:        movl    #(IDPROMSIZE-1),d1      | byte loop counter
                    980: 0:     movsb   a1@+,d0                 | get a byte
                    981:        movb    d0,a0@+                 | save it
                    982:        dbra    d1,0b                   | and loop
                    983:        rts
                    984: 
                    985: /*
                    986:  * Enable and disable video.
                    987:  */
                    988:        ENTRY(setvideoenable)
                    989: 1:     
                    990:        tstl    sp@(4)                  | is bit on or off
                    991:        jeq     2f
                    992:        orb     #ENA_VIDEO,_enablereg   | enable video
                    993:        jra     3f
                    994: 2:
                    995:        andb    #~ENA_VIDEO,_enablereg  | disable video
                    996: 3:
                    997:        movb    _enablereg,d0           | get it in a register
                    998:        movsb   d0,ENABLEREG            | put enable register back
                    999:        cmpb    _enablereg,d0           | see if someone higher changed it
                   1000:        bne     1b                      | if so, try again
                   1001:        rts
                   1002: 
                   1003: /*
                   1004:  * Enable and disable video Copy.
                   1005:  */
                   1006:        ENTRY(setcopyenable)
                   1007: 1:     
                   1008:        tstl    sp@(4)                  | is bit on or off
                   1009:        jeq     2f
                   1010:        orb     #ENA_COPY,_enablereg    | enable video copy
                   1011:        jra     3f
                   1012: 2:
                   1013:        andb    #~ENA_COPY,_enablereg   | disable copy
                   1014: 3:
                   1015:        movb    _enablereg,d0           | get it in a register
                   1016:        movsb   d0,ENABLEREG            | put enable register back
                   1017:        cmpb    _enablereg,d0           | see if someone higher changed it
                   1018:        bne     1b                      | if so, try again
                   1019:        rts
                   1020: 
                   1021: /*
                   1022:  * Enable and disable video interrupt.
                   1023:  */
                   1024:        ENTRY(setintrenable)
                   1025:        tstl    sp@(4)                  | is bit on or off
                   1026:        jeq     1f
                   1027:        orb     #IR_ENA_VID4,INTERREG   | enable video interrupt
                   1028:        rts
                   1029: 1:     
                   1030:        andb    #~IR_ENA_VID4,INTERREG  | disable
                   1031:        rts
                   1032: 
                   1033: /*
                   1034:  * Read the bus error register
                   1035:  */
                   1036:        ENTRY(getbuserr)
                   1037:        clrl    d0
                   1038:        movsb   BUSERRREG,d0            | get the buserr register
                   1039:        rts
                   1040: 
                   1041: /*
                   1042:  * Set the fpp registers to the u area values
                   1043:  */
                   1044:        ENTRY(setfppregs)
                   1045:        tstw    _fppstate               | is fpp present and enabled?
                   1046:        jle     1f                      | branch if not
                   1047:        fmovem  _u+U_FPS_REGS,fp0-fp7   | set fp data registers
                   1048:        fmovem  _u+U_FPS_CTRL,fpc/fps/fpi | set control registers
                   1049: 1:
                   1050:        rts
                   1051: 
                   1052: /*
                   1053:  * Define some variables used by post-modem debuggers
                   1054:  * to help them work on kernels with changing structures.
                   1055:  */
                   1056:        .globl UPAGES_DEBUG, KERNELBASE_DEBUG, VADDR_MASK_DEBUG
                   1057:        .globl PGSHIFT_DEBUG, SLOAD_DEBUG
                   1058: 
                   1059: UPAGES_DEBUG           = UPAGES
                   1060: KERNELBASE_DEBUG       = KERNELBASE
                   1061: VADDR_MASK_DEBUG       = 0x0fffffff
                   1062: PGSHIFT_DEBUG          = PGSHIFT
                   1063: SLOAD_DEBUG            = SLOAD

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.