Annotation of qemu/roms/openbios/arch/amd64/switch.S, revision 1.1

1.1     ! root        1:        .globl  entry, __switch_context, __exit_context, halt
        !             2: 
        !             3:        .text
        !             4:        .align  4
        !             5: 
        !             6: /*
        !             7:  * Entry point
        !             8:  * We start execution from here.
        !             9:  * It is assumed that CPU is in 32-bit protected mode and
        !            10:  * all segments are 4GB and base zero (flat model).
        !            11:  */
        !            12: entry:
        !            13:        /* Save boot context and switch to our main context.
        !            14:         * Main context is statically defined in C.
        !            15:         */
        !            16:        pushl   %cs
        !            17:        call    __switch_context
        !            18: 
        !            19:        /* We get here when the main context switches back to
        !            20:         * the boot context.
        !            21:         * Return to previous bootloader.
        !            22:         */
        !            23:        ret
        !            24: 
        !            25: /*
        !            26:  * Switch execution context
        !            27:  * This saves registers, segments, and GDT in the stack, then
        !            28:  * switches the stack, and restores everything from the new stack.
        !            29:  * This function takes no argument. New stack pointer is
        !            30:  * taken from global variable __context, and old stack pointer
        !            31:  * is also saved to __context. This way we can just jump to
        !            32:  * this routine to get back to the original context.
        !            33:  *
        !            34:  * Call this routine with lcall or pushl %cs; call.
        !            35:  */
        !            36: __switch_context:
        !            37:        /* Save everything in current stack */
        !            38:        pushfl              /* 56 */
        !            39:        pushl   %ds         /* 52 */
        !            40:        pushl   %es         /* 48 */
        !            41:        pushl   %fs         /* 44 */
        !            42:        pushl   %gs         /* 40 */
        !            43:        pushal              /* 8 */
        !            44:        subl    $8, %esp
        !            45:        movw    %ss, (%esp) /* 0 */
        !            46:        sgdt    2(%esp)     /* 2 */
        !            47: 
        !            48: #if 0
        !            49:        /* Swap %cs and %eip on the stack, so lret will work */
        !            50:        movl    60(%esp), %eax
        !            51:        xchgl   %eax, 64(%esp)
        !            52:        movl    %eax, 60(%esp)
        !            53: #endif
        !            54: 
        !            55:        /* At this point we don't know if we are on flat segment
        !            56:         * or relocated. So compute the address offset from %eip.
        !            57:         * Assuming CS.base==DS.base==SS.base.
        !            58:         */
        !            59:        call    1f
        !            60: 1:     popl    %ebx
        !            61:        subl    $1b, %ebx
        !            62: 
        !            63:        /* Interrupts are not allowed... */
        !            64:        cli
        !            65: 
        !            66:        /* Current context pointer is our stack pointer */
        !            67:        movl    %esp, %esi
        !            68: 
        !            69:        /* Normalize the ctx pointer */
        !            70:        subl    %ebx, %esi
        !            71: 
        !            72:        /* Swap it with new value */
        !            73:        xchgl   %esi, __context(%ebx)
        !            74: 
        !            75:        /* Adjust new ctx pointer for current address offset */
        !            76:        addl    %ebx, %esi
        !            77: 
        !            78:        /* Load new %ss and %esp to temporary */
        !            79:        movzwl  (%esi), %edx
        !            80:        movl    20(%esi), %eax
        !            81: 
        !            82:        /* Load new GDT */
        !            83:        lgdt    2(%esi)
        !            84: 
        !            85:        /* Load new stack segment with new GDT */
        !            86:        movl    %edx, %ss
        !            87: 
        !            88:        /* Set new stack pointer, but we have to adjust it because
        !            89:         * pushal saves %esp value before pushal, and we want the value
        !            90:         * after pushal.
        !            91:         */
        !            92:        leal    -32(%eax), %esp
        !            93: 
        !            94:        /* Load the rest from new stack */
        !            95:        popal
        !            96:        popl    %gs
        !            97:        popl    %fs
        !            98:        popl    %es
        !            99:        popl    %ds
        !           100:        popfl
        !           101: 
        !           102:        /* Finally, load new %cs and %eip */
        !           103:        lret
        !           104: 
        !           105: __exit_context:
        !           106:        /* Get back to the original context */
        !           107:        pushl   %cs
        !           108:        call    __switch_context
        !           109: 
        !           110:        /* We get here if the other context attempt to switch to this
        !           111:         * dead context. This should not happen. */
        !           112: 
        !           113: halt:
        !           114:        cli
        !           115:        hlt
        !           116:        jmp     halt

unix.superglobalmegacorp.com

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