socsvn commit: r255933 - soc2013/zcore/head/usr.sbin/bhyve
zcore at FreeBSD.org
zcore at FreeBSD.org
Wed Aug 14 15:20:14 UTC 2013
Author: zcore
Date: Wed Aug 14 15:20:14 2013
New Revision: 255933
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=255933
Log:
add ahci_write_fis to emulate d2h/sdb fis
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 Wed Aug 14 15:19:16 2013 (r255932)
+++ soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c Wed Aug 14 15:20:14 2013 (r255933)
@@ -52,13 +52,27 @@
#include "ahci.h"
#include "block_if.h"
+#define PxSIG_ATA 0x00000101 /* ATA drive */
+#define PxSIG_ATAPI 0xeb140101 /* ATAPI drive */
+
+enum sata_fis_type {
+ FIS_TYPE_REGH2D = 0x27, /* Register FIS - host to device */
+ FIS_TYPE_REGD2H = 0x34, /* Register FIS - device to host */
+ FIS_TYPE_DMAACT = 0x39, /* DMA activate FIS - device to host */
+ FIS_TYPE_DMASETUP = 0x41, /* DMA setup FIS - bidirectional */
+ FIS_TYPE_DATA = 0x46, /* Data FIS - bidirectional */
+ FIS_TYPE_BIST = 0x58, /* BIST activate FIS - bidirectional */
+ FIS_TYPE_PIOSETUP = 0x5F, /* PIO setup FIS - device to host */
+ FIS_TYPE_SETDEVBITS = 0xA1, /* Set device bits FIS - device to host */
+};
+
/*
* Debug printf
*/
static FILE *dbg;
#define dprintf(format, arg...) do{fprintf(dbg, format, ##arg);fflush(dbg);}while(0)
#define DPRINTF(params) dprintf params
-#define WPRINTF(params) printf params
+#define WPRINTF(params) dprintf params
struct ahci_ioreq {
struct blockif_req io_req;
@@ -74,6 +88,8 @@
struct pci_ahci_softc *pr_sc;
uint64_t cmd_lst;
uint64_t rfis;
+ int atapi;
+
uint32_t clb;
uint32_t clbu;
uint32_t fb;
@@ -155,6 +171,50 @@
pci_generate_msi(sc->asc_pi, 0);
}
+static void ahci_write_fis(struct ahci_port *p, enum sata_fis_type ft,
+ uint8_t *fis)
+{
+ int offset, len, irq;
+
+ if (p->rfis == 0 || !(p->cmd & AHCI_P_CMD_FRE))
+ return;
+
+ switch (ft) {
+ case FIS_TYPE_REGD2H:
+ offset = 0x40;
+ len = 20;
+ irq = AHCI_P_IX_DHR;
+ break;
+ case FIS_TYPE_SETDEVBITS:
+ offset = 0x58;
+ len = 8;
+ irq = AHCI_P_IX_SDB;
+ break;
+ default:
+ WPRINTF(("unsupported fis type %d\n", ft));
+ break;
+ }
+ memcpy(p->rfis + offset, fis, len);
+ p->is |= irq;
+ ahci_generate_intr(p->pr_sc);
+}
+
+static void ahci_write_fis_d2h(struct ahci_port *p)
+{
+ uint8_t fis[20];
+
+ memset(fis, 0, sizeof(fis));
+ fis[0] = FIS_TYPE_REGD2H;
+ fis[3] = 1;
+ fis[4] = 1;
+ if (p->atapi) {
+ fis[5] = 0x14;
+ fis[6] = 0xeb;
+ }
+ fis[12] = 1;
+ ahci_write_fis(p, FIS_TYPE_REGD2H, fis);
+}
+
/*
* blockif callback routine - this runs in the context of the blockif
* i/o thread, so the mutex needs to be acquired.
@@ -219,14 +279,21 @@
pr->serr = 0;
pr->sact = 0;
- /* TODO set signature by the device kind */
- pr->sig = 0x00000101;
- pr->tfd = 0;
- if (pr->bctx)
- pr->ssts = ATA_SS_DET_PHY_ONLINE | ATA_SS_SPD_GEN2 |
- ATA_SS_IPM_ACTIVE;
- else
+ if (!pr->bctx) {
pr->ssts = ATA_SS_DET_NO_DEVICE;
+ pr->sig = 0xFFFFFFFF;
+ pr->tfd = 0x7F;
+ return;
+ }
+ pr->ssts = ATA_SS_DET_PHY_ONLINE | ATA_SS_SPD_GEN2 |
+ ATA_SS_IPM_ACTIVE;
+ pr->tfd = (1 << 8) | ATA_S_DSC | ATA_S_DMA;
+ if (!pr->atapi) {
+ pr->sig = PxSIG_ATA;
+ pr->tfd |= ATA_S_READY;
+ } else
+ pr->sig = PxSIG_ATAPI;
+ ahci_write_fis_d2h(pr);
}
static void
More information about the svn-soc-all
mailing list