Annotation of qemu/roms/openbios/arch/amd64/switch.S, revision 1.1.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.