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

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

unix.superglobalmegacorp.com

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