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, &sectsz)) {
-			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