Annotation of qemu/roms/seabios/src/romlayout.S, revision 1.1.1.6

1.1       root        1: // Rom layout and bios assembler to C interface.
                      2: //
1.1.1.6 ! root        3: // Copyright (C) 2008-2012  Kevin O'Connor <[email protected]>
1.1       root        4: // Copyright (C) 2002  MandrakeSoft S.A.
                      5: //
                      6: // This file may be distributed under the terms of the GNU LGPLv3 license.
                      7: 
                      8: #include "config.h" // CONFIG_*
                      9: #include "ioport.h" // PORT_A20
                     10: #include "bregs.h" // CR0_*
                     11: #include "cmos.h" // CMOS_RESET_CODE
1.1.1.4   root       12: #include "asm-offsets.h" // BREGS_*
1.1       root       13: #include "entryfuncs.S" // ENTRY_*
                     14: 
                     15: 
                     16: /****************************************************************
                     17:  * Call trampolines
                     18:  ****************************************************************/
                     19: 
                     20: // Place CPU into 32bit mode from 16bit mode.
1.1.1.4   root       21: // %edx = return location (in 32bit mode)
1.1       root       22: // Clobbers: ecx, flags, segment registers, cr0, idt/gdt
                     23:         DECLFUNC transition32
1.1.1.6 ! root       24:         .code16gcc
1.1       root       25: transition32:
                     26:         movl %eax, %ecx
                     27: 
                     28:         // Disable irqs (and clear direction flag)
                     29:         cli
                     30:         cld
                     31: 
                     32:         // Disable nmi
                     33:         movl $CMOS_RESET_CODE|NMI_DISABLE_BIT, %eax
                     34:         outb %al, $PORT_CMOS_INDEX
                     35:         inb $PORT_CMOS_DATA, %al
                     36: 
                     37:         // enable a20
                     38:         inb $PORT_A20, %al
                     39:         orb $A20_ENABLE_BIT, %al
                     40:         outb %al, $PORT_A20
                     41: 
                     42:         // Set segment descriptors
                     43:         lidtw %cs:pmode_IDT_info
                     44:         lgdtw %cs:rombios32_gdt_48
                     45: 
                     46:         // Enable protected mode
                     47:         movl %cr0, %eax
                     48:         orl $CR0_PE, %eax
                     49:         movl %eax, %cr0
                     50: 
                     51:         // start 32bit protected mode code
                     52:         ljmpl $SEG32_MODE32_CS, $(BUILD_BIOS_ADDR + 1f)
                     53: 
                     54:         .code32
                     55: 1:
                     56:         // init data segments
                     57:         movl $SEG32_MODE32_DS, %eax
                     58:         movw %ax, %ds
                     59:         movw %ax, %es
                     60:         movw %ax, %ss
                     61:         movw %ax, %fs
                     62:         movw %ax, %gs
                     63: 
                     64:         movl %ecx, %eax
1.1.1.4   root       65:         jmpl *%edx
1.1       root       66: 
                     67: // Place CPU into 16bit mode from 32bit mode.
1.1.1.4   root       68: // %edx = return location (in 16bit mode)
1.1       root       69: // Clobbers: ecx, flags, segment registers, cr0, idt/gdt
                     70:         DECLFUNC transition16
                     71:         .global transition16big
                     72: transition16:
                     73:         movl %eax, %ecx
                     74: 
                     75:         // restore data segment limits to 0xffff
                     76:         movl $SEG32_MODE16_DS, %eax
                     77:         movw %ax, %ds
                     78:         movw %ax, %es
                     79:         movw %ax, %ss
                     80:         movw %ax, %fs
                     81:         movw %ax, %gs
                     82: 
                     83: #if CONFIG_DISABLE_A20
                     84:         // disable a20
                     85:         inb $PORT_A20, %al
                     86:         andb $~A20_ENABLE_BIT, %al
                     87:         outb %al, $PORT_A20
                     88: #endif
                     89: 
                     90:         // Jump to 16bit mode
                     91:         ljmpw $SEG32_MODE16_CS, $1f
                     92: 
                     93: transition16big:
                     94:         movl %eax, %ecx
                     95: 
                     96:         movl $SEG32_MODE16BIG_DS, %eax
                     97:         movw %ax, %ds
                     98:         movw %ax, %es
                     99:         movw %ax, %ss
                    100:         movw %ax, %fs
                    101:         movw %ax, %gs
                    102: 
