From owner-svn-src-stable-12@freebsd.org Tue Aug 18 03:40:10 2020 Return-Path: Delivered-To: svn-src-stable-12@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 5D2B23AC61F; Tue, 18 Aug 2020 03:40:10 +0000 (UTC) (envelope-from grehan@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4BVxWG0ZtTz4dlT; Tue, 18 Aug 2020 03:40:10 +0000 (UTC) (envelope-from grehan@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id EB389B987; Tue, 18 Aug 2020 03:40:09 +0000 (UTC) (envelope-from grehan@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 07I3e9Eh005664; Tue, 18 Aug 2020 03:40:09 GMT (envelope-from grehan@FreeBSD.org) Received: (from grehan@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 07I3e9t0005662; Tue, 18 Aug 2020 03:40:09 GMT (envelope-from grehan@FreeBSD.org) Message-Id: <202008180340.07I3e9t0005662@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: grehan set sender to grehan@FreeBSD.org using -f From: Peter Grehan Date: Tue, 18 Aug 2020 03:40:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r364334 - in stable/12: sys/sys usr.sbin/bhyve X-SVN-Group: stable-12 X-SVN-Commit-Author: grehan X-SVN-Commit-Paths: in stable/12: sys/sys usr.sbin/bhyve X-SVN-Commit-Revision: 364334 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-12@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for only the 12-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Aug 2020 03:40:10 -0000 Author: grehan Date: Tue Aug 18 03:40:09 2020 New Revision: 364334 URL: https://svnweb.freebsd.org/changeset/base/364334 Log: MFC 363596, 363719, 363733 363596 Support the setting of additional AHCI controller parameters. 363719 Definition for the 'removable media flag' from word 0 in the Identify page. 363733 Replace magic numbers in Identify page register 0 with ATA definitions. Relnotes: yes Modified: stable/12/sys/sys/ata.h stable/12/usr.sbin/bhyve/bhyve.8 stable/12/usr.sbin/bhyve/pci_ahci.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/sys/ata.h ============================================================================== --- stable/12/sys/sys/ata.h Tue Aug 18 02:42:51 2020 (r364333) +++ stable/12/sys/sys/ata.h Tue Aug 18 03:40:09 2020 (r364334) @@ -46,6 +46,7 @@ struct ata_params { #define ATA_ATAPI_TYPE_TAPE 0x0100 /* streaming tape */ #define ATA_ATAPI_TYPE_CDROM 0x0500 /* CD-ROM device */ #define ATA_ATAPI_TYPE_OPTICAL 0x0700 /* optical disk */ +#define ATA_ATAPI_REMOVABLE 0x0080 #define ATA_DRQ_MASK 0x0060 #define ATA_DRQ_SLOW 0x0000 /* cpu 3 ms delay */ #define ATA_DRQ_INTR 0x0020 /* interrupt 10 ms delay */ Modified: stable/12/usr.sbin/bhyve/bhyve.8 ============================================================================== --- stable/12/usr.sbin/bhyve/bhyve.8 Tue Aug 18 02:42:51 2020 (r364333) +++ stable/12/usr.sbin/bhyve/bhyve.8 Tue Aug 18 03:40:09 2020 (r364334) @@ -494,6 +494,27 @@ Sector size (defaults to blockif sector size). .It Li ser Serial number with maximum 20 characters. .El +.Pp +AHCI devices: +.Bl -tag -width 10n +.It Li nmrr +Nominal Media Rotation Rate, known as RPM. value 1 will indicate device as Solid State Disk. default value is 0, not report. +.It Li ser +Serial Number with maximum 20 characters. +.It Li rev +Revision Number with maximum 8 characters. +.It Li model +Model Number with maximum 40 characters. +.El +.Pp +HD Audio devices: +.Bl -tag -width 10n +.It Li play +Playback device, typically +.Ar /dev/dsp0 . +.It Li rec +Recording device, typically +.Ar /dev/dsp0 . .El .It Fl S Wire guest memory. Modified: stable/12/usr.sbin/bhyve/pci_ahci.c ============================================================================== --- stable/12/usr.sbin/bhyve/pci_ahci.c Tue Aug 18 02:42:51 2020 (r364333) +++ stable/12/usr.sbin/bhyve/pci_ahci.c Tue Aug 18 03:40:09 2020 (r364334) @@ -136,9 +136,9 @@ struct ahci_ioreq { struct ahci_port { struct blockif_ctxt *bctx; struct pci_ahci_softc *pr_sc; + struct ata_params ata_ident; uint8_t *cmd_lst; uint8_t *rfis; - char ident[AHCI_PORT_IDENT]; int port; int atapi; int reset; @@ -983,7 +983,50 @@ handle_identify(struct ahci_port *p, int slot, uint8_t ahci_write_fis_d2h(p, slot, cfis, (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); } else { - uint16_t buf[256]; + ahci_write_fis_piosetup(p); + write_prdt(p, slot, cfis, (void*)&p->ata_ident, sizeof(struct ata_params)); + ahci_write_fis_d2h(p, slot, cfis, ATA_S_DSC | ATA_S_READY); + } +} + +static void +ata_identify_init(struct ahci_port* p, int atapi) +{ + struct ata_params* ata_ident = &p->ata_ident; + + if (atapi) { + ata_ident->config = ATA_PROTO_ATAPI | ATA_ATAPI_TYPE_CDROM | + ATA_ATAPI_REMOVABLE | ATA_DRQ_FAST; + ata_ident->capabilities1 = ATA_SUPPORT_LBA | + ATA_SUPPORT_DMA; + ata_ident->capabilities2 = (1 << 14 | 1); + ata_ident->atavalid = ATA_FLAG_54_58 | ATA_FLAG_64_70; + ata_ident->obsolete62 = 0x3f; + ata_ident->mwdmamodes = 7; + if (p->xfermode & ATA_WDMA0) + ata_ident->mwdmamodes |= (1 << ((p->xfermode & 7) + 8)); + ata_ident->apiomodes = 3; + ata_ident->mwdmamin = 0x0078; + ata_ident->mwdmarec = 0x0078; + ata_ident->pioblind = 0x0078; + ata_ident->pioiordy = 0x0078; + ata_ident->satacapabilities = (ATA_SATA_GEN1 | ATA_SATA_GEN2 | ATA_SATA_GEN3); + ata_ident->satacapabilities2 = ((p->ssts & ATA_SS_SPD_MASK) >> 3); + ata_ident->satasupport = ATA_SUPPORT_NCQ_STREAM; + ata_ident->version_major = 0x3f0; + ata_ident->support.command1 = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_PACKET | + ATA_SUPPORT_RESET | ATA_SUPPORT_NOP); + ata_ident->support.command2 = (1 << 14); + ata_ident->support.extension = (1 << 14); + ata_ident->enabled.command1 = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_PACKET | + ATA_SUPPORT_RESET | ATA_SUPPORT_NOP); + ata_ident->enabled.extension = (1 << 14); + ata_ident->udmamodes = 0x7f; + if (p->xfermode & ATA_UDMA0) + ata_ident->udmamodes |= (1 << ((p->xfermode & 7) + 8)); + ata_ident->transport_major = 0x1020; + ata_ident->integrity = 0x00a5; + } else { uint64_t sectors; int sectsz, psectsz, psectoff, candelete, ro; uint16_t cyl; @@ -995,87 +1038,85 @@ handle_identify(struct ahci_port *p, int slot, uint8_t sectors = blockif_size(p->bctx) / sectsz; blockif_chs(p->bctx, &cyl, &heads, &sech); blockif_psectsz(p->bctx, &psectsz, &psectoff); - memset(buf, 0, sizeof(buf)); - buf[0] = 0x0040; - buf[1] = cyl; - buf[3] = heads; - buf[6] = sech; - ata_string((uint8_t *)(buf+10), p->ident, 20); - ata_string((uint8_t *)(buf+23), "001", 8); - ata_string((uint8_t *)(buf+27), "BHYVE SATA DISK", 40); - buf[47] = (0x8000 | 128); - buf[48] = 0; - buf[49] = (1 << 8 | 1 << 9 | 1 << 11); - buf[50] = (1 << 14); - buf[53] = (1 << 1 | 1 << 2); + ata_ident->config = ATA_DRQ_FAST; + ata_ident->cylinders = cyl; + ata_ident->heads = heads; + ata_ident->sectors = sech; + + ata_ident->sectors_intr = (0x8000 | 128); + ata_ident->tcg = 0; + + ata_ident->capabilities1 = ATA_SUPPORT_DMA | + ATA_SUPPORT_LBA | ATA_SUPPORT_IORDY; + ata_ident->capabilities2 = (1 << 14); + ata_ident->atavalid = ATA_FLAG_54_58 | + ATA_FLAG_64_70; if (p->mult_sectors) - buf[59] = (0x100 | p->mult_sectors); + ata_ident->multi = (ATA_MULTI_VALID | p->mult_sectors); if (sectors <= 0x0fffffff) { - buf[60] = sectors; - buf[61] = (sectors >> 16); + ata_ident->lba_size_1 = sectors; + ata_ident->lba_size_2 = (sectors >> 16); } else { - buf[60] = 0xffff; - buf[61] = 0x0fff; + ata_ident->lba_size_1 = 0xffff; + ata_ident->lba_size_2 = 0x0fff; } - buf[63] = 0x7; + ata_ident->mwdmamodes = 0x7; if (p->xfermode & ATA_WDMA0) - buf[63] |= (1 << ((p->xfermode & 7) + 8)); - buf[64] = 0x3; - buf[65] = 120; - buf[66] = 120; - buf[67] = 120; - buf[68] = 120; - buf[69] = 0; - buf[75] = 31; - buf[76] = (ATA_SATA_GEN1 | ATA_SATA_GEN2 | ATA_SATA_GEN3 | - ATA_SUPPORT_NCQ); - buf[77] = (ATA_SUPPORT_RCVSND_FPDMA_QUEUED | - (p->ssts & ATA_SS_SPD_MASK) >> 3); - buf[80] = 0x3f0; - buf[81] = 0x28; - buf[82] = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_WRITECACHE| - ATA_SUPPORT_LOOKAHEAD | ATA_SUPPORT_NOP); - buf[83] = (ATA_SUPPORT_ADDRESS48 | ATA_SUPPORT_FLUSHCACHE | - ATA_SUPPORT_FLUSHCACHE48 | 1 << 14); - buf[84] = (1 << 14); - buf[85] = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_WRITECACHE| - ATA_SUPPORT_LOOKAHEAD | ATA_SUPPORT_NOP); - buf[86] = (ATA_SUPPORT_ADDRESS48 | ATA_SUPPORT_FLUSHCACHE | - ATA_SUPPORT_FLUSHCACHE48 | 1 << 15); - buf[87] = (1 << 14); - buf[88] = 0x7f; + ata_ident->mwdmamodes |= (1 << ((p->xfermode & 7) + 8)); + ata_ident->apiomodes = 0x3; + ata_ident->mwdmamin = 0x0078; + ata_ident->mwdmarec = 0x0078; + ata_ident->pioblind = 0x0078; + ata_ident->pioiordy = 0x0078; + ata_ident->support3 = 0; + ata_ident->queue = 31; + ata_ident->satacapabilities = (ATA_SATA_GEN1 | ATA_SATA_GEN2 | ATA_SATA_GEN3 | + ATA_SUPPORT_NCQ); + ata_ident->satacapabilities2 = (ATA_SUPPORT_RCVSND_FPDMA_QUEUED | + (p->ssts & ATA_SS_SPD_MASK) >> 3); + ata_ident->version_major = 0x3f0; + ata_ident->version_minor = 0x28; + ata_ident->support.command1 = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_WRITECACHE | + ATA_SUPPORT_LOOKAHEAD | ATA_SUPPORT_NOP); + ata_ident->support.command2 = (ATA_SUPPORT_ADDRESS48 | ATA_SUPPORT_FLUSHCACHE | + ATA_SUPPORT_FLUSHCACHE48 | 1 << 14); + ata_ident->support.extension = (1 << 14); + ata_ident->enabled.command1 = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_WRITECACHE | + ATA_SUPPORT_LOOKAHEAD | ATA_SUPPORT_NOP); + ata_ident->enabled.command2 = (ATA_SUPPORT_ADDRESS48 | ATA_SUPPORT_FLUSHCACHE | + ATA_SUPPORT_FLUSHCACHE48 | 1 << 15); + ata_ident->enabled.extension = (1 << 14); + ata_ident->udmamodes = 0x7f; if (p->xfermode & ATA_UDMA0) - buf[88] |= (1 << ((p->xfermode & 7) + 8)); - buf[100] = sectors; - buf[101] = (sectors >> 16); - buf[102] = (sectors >> 32); - buf[103] = (sectors >> 48); + ata_ident->udmamodes |= (1 << ((p->xfermode & 7) + 8)); + ata_ident->lba_size48_1 = sectors; + ata_ident->lba_size48_2 = (sectors >> 16); + ata_ident->lba_size48_3 = (sectors >> 32); + ata_ident->lba_size48_4 = (sectors >> 48); + if (candelete && !ro) { - buf[69] |= ATA_SUPPORT_RZAT | ATA_SUPPORT_DRAT; - buf[105] = 1; - buf[169] = ATA_SUPPORT_DSM_TRIM; + ata_ident->support3 |= ATA_SUPPORT_RZAT | ATA_SUPPORT_DRAT; + ata_ident->max_dsm_blocks = 1; + ata_ident->support_dsm = ATA_SUPPORT_DSM_TRIM; } - buf[106] = 0x4000; - buf[209] = 0x4000; + ata_ident->pss = ATA_PSS_VALID_VALUE; + ata_ident->lsalign = 0x4000; if (psectsz > sectsz) { - buf[106] |= 0x2000; - buf[106] |= ffsl(psectsz / sectsz) - 1; - buf[209] |= (psectoff / sectsz); + ata_ident->pss |= ATA_PSS_MULTLS; + ata_ident->pss |= ffsl(psectsz / sectsz) - 1; + ata_ident->lsalign |= (psectoff / sectsz); } if (sectsz > 512) { - buf[106] |= 0x1000; - buf[117] = sectsz / 2; - buf[118] = ((sectsz / 2) >> 16); + ata_ident->pss |= ATA_PSS_LSSABOVE512; + ata_ident->lss_1 = sectsz / 2; + ata_ident->lss_2 = ((sectsz / 2) >> 16); } - buf[119] = (ATA_SUPPORT_RWLOGDMAEXT | 1 << 14); - buf[120] = (ATA_SUPPORT_RWLOGDMAEXT | 1 << 14); - buf[222] = 0x1020; - buf[255] = 0x00a5; - ahci_checksum((uint8_t *)buf, sizeof(buf)); - ahci_write_fis_piosetup(p); - write_prdt(p, slot, cfis, (void *)buf, sizeof(buf)); - ahci_write_fis_d2h(p, slot, cfis, ATA_S_DSC | ATA_S_READY); + ata_ident->support2 = (ATA_SUPPORT_RWLOGDMAEXT | 1 << 14); + ata_ident->enabled2 = (ATA_SUPPORT_RWLOGDMAEXT | 1 << 14); + ata_ident->transport_major = 0x1020; + ata_ident->integrity = 0x00a5; } + ahci_checksum((uint8_t*)ata_ident, sizeof(struct ata_params)); } static void @@ -1085,44 +1126,8 @@ handle_atapi_identify(struct ahci_port *p, int slot, u ahci_write_fis_d2h(p, slot, cfis, (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); } else { - uint16_t buf[256]; - - memset(buf, 0, sizeof(buf)); - buf[0] = (2 << 14 | 5 << 8 | 1 << 7 | 2 << 5); - ata_string((uint8_t *)(buf+10), p->ident, 20); - ata_string((uint8_t *)(buf+23), "001", 8); - ata_string((uint8_t *)(buf+27), "BHYVE SATA DVD ROM", 40); - buf[49] = (1 << 9 | 1 << 8); - buf[50] = (1 << 14 | 1); - buf[53] = (1 << 2 | 1 << 1); - buf[62] = 0x3f; - buf[63] = 7; - if (p->xfermode & ATA_WDMA0) - buf[63] |= (1 << ((p->xfermode & 7) + 8)); - buf[64] = 3; - buf[65] = 120; - buf[66] = 120; - buf[67] = 120; - buf[68] = 120; - buf[76] = (ATA_SATA_GEN1 | ATA_SATA_GEN2 | ATA_SATA_GEN3); - buf[77] = ((p->ssts & ATA_SS_SPD_MASK) >> 3); - buf[78] = (1 << 5); - buf[80] = 0x3f0; - buf[82] = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_PACKET | - ATA_SUPPORT_RESET | ATA_SUPPORT_NOP); - buf[83] = (1 << 14); - buf[84] = (1 << 14); - buf[85] = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_PACKET | - ATA_SUPPORT_RESET | ATA_SUPPORT_NOP); - buf[87] = (1 << 14); - buf[88] = 0x7f; - if (p->xfermode & ATA_UDMA0) - buf[88] |= (1 << ((p->xfermode & 7) + 8)); - buf[222] = 0x1020; - buf[255] = 0x00a5; - ahci_checksum((uint8_t *)buf, sizeof(buf)); ahci_write_fis_piosetup(p); - write_prdt(p, slot, cfis, (void *)buf, sizeof(buf)); + write_prdt(p, slot, cfis, (void *)&p->ata_ident, sizeof(struct ata_params)); ahci_write_fis_d2h(p, slot, cfis, ATA_S_DSC | ATA_S_READY); } } @@ -2314,6 +2319,10 @@ pci_ahci_init(struct vmctx *ctx, struct pci_devinst *p MD5_CTX mdctx; u_char digest[16]; char *next, *next2; + char *bopt, *uopt, *xopts, *config; + FILE* fp; + size_t block_len; + int comma, optpos; ret = 0; @@ -2330,6 +2339,9 @@ pci_ahci_init(struct vmctx *ctx, struct pci_devinst *p slots = 32; for (p = 0; p < MAX_PORTS && opts != NULL; p++, opts = next) { + struct ata_params *ata_ident = &sc->port[p].ata_ident; + memset(ata_ident, 0, sizeof(struct ata_params)); + /* Identify and cut off type of present port. */ if (strncmp(opts, "hd:", 3) == 0) { atapi = 0; @@ -2352,13 +2364,82 @@ pci_ahci_init(struct vmctx *ctx, struct pci_devinst *p if (opts[0] == 0) continue; + uopt = strdup(opts); + bopt = NULL; + fp = open_memstream(&bopt, &block_len); + comma = 0; + optpos = 0; + + for (xopts = strtok(uopt, ","); + xopts != NULL; + xopts = strtok(NULL, ",")) { + + /* First option assume as block filename. */ + if (optpos == 0) { + /* + * Create an identifier for the backing file. + * Use parts of the md5 sum of the filename + */ + char ident[AHCI_PORT_IDENT]; + MD5Init(&mdctx); + MD5Update(&mdctx, opts, strlen(opts)); + MD5Final(digest, &mdctx); + snprintf(ident, AHCI_PORT_IDENT, + "BHYVE-%02X%02X-%02X%02X-%02X%02X", + digest[0], digest[1], digest[2], digest[3], digest[4], + digest[5]); + ata_string((uint8_t*)&ata_ident->serial, ident, 20); + ata_string((uint8_t*)&ata_ident->revision, "001", 8); + if (atapi) { + ata_string((uint8_t*)&ata_ident->model, "BHYVE SATA DVD ROM", 40); + } + else { + ata_string((uint8_t*)&ata_ident->model, "BHYVE SATA DISK", 40); + } + } + + if ((config = strchr(xopts, '=')) != NULL) { + *config++ = '\0'; + if (!strcmp("nmrr", xopts)) { + ata_ident->media_rotation_rate = atoi(config); + } + else if (!strcmp("ser", xopts)) { + ata_string((uint8_t*)(&ata_ident->serial), config, 20); + } + else if (!strcmp("rev", xopts)) { + ata_string((uint8_t*)(&ata_ident->revision), config, 8); + } + else if (!strcmp("model", xopts)) { + ata_string((uint8_t*)(&ata_ident->model), config, 40); + } + else { + /* Pass all other options to blockif_open. */ + *--config = '='; + fprintf(fp, "%s%s", comma ? "," : "", xopts); + comma = 1; + } + } + else { + /* Pass all other options to blockif_open. */ + fprintf(fp, "%s%s", comma ? "," : "", xopts); + comma = 1; + } + optpos++; + } + free(uopt); + fclose(fp); + + DPRINTF("%s\n", bopt); + /* * Attempt to open the backing image. Use the PCI slot/func * and the port number for the identifier string. */ snprintf(bident, sizeof(bident), "%d:%d:%d", pi->pi_slot, pi->pi_func, p); - bctxt = blockif_open(opts, bident); + bctxt = blockif_open(bopt, bident); + free(bopt); + if (bctxt == NULL) { sc->ports = p; ret = 1; @@ -2369,17 +2450,7 @@ pci_ahci_init(struct vmctx *ctx, struct pci_devinst *p sc->port[p].port = p; sc->port[p].atapi = atapi; - /* - * Create an identifier for the backing file. - * Use parts of the md5 sum of the filename - */ - MD5Init(&mdctx); - MD5Update(&mdctx, opts, strlen(opts)); - MD5Final(digest, &mdctx); - snprintf(sc->port[p].ident, AHCI_PORT_IDENT, - "BHYVE-%02X%02X-%02X%02X-%02X%02X", - digest[0], digest[1], digest[2], digest[3], digest[4], - digest[5]); + ata_identify_init(&sc->port[p], atapi); /* * Allocate blockif request structures and add them