Annotation of MiNT/src/gas/context.s, revision 1.1

1.1     ! root        1: |
        !             2: 
        !             3: | routines for saving/restoring user contexts
        !             4: 
        !             5: |
        !             6: 
        !             7: | long build_context(struct context *sav):
        !             8: 
        !             9: |      Called from an interrupt handler (such as the trap #1 routine
        !            10: 
        !            11: |      for system calls) saves the context of the interrupted
        !            12: 
        !            13: |      routine. Assumes that no user registers have been changed
        !            14: 
        !            15: |      since the interrupt, and that the PC and status register
        !            16: 
        !            17: |      are still on the stack. Returns the stack pointer being used
        !            18: 
        !            19: |      at the time of the interrupt **in register a1**.
        !            20: 
        !            21: |
        !            22: 
        !            23: | long save_context(struct context *sav):
        !            24: 
        !            25: |      Saves the context of the calling routine in the area pointed
        !            26: 
        !            27: |      to by sav. Save_context always returns 0 when initially called;
        !            28: 
        !            29: |      this is so processes can (by suitably manipulating the
        !            30: 
        !            31: |      saved registers) tell when the return from save_context is
        !            32: 
        !            33: |      actually caused by restoring the context, e.g.:
        !            34: 
        !            35: |              if (save_context(sav) == 0) {           <<-- L1
        !            36: 
        !            37: |                      /* do some stuff */
        !            38: 
        !            39: |                      sav.regs[D0] = 1;       /* for restore context */
        !            40: 
        !            41: |                      restore_context(sav);   /* goes back to L1 */
        !            42: 
        !            43: |              }
        !            44: 
        !            45: |              else /* this is the second time through */
        !            46: 
        !            47: |
        !            48: 
        !            49: | void restore_context(struct context *sav):
        !            50: 
        !            51: |      Restores a context previously saved by build_context or save_context.
        !            52: 
        !            53: |      Since the program counter is part of the context, this function
        !            54: 
        !            55: |      will never return (it's like longjmp()).
        !            56: 
        !            57: 
        !            58: 
        !            59:        .globl  _build_context
        !            60: 
        !            61:        .globl  _save_context
        !            62: 
        !            63:        .globl  _restore_context
        !            64: 
        !            65:        .globl  _fpu
        !            66: 
        !            67:        .globl  _m68010
        !            68: 
        !            69: 
        !            70: 
        !            71: _build_context:
        !            72: 
        !            73:        movel   a0, sp@-        | save a0; we'll use it for scratch
        !            74: 
        !            75:        movel   sp@(8), a0      | get address of save area
        !            76: 
        !            77:        tstw    _fpu            | is there a real FPU in the system?
        !            78: 
        !            79:        beq     nofpu           | no -- we can skip the FPU save
        !            80: 
        !            81:        fsave   a0@(78)         | save internal state frame
        !            82: 
        !            83:        tstb    a0@(78)         | if NULL frame then FPU not in use
        !            84: 
        !            85:        beq     nofpu
        !            86: 
        !            87:        fmovemx fp0-fp7,a0@(294)                | save data registers
        !            88: 
        !            89:        fmoveml fpcr/fpsr/fpi,a0@(390)  | and control registers
        !            90: 
        !            91: nofpu:
        !            92: 
        !            93:        moveml  d0-d7/a0-a6, a0@ | save registers D0-D7/A0-A6
        !            94: 
        !            95:        movel   sp@(14), a0@(66) | save PC of context
        !            96: 
        !            97:        movew   sp@(12), d0     | get SR of context
        !            98: 
        !            99:        movew   d0, a0@(64)     | save it 
        !           100: 
        !           101:        tstw    0x59e           | test longframe (AKP)
        !           102: 
        !           103:        beq     short1          | short
        !           104: 
        !           105:        lea     sp@(20), a1     | else long
        !           106: 
        !           107:        movew   sp@(18), d1     | fetch frame format word
        !           108: 
        !           109:        movew   d1, a0@(402)    | stash it away for later
        !           110: 
        !           111:        tstw    _m68010         | are we running on a 68010?
        !           112: 
        !           113:        bne     short2          | yes -- definitely a simple interrupt frame
        !           114: 
        !           115: |
        !           116: 
        !           117: | note: in order to have got to this point in the code we must be
        !           118: 
        !           119: | running on an 020/030
        !           120: 
        !           121: |
        !           122: 
        !           123:        bftst   d1{#16:#4}      | is it the simple interrupt frame?
        !           124: 
        !           125:        beq     short2          | yes -- just dump the stack contents
        !           126: 
        !           127:        moveml  a1@+, d1-d3     | get instruction address/4 internal words
        !           128: 
        !           129:        moveml  d1-d3, a0@(404) | save them
        !           130: 
        !           131:        bra     short2
        !           132: 
        !           133: short1:
        !           134: 
        !           135:        lea     sp@(18), a1     | save supervisor stack pointer
        !           136: 
        !           137: short2:                                | note that it should be pointing above the PC
        !           138: 
        !           139:        movel   a1, a0@(70)
        !           140: 
        !           141:        movel   usp, a1         | save user stack pointer
        !           142: 
        !           143:        movel   a1, a0@(60)
        !           144: 
        !           145:        btst    #13, d0         | check for supervisor mode
        !           146: 
        !           147:        beq     L_CONT1         | user mode; we already have stack in a1
        !           148: 
        !           149: L_SUPER1:
        !           150: 
        !           151: | note: this was lea a0@(18), but moving from the save state buffer 
        !           152: 
        !           153: | means not testing longframe again. (AKP)
        !           154: 
        !           155:        movel   a0@(70), a1     | was using super stack pointer before interrupt
        !           156: 
        !           157:                                | 
        !           158: 
        !           159: L_CONT1:
        !           160: 
        !           161:        movel   0x408, a0@(74)  | save GEMDOS terminate vector
        !           162: 
        !           163:        movel   sp@+, a0@(32)   | save old register a0
        !           164: 
        !           165:        rts
        !           166: 
        !           167: 
        !           168: 
        !           169: _save_context:
        !           170: 
        !           171:        movel   a0, sp@-        | save a0
        !           172: 
        !           173:        movel   sp@(8), a0      | get address of context save area
        !           174: 
        !           175: 
        !           176: 
        !           177: | if running with a true coprocessor we need to save the FPU state
        !           178: 
        !           179: 
        !           180: 
        !           181:        tstw    _fpu            | is there a true FPU in the system
        !           182: 
        !           183:        beq     nofpu2
        !           184: 
        !           185:        fsave   a0@(78)         | save internal state frame
        !           186: 
        !           187:        tstb    a0@(78)         | if NULL frame then the FPU is not in use
        !           188: 
        !           189:        beq     nofpu2          | skip programmer's model save
        !           190: 
        !           191:        fmovemx fp0-fp7,a0@(294)                | save data registers
        !           192: 
        !           193:        fmoveml fpcr/fpsr/fpi,a0@(390)  | and control registers
        !           194: 
        !           195: nofpu2:
        !           196: 
        !           197: | AGK: I am somewhat unsure of this assumption, viz that save_context
        !           198: 
        !           199: | can never be called in a situation where a co-processor
        !           200: 
        !           201: | mid-instruction stack frame would be required. I suspect this is a
        !           202: 
        !           203: | valid assumption, in which case the above FPU code is redundant, the
        !           204: 
        !           205: | next line is not however!
        !           206: 
        !           207: 
        !           208: 
        !           209:        clrw    a0@(402)                | mark as a 4 word stack frame
        !           210: 
        !           211: 
        !           212: 
        !           213:        moveml  d0-d7/a0-a6, a0@        | save D0-D7/A0-A6
        !           214: 
        !           215:        lea     sp@(8), a1
        !           216: 
        !           217:        movel   a1, a0@(70)     | save supervisor stack pointer
        !           218: 
        !           219:                                | note that it should be pointing above the PC
        !           220: 
        !           221:        movel   a1@(-4), a0@(66)        | save PC
        !           222: 
        !           223:        movel   usp, a1
        !           224: 
        !           225:        movel   a1, a0@(60)     | save user stack pointer
        !           226: 
        !           227:        movew   sr, d0
        !           228: 
        !           229:        movew   d0, a0@(64)     | save status register
        !           230: 
        !           231:        movel   0x408, a0@(74)  | save GEMDOS terminate vector
        !           232: 
        !           233:        movel   sp@+, a0@(32)   | save old a0
        !           234: 
        !           235:        moveql  #0, d0          | return 0
        !           236: 
        !           237:        rts
        !           238: 
        !           239: 
        !           240: 
        !           241: _restore_context:
        !           242: 
        !           243:        orw     #0x0700, sr     | mask interrupts
        !           244: 
        !           245:        movel   sp@(4), a0      | address of context save area
        !           246: 
        !           247:        movel   a0@(70), sp     | supervisor stack pointer
        !           248: 
        !           249:        movel   a0@(60), a1
        !           250: 
        !           251:        movel   a1, usp         | set user stack pointer
        !           252: 
        !           253:        movel   a0@(74), 0x408  | restore GEMDOS terminate vector
        !           254: 
        !           255: 
        !           256: 
        !           257:        tstw    0x59e           | test longframe (AKP)
        !           258: 
        !           259:        beq     short3
        !           260: 
        !           261: 
        !           262: 
        !           263:        movew   a0@(402),d0     | fetch frame format word
        !           264: 
        !           265:        tstw    _m68010         | are we on a 68010?
        !           266: 
        !           267:        bne     just0           | yes, so it's a simple interrupt frame
        !           268: 
        !           269: 
        !           270: 
        !           271:        bftst   d0{#16:#4}      | is it the simple interrupt frame ?
        !           272: 
        !           273:        beq     just0           | yes so just push a zero
        !           274: 
        !           275:        moveml  a0@(404),d1-d3  | saved instruction address/4 internal words
        !           276: 
        !           277:        moveml  d1-d3,sp@-
        !           278: 
        !           279: just0: movew   d0,sp@-
        !           280: 
        !           281: 
        !           282: 
        !           283: short3:
        !           284: 
        !           285:        movel   a0@(66), sp@-   | push the PC
        !           286: 
        !           287:        movew   a0@(64), d0     | get status register
        !           288: 
        !           289:        movew   d0, sp@-        | push the status register
        !           290: 
        !           291: 
        !           292: 
        !           293: | if running with a true co-processor we need to restore the FPU state
        !           294: 
        !           295: 
        !           296: 
        !           297:        tstw    _fpu
        !           298: 
        !           299:        beq     nofpu3
        !           300: 
        !           301:        tstb    a0@(78)                 | if NULL frame then FPU not in use
        !           302: 
        !           303:        beq     short7                  | skip programmer's model restore
        !           304: 
        !           305:        fmoveml a0@(390), fpcr/fpsr/fpi | restore control registers
        !           306: 
        !           307:        fmovemx a0@(294), fp0-fp7               | and data registers
        !           308: 
        !           309: short7: frestore a0@(78)                       | finally the internal state
        !           310: 
        !           311: 
        !           312: 
        !           313: nofpu3:
        !           314: 
        !           315:        moveml  a0@, d0-d7/a0-a6        | restore registers d0-d7/a0-a6
        !           316: 
        !           317:        rte                             | jump back to old context
        !           318: 
        !           319: 
        !           320: 

unix.superglobalmegacorp.com

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