1.1.1.3   root      103:         ljmpw $SEG32_MODE16BIG_CS, $1f
1.1       root      104: 
                    105:         .code16gcc
                    106: 1:
                    107:         // Disable protected mode
                    108:         movl %cr0, %eax
                    109:         andl $~CR0_PE, %eax
                    110:         movl %eax, %cr0
                    111: 
                    112:         // far jump to flush CPU queue after transition to real mode
                    113:         ljmpw $SEG_BIOS, $2f
                    114: 
                    115: 2:
                    116:         // restore IDT to normal real-mode defaults
                    117:         lidtw %cs:rmode_IDT_info
                    118: 
                    119:         // Clear segment registers
                    120:         xorw %ax, %ax
                    121:         movw %ax, %fs
                    122:         movw %ax, %gs
                    123:         movw %ax, %es
                    124:         movw %ax, %ds
                    125:         movw %ax, %ss  // Assume stack is in segment 0
                    126: 
                    127:         movl %ecx, %eax
1.1.1.4   root      128:         jmpl *%edx
1.1       root      129: 
                    130: // Call a 16bit function from 16bit mode with a specified cpu register state
                    131: // %eax = address of struct bregs
                    132: // Clobbers: %e[bcd]x, %e[ds]i, flags
                    133:         DECLFUNC __call16
                    134: __call16:
                    135:         // Save %eax, %ebp
                    136:         pushl %ebp
                    137:         pushl %eax
                    138: 
                    139:         // Setup for iretw call
                    140:         pushw %cs
                    141:         pushw $1f               // return point
                    142:         pushw BREGS_flags(%eax) // flags
                    143:         pushl BREGS_code(%eax)  // CS:IP
                    144: 
                    145:         // Load calling registers.
                    146:         movl BREGS_edi(%eax), %edi
                    147:         movl BREGS_esi(%eax), %esi
                    148:         movl BREGS_ebp(%eax), %ebp
                    149:         movl BREGS_ebx(%eax), %ebx
                    150:         movl BREGS_edx(%eax), %edx
                    151:         movl BREGS_ecx(%eax), %ecx
                    152:         movw BREGS_es(%eax), %es
                    153:         movw BREGS_ds(%eax), %ds
                    154:         movl %ss:BREGS_eax(%eax), %eax
                    155: 
                    156:         // Invoke call
                    157:         iretw                   // XXX - just do a lcalll
                    158: 1:
                    159:         // Store flags, eax, ecx
                    160:         pushfw
                    161:         pushl %eax
                    162:         movl 0x06(%esp), %eax
                    163:         movl %ecx, %ss:BREGS_ecx(%eax)
                    164:         movw %ds, %ss:BREGS_ds(%eax)
                    165:         movw %ss, %cx
                    166:         movw %cx, %ds           // Restore %ds == %ss
                    167:         popl %ecx
                    168:         movl %ecx, BREGS_eax(%eax)
                    169:         popw %cx
                    170:         movw %cx, BREGS_flags(%eax)
                    171: 
                    172:         // Store remaining registers
                    173:         movw %es, BREGS_es(%eax)
                    174:         movl %edi, BREGS_edi(%eax)
                    175:         movl %esi, BREGS_esi(%eax)
                    176:         movl %ebp, BREGS_ebp(%eax)
                    177:         movl %ebx, BREGS_ebx(%eax)
                    178:         movl %edx, BREGS_edx(%eax)
                    179: 
                    180:         // Remove %eax, restore %ebp
                    181:         popl %eax
                    182:         popl %ebp
                    183: 
                    184:         retl
                    185: 
                    186: // Call a 16bit function from 32bit mode.
                    187: // %eax = address of struct bregs
                    188: // Clobbers: %e[bcd]x, %e[ds]i, flags, segment registers, idt/gdt
                    189:         DECLFUNC __call16_from32
                    190:         .global __call16big_from32
                    191:         .code32
                    192: __call16_from32:
1.1.1.4   root      193:         movl $1f, %edx
1.1       root      194:         jmp transition16
                    195: __call16big_from32:
1.1.1.4   root      196:         movl $1f, %edx
1.1       root      197:         jmp transition16big
                    198: 
                    199:         // Make call.
                    200:         .code16gcc
                    201: 1:      calll __call16
                    202:         // Return via transition32
1.1.1.4   root      203:         movl $(2f + BUILD_BIOS_ADDR), %edx
1.1       root      204:         jmp transition32
1.1.1.4   root      205:         .code32
                    206: 2:      retl
