Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 20 Jul 2013 08:50:06 GMT
From:      zcore@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r254959 - soc2013/zcore/head/usr.sbin/bhyve
Message-ID:  <201307200850.r6K8o6H0069562@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: zcore
Date: Sat Jul 20 08:50:06 2013
New Revision: 254959
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=254959

Log:
  fix pci bar type and add more register i/o

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	Sat Jul 20 07:58:03 2013	(r254958)
+++ soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c	Sat Jul 20 08:50:06 2013	(r254959)
@@ -60,10 +60,18 @@
 #define DPRINTF(params) dprintf params
 #define WPRINTF(params) printf params
 
-/*
- * Per-device softc
- */
+struct ahci_ioreq {
+	struct blockif_req io_req;
+	struct ahci_port *io_pr;
+	uint32_t io_genid;
+	STAILQ_ENTRY(ahci_ioreq) io_list;
+	int io_didx;
+	uint8_t *io_status;
+};
+
 struct ahci_port {
+	struct blockif_ctxt *bctx;
+	struct pci_ahci_softc *pr_sc;
 	uint32_t clb;
 	uint32_t clbu;
 	uint32_t fb;
@@ -81,11 +89,26 @@
 	uint32_t ci;
 	uint32_t sntf;
 	uint32_t fbs;
+
+	/*
+	 * i/o request info
+	 */
+	struct ahci_ioreq *ioreq;
+	int ioqsz;
+	int iofree;
+	STAILQ_HEAD(ahci_fhead, ahci_ioreq) iofhd;
+};
+
+struct ahci_cmd_hdr {
+	uint16_t flags;
+	uint16_t prdtl;
+	uint32_t prdbc;
+	uint64_t ctba;
+	uint32_t reserved[4];
 };
 
 struct pci_ahci_softc {
 	struct pci_devinst *asc_pi;
-	struct blockif_ctxt *bctx;
 	pthread_mutex_t	mtx;
 	int ports;
 	int vbsc_lastq;
@@ -103,14 +126,64 @@
 	struct ahci_port port[AHCI_MAX_PORTS];
 };
 
+/*
+ * blockif callback routine - this runs in the context of the blockif
+ * i/o thread, so the mutex needs to be acquired.
+ */
 static void
-pci_ahci_ioreq_init(struct pci_ahci_softc *sc)
+pci_ahci_ioreq_cb(struct blockif_req *br, int err)
 {
+	struct ahci_port *pr;
+	struct pci_ahci_softc *sc;
+	struct ahci_ioreq *vio;
+
+	vio = br->br_param;
+	pr = vio->io_pr;
+	sc = pr->pr_sc;
+
+	DPRINTF(("ahci_ioreq_cb %d\n", err));
+	pthread_mutex_lock(&sc->mtx);
+
+	/* TODO */
+
+	/*
+	 * Move the blockif request back to the free list
+	 */
+	STAILQ_INSERT_TAIL(&pr->iofhd, vio, io_list);
+	pr->iofree++;
+
+	pthread_mutex_unlock(&sc->mtx);
+	DPRINTF(("%s exit\n", __func__));
+
+}
+
+static void
+pci_ahci_ioreq_init(struct ahci_port *pr)
+{
+	struct ahci_ioreq *vr;
+	int i;
+
+	pr->ioqsz = blockif_queuesz(pr->bctx);
+	pr->ioreq = calloc(pr->ioqsz, sizeof(struct ahci_ioreq));
+	STAILQ_INIT(&pr->iofhd);
+
+	/*
+	 * Add all i/o request entries to the free queue
+	 */
+	for (i = 0; i < pr->ioqsz; i++) {
+		vr = &pr->ioreq[i];
+		vr->io_pr = pr;
+		vr->io_req.br_callback = pci_ahci_ioreq_cb;
+		vr->io_req.br_param = vr;
+		STAILQ_INSERT_TAIL(&pr->iofhd, vr, io_list);
+		pr->iofree++;
+	}
 }
 
 static int
 pci_ahci_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
 {
+	int i;
 	struct pci_ahci_softc *sc;
 	char bident[sizeof("XX:X")];
 	struct blockif_ctxt *bctxt;
@@ -140,12 +213,14 @@
 	pi->pi_arg = sc;
 	sc->asc_pi = pi;
 
+	for (i = 0; i < AHCI_MAX_PORTS; i++)
+		sc->port[i].pr_sc = sc;
 	/*
 	 * Allocate blockif request structures and add them
 	 * to the free list
 	 */
-	sc->bctx = bctxt;
-	pci_ahci_ioreq_init(sc);
+	sc->port[0].bctx = bctxt;
+	pci_ahci_ioreq_init(&sc->port[0]);
 
 	pthread_mutex_init(&sc->mtx, NULL);
 
@@ -169,7 +244,7 @@
 
 	pci_emul_add_msicap(pi, 1);
 	
-	pci_emul_alloc_bar(pi, 5, PCIBAR_IO, AHCI_OFFSET+sc->ports*AHCI_STEP);
+	pci_emul_alloc_bar(pi, 5, PCIBAR_MEM32, AHCI_OFFSET+sc->ports*AHCI_STEP);
 
 	return (0);
 }
