socsvn commit: r254844 - soc2013/zcore/head/usr.sbin/bhyve
zcore at FreeBSD.org
zcore at FreeBSD.org
Tue Jul 16 14:51:06 UTC 2013
Author: zcore
Date: Tue Jul 16 14:51:06 2013
New Revision: 254844
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=254844
Log:
use block_if and add ahci port
Modified:
soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c
Modified: soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c
==============================================================================
--- soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c Tue Jul 16 13:56:17 2013 (r254843)
+++ soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c Tue Jul 16 14:51:06 2013 (r254844)
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2011 NetApp, Inc.
+ * Copyright (c) 2013 ZCORE <zcore at freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -50,8 +50,7 @@
#include "bhyverun.h"
#include "pci_emul.h"
#include "ahci.h"
-
-#define AHCI_REGSZ (AHCI_OFFSET+6*AHCI_STEP)
+#include "block_if.h"
/*
* Debug printf
@@ -63,20 +62,57 @@
/*
* Per-device softc
*/
+struct ahci_port {
+ uint32_t clb;
+ uint32_t clbu;
+ uint32_t fb;
+ uint32_t fbu;
+ uint32_t is;
+ uint32_t ie;
+ uint32_t cmd;
+ uint32_t unused0;
+ uint32_t tfd;
+ uint32_t sig;
+ uint32_t ssts;
+ uint32_t sctl;
+ uint32_t serr;
+ uint32_t sact;
+ uint32_t ci;
+ uint32_t sntf;
+ uint32_t fbs;
+};
+
struct pci_ahci_softc {
struct pci_devinst *asc_pi;
- int asc_fd;
- int vbsc_lastq;
+ struct blockif_ctxt *bctx;
+ pthread_mutex_t mtx;
+ int ports;
+ int vbsc_lastq;
+ uint32_t cap;
+ uint32_t ghc;
+ uint32_t is;
+ uint32_t pi;
+ uint32_t vs;
+ uint32_t ccc_ctl;
+ uint32_t ccc_pts;
+ uint32_t em_loc;
+ uint32_t em_ctl;
+ uint32_t cap2;
+ uint32_t bohc;
+ struct ahci_port port[AHCI_MAX_PORTS];
};
+static void
+pci_ahci_ioreq_init(struct pci_ahci_softc *sc)
+{
+}
+
static int
pci_ahci_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
{
- struct stat sbuf;
struct pci_ahci_softc *sc;
- off_t size;
- int fd;
- int sectsz;
+ char bident[sizeof("XX:X")];
+ struct blockif_ctxt *bctxt;
if (opts == NULL) {
printf("pci_ahci: backing device required\n");
@@ -84,44 +120,43 @@
}
/*
- * The supplied backing file has to exist
+ * Attempt to open the backing image. Use the PCI slot/func
+ * for the identifier string since that uniquely identifies
+ * a storage device.
*/
- fd = open(opts, O_RDWR);
- if (fd < 0) {
- perror("Could not open backing file");
- return (1);
- }
+ snprintf(bident, sizeof(bident), "%d:%d", pi->pi_slot, pi->pi_func);
- if (fstat(fd, &sbuf) < 0) {
- perror("Could not stat backing file");
- close(fd);
+ bctxt = blockif_open(opts, bident);
+ if (bctxt == NULL)
return (1);
- }
-
- /*
- * Deal with raw devices
- */
- size = sbuf.st_size;
- sectsz = DEV_BSIZE;
- if (S_ISCHR(sbuf.st_mode)) {
- if (ioctl(fd, DIOCGMEDIASIZE, &size) < 0 ||
- ioctl(fd, DIOCGSECTORSIZE, §sz)) {
- perror("Could not fetch dev blk/sector size");
- close(fd);
- return (1);
- }
- assert(size != 0);
- assert(sectsz != 0);
- }
sc = malloc(sizeof(struct pci_ahci_softc));
memset(sc, 0, sizeof(struct pci_ahci_softc));
pi->pi_arg = sc;
sc->asc_pi = pi;
- sc->asc_fd = fd;
+
+ /*
+ * Allocate blockif request structures and add them
+ * to the free list
+ */
+ sc->bctx = bctxt;
+ pci_ahci_ioreq_init(sc);
+
+ pthread_mutex_init(&sc->mtx, NULL);
/* Intel Cougar Point AHCI */
+ sc->ports = 6;
+ sc->cap = AHCI_CAP_64BIT | AHCI_CAP_SNCQ | AHCI_CAP_SSNTF |
+ AHCI_CAP_SMPS | AHCI_CAP_SSS | AHCI_CAP_SALP |
+ AHCI_CAP_SAL | AHCI_CAP_SCLO | (0x3 << AHCI_CAP_ISS_SHIFT)|
+ AHCI_CAP_PMD | AHCI_CAP_SSC | AHCI_CAP_PSC |
+ (0x1f << AHCI_CAP_NCS_SHIFT) | AHCI_CAP_EMS |
+ AHCI_CAP_SXS | (sc->ports - 1);
+ sc->pi = (1 << sc->ports) - 1;
+ sc->vs = 0x10300;
+ sc->cap2 = AHCI_CAP2_APST;
+
pci_set_cfgdata16(pi, PCIR_DEVICE, 0x1c03);
pci_set_cfgdata16(pi, PCIR_VENDOR, 0x8086);
pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_STORAGE);
@@ -130,58 +165,135 @@
pci_emul_add_msicap(pi, 1);
- pci_emul_alloc_bar(pi, 5, PCIBAR_IO, AHCI_REGSZ);
+ pci_emul_alloc_bar(pi, 5, PCIBAR_IO, AHCI_OFFSET+sc->ports*AHCI_STEP);
return (0);
}
static void
-pci_ahci_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
- int baridx, uint64_t offset, int size, uint64_t value)
+pci_ahci_port_write(struct pci_ahci_softc *sc, uint64_t offset, uint64_t value)
{
-
- assert(baridx == 5);
+ int port = (offset - AHCI_OFFSET) / AHCI_STEP;
+ offset = (offset - AHCI_OFFSET) % AHCI_STEP;
switch (offset) {
+ case AHCI_P_CLB:
+ break;
default:
- DPRINTF(("pci_ahci: unknown i/o write offset %ld\n\r", offset));
+ DPRINTF(("pci_ahci_port %d: unknown i/o write offset %ld\n\r",
+ port, offset));
value = 0;
break;
}
}
-uint64_t
-pci_ahci_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
- int baridx, uint64_t offset, int size)
+static void
+pci_ahci_host_write(struct pci_ahci_softc *sc, uint64_t offset, uint64_t value)
{
- uint32_t value;
+ switch (offset) {
+ case AHCI_CAP:
+ case AHCI_PI:
+ case AHCI_VS:
+ case AHCI_CAP2:
+ WPRINTF(("pci_ahci_host: read only registers: %ld\n", offset));
+ break;
+ default:
+ DPRINTF(("pci_ahci_host: unknown i/o write offset %ld\n\r", offset));
+ break;
+ }
+}
+
+static void
+pci_ahci_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
+ int baridx, uint64_t offset, int size, uint64_t value)
+{
+ struct pci_ahci_softc *sc = pi->pi_arg;
assert(baridx == 5);
+ assert(size == 4);
+
+ pthread_mutex_lock(&sc->mtx);
+
+ if (offset < AHCI_OFFSET)
+ pci_ahci_host_write(sc, offset, value);
+ else if (offset < AHCI_OFFSET + sc->ports * AHCI_STEP)
+ pci_ahci_port_write(sc, offset, value);
+ else
+ DPRINTF(("pci_ahci: unknown i/o write offset %ld\n\r", offset));
+
+ pthread_mutex_unlock(&sc->mtx);
+}
+
+static uint64_t
+pci_ahci_host_read(struct pci_ahci_softc *sc, uint64_t offset)
+{
+ uint32_t value;
switch (offset) {
case AHCI_CAP:
- assert(size == 4);
- value = AHCI_CAP_64BIT | AHCI_CAP_SNCQ | AHCI_CAP_SSNTF |
- AHCI_CAP_SMPS | AHCI_CAP_SSS | AHCI_CAP_SALP |
- AHCI_CAP_SAL | AHCI_CAP_SCLO | (0x3 << AHCI_CAP_ISS_SHIFT)|
- AHCI_CAP_PMD | AHCI_CAP_SSC | AHCI_CAP_PSC |
- (0x1f << AHCI_CAP_NCS_SHIFT) | AHCI_CAP_EMS |
- AHCI_CAP_SXS | 0x5;
+ value = sc->cap;
break;
+ case AHCI_GHC:
+ value = sc->ghc;
+ case AHCI_IS:
+ value = sc->is;
+ case AHCI_PI:
+ value = sc->pi;
case AHCI_VS:
- assert(size == 4);
- value = 0x10300;
+ value = sc->vs;
break;
case AHCI_CAP2:
- assert(size == 4);
- value = AHCI_CAP2_APST;
+ value = sc->cap2;
break;
default:
- DPRINTF(("pci_ahci: unknown i/o read offset %ld\n\r", offset));
+ DPRINTF(("pci_ahci_host: unknown i/o read offset %ld\n\r", offset));
+ value = 0;
+ break;
+ }
+ return (value);
+}
+
+static uint64_t
+pci_ahci_port_read(struct pci_ahci_softc *sc, uint64_t offset)
+{
+ uint32_t value;
+ int port = (offset - AHCI_OFFSET) / AHCI_STEP;
+ offset = (offset - AHCI_OFFSET) % AHCI_STEP;
+
+ switch (offset) {
+ case AHCI_P_CLB:
+ break;
+ default:
+ DPRINTF(("pci_ahci_port%d: unknown i/o read offset %ld\n\r",
+ port, offset));
value = 0;
break;
}
+ return value;
+}
+
+static uint64_t
+pci_ahci_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
+ int baridx, uint64_t offset, int size)
+{
+ uint32_t value;
+ struct pci_ahci_softc *sc = pi->pi_arg;
+
+ assert(baridx == 5);
+ assert(size == 4);
+
+ pthread_mutex_lock(&sc->mtx);
+
+ if (offset < AHCI_OFFSET)
+ value = pci_ahci_host_read(sc, offset);
+ else if (offset < AHCI_OFFSET + sc->ports * AHCI_STEP)
+ value = pci_ahci_port_read(sc, offset);
+ else
+ DPRINTF(("pci_ahci: unknown i/o read offset %ld\n\r", offset));
+
+ pthread_mutex_unlock(&sc->mtx);
+
return (value);
}
More information about the svn-soc-all
mailing list