1.1       root      207: 
1.1.1.4   root      208:         .code16gcc
1.1       root      209: // IRQ trampolines
                    210:         .macro IRQ_TRAMPOLINE num
                    211:         DECLFUNC irq_trampoline_0x\num
                    212:         irq_trampoline_0x\num :
                    213:         int $0x\num
                    214:         lretw
                    215:         .endm
                    216: 
                    217:         IRQ_TRAMPOLINE 10
                    218:         IRQ_TRAMPOLINE 13
                    219:         IRQ_TRAMPOLINE 15
                    220:         IRQ_TRAMPOLINE 16
                    221:         IRQ_TRAMPOLINE 18
                    222:         IRQ_TRAMPOLINE 19
                    223: 
                    224: 
                    225: /****************************************************************
1.1.1.5   root      226:  * Misc. entry points.
1.1       root      227:  ****************************************************************/
                    228: 
1.1.1.5   root      229: // Resume (and reboot) entry point - called from entry_post
                    230:         DECLFUNC entry_resume
                    231: entry_resume:
1.1       root      232:         // Disable interrupts
                    233:         cli
                    234:         cld
                    235:         // Use a stack in EBDA
                    236:         movw $SEG_BDA, %ax
                    237:         movw %ax, %ds
                    238:         movw BDA_ebda_seg, %ax
1.1.1.5   root      239:         movw %ax, %ds
1.1       root      240:         movw %ax, %ss
                    241:         movl $EBDA_OFFSET_TOP_STACK, %esp
                    242:         // Call handler.
                    243:         jmp handle_resume
                    244: 
                    245: // PMM entry point
                    246:         DECLFUNC entry_pmm
                    247: entry_pmm:
                    248:         pushl %esp              // Backup %esp, then clear high bits
                    249:         movzwl %sp, %esp
                    250:         pushfl                  // Save registers clobbered by C code
                    251:         cli
                    252:         cld
                    253:         pushl %eax
                    254:         pushl %ecx
                    255:         pushl %edx
                    256:         pushw %es
                    257:         pushw %ds
                    258:         movw %ss, %cx           // Move %ss to %ds
                    259:         movw %cx, %ds
1.1.1.5   root      260:         movl $_cfunc32flat_handle_pmm, %eax // Setup: call32(handle_pmm, args, -1)
                    261:         leal 28(%esp), %edx     // %edx points to start of args
                    262:         movl $-1, %ecx
                    263:         calll call32
1.1       root      264:         movw %ax, 12(%esp)      // Modify %ax:%dx to return %eax
                    265:         shrl $16, %eax
                    266:         movw %ax, 4(%esp)
                    267:         popw %ds                // Restore saved registers
                    268:         popw %es
                    269:         popl %edx
                    270:         popl %ecx
                    271:         popl %eax
                    272:         popfl
                    273:         popl %esp
                    274:         lretw
                    275: 
                    276: // PnP entry points
                    277:         DECLFUNC entry_pnp_real
                    278:         .global entry_pnp_prot
                    279: entry_pnp_prot:
                    280:         pushl %esp
                    281:         jmp 1f
                    282: entry_pnp_real:
                    283:         pushl %esp              // Backup %esp, then clear high bits
                    284:         movzwl %sp, %esp
                    285: 1:
                    286:         pushfl                  // Save registers clobbered by C code
                    287:         cli
                    288:         cld
                    289:         pushl %eax
                    290:         pushl %ecx
                    291:         pushl %edx
                    292:         pushw %es
                    293:         pushw %ds
                    294:         movw %ss, %cx           // Move %ss to %ds
                    295:         movw %cx, %ds
                    296:         leal 28(%esp), %eax     // %eax points to start of u16 args
                    297:         calll handle_pnp
                    298:         movw %ax, 12(%esp)      // Modify %eax to return %ax
                    299:         popw %ds
                    300:         popw %es
                    301:         popl %edx
                    302:         popl %ecx
                    303:         popl %eax
                    304:         popfl
                    305:         popl %esp
                    306:         lretw
                    307: 
                    308: // APM entry points
1.1.1.5   root      309:         DECLFUNC entry_apm16
                    310: entry_apm16:
1.1       root      311:         pushfw          // save flags
                    312:         pushl %eax      // dummy
1.1.1.2   root      313:         ENTRY_ARG handle_apm16
1.1       root      314:         addw $4, %sp    // pop dummy
                    315:         popfw           // restore flags
                    316:         lretw
                    317: 
                    318:         .code32
1.1.1.5   root      319:         DECLFUNC entry_apm32
                    320: entry_apm32:
1.1.1.2   root      321:         pushfl
                    322:         pushl %gs
                    323:         pushl %cs               // Move second descriptor after %cs to %gs
                    324:         addl $16, (%esp)
                    325:         popl %gs
