Annotation of qemu/pc-bios/optionrom/kvmvapic.S, revision 1.1.1.1

1.1       root        1: #
                      2: # Local APIC acceleration for Windows XP and related guests
                      3: #
                      4: # Copyright 2011 Red Hat, Inc. and/or its affiliates
                      5: #
                      6: # Author: Avi Kivity <[email protected]>
                      7: #
                      8: # This work is licensed under the terms of the GNU GPL, version 2, or (at your
                      9: # option) any later version.  See the COPYING file in the top-level directory.
                     10: #
                     11: 
                     12: #include "optionrom.h"
                     13: 
                     14: OPTION_ROM_START
                     15: 
                     16:        # clear vapic area: firmware load using rep insb may cause
                     17:        # stale tpr/isr/irr data to corrupt the vapic area.
                     18:        push %es
                     19:        push %cs
                     20:        pop %es
                     21:        xor %ax, %ax
                     22:        mov $vapic_size/2, %cx
                     23:        lea vapic, %di
                     24:        cld
                     25:        rep stosw
                     26:        pop %es
                     27: 
                     28:        # announce presence to the hypervisor
                     29:        mov $vapic_base, %ax
                     30:        out %ax, $0x7e
                     31: 
                     32:        lret
                     33: 
                     34:        .code32
                     35: vapic_size = 2*4096
                     36: 
                     37: .macro fixup delta=-4
                     38: 777:
                     39:        .text 1
                     40:        .long 777b + \delta  - vapic_base
                     41:        .text 0
                     42: .endm
                     43: 
                     44: .macro reenable_vtpr
                     45:        out %al, $0x7e
                     46: .endm
                     47: 
                     48: .text 1
                     49:        fixup_start = .
                     50: .text 0
                     51: 
                     52: .align 16
                     53: 
                     54: vapic_base:
                     55:        .ascii "kvm aPiC"
                     56: 
                     57:        /* relocation data */
                     58:        .long vapic_base        ; fixup
                     59:        .long fixup_start       ; fixup
                     60:        .long fixup_end         ; fixup
                     61: 
                     62:        .long vapic             ; fixup
                     63:        .long vapic_size
                     64: vcpu_shift:
                     65:        .long 0
                     66: real_tpr:
                     67:        .long 0
                     68:        .long up_set_tpr        ; fixup
                     69:        .long up_set_tpr_eax    ; fixup
                     70:        .long up_get_tpr_eax    ; fixup
                     71:        .long up_get_tpr_ecx    ; fixup
                     72:        .long up_get_tpr_edx    ; fixup
                     73:        .long up_get_tpr_ebx    ; fixup
                     74:        .long 0 /* esp. won't work. */
                     75:        .long up_get_tpr_ebp    ; fixup
                     76:        .long up_get_tpr_esi    ; fixup
                     77:        .long up_get_tpr_edi    ; fixup
                     78:        .long up_get_tpr_stack  ; fixup
                     79:        .long mp_set_tpr        ; fixup
                     80:        .long mp_set_tpr_eax    ; fixup
                     81:        .long mp_get_tpr_eax    ; fixup
                     82:        .long mp_get_tpr_ecx    ; fixup
                     83:        .long mp_get_tpr_edx    ; fixup
                     84:        .long mp_get_tpr_ebx    ; fixup
                     85:        .long 0 /* esp. won't work. */
                     86:        .long mp_get_tpr_ebp    ; fixup
                     87:        .long mp_get_tpr_esi    ; fixup
                     88:        .long mp_get_tpr_edi    ; fixup
                     89:        .long mp_get_tpr_stack  ; fixup
                     90: 
                     91: .macro kvm_hypercall
                     92:        .byte 0x0f, 0x01, 0xc1
                     93: .endm
                     94: 
                     95: kvm_hypercall_vapic_poll_irq = 1
                     96: 
                     97: pcr_cpu = 0x51
                     98: 
                     99: .align 64
                    100: 
                    101: mp_get_tpr_eax:
                    102:        pushf
                    103:        cli
                    104:        reenable_vtpr
                    105:        push %ecx
                    106: 
                    107:        fs/movzbl pcr_cpu, %eax
                    108: 
                    109:        mov vcpu_shift, %ecx    ; fixup
                    110:        shl %cl, %eax
                    111:        testb $1, vapic+4(%eax) ; fixup delta=-5
                    112:        jz mp_get_tpr_bad
                    113:        movzbl vapic(%eax), %eax ; fixup
                    114: 
                    115: mp_get_tpr_out:
                    116:        pop %ecx
                    117:        popf
                    118:        ret
                    119: 
                    120: mp_get_tpr_bad:
                    121:        mov real_tpr, %eax      ; fixup
                    122:        mov (%eax), %eax
                    123:        jmp mp_get_tpr_out
                    124: 
                    125: mp_get_tpr_ebx:
                    126:        mov %eax, %ebx
                    127:        call mp_get_tpr_eax
                    128:        xchg %eax, %ebx
                    129:        ret
                    130: 
                    131: mp_get_tpr_ecx:
                    132:        mov %eax, %ecx
                    133:        call mp_get_tpr_eax
                    134:        xchg %eax, %ecx
                    135:        ret
                    136: 
                    137: mp_get_tpr_edx:
                    138:        mov %eax, %edx
                    139:        call mp_get_tpr_eax
                    140:        xchg %eax, %edx
                    141:        ret
                    142: 
                    143: mp_get_tpr_esi:
                    144:        mov %eax, %esi
                    145:        call mp_get_tpr_eax
                    146:        xchg %eax, %esi
                    147:        ret
                    148: 
                    149: mp_get_tpr_edi:
                    150:        mov %eax, %edi
                    151:        call mp_get_tpr_edi
                    152:        xchg %eax, %edi
                    153:        ret
                    154: 
                    155: mp_get_tpr_ebp:
                    156:        mov %eax, %ebp
                    157:        call mp_get_tpr_eax
                    158:        xchg %eax, %ebp
                    159:        ret
                    160: 
                    161: mp_get_tpr_stack:
                    162:        call mp_get_tpr_eax
                    163:        xchg %eax, 4(%esp)
                    164:        ret
                    165: 
                    166: mp_set_tpr_eax:
                    167:        push %eax
                    168:        call mp_set_tpr
                    169:        ret
                    170: 
                    171: mp_set_tpr:
                    172:        pushf
                    173:        push %eax
                    174:        push %ecx
                    175:        push %edx
                    176:        push %ebx
                    177:        cli
                    178:        reenable_vtpr
                    179: 
                    180: mp_set_tpr_failed:
                    181:        fs/movzbl pcr_cpu, %edx
                    182: 
                    183:        mov vcpu_shift, %ecx    ; fixup
                    184:        shl %cl, %edx
                    185: 
                    186:        testb $1, vapic+4(%edx) ; fixup delta=-5
                    187:        jz mp_set_tpr_bad
                    188: 
                    189:        mov vapic(%edx), %eax   ; fixup
                    190: 
                    191:        mov %eax, %ebx
                    192:        mov 24(%esp), %bl
                    193: 
                    194:        /* %ebx = new vapic (%bl = tpr, %bh = isr, %b3 = irr) */
                    195: 
                    196:        lock cmpxchg %ebx, vapic(%edx) ; fixup
                    197:        jnz mp_set_tpr_failed
                    198: 
                    199:        /* compute ppr */
                    200:        cmp %bh, %bl
                    201:        jae mp_tpr_is_bigger
                    202: mp_isr_is_bigger:
                    203:        mov %bh, %bl
                    204: mp_tpr_is_bigger:
                    205:        /* %bl = ppr */
                    206:        rol $8, %ebx
                    207:        /* now: %bl = irr, %bh = ppr */
                    208:        cmp %bh, %bl
                    209:        ja mp_set_tpr_poll_irq
                    210: 
                    211: mp_set_tpr_out:
                    212:        pop %ebx
                    213:        pop %edx
                    214:        pop %ecx
                    215:        pop %eax
                    216:        popf
                    217:        ret $4
                    218: 
                    219: mp_set_tpr_poll_irq:
                    220:        mov $kvm_hypercall_vapic_poll_irq, %eax
                    221:        kvm_hypercall
                    222:        jmp mp_set_tpr_out
                    223: 
                    224: mp_set_tpr_bad:
                    225:        mov 24(%esp), %ecx
                    226:        mov real_tpr, %eax      ; fixup
                    227:        mov %ecx, (%eax)
                    228:        jmp mp_set_tpr_out
                    229: 
                    230: up_get_tpr_eax:
                    231:        reenable_vtpr
                    232:        movzbl vapic, %eax ; fixup
                    233:        ret
                    234: 
                    235: up_get_tpr_ebx:
                    236:        reenable_vtpr
                    237:        movzbl vapic, %ebx ; fixup
                    238:        ret
                    239: 
                    240: up_get_tpr_ecx:
                    241:        reenable_vtpr
                    242:        movzbl vapic, %ecx ; fixup
                    243:        ret
                    244: 
                    245: up_get_tpr_edx:
                    246:        reenable_vtpr
                    247:        movzbl vapic, %edx ; fixup
                    248:        ret
                    249: 
                    250: up_get_tpr_esi:
                    251:        reenable_vtpr
                    252:        movzbl vapic, %esi ; fixup
                    253:        ret
                    254: 
                    255: up_get_tpr_edi:
                    256:        reenable_vtpr
                    257:        movzbl vapic, %edi ; fixup
                    258:        ret
                    259: 
                    260: up_get_tpr_ebp:
                    261:        reenable_vtpr
                    262:        movzbl vapic, %ebp ; fixup
                    263:        ret
                    264: 
                    265: up_get_tpr_stack:
                    266:        reenable_vtpr
                    267:        movzbl vapic, %eax ; fixup
                    268:        xchg %eax, 4(%esp)
                    269:        ret
                    270: 
                    271: up_set_tpr_eax:
                    272:        push %eax
                    273:        call up_set_tpr
                    274:        ret
                    275: 
                    276: up_set_tpr:
                    277:        pushf
                    278:        push %eax
                    279:        push %ebx
                    280:        reenable_vtpr
                    281: 
                    282: up_set_tpr_failed:
                    283:        mov vapic, %eax ; fixup
                    284: 
                    285:        mov %eax, %ebx
                    286:        mov 16(%esp), %bl
                    287: 
                    288:        /* %ebx = new vapic (%bl = tpr, %bh = isr, %b3 = irr) */
                    289: 
                    290:        lock cmpxchg %ebx, vapic ; fixup
                    291:        jnz up_set_tpr_failed
                    292: 
                    293:        /* compute ppr */
                    294:        cmp %bh, %bl
                    295:        jae up_tpr_is_bigger
                    296: up_isr_is_bigger:
                    297:        mov %bh, %bl
                    298: up_tpr_is_bigger:
                    299:        /* %bl = ppr */
                    300:        rol $8, %ebx
                    301:        /* now: %bl = irr, %bh = ppr */
                    302:        cmp %bh, %bl
                    303:        ja up_set_tpr_poll_irq
                    304: 
                    305: up_set_tpr_out:
                    306:        pop %ebx
                    307:        pop %eax
                    308:        popf
                    309:        ret $4
                    310: 
                    311: up_set_tpr_poll_irq:
                    312:        mov $kvm_hypercall_vapic_poll_irq, %eax
                    313:        kvm_hypercall
                    314:        jmp up_set_tpr_out
                    315: 
                    316: .text 1
                    317:        fixup_end = .
                    318: .text 0
                    319: 
                    320: /*
                    321:  * vapic format:
                    322:  *  per-vcpu records of size 2^vcpu shift.
                    323:  *     byte 0: tpr (r/w)
                    324:  *     byte 1: highest in-service interrupt (isr) (r/o); bits 3:0 are zero
                    325:  *     byte 2: zero (r/o)
                    326:  *     byte 3: highest pending interrupt (irr) (r/o)
                    327:  */
                    328: .text 2
                    329: 
                    330: .align 128
                    331: 
                    332: vapic:
                    333: . = . + vapic_size
                    334: 
                    335: OPTION_ROM_END

unix.superglobalmegacorp.com

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