@@ -179,14 +254,51 @@
 {
 	int port = (offset - AHCI_OFFSET) / AHCI_STEP;
 	offset = (offset - AHCI_OFFSET) % AHCI_STEP;
+	struct ahci_port *p = &sc->port[port];
 
+	DPRINTF(("pci_ahci_port %d: write offset 0x%lx value 0x%lx\n\r",
+		port, offset, value));
 	switch (offset) {
 	case AHCI_P_CLB:
+		p->clb = value;
+		break;
+	case AHCI_P_CLBU:
+		p->clbu = value;
+		break;
+	case AHCI_P_FB:
+		p->fb = value;
+		break;
+	case AHCI_P_FBU:
+		p->fbu = value;
 		break;
+	case AHCI_P_IS:
+		p->is &= ~value;
+		break;
+	case AHCI_P_IE:
+		p->ie = value & 0xfdc000ff;
+		break;
+	case AHCI_P_CMD:
+		/* TODO */
+		break;
+	case AHCI_P_TFD:
+	case AHCI_P_SIG:
+	case AHCI_P_SSTS:
+		WPRINTF(("pci_ahci_port: read only registers 0x%lx\n", offset));
+		break;
+	case AHCI_P_SCTL:
+		/* TODO */
+		break;
+	case AHCI_P_SERR:
+		p->serr &= ~value;
+		break;
+	case AHCI_P_SACT:
+		break;
+	case AHCI_P_CI:
+		/* TODO */
+		break;
+	case AHCI_P_SNTF:
+	case AHCI_P_FBS:
 	default:
-		DPRINTF(("pci_ahci_port %d: unknown i/o write offset %ld\n\r",
-			port, offset));
-		value = 0;
 		break;
 	}
 }
@@ -194,15 +306,17 @@
 static void
 pci_ahci_host_write(struct pci_ahci_softc *sc, uint64_t offset, uint64_t value)
 {
+	DPRINTF(("pci_ahci_host: write offset 0x%lx value 0x%lx\n\r",
+		offset, 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));
+		WPRINTF(("pci_ahci_host: read only registers 0x%lx\n", offset));
 		break;
 	default:
-		DPRINTF(("pci_ahci_host: unknown i/o write offset %ld\n\r", offset));
 		break;
 	}
 }
@@ -223,7 +337,7 @@
 	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));
+		DPRINTF(("pci_ahci: unknown i/o write offset 0x%lx\n\r", offset));
 
 	pthread_mutex_unlock(&sc->mtx);
 }
@@ -251,10 +365,12 @@
 		break;
 	}
 	default:
-		DPRINTF(("pci_ahci_host: unknown i/o read offset %ld\n\r", offset));
 		value = 0;
 		break;
 	}
+	DPRINTF(("pci_ahci_host: read offset 0x%lx value 0x%x\n\r",
+		offset, value));
+
 	return (value);
 }
 
@@ -274,6 +390,7 @@
 	case AHCI_P_IE:
 	case AHCI_P_CMD:
 	case AHCI_P_TFD:
+		/* TODO */
 	case AHCI_P_SIG:
 	case AHCI_P_SSTS:
 	case AHCI_P_SCTL:
@@ -289,11 +406,11 @@
 		break;
 	}
 	default:
-		DPRINTF(("pci_ahci_port%d: unknown i/o read offset %ld\n\r",
-			port, offset));
 		value = 0;
 		break;
 	}
+	DPRINTF(("pci_ahci_port %d: read offset 0x%lx value 0x%x\n\r",
+		port, offset, value));
 
 	return value;
 }
@@ -315,7 +432,7 @@
 	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));
+		DPRINTF(("pci_ahci: unknown i/o read offset 0x%lx\n\r", offset));
 
 	pthread_mutex_unlock(&sc->mtx);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201307200850.r6K8o6H0069562>