1.1.1.4   root      326:         ENTRY_ARG_ESP _cfunc32seg_handle_apm32
1.1.1.2   root      327:         popl %gs
                    328:         popfl
                    329:         lretl
1.1       root      330: 
1.1.1.2   root      331: // PCI-BIOS 32bit entry point
1.1.1.5   root      332:         DECLFUNC entry_pcibios32
                    333: entry_pcibios32:
1.1.1.2   root      334:         pushfl
                    335:         pushl %gs               // Backup %gs and set %gs=%ds
                    336:         pushl %ds
                    337:         popl %gs
1.1.1.4   root      338:         ENTRY_ARG_ESP _cfunc32seg_handle_pcibios32
1.1.1.2   root      339:         popl %gs
                    340:         popfl
                    341:         lretl
                    342: 
                    343: // BIOS32 support
1.1.1.5   root      344:         EXPORTFUNC entry_bios32
                    345: entry_bios32:
1.1.1.2   root      346:         pushfl
                    347: #if CONFIG_PCIBIOS
                    348:         // Check for PCI-BIOS request
                    349:         cmpl $0x49435024, %eax // $PCI
                    350:         jne 1f
                    351:         movl $BUILD_BIOS_ADDR, %ebx
                    352:         movl $BUILD_BIOS_SIZE, %ecx
1.1.1.5   root      353:         movl $entry_pcibios32, %edx
1.1.1.2   root      354:         xorb %al, %al
                    355:         jmp 2f
                    356: #endif
                    357:         // Unknown request
                    358: 1:      movb $0x80, %al
                    359:         // Return to caller
                    360: 2:      popfl
1.1       root      361:         lretl
                    362: 
                    363: // 32bit elf entry point
1.1.1.5   root      364:         EXPORTFUNC entry_elf
                    365: entry_elf:
1.1       root      366:         cli
                    367:         cld
                    368:         lidtl (BUILD_BIOS_ADDR + pmode_IDT_info)
                    369:         lgdtl (BUILD_BIOS_ADDR + rombios32_gdt_48)
                    370:         movl $SEG32_MODE32_DS, %eax
                    371:         movw %ax, %ds
                    372:         movw %ax, %es
                    373:         movw %ax, %fs
                    374:         movw %ax, %gs
                    375:         movw %ax, %ss
                    376:         movl $BUILD_STACK_ADDR, %esp
1.1.1.5   root      377:         ljmpl $SEG32_MODE32_CS, $_cfunc32flat_handle_post
1.1       root      378: 
                    379:         .code16gcc
                    380: 
                    381: 
                    382: /****************************************************************
                    383:  * Interrupt entry points
                    384:  ****************************************************************/
                    385: 
1.1.1.4   root      386:         // Main entry point for interrupts without args
                    387:         DECLFUNC irqentry
                    388: irqentry:
                    389:         ENTRY_ST
                    390:         iretw
                    391: 
                    392:         // Main entry point for interrupts with args
                    393:         DECLFUNC irqentryarg
                    394: irqentryarg:
                    395:         ENTRY_ARG_ST
                    396:         iretw
                    397: 
1.1       root      398:         // Define an entry point for an interrupt (no args passed).
                    399:         .macro IRQ_ENTRY num
                    400:         .global entry_\num
                    401:         entry_\num :
                    402:         pushl $ handle_\num
                    403:         jmp irqentry
                    404:         .endm
                    405: 
1.1.1.4   root      406:         .macro DECL_IRQ_ENTRY num
                    407:         DECLFUNC entry_\num
                    408:         IRQ_ENTRY \num
                    409:         .endm
                    410: 
1.1       root      411:         // Define an entry point for an interrupt (can read/modify args).
                    412:         .macro IRQ_ENTRY_ARG num
                    413:         .global entry_\num
                    414:         entry_\num :
                    415:         pushl $ handle_\num
                    416:         jmp irqentryarg
                    417:         .endm
                    418: 
                    419:         .macro DECL_IRQ_ENTRY_ARG num
                    420:         DECLFUNC entry_\num
                    421:         IRQ_ENTRY_ARG \num
                    422:         .endm
                    423: 
1.1.1.4   root      424:         // Various entry points (that don't require a fixed location).
1.1       root      425:         DECL_IRQ_ENTRY_ARG 13
                    426:         DECL_IRQ_ENTRY 76
                    427:         DECL_IRQ_ENTRY 70
                    428:         DECL_IRQ_ENTRY 74
                    429:         DECL_IRQ_ENTRY 75
                    430:         DECL_IRQ_ENTRY hwpic1
                    431:         DECL_IRQ_ENTRY hwpic2
                    432: 
                    433:         // int 18/19 are special - they reset stack and call into 32bit mode.
                    434:         DECLFUNC entry_19
                    435: entry_19:
