qemu/pc-bios/optionrom/optrom_fw_cfg.h
<<
>>
Prefs
   1/*
   2 * Common Option ROM Functions for fw_cfg
   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 (c) 2015-2019 Red Hat Inc.
  18 *   Authors:
  19 *     Marc MarĂ­ <marc.mari.barcelo@gmail.com>
  20 *     Richard W.M. Jones <rjones@redhat.com>
  21 *     Stefano Garzarella <sgarzare@redhat.com>
  22 */
  23
  24#ifndef OPTROM_FW_CFG_H
  25#define OPTROM_FW_CFG_H
  26
  27#include "../../include/standard-headers/linux/qemu_fw_cfg.h"
  28
  29#define BIOS_CFG_IOPORT_CFG     0x510
  30#define BIOS_CFG_IOPORT_DATA    0x511
  31#define BIOS_CFG_DMA_ADDR_HIGH  0x514
  32#define BIOS_CFG_DMA_ADDR_LOW   0x518
  33
  34static __attribute__((unused))
  35void bios_cfg_select(uint16_t key)
  36{
  37    outw(key, BIOS_CFG_IOPORT_CFG);
  38}
  39
  40static __attribute__((unused))
  41void bios_cfg_read_entry_io(void *buf, uint16_t entry, uint32_t len)
  42{
  43    bios_cfg_select(entry);
  44    insb(BIOS_CFG_IOPORT_DATA, buf, len);
  45}
  46
  47/*
  48 * clang is happy to inline this function, and bloats the
  49 * ROM.
  50 */
  51static __attribute__((__noinline__)) __attribute__((unused))
  52void bios_cfg_read_entry_dma(void *buf, uint16_t entry, uint32_t len)
  53{
  54    struct fw_cfg_dma_access access;
  55    uint32_t control = (entry << 16) | FW_CFG_DMA_CTL_SELECT
  56                        | FW_CFG_DMA_CTL_READ;
  57
  58    access.address = cpu_to_be64((uint64_t)(uint32_t)buf);
  59    access.length = cpu_to_be32(len);
  60    access.control = cpu_to_be32(control);
  61
  62    barrier();
  63
  64    outl(cpu_to_be32((uint32_t)&access), BIOS_CFG_DMA_ADDR_LOW);
  65
  66    while (be32_to_cpu(access.control) & ~FW_CFG_DMA_CTL_ERROR) {
  67        barrier();
  68    }
  69}
  70
  71static __attribute__((unused))
  72void bios_cfg_read_entry(void *buf, uint16_t entry, uint32_t len,
  73                         uint32_t version)
  74{
  75    if (version & FW_CFG_VERSION_DMA) {
  76        bios_cfg_read_entry_dma(buf, entry, len);
  77    } else {
  78        bios_cfg_read_entry_io(buf, entry, len);
  79    }
  80}
  81
  82static __attribute__((unused))
  83uint32_t bios_cfg_version(void)
  84{
  85    uint32_t version;
  86
  87    bios_cfg_read_entry_io(&version, FW_CFG_ID, sizeof(version));
  88
  89    return version;
  90}
  91
  92#endif /* OPTROM_FW_CFG_H */
  93