From owner-svn-soc-all@FreeBSD.ORG Tue Jul 16 14:51:06 2013 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 7C56B556 for ; Tue, 16 Jul 2013 14:51:06 +0000 (UTC) (envelope-from zcore@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) by mx1.freebsd.org (Postfix) with ESMTP id 5F3C6B8E for ; Tue, 16 Jul 2013 14:51:06 +0000 (UTC) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6GEp6Wi050695 for ; Tue, 16 Jul 2013 14:51:06 GMT (envelope-from zcore@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.7/8.14.6/Submit) id r6GEp6V5050689 for svn-soc-all@FreeBSD.org; Tue, 16 Jul 2013 14:51:06 GMT (envelope-from zcore@FreeBSD.org) Date: Tue, 16 Jul 2013 14:51:06 GMT Message-Id: <201307161451.r6GEp6V5050689@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to zcore@FreeBSD.org using -f From: zcore@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r254844 - soc2013/zcore/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Jul 2013 14:51:06 -0000 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 * 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); }