Kevin O'Connor | 1f2c307 | 2009-05-06 23:35:59 -0400 | [diff] [blame] | 1 | // Rom layout and bios assembler to C interface. |
| 2 | // |
Kevin O'Connor | dab0a74 | 2013-12-03 11:50:49 -0500 | [diff] [blame] | 3 | // Copyright (C) 2009-2013 Kevin O'Connor <kevin@koconnor.net> |
Kevin O'Connor | 1f2c307 | 2009-05-06 23:35:59 -0400 | [diff] [blame] | 4 | // |
| 5 | // This file may be distributed under the terms of the GNU LGPLv3 license. |
| 6 | |
| 7 | |
Kevin O'Connor | 4a8b58c | 2013-11-30 19:16:15 -0500 | [diff] [blame] | 8 | #include "asm-offsets.h" // BREGS_* |
Julian Pidancet | 7c6509c | 2011-12-19 05:07:55 +0000 | [diff] [blame] | 9 | #include "config.h" // CONFIG_* |
Kevin O'Connor | 1f2c307 | 2009-05-06 23:35:59 -0400 | [diff] [blame] | 10 | #include "entryfuncs.S" // ENTRY_* |
| 11 | |
| 12 | |
| 13 | /**************************************************************** |
| 14 | * Rom Header |
| 15 | ****************************************************************/ |
| 16 | |
| 17 | .section .rom.header |
Kevin O'Connor | 36feea9 | 2012-02-11 10:49:45 -0500 | [diff] [blame] | 18 | .code16gcc |
Kevin O'Connor | 1f2c307 | 2009-05-06 23:35:59 -0400 | [diff] [blame] | 19 | .global _rom_header, _rom_header_size, _rom_header_checksum |
| 20 | _rom_header: |
| 21 | .word 0xaa55 |
| 22 | _rom_header_size: |
| 23 | .byte 0 |
| 24 | _rom_header_entry: |
| 25 | jmp _optionrom_entry |
| 26 | _rom_header_checksum: |
Kevin O'Connor | c9d3c2d | 2010-01-01 12:53:32 -0500 | [diff] [blame] | 27 | .byte 0 |
| 28 | _rom_header_other: |
Julian Pidancet | 7c6509c | 2011-12-19 05:07:55 +0000 | [diff] [blame] | 29 | .space 17 |
| 30 | _rom_header_pcidata: |
| 31 | #if CONFIG_VGA_PCI == 1 |
| 32 | .word rom_pci_data |
| 33 | #else |
| 34 | .word 0 |
| 35 | #endif |
| 36 | _rom_header_pnpdata: |
| 37 | .word 0 |
Kevin O'Connor | 72b5e45 | 2011-12-23 23:01:48 -0500 | [diff] [blame] | 38 | _rom_header_other2: |
| 39 | .word 0 |
| 40 | _rom_header_signature: |
| 41 | .asciz "IBM" |
Kevin O'Connor | 1f2c307 | 2009-05-06 23:35:59 -0400 | [diff] [blame] | 42 | |
| 43 | |
| 44 | /**************************************************************** |
| 45 | * Entry points |
| 46 | ****************************************************************/ |
| 47 | |
Kevin O'Connor | 9332f9b | 2013-11-30 12:52:44 -0500 | [diff] [blame] | 48 | // This macro is the same as ENTRY_ARG except the "calll" |
| 49 | // instruction is avoided to work around known issues in the |
| 50 | // emulation of some versions of x86emu. |
| 51 | .macro ENTRY_ARG_VGA cfunc |
| 52 | cli |
| 53 | cld |
| 54 | PUSHBREGS |
| 55 | movw %ss, %ax // Move %ss to %ds |
| 56 | movw %ax, %ds |
| 57 | movl %esp, %ebx // Backup %esp, then zero high bits |
| 58 | movzwl %sp, %esp |
| 59 | movl %esp, %eax // First arg is pointer to struct bregs |
| 60 | pushw %ax ; callw \cfunc |
| 61 | movl %ebx, %esp // Restore %esp (including high bits) |
| 62 | POPBREGS |
| 63 | .endm |
| 64 | |
Kevin O'Connor | 9961f99 | 2012-01-21 11:53:44 -0500 | [diff] [blame] | 65 | DECLFUNC entry_104f05 |
| 66 | entry_104f05: |
Kevin O'Connor | 9332f9b | 2013-11-30 12:52:44 -0500 | [diff] [blame] | 67 | ENTRY_ARG_VGA vbe_104f05 |
Kevin O'Connor | 9961f99 | 2012-01-21 11:53:44 -0500 | [diff] [blame] | 68 | lretw |
| 69 | |
Kevin O'Connor | 1f2c307 | 2009-05-06 23:35:59 -0400 | [diff] [blame] | 70 | DECLFUNC _optionrom_entry |
| 71 | _optionrom_entry: |
Kevin O'Connor | 9332f9b | 2013-11-30 12:52:44 -0500 | [diff] [blame] | 72 | ENTRY_ARG_VGA vga_post |
Kevin O'Connor | 1f2c307 | 2009-05-06 23:35:59 -0400 | [diff] [blame] | 73 | lretw |
| 74 | |
Kevin O'Connor | 9f193b9 | 2009-05-16 23:31:27 -0400 | [diff] [blame] | 75 | DECLFUNC entry_10 |
| 76 | entry_10: |
Kevin O'Connor | 9332f9b | 2013-11-30 12:52:44 -0500 | [diff] [blame] | 77 | ENTRY_ARG_VGA handle_10 |
Kevin O'Connor | 9f193b9 | 2009-05-16 23:31:27 -0400 | [diff] [blame] | 78 | iretw |
Kevin O'Connor | 4a8b58c | 2013-11-30 19:16:15 -0500 | [diff] [blame] | 79 | |
| 80 | // Entry point using extra stack |
| 81 | DECLFUNC entry_10_extrastack |
| 82 | entry_10_extrastack: |
| 83 | cli |
| 84 | cld |
| 85 | pushw %ds // Set %ds:%eax to space on ExtraStack |
| 86 | pushl %eax |
Kevin O'Connor | feb0284 | 2013-12-09 20:30:30 -0500 | [diff] [blame^] | 87 | movw %cs:ExtraStackSeg, %ds |
Kevin O'Connor | 4a8b58c | 2013-11-30 19:16:15 -0500 | [diff] [blame] | 88 | movl $(CONFIG_VGA_EXTRA_STACK_SIZE-BREGS_size-8), %eax |
| 89 | popl BREGS_eax(%eax) // Backup registers |
| 90 | popw BREGS_ds(%eax) |
| 91 | movl %edi, BREGS_edi(%eax) |
| 92 | movl %esi, BREGS_esi(%eax) |
| 93 | movl %ebp, BREGS_ebp(%eax) |
| 94 | movl %ebx, BREGS_ebx(%eax) |
| 95 | movl %edx, BREGS_edx(%eax) |
| 96 | movl %ecx, BREGS_ecx(%eax) |
| 97 | movw %es, BREGS_es(%eax) |
| 98 | movl %esp, BREGS_size+0(%eax) |
Kevin O'Connor | 4a8b58c | 2013-11-30 19:16:15 -0500 | [diff] [blame] | 99 | movw %ss, BREGS_size+4(%eax) |
Kevin O'Connor | 41c6061 | 2013-12-09 17:27:54 -0500 | [diff] [blame] | 100 | popl BREGS_code(%eax) |
| 101 | popw BREGS_flags(%eax) |
Kevin O'Connor | 4a8b58c | 2013-11-30 19:16:15 -0500 | [diff] [blame] | 102 | |
| 103 | movw %ds, %dx // Setup %ss/%esp and call function |
| 104 | movw %dx, %ss |
| 105 | movl %eax, %esp |
| 106 | pushw %ax ; callw handle_10 |
| 107 | |
| 108 | movl %esp, %eax // Restore registers and return |
| 109 | movw BREGS_size+4(%eax), %ss |
| 110 | movl BREGS_size+0(%eax), %esp |
| 111 | popl %edx |
| 112 | popw %dx |
| 113 | pushw BREGS_flags(%eax) |
| 114 | pushl BREGS_code(%eax) |
| 115 | movl BREGS_edi(%eax), %edi |
| 116 | movl BREGS_esi(%eax), %esi |
| 117 | movl BREGS_ebp(%eax), %ebp |
| 118 | movl BREGS_ebx(%eax), %ebx |
| 119 | movl BREGS_edx(%eax), %edx |
| 120 | movl BREGS_ecx(%eax), %ecx |
| 121 | movw BREGS_es(%eax), %es |
| 122 | pushw BREGS_ds(%eax) |
| 123 | pushl BREGS_eax(%eax) |
| 124 | popl %eax |
| 125 | popw %ds |
| 126 | iretw |