diff options
author | RajithaY <rajithax.yerrumsetty@intel.com> | 2017-04-25 03:31:15 -0700 |
---|---|---|
committer | Rajitha Yerrumchetty <rajithax.yerrumsetty@intel.com> | 2017-05-22 06:48:08 +0000 |
commit | bb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch) | |
tree | ca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/roms/seabios/src/hw/pvscsi.c | |
parent | a14b48d18a9ed03ec191cf16b162206998a895ce (diff) |
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to
kvmfornfv repo and make use of the updated latest qemu for the
execution of all testcase
Change-Id: I1280af507a857675c7f81d30c95255635667bdd7
Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/roms/seabios/src/hw/pvscsi.c')
-rw-r--r-- | qemu/roms/seabios/src/hw/pvscsi.c | 338 |
1 files changed, 0 insertions, 338 deletions
diff --git a/qemu/roms/seabios/src/hw/pvscsi.c b/qemu/roms/seabios/src/hw/pvscsi.c deleted file mode 100644 index fa20efef7..000000000 --- a/qemu/roms/seabios/src/hw/pvscsi.c +++ /dev/null @@ -1,338 +0,0 @@ -// QEMU VMWARE Paravirtualized SCSI boot support. -// -// Copyright (c) 2013 Ravello Systems LTD (http://ravellosystems.com) -// -// Authors: -// Evgeny Budilovsky <evgeny.budilovsky@ravellosystems.com> -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "block.h" // struct drive_s -#include "blockcmd.h" // scsi_drive_setup -#include "config.h" // CONFIG_* -#include "malloc.h" // free -#include "memmap.h" // PAGE_SHIFT, virt_to_phys -#include "output.h" // dprintf -#include "pci.h" // foreachpci -#include "pci_ids.h" // PCI_DEVICE_ID_VMWARE_PVSCSI -#include "pci_regs.h" // PCI_VENDOR_ID -#include "pvscsi.h" // pvscsi_setup -#include "std/disk.h" // DISK_RET_SUCCESS -#include "string.h" // memset -#include "util.h" // usleep -#include "x86.h" // writel - -#define MASK(n) ((1 << (n)) - 1) - -#define SIMPLE_QUEUE_TAG 0x20 - -#define PVSCSI_INTR_CMPL_0 (1 << 0) -#define PVSCSI_INTR_CMPL_1 (1 << 1) -#define PVSCSI_INTR_CMPL_MASK MASK(2) - -#define PVSCSI_INTR_MSG_0 (1 << 2) -#define PVSCSI_INTR_MSG_1 (1 << 3) -#define PVSCSI_INTR_MSG_MASK (MASK(2) << 2) -#define PVSCSI_INTR_ALL_SUPPORTED MASK(4) - -#define PVSCSI_FLAG_CMD_WITH_SG_LIST (1 << 0) -#define PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB (1 << 1) -#define PVSCSI_FLAG_CMD_DIR_NONE (1 << 2) -#define PVSCSI_FLAG_CMD_DIR_TOHOST (1 << 3) -#define PVSCSI_FLAG_CMD_DIR_TODEVICE (1 << 4) - -enum PVSCSIRegOffset { - PVSCSI_REG_OFFSET_COMMAND = 0x0, - PVSCSI_REG_OFFSET_COMMAND_DATA = 0x4, - PVSCSI_REG_OFFSET_COMMAND_STATUS = 0x8, - PVSCSI_REG_OFFSET_LAST_STS_0 = 0x100, - PVSCSI_REG_OFFSET_LAST_STS_1 = 0x104, - PVSCSI_REG_OFFSET_LAST_STS_2 = 0x108, - PVSCSI_REG_OFFSET_LAST_STS_3 = 0x10c, - PVSCSI_REG_OFFSET_INTR_STATUS = 0x100c, - PVSCSI_REG_OFFSET_INTR_MASK = 0x2010, - PVSCSI_REG_OFFSET_KICK_NON_RW_IO = 0x3014, - PVSCSI_REG_OFFSET_DEBUG = 0x3018, - PVSCSI_REG_OFFSET_KICK_RW_IO = 0x4018, -}; - -enum PVSCSICommands { - PVSCSI_CMD_FIRST = 0, - PVSCSI_CMD_ADAPTER_RESET = 1, - PVSCSI_CMD_ISSUE_SCSI = 2, - PVSCSI_CMD_SETUP_RINGS = 3, - PVSCSI_CMD_RESET_BUS = 4, - PVSCSI_CMD_RESET_DEVICE = 5, - PVSCSI_CMD_ABORT_CMD = 6, - PVSCSI_CMD_CONFIG = 7, - PVSCSI_CMD_SETUP_MSG_RING = 8, - PVSCSI_CMD_DEVICE_UNPLUG = 9, - PVSCSI_CMD_LAST = 10 -}; - -#define PVSCSI_SETUP_RINGS_MAX_NUM_PAGES 32 -struct PVSCSICmdDescSetupRings { - u32 reqRingNumPages; - u32 cmpRingNumPages; - u64 ringsStatePPN; - u64 reqRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES]; - u64 cmpRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES]; -} PACKED; - -struct PVSCSIRingCmpDesc { - u64 context; - u64 dataLen; - u32 senseLen; - u16 hostStatus; - u16 scsiStatus; - u32 pad[2]; -} PACKED; - -struct PVSCSIRingsState { - u32 reqProdIdx; - u32 reqConsIdx; - u32 reqNumEntriesLog2; - - u32 cmpProdIdx; - u32 cmpConsIdx; - u32 cmpNumEntriesLog2; - - u8 pad[104]; - - u32 msgProdIdx; - u32 msgConsIdx; - u32 msgNumEntriesLog2; -} PACKED; - -struct PVSCSIRingReqDesc { - u64 context; - u64 dataAddr; - u64 dataLen; - u64 senseAddr; - u32 senseLen; - u32 flags; - u8 cdb[16]; - u8 cdbLen; - u8 lun[8]; - u8 tag; - u8 bus; - u8 target; - u8 vcpuHint; - u8 unused[59]; -} PACKED; - -struct pvscsi_ring_dsc_s { - struct PVSCSIRingsState *ring_state; - struct PVSCSIRingReqDesc *ring_reqs; - struct PVSCSIRingCmpDesc *ring_cmps; -}; - -struct pvscsi_lun_s { - struct drive_s drive; - void *iobase; - u8 target; - u8 lun; - struct pvscsi_ring_dsc_s *ring_dsc; -}; - -static void -pvscsi_write_cmd_desc(void *iobase, u32 cmd, const void *desc, size_t len) -{ - const u32 *ptr = desc; - size_t i; - - len /= sizeof(*ptr); - writel(iobase + PVSCSI_REG_OFFSET_COMMAND, cmd); - for (i = 0; i < len; i++) - writel(iobase + PVSCSI_REG_OFFSET_COMMAND_DATA, ptr[i]); -} - -static void -pvscsi_kick_rw_io(void *iobase) -{ - writel(iobase + PVSCSI_REG_OFFSET_KICK_RW_IO, 0); -} - -static void -pvscsi_wait_intr_cmpl(void *iobase) -{ - while (!(readl(iobase + PVSCSI_REG_OFFSET_INTR_STATUS) & PVSCSI_INTR_CMPL_MASK)) - usleep(5); - writel(iobase + PVSCSI_REG_OFFSET_INTR_STATUS, PVSCSI_INTR_CMPL_MASK); -} - -static void -pvscsi_init_rings(void *iobase, struct pvscsi_ring_dsc_s **ring_dsc) -{ - struct PVSCSICmdDescSetupRings cmd = {0,}; - - struct pvscsi_ring_dsc_s *dsc = memalign_low(sizeof(*dsc), PAGE_SIZE); - if (!dsc) { - warn_noalloc(); - return; - } - - dsc->ring_state = - (struct PVSCSIRingsState *)memalign_low(PAGE_SIZE, PAGE_SIZE); - dsc->ring_reqs = - (struct PVSCSIRingReqDesc *)memalign_low(PAGE_SIZE, PAGE_SIZE); - dsc->ring_cmps = - (struct PVSCSIRingCmpDesc *)memalign_low(PAGE_SIZE, PAGE_SIZE); - if (!dsc->ring_state || !dsc->ring_reqs || !dsc->ring_cmps) { - warn_noalloc(); - return; - } - memset(dsc->ring_state, 0, PAGE_SIZE); - memset(dsc->ring_reqs, 0, PAGE_SIZE); - memset(dsc->ring_cmps, 0, PAGE_SIZE); - - cmd.reqRingNumPages = 1; - cmd.cmpRingNumPages = 1; - cmd.ringsStatePPN = virt_to_phys(dsc->ring_state) >> PAGE_SHIFT; - cmd.reqRingPPNs[0] = virt_to_phys(dsc->ring_reqs) >> PAGE_SHIFT; - cmd.cmpRingPPNs[0] = virt_to_phys(dsc->ring_cmps) >> PAGE_SHIFT; - - pvscsi_write_cmd_desc(iobase, PVSCSI_CMD_SETUP_RINGS, - &cmd, sizeof(cmd)); - *ring_dsc = dsc; -} - -static u32 -pvscsi_get_rsp(struct PVSCSIRingsState *s, - struct PVSCSIRingCmpDesc *rsp) -{ - u32 status = rsp->hostStatus; - s->cmpConsIdx = s->cmpConsIdx + 1; - return status; -} - -int -pvscsi_process_op(struct disk_op_s *op) -{ - if (!CONFIG_PVSCSI) - return DISK_RET_EBADTRACK; - struct pvscsi_lun_s *plun = - container_of(op->drive_gf, struct pvscsi_lun_s, drive); - struct pvscsi_ring_dsc_s *ring_dsc = plun->ring_dsc; - struct PVSCSIRingsState *s = ring_dsc->ring_state; - u32 req_entries = s->reqNumEntriesLog2; - u32 cmp_entries = s->cmpNumEntriesLog2; - struct PVSCSIRingReqDesc *req; - struct PVSCSIRingCmpDesc *rsp; - u32 status; - - if (s->reqProdIdx - s->cmpConsIdx >= 1 << req_entries) { - dprintf(1, "pvscsi: ring full: reqProdIdx=%d cmpConsIdx=%d\n", - s->reqProdIdx, s->cmpConsIdx); - return DISK_RET_EBADTRACK; - } - - req = ring_dsc->ring_reqs + (s->reqProdIdx & MASK(req_entries)); - int blocksize = scsi_fill_cmd(op, req->cdb, 16); - if (blocksize < 0) - return default_process_op(op); - req->bus = 0; - req->target = plun->target; - memset(req->lun, 0, sizeof(req->lun)); - req->lun[1] = plun->lun; - req->senseLen = 0; - req->senseAddr = 0; - req->cdbLen = 16; - req->vcpuHint = 0; - req->tag = SIMPLE_QUEUE_TAG; - req->flags = scsi_is_read(op) ? - PVSCSI_FLAG_CMD_DIR_TOHOST : PVSCSI_FLAG_CMD_DIR_TODEVICE; - req->dataLen = op->count * blocksize; - req->dataAddr = (u32)op->buf_fl; - s->reqProdIdx = s->reqProdIdx + 1; - - pvscsi_kick_rw_io(plun->iobase); - pvscsi_wait_intr_cmpl(plun->iobase); - - rsp = ring_dsc->ring_cmps + (s->cmpConsIdx & MASK(cmp_entries)); - status = pvscsi_get_rsp(s, rsp); - - return status == 0 ? DISK_RET_SUCCESS : DISK_RET_EBADTRACK; -} - -static int -pvscsi_add_lun(struct pci_device *pci, void *iobase, - struct pvscsi_ring_dsc_s *ring_dsc, u8 target, u8 lun) -{ - struct pvscsi_lun_s *plun = malloc_fseg(sizeof(*plun)); - if (!plun) { - warn_noalloc(); - return -1; - } - memset(plun, 0, sizeof(*plun)); - plun->drive.type = DTYPE_PVSCSI; - plun->drive.cntl_id = pci->bdf; - plun->target = target; - plun->lun = lun; - plun->iobase = iobase; - plun->ring_dsc = ring_dsc; - - char *name = znprintf(16, "pvscsi %02x:%02x.%x %d:%d", - pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf), - pci_bdf_to_fn(pci->bdf), target, lun); - int prio = bootprio_find_scsi_device(pci, target, lun); - int ret = scsi_drive_setup(&plun->drive, name, prio); - free(name); - if (ret) - goto fail; - return 0; - -fail: - free(plun); - return -1; -} - -static void -pvscsi_scan_target(struct pci_device *pci, void *iobase, - struct pvscsi_ring_dsc_s *ring_dsc, u8 target) -{ - /* TODO: send REPORT LUNS. For now, only LUN 0 is recognized. */ - pvscsi_add_lun(pci, iobase, ring_dsc, target, 0); -} - -static void -init_pvscsi(struct pci_device *pci) -{ - struct pvscsi_ring_dsc_s *ring_dsc = NULL; - int i; - u16 bdf = pci->bdf; - void *iobase = (void*)(pci_config_readl(pci->bdf, PCI_BASE_ADDRESS_0) - & PCI_BASE_ADDRESS_MEM_MASK); - - pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER); - - dprintf(1, "found pvscsi at %02x:%02x.%x, io @ %p\n", - pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), - pci_bdf_to_fn(bdf), iobase); - - pvscsi_write_cmd_desc(iobase, PVSCSI_CMD_ADAPTER_RESET, NULL, 0); - - pvscsi_init_rings(iobase, &ring_dsc); - for (i = 0; i < 7; i++) - pvscsi_scan_target(pci, iobase, ring_dsc, i); - - return; -} - -void -pvscsi_setup(void) -{ - ASSERT32FLAT(); - if (! CONFIG_PVSCSI) - return; - - dprintf(3, "init pvscsi\n"); - - struct pci_device *pci; - foreachpci(pci) { - if (pci->vendor != PCI_VENDOR_ID_VMWARE - || pci->device != PCI_DEVICE_ID_VMWARE_PVSCSI) - continue; - init_pvscsi(pci); - } -} |