Skip to content

Commit d4b9bd5

Browse files
Tomas Winklerwenlingz
authored andcommitted
dm: mei: add module initialization
Register virtio device virtio-mei. Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Tracked-On: #1536 Signed-off-by: Liu Shuo <shuo.a.liu@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Acked-by: Wang, Yu1 <yu1.wang@intel.com>
1 parent f6e6e85 commit d4b9bd5

File tree

1 file changed

+235
-0
lines changed

1 file changed

+235
-0
lines changed

devicemodel/hw/pci/virtio/virtio_mei.c

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2079,3 +2079,238 @@ struct virtio_ops virtio_mei_ops = {
20792079
.apply_features = NULL,
20802080
.set_status = NULL,
20812081
};
2082+
2083+
static int filter_dirs(const struct dirent *d)
2084+
{
2085+
return !((strcmp(d->d_name, ".") == 0) ||
2086+
(strcmp(d->d_name, "..") == 0));
2087+
}
2088+
2089+
static int
2090+
vmei_get_devname(char *name, size_t namesize,
2091+
unsigned int bus, unsigned int slot, unsigned int func)
2092+
{
2093+
char path[256];
2094+
struct stat buf;
2095+
struct dirent **namelist = NULL;
2096+
int n, ret = 0;
2097+
2098+
snprintf(path, sizeof(path),
2099+
"/sys/bus/pci/drivers/mei_me/0000:%02x:%02x.%1u/mei/",
2100+
bus, slot, func);
2101+
2102+
if (stat(path, &buf) < 0)
2103+
return -1;
2104+
2105+
n = scandir(path, &namelist, filter_dirs, alphasort);
2106+
if (n == 1)
2107+
snprintf(name, namesize, "%s", namelist[0]->d_name);
2108+
else
2109+
ret = -1;
2110+
2111+
while (n-- > 0)
2112+
free(namelist[n]);
2113+
free(namelist);
2114+
2115+
return ret;
2116+
}
2117+
2118+
static int
2119+
vmei_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
2120+
{
2121+
struct virtio_mei *vmei;
2122+
char tname[MAXCOMLEN + 1];
2123+
pthread_mutexattr_t attr;
2124+
int i, rc;
2125+
char *endptr = NULL;
2126+
char *opt;
2127+
unsigned int bus = 0, slot = 0, func = 0;
2128+
char name[DEV_NAME_SIZE + 1];
2129+
2130+
vmei_debug = 0;
2131+
2132+
if (!opts)
2133+
goto init;
2134+
2135+
while ((opt = strsep(&opts, ",")) != NULL) {
2136+
if (sscanf(opt, "%x/%x/%x", &bus, &slot, &func) == 3)
2137+
continue;
2138+
if (!strncmp(opt, "d", 1)) {
2139+
vmei_debug = strtoul(opt + 1, &endptr, 10);
2140+
if (endptr == opt || vmei_debug > 8) {
2141+
vmei_debug = 0;
2142+
WPRINTF("init: unknown debug flag %s\n",
2143+
opts + 1);
2144+
}
2145+
continue;
2146+
}
2147+
WPRINTF("Invalid option: %s\n", opt);
2148+
}
2149+
2150+
if (vmei_debug)
2151+
vmei_dbg_file = fopen("/tmp/vmei_log", "a+");
2152+
2153+
init:
2154+
rc = vmei_get_devname(name, sizeof(name), bus, slot, func);
2155+
if (rc) {
2156+
WPRINTF("init: fail to get mei path!\n");
2157+
strncpy(name, "mei0", sizeof(name));
2158+
}
2159+
2160+
DPRINTF("init: starting\n");
2161+
vmei = calloc(1, sizeof(*vmei));
2162+
if (!vmei) {
2163+
WPRINTF("init: fail to alloc virtio_heci!\n");
2164+
goto fail;
2165+
}
2166+
2167+
vmei->config = calloc(1, sizeof(*vmei->config));
2168+
if (!vmei->config) {
2169+
WPRINTF("init: fail to alloc vmei_config!\n");
2170+
goto fail;
2171+
}
2172+
2173+
/* FIXME: fix get correct mapping */
2174+
vmei->vtag = ctx->vmid;
2175+
if (!vmei->vtag)
2176+
vmei->vtag = 1;
2177+
2178+
vmei->config->buf_depth = VMEI_BUF_DEPTH;
2179+
vmei->config->hw_ready = 0;
2180+
2181+
strncpy(vmei->name, name, sizeof(vmei->name));
2182+
vmei->name[sizeof(vmei->name) - 1] = 0;
2183+
snprintf(vmei->devnode, sizeof(vmei->devnode) - 1,
2184+
"/dev/%s", vmei->name);
2185+
2186+
DPRINTF("devnode = %s\n", vmei->devnode);
2187+
2188+
if (vmei_add_reset_event(vmei) < 0)
2189+
WPRINTF("init: resets won't be detected\n");
2190+
2191+
/* init mutex attribute properly */
2192+
rc = pthread_mutexattr_init(&attr);
2193+
if (rc) {
2194+
WPRINTF("init: mutexattr init fail, error %d!\n", rc);
2195+
goto fail;
2196+
}
2197+
2198+
if (virtio_uses_msix()) {
2199+
rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT);
2200+
if (rc) {
2201+
WPRINTF("init: mutexattr_settype failed, error %d!\n",
2202+
rc);
2203+
goto fail;
2204+
}
2205+
} else {
2206+
rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
2207+
if (rc) {
2208+
WPRINTF("init: mutexattr_settype failed, error %d!\n",
2209+
rc);
2210+
goto fail;
2211+
}
2212+
}
2213+
rc = pthread_mutex_init(&vmei->mutex, &attr);
2214+
pthread_mutexattr_destroy(&attr);
2215+
if (rc) {
2216+
WPRINTF("init: mutex init failed, error %d!\n", rc);
2217+
goto fail;
2218+
}
2219+
2220+
virtio_linkup(&vmei->base, &virtio_mei_ops, vmei, dev, vmei->vqs);
2221+
vmei->base.mtx = &vmei->mutex;
2222+
2223+
for (i = 0; i < VMEI_VQ_NUM; i++)
2224+
vmei->vqs[i].qsize = VMEI_RING_SZ;
2225+
vmei->vqs[VMEI_RXQ].notify = vmei_notify_rx;
2226+
vmei->vqs[VMEI_TXQ].notify = vmei_notify_tx;
2227+
2228+
/* initialize config space */
2229+
pci_set_cfgdata16(dev, PCIR_DEVICE, VIRTIO_DEV_HECI);
2230+
pci_set_cfgdata16(dev, PCIR_VENDOR, INTEL_VENDOR_ID);
2231+
pci_set_cfgdata8(dev, PCIR_CLASS, PCIC_SIMPLECOMM);
2232+
pci_set_cfgdata8(dev, PCIR_SUBCLASS, PCIS_SIMPLECOMM_OTHER);
2233+
pci_set_cfgdata16(dev, PCIR_SUBDEV_0, VIRTIO_TYPE_HECI);
2234+
pci_set_cfgdata16(dev, PCIR_SUBVEND_0, INTEL_VENDOR_ID);
2235+
2236+
if (virtio_interrupt_init(&vmei->base, virtio_uses_msix()))
2237+
goto setup_fail;
2238+
virtio_set_io_bar(&vmei->base, 0);
2239+
2240+
/*
2241+
* tx stuff, thread, mutex, cond
2242+
*/
2243+
pthread_mutex_init(&vmei->tx_mutex, NULL);
2244+
pthread_cond_init(&vmei->tx_cond, NULL);
2245+
pthread_create(&vmei->tx_thread, NULL,
2246+
vmei_tx_thread, vmei);
2247+
snprintf(tname, sizeof(tname), "vmei-%d:%d tx", dev->slot, dev->func);
2248+
pthread_setname_np(vmei->tx_thread, tname);
2249+
2250+
/*
2251+
* rx stuff
2252+
*/
2253+
pthread_mutex_init(&vmei->rx_mutex, NULL);
2254+
pthread_cond_init(&vmei->rx_cond, NULL);
2255+
pthread_create(&vmei->rx_thread, NULL,
2256+
vmei_rx_thread, (void *)vmei);
2257+
snprintf(tname, sizeof(tname), "vmei-%d:%d rx", dev->slot, dev->func);
2258+
pthread_setname_np(vmei->rx_thread, tname);
2259+
2260+
/*
2261+
* init clients
2262+
*/
2263+
pthread_mutexattr_init(&attr);
2264+
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
2265+
pthread_mutex_init(&vmei->list_mutex, &attr);
2266+
pthread_mutexattr_destroy(&attr);
2267+
LIST_INIT(&vmei->active_clients);
2268+
2269+
/*
2270+
* start mei backend
2271+
*/
2272+
if (vmei_start(vmei, true) < 0)
2273+
goto start_fail;
2274+
2275+
return 0;
2276+
2277+
start_fail:
2278+
vmei_stop(vmei);
2279+
setup_fail:
2280+
pthread_mutex_destroy(&vmei->mutex);
2281+
fail:
2282+
if (vmei) {
2283+
free(vmei->config);
2284+
free(vmei);
2285+
}
2286+
2287+
WPRINTF("init: error\n");
2288+
return -1;
2289+
}
2290+
2291+
static void
2292+
vmei_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
2293+
{
2294+
struct virtio_mei *vmei = (struct virtio_mei *)dev->arg;
2295+
2296+
(void)opts;
2297+
2298+
if (!vmei)
2299+
return;
2300+
2301+
vmei_del_reset_event(vmei);
2302+
vmei_stop(vmei);
2303+
2304+
pthread_mutex_destroy(&vmei->mutex);
2305+
free(vmei->config);
2306+
free(vmei);
2307+
}
2308+
2309+
const struct pci_vdev_ops pci_ops_vmei = {
2310+
.class_name = "virtio-heci",
2311+
.vdev_init = vmei_init,
2312+
.vdev_barwrite = virtio_pci_write,
2313+
.vdev_barread = virtio_pci_read,
2314+
.vdev_deinit = vmei_deinit
2315+
};
2316+
DEFINE_PCI_DEVTYPE(pci_ops_vmei);

0 commit comments

Comments
 (0)