qemu/pc-bios/optionrom/optionrom.h
<<
>>
Prefs
   1/*
   2 * Common Option ROM Functions
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License as published by
   6 * the Free Software Foundation; either version 2 of the License, or
   7 * (at your option) any later version.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12 * GNU General Public License for more details.
  13 *
  14 * You should have received a copy of the GNU General Public License
  15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
  16 *
  17 * Copyright Novell Inc, 2009
  18 *   Authors: Alexander Graf <agraf@suse.de>
  19 */
  20
  21
  22#define FW_CFG_KERNEL_ADDR      0x07
  23#define FW_CFG_KERNEL_SIZE      0x08
  24#define FW_CFG_KERNEL_CMDLINE   0x09
  25#define FW_CFG_INITRD_ADDR      0x0a
  26#define FW_CFG_INITRD_SIZE      0x0b
  27#define FW_CFG_KERNEL_ENTRY     0x10
  28#define FW_CFG_KERNEL_DATA      0x11
  29#define FW_CFG_INITRD_DATA      0x12
  30#define FW_CFG_CMDLINE_ADDR     0x13
  31#define FW_CFG_CMDLINE_SIZE     0x14
  32#define FW_CFG_CMDLINE_DATA     0x15
  33#define FW_CFG_SETUP_ADDR       0x16
  34#define FW_CFG_SETUP_SIZE       0x17
  35#define FW_CFG_SETUP_DATA       0x18
  36
  37#define BIOS_CFG_IOPORT_CFG     0x510
  38#define BIOS_CFG_IOPORT_DATA    0x511
  39
  40#define FW_CFG_DMA_CTL_ERROR   0x01
  41#define FW_CFG_DMA_CTL_READ    0x02
  42#define FW_CFG_DMA_CTL_SKIP    0x04
  43#define FW_CFG_DMA_CTL_SELECT  0x08
  44#define FW_CFG_DMA_CTL_WRITE   0x10
  45
  46#define FW_CFG_DMA_SIGNATURE 0x51454d5520434647ULL /* "QEMU CFG" */
  47
  48#define BIOS_CFG_DMA_ADDR_HIGH  0x514
  49#define BIOS_CFG_DMA_ADDR_LOW   0x518
  50
  51/* Break the translation block flow so -d cpu shows us values */
  52#define DEBUG_HERE \
  53        jmp             1f;                             \
  54        1:
  55        
  56/*
  57 * Read a variable from the fw_cfg device.
  58 * Clobbers:    %edx
  59 * Out:         %eax
  60 */
  61.macro read_fw VAR
  62        mov             $\VAR, %ax
  63        mov             $BIOS_CFG_IOPORT_CFG, %dx
  64        outw            %ax, (%dx)
  65        mov             $BIOS_CFG_IOPORT_DATA, %dx
  66        inb             (%dx), %al
  67        shl             $8, %eax
  68        inb             (%dx), %al
  69        shl             $8, %eax
  70        inb             (%dx), %al
  71        shl             $8, %eax
  72        inb             (%dx), %al
  73        bswap           %eax
  74.endm
  75
  76
  77/*
  78 * Read data from the fw_cfg device using DMA.
  79 * Clobbers:    %edx, %eax, ADDR, SIZE, memory[%esp-16] to memory[%esp]
  80 */
  81.macro read_fw_dma VAR, SIZE, ADDR
  82        /* Address */
  83        bswapl          \ADDR
  84        pushl           \ADDR
  85
  86        /* We only support 32 bit target addresses */
  87        xorl            %eax, %eax
  88        pushl           %eax
  89        mov             $BIOS_CFG_DMA_ADDR_HIGH, %dx
  90        outl            %eax, (%dx)
  91
  92        /* Size */
  93        bswapl          \SIZE
  94        pushl           \SIZE
  95
  96        /* Control */
  97        movl            $(\VAR << 16) | (FW_CFG_DMA_CTL_READ | FW_CFG_DMA_CTL_SELECT), %eax
  98        bswapl          %eax
  99        pushl           %eax
 100
 101        movl            %esp, %eax /* Address of the struct we generated */
 102        bswapl          %eax
 103        mov             $BIOS_CFG_DMA_ADDR_LOW, %dx
 104        outl            %eax, (%dx) /* Initiate DMA */
 105
 1061:  mov         (%esp), %eax /* Wait for completion */
 107        bswapl          %eax
 108        testl           $~FW_CFG_DMA_CTL_ERROR, %eax
 109        jnz             1b
 110       addl            $16, %esp
 111.endm
 112
 113
 114/*
 115 * Read a blob from the fw_cfg device using DMA
 116 * Requires _ADDR, _SIZE and _DATA values for the parameter.
 117 *
 118 * Clobbers:    %eax, %edx, %es, %ecx, %edi and adresses %esp-20 to %esp
 119 */
 120#ifdef USE_FW_CFG_DMA
 121#define read_fw_blob_dma(var) \
 122        read_fw         var ## _SIZE; \
 123        mov             %eax, %ecx; \
 124        read_fw         var ## _ADDR; \
 125        mov             %eax, %edi ;\
 126        read_fw_dma     var ## _DATA, %ecx, %edi
 127#else
 128#define read_fw_blob_dma(var) read_fw_blob(var)
 129#endif
 130
 131#define read_fw_blob_pre(var)                           \
 132        read_fw         var ## _SIZE;                   \
 133        mov             %eax, %ecx;                     \
 134        mov             $var ## _DATA, %ax;             \
 135        mov             $BIOS_CFG_IOPORT_CFG, %edx;     \
 136        outw            %ax, (%dx);                     \
 137        mov             $BIOS_CFG_IOPORT_DATA, %dx;     \
 138        cld
 139
 140/*
 141 * Read a blob from the fw_cfg device.
 142 * Requires _ADDR, _SIZE and _DATA values for the parameter.
 143 *
 144 * Clobbers:    %eax, %edx, %es, %ecx, %edi
 145 */
 146#define read_fw_blob(var)                               \
 147        read_fw         var ## _ADDR;                   \
 148        mov             %eax, %edi;                     \
 149        read_fw_blob_pre(var);                          \
 150        /* old as(1) doesn't like this insn so emit the bytes instead: \
 151        rep insb        (%dx), %es:(%edi);              \
 152        */                                              \
 153        .dc.b           0xf3,0x6c
 154
 155/*
 156 * Read a blob from the fw_cfg device in forced addr32 mode.
 157 * Requires _ADDR, _SIZE and _DATA values for the parameter.
 158 *
 159 * Clobbers:    %eax, %edx, %es, %ecx, %edi
 160 */
 161#define read_fw_blob_addr32(var)                        \
 162        read_fw         var ## _ADDR;                   \
 163        mov             %eax, %edi;                     \
 164        read_fw_blob_pre(var);                          \
 165        /* old as(1) doesn't like this insn so emit the bytes instead: \
 166        addr32 rep insb (%dx), %es:(%edi);              \
 167        */                                              \
 168        .dc.b           0x67,0xf3,0x6c
 169
 170/*
 171 * Read a blob from the fw_cfg device in forced addr32 mode, address is in %edi.
 172 * Requires _SIZE and _DATA values for the parameter.
 173 *
 174 * Clobbers:    %eax, %edx, %edi, %es, %ecx
 175 */
 176#define read_fw_blob_addr32_edi(var)                    \
 177        read_fw_blob_pre(var);                          \
 178        /* old as(1) doesn't like this insn so emit the bytes instead: \
 179        addr32 rep insb (%dx), %es:(%edi);              \
 180        */                                              \
 181        .dc.b           0x67,0xf3,0x6c
 182
 183#define OPTION_ROM_START                                        \
 184    .code16;                                            \
 185    .text;                                              \
 186        .global         _start;                         \
 187    _start:;                                            \
 188        .short          0xaa55;                         \
 189        .byte           (_end - _start) / 512;
 190
 191#define BOOT_ROM_START                                  \
 192        OPTION_ROM_START                                \
 193        lret;                                           \
 194        .org            0x18;                           \
 195        .short          0;                              \
 196        .short          _pnph;                          \
 197    _pnph:                                              \
 198        .ascii          "$PnP";                         \
 199        .byte           0x01;                           \
 200        .byte           ( _pnph_len / 16 );             \
 201        .short          0x0000;                         \
 202        .byte           0x00;                           \
 203        .byte           0x00;                           \
 204        .long           0x00000000;                     \
 205        .short          _manufacturer;                  \
 206        .short          _product;                       \
 207        .long           0x00000000;                     \
 208        .short          0x0000;                         \
 209        .short          0x0000;                         \
 210        .short          _bev;                           \
 211        .short          0x0000;                         \
 212        .short          0x0000;                         \
 213        .equ            _pnph_len, . - _pnph;           \
 214    _bev:;                                              \
 215        /* DS = CS */                                   \
 216        movw            %cs, %ax;                       \
 217        movw            %ax, %ds;
 218
 219#define OPTION_ROM_END                                  \
 220        .byte           0;                              \
 221        .align          512, 0;                         \
 222    _end:
 223
 224#define BOOT_ROM_END                                    \
 225    _manufacturer:;                                     \
 226        .asciz "QEMU";                                  \
 227    _product:;                                          \
 228        .asciz BOOT_ROM_PRODUCT;                        \
 229        OPTION_ROM_END
 230
 231