/* * Common Option ROM Functions * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Copyright Novell Inc, 2009 * Authors: Alexander Graf */ #include "../../include/hw/nvram/fw_cfg_keys.h" #define BIOS_CFG_IOPORT_CFG 0x510 #define BIOS_CFG_IOPORT_DATA 0x511 /* Break the translation block flow so -d cpu shows us values */ #define DEBUG_HERE \ jmp 1f; \ 1: /* * Read a variable from the fw_cfg device. * Clobbers: %edx * Out: %eax */ .macro read_fw VAR mov $\VAR, %ax mov $BIOS_CFG_IOPORT_CFG, %dx outw %ax, (%dx) mov $BIOS_CFG_IOPORT_DATA, %dx inb (%dx), %al shl $8, %eax inb (%dx), %al shl $8, %eax inb (%dx), %al shl $8, %eax inb (%dx), %al bswap %eax .endm #define read_fw_blob_pre(var) \ read_fw var ## _SIZE; \ mov %eax, %ecx; \ mov $var ## _DATA, %ax; \ mov $BIOS_CFG_IOPORT_CFG, %edx; \ outw %ax, (%dx); \ mov $BIOS_CFG_IOPORT_DATA, %dx; \ cld /* * Read a blob from the fw_cfg device. * Requires _ADDR, _SIZE and _DATA values for the parameter. * * Clobbers: %eax, %edx, %es, %ecx, %edi */ #define read_fw_blob(var) \ read_fw var ## _ADDR; \ mov %eax, %edi; \ read_fw_blob_pre(var); \ /* old as(1) doesn't like this insn so emit the bytes instead: \ rep insb (%dx), %es:(%edi); \ */ \ .dc.b 0xf3,0x6c /* * Read a blob from the fw_cfg device in forced addr32 mode. * Requires _ADDR, _SIZE and _DATA values for the parameter. * * Clobbers: %eax, %edx, %es, %ecx, %edi */ #define read_fw_blob_addr32(var) \ read_fw var ## _ADDR; \ mov %eax, %edi; \ read_fw_blob_pre(var); \ /* old as(1) doesn't like this insn so emit the bytes instead: \ addr32 rep insb (%dx), %es:(%edi); \ */ \ .dc.b 0x67,0xf3,0x6c /* * Read a blob from the fw_cfg device in forced addr32 mode, address is in %edi. * Requires _SIZE and _DATA values for the parameter. * * Clobbers: %eax, %edx, %edi, %es, %ecx */ #define read_fw_blob_addr32_edi(var) \ read_fw_blob_pre(var); \ /* old as(1) doesn't like this insn so emit the bytes instead: \ addr32 rep insb (%dx), %es:(%edi); \ */ \ .dc.b 0x67,0xf3,0x6c #define OPTION_ROM_START \ .code16; \ .text; \ .global _start; \ _start:; \ .short 0xaa55; \ .byte (_end - _start) / 512; #define BOOT_ROM_START \ OPTION_ROM_START \ lret; \ .org 0x18; \ .short 0; \ .short _pnph; \ _pnph: \ .ascii "$PnP"; \ .byte 0x01; \ .byte ( _pnph_len / 16 ); \ .short 0x0000; \ .byte 0x00; \ .byte 0x00; \ .long 0x00000000; \ .short _manufacturer; \ .short _product; \ .long 0x00000000; \ .short 0x0000; \ .short 0x0000; \ .short _bev; \ .short 0x0000; \ .short 0x0000; \ .equ _pnph_len, . - _pnph; \ _bev:; \ /* DS = CS */ \ movw %cs, %ax; \ movw %ax, %ds; #define OPTION_ROM_END \ .byte 0; \ .align 512, 0; \ _end: #define BOOT_ROM_END \ _manufacturer:; \ .asciz "QEMU"; \ _product:; \ .asciz BOOT_ROM_PRODUCT; \ OPTION_ROM_END