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 |
David Woodhouse | 67fd42c | 2014-06-03 17:28:58 +0100 | [diff] [blame] | 18 | .code16 |
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 | 8032b8a | 2014-02-05 22:47:29 -0500 | [diff] [blame] | 48 | // This macro implements a call while avoiding instructions |
| 49 | // that old versions of x86emu have problems with. |
| 50 | .macro VGA_CALLL cfunc |
Kevin O'Connor | 799b20b | 2015-04-09 17:15:23 -0400 | [diff] [blame] | 51 | #if CONFIG_VGA_FIXUP_ASM |
Kevin O'Connor | 0b2165d | 2015-04-09 17:20:16 -0400 | [diff] [blame] | 52 | pushw %ax |
Kevin O'Connor | 8032b8a | 2014-02-05 22:47:29 -0500 | [diff] [blame] | 53 | callw \cfunc |
Kevin O'Connor | 799b20b | 2015-04-09 17:15:23 -0400 | [diff] [blame] | 54 | #else |
| 55 | calll \cfunc |
| 56 | #endif |
Kevin O'Connor | 8032b8a | 2014-02-05 22:47:29 -0500 | [diff] [blame] | 57 | .endm |
| 58 | |
| 59 | // This macro is the same as ENTRY_ARG except VGA_CALLL is used. |
Kevin O'Connor | 9332f9b | 2013-11-30 12:52:44 -0500 | [diff] [blame] | 60 | .macro ENTRY_ARG_VGA cfunc |
| 61 | cli |
| 62 | cld |
| 63 | PUSHBREGS |
| 64 | movw %ss, %ax // Move %ss to %ds |
| 65 | movw %ax, %ds |
| 66 | movl %esp, %ebx // Backup %esp, then zero high bits |
| 67 | movzwl %sp, %esp |
| 68 | movl %esp, %eax // First arg is pointer to struct bregs |
Kevin O'Connor | 8032b8a | 2014-02-05 22:47:29 -0500 | [diff] [blame] | 69 | VGA_CALLL \cfunc |
Kevin O'Connor | 9332f9b | 2013-11-30 12:52:44 -0500 | [diff] [blame] | 70 | movl %ebx, %esp // Restore %esp (including high bits) |
| 71 | POPBREGS |
| 72 | .endm |
| 73 | |
Kevin O'Connor | 9961f99 | 2012-01-21 11:53:44 -0500 | [diff] [blame] | 74 | DECLFUNC entry_104f05 |
| 75 | entry_104f05: |
Kevin O'Connor | 9332f9b | 2013-11-30 12:52:44 -0500 | [diff] [blame] | 76 | ENTRY_ARG_VGA vbe_104f05 |
Kevin O'Connor | 9961f99 | 2012-01-21 11:53:44 -0500 | [diff] [blame] | 77 | lretw |
| 78 | |
Kevin O'Connor | 1f2c307 | 2009-05-06 23:35:59 -0400 | [diff] [blame] | 79 | DECLFUNC _optionrom_entry |
| 80 | _optionrom_entry: |
Kevin O'Connor | 9332f9b | 2013-11-30 12:52:44 -0500 | [diff] [blame] | 81 | ENTRY_ARG_VGA vga_post |
Kevin O'Connor | 1f2c307 | 2009-05-06 23:35:59 -0400 | [diff] [blame] | 82 | lretw |
| 83 | |
Kevin O'Connor | 9f193b9 | 2009-05-16 23:31:27 -0400 | [diff] [blame] | 84 | DECLFUNC entry_10 |
| 85 | entry_10: |
Kevin O'Connor | 9332f9b | 2013-11-30 12:52:44 -0500 | [diff] [blame] | 86 | ENTRY_ARG_VGA handle_10 |
Kevin O'Connor | 9f193b9 | 2009-05-16 23:31:27 -0400 | [diff] [blame] | 87 | iretw |
Kevin O'Connor | 4a8b58c | 2013-11-30 19:16:15 -0500 | [diff] [blame] | 88 | |
Kevin O'Connor | 251e263 | 2015-03-17 11:37:25 -0400 | [diff] [blame] | 89 | #define VGA_CUSTOM_BDA_FLAGS 0xb9 |
| 90 | #define BF_EXTRA_STACK 0x40 |
| 91 | |
Kevin O'Connor | 4a8b58c | 2013-11-30 19:16:15 -0500 | [diff] [blame] | 92 | // Entry point using extra stack |
| 93 | DECLFUNC entry_10_extrastack |
| 94 | entry_10_extrastack: |
| 95 | cli |
| 96 | cld |
Kevin O'Connor | 251e263 | 2015-03-17 11:37:25 -0400 | [diff] [blame] | 97 | pushw %ds |
Kevin O'Connor | 4a8b58c | 2013-11-30 19:16:15 -0500 | [diff] [blame] | 98 | pushl %eax |
Kevin O'Connor | 251e263 | 2015-03-17 11:37:25 -0400 | [diff] [blame] | 99 | |
| 100 | movw $SEG_BDA, %ax // Check if extra stack is enabled |
| 101 | movw %ax, %ds |
| 102 | testb $BF_EXTRA_STACK, VGA_CUSTOM_BDA_FLAGS |
| 103 | jz 1f |
| 104 | |
| 105 | movw %cs:ExtraStackSeg, %ds // Set %ds:%eax to space on ExtraStack |
Kevin O'Connor | aa66d65 | 2014-11-05 09:05:36 -0500 | [diff] [blame] | 106 | movl $(CONFIG_VGA_EXTRA_STACK_SIZE-PUSHBREGS_size-16), %eax |
Kevin O'Connor | 46000f5 | 2014-10-21 02:23:02 -0400 | [diff] [blame] | 107 | SAVEBREGS_POP_DSEAX // Save registers on extra stack |
Kevin O'Connor | aa66d65 | 2014-11-05 09:05:36 -0500 | [diff] [blame] | 108 | movl %esp, PUSHBREGS_size+8(%eax) |
| 109 | movw %ss, PUSHBREGS_size+12(%eax) |
Kevin O'Connor | 41c6061 | 2013-12-09 17:27:54 -0500 | [diff] [blame] | 110 | popl BREGS_code(%eax) |
| 111 | popw BREGS_flags(%eax) |
Kevin O'Connor | 4a8b58c | 2013-11-30 19:16:15 -0500 | [diff] [blame] | 112 | |
| 113 | movw %ds, %dx // Setup %ss/%esp and call function |
| 114 | movw %dx, %ss |
| 115 | movl %eax, %esp |
Kevin O'Connor | 8032b8a | 2014-02-05 22:47:29 -0500 | [diff] [blame] | 116 | VGA_CALLL handle_10 |
Kevin O'Connor | 4a8b58c | 2013-11-30 19:16:15 -0500 | [diff] [blame] | 117 | |
| 118 | movl %esp, %eax // Restore registers and return |
Kevin O'Connor | aa66d65 | 2014-11-05 09:05:36 -0500 | [diff] [blame] | 119 | movw PUSHBREGS_size+12(%eax), %ss |
| 120 | movl PUSHBREGS_size+8(%eax), %esp |
Kevin O'Connor | 4a8b58c | 2013-11-30 19:16:15 -0500 | [diff] [blame] | 121 | popl %edx |
| 122 | popw %dx |
| 123 | pushw BREGS_flags(%eax) |
| 124 | pushl BREGS_code(%eax) |
Kevin O'Connor | 46000f5 | 2014-10-21 02:23:02 -0400 | [diff] [blame] | 125 | RESTOREBREGS_DSEAX |
Kevin O'Connor | 4a8b58c | 2013-11-30 19:16:15 -0500 | [diff] [blame] | 126 | iretw |
Kevin O'Connor | b4eb6fc | 2014-10-17 22:15:42 -0400 | [diff] [blame] | 127 | |
Kevin O'Connor | 251e263 | 2015-03-17 11:37:25 -0400 | [diff] [blame] | 128 | 1: // Use regular entry point if the extra stack is disabled |
| 129 | popl %eax |
| 130 | popw %ds |
| 131 | jmp entry_10 |
| 132 | |
Kevin O'Connor | b4eb6fc | 2014-10-17 22:15:42 -0400 | [diff] [blame] | 133 | // Timer irq handling |
| 134 | DECLFUNC entry_timer_hook |
| 135 | entry_timer_hook: |
| 136 | ENTRY handle_timer_hook |
| 137 | ljmpw *%cs:Timer_Hook_Resume |
| 138 | |
| 139 | // Timer irq handling on extra stack |
| 140 | DECLFUNC entry_timer_hook_extrastack |
| 141 | entry_timer_hook_extrastack: |
| 142 | cli |
| 143 | cld |
| 144 | pushw %ds // Set %ds:%eax to space on ExtraStack |
| 145 | pushl %eax |
| 146 | movw %cs:ExtraStackSeg, %ds |
Kevin O'Connor | aa66d65 | 2014-11-05 09:05:36 -0500 | [diff] [blame] | 147 | movl $(CONFIG_VGA_EXTRA_STACK_SIZE-PUSHBREGS_size-8), %eax |
Kevin O'Connor | b4eb6fc | 2014-10-17 22:15:42 -0400 | [diff] [blame] | 148 | SAVEBREGS_POP_DSEAX |
Kevin O'Connor | aa66d65 | 2014-11-05 09:05:36 -0500 | [diff] [blame] | 149 | movl %esp, PUSHBREGS_size(%eax) |
| 150 | movw %ss, PUSHBREGS_size+4(%eax) |
Kevin O'Connor | b4eb6fc | 2014-10-17 22:15:42 -0400 | [diff] [blame] | 151 | |
| 152 | movw %ds, %dx // Setup %ss/%esp and call function |
| 153 | movw %dx, %ss |
| 154 | movl %eax, %esp |
| 155 | calll handle_timer_hook |
| 156 | |
| 157 | movl %esp, %eax // Restore registers and return |
Kevin O'Connor | aa66d65 | 2014-11-05 09:05:36 -0500 | [diff] [blame] | 158 | movw PUSHBREGS_size+4(%eax), %ss |
| 159 | movl PUSHBREGS_size(%eax), %esp |
Kevin O'Connor | b4eb6fc | 2014-10-17 22:15:42 -0400 | [diff] [blame] | 160 | RESTOREBREGS_DSEAX |
| 161 | ljmpw *%cs:Timer_Hook_Resume |