1.1.1.4   root      436:         ENTRY_INTO32 _cfunc32flat_handle_19
1.1       root      437: 
                    438:         DECLFUNC entry_18
                    439: entry_18:
1.1.1.4   root      440:         ENTRY_INTO32 _cfunc32flat_handle_18
1.1       root      441: 
                    442: 
                    443: /****************************************************************
                    444:  * Fixed position entry points
                    445:  ****************************************************************/
                    446: 
                    447:         // Specify a location in the fixed part of bios area.
                    448:         .macro ORG addr
                    449:         .section .fixedaddr.\addr
                    450:         .endm
                    451: 
                    452:         ORG 0xe05b
1.1.1.5   root      453: entry_post:
                    454:         cmpl $0, %cs:HaveRunPost                // Check for resume/reboot
                    455:         jnz entry_resume
                    456:         ENTRY_INTO32 _cfunc32flat_handle_post   // Normal entry point
1.1       root      457: 
                    458:         ORG 0xe2c3
                    459:         IRQ_ENTRY 02
                    460: 
                    461:         ORG 0xe3fe
                    462:         .global entry_13_official
                    463: entry_13_official:
                    464:         jmp entry_13
                    465: 
                    466:         // 0xe401 - OldFDPT in disk.c
                    467: 
                    468:         ORG 0xe6f2
                    469:         .global entry_19_official
                    470: entry_19_official:
                    471:         jmp entry_19
                    472: 
                    473:         // 0xe6f5 - BIOS_CONFIG_TABLE in misc.c
                    474: 
                    475:         // 0xe729 - BaudTable in serial.c
                    476: 
                    477:         ORG 0xe739
                    478:         IRQ_ENTRY_ARG 14
                    479: 
                    480:         ORG 0xe82e
                    481:         IRQ_ENTRY_ARG 16
                    482: 
                    483:         ORG 0xe987
                    484:         IRQ_ENTRY 09
                    485: 
                    486:         ORG 0xec59
                    487:         IRQ_ENTRY_ARG 40
                    488: 
                    489:         ORG 0xef57
                    490:         IRQ_ENTRY 0e
                    491: 
                    492:         // 0xefc7 - diskette_param_table in floppy.c
                    493: 
                    494:         ORG 0xefd2
                    495:         IRQ_ENTRY_ARG 17
                    496: 
                    497:         ORG 0xf045
                    498: entry_10_0x0f:
                    499:         // XXX - INT 10 Functions 0-Fh Entry Point
                    500:         iretw
                    501: 
                    502:         ORG 0xf065
                    503:         IRQ_ENTRY_ARG 10
                    504: 
                    505:         // 0xf0a4 - VideoParams in misc.c
                    506: 
                    507:         ORG 0xf841
                    508:         IRQ_ENTRY_ARG 12
                    509: 
                    510:         ORG 0xf84d
                    511:         IRQ_ENTRY_ARG 11
                    512: 
                    513:         ORG 0xf859
                    514:         IRQ_ENTRY_ARG 15
                    515: 
                    516:         // 0xfa6e - vgafont8 in font.c
                    517: 
                    518:         ORG 0xfe6e
                    519:         IRQ_ENTRY_ARG 1a
                    520: 
                    521:         ORG 0xfea5
                    522:         IRQ_ENTRY 08
                    523: 
                    524:         // 0xfef3 - InitVectors in misc.c
                    525: 
                    526:         // 0xff00 - BiosCopyright in misc.c
                    527: 
                    528:         ORG 0xff53
                    529:         .global entry_iret_official
                    530: entry_iret_official:
                    531:         iretw
                    532: 
                    533:         ORG 0xff54
                    534:         IRQ_ENTRY_ARG 05
                    535: 
                    536:         ORG 0xfff0 // Power-up Entry Point
                    537:         .global reset_vector
                    538: reset_vector:
1.1.1.5   root      539:         ljmpw $SEG_BIOS, $entry_post
1.1       root      540: 
                    541:         // 0xfff5 - BiosDate in misc.c
                    542: 
                    543:         // 0xfffe - BiosModelId in misc.c
                    544: 
                    545:         // 0xffff - BiosChecksum in misc.c
                    546: 
                    547:         .end

unix.superglobalmegacorp.com

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