diff options
-rw-r--r-- | usr/src/cmd/Makefile | 2 | ||||
-rw-r--r-- | usr/src/cmd/amdzen/Makefile (renamed from usr/src/cmd/usmn/Makefile) | 2 | ||||
-rw-r--r-- | usr/src/cmd/amdzen/udf.c | 118 | ||||
-rw-r--r-- | usr/src/cmd/amdzen/usmn.c (renamed from usr/src/cmd/usmn/usmn.c) | 0 | ||||
-rw-r--r-- | usr/src/man/man7d/Makefile | 1 | ||||
-rw-r--r-- | usr/src/man/man7d/amdzen.7d | 4 | ||||
-rw-r--r-- | usr/src/man/man7d/usmn.7d | 3 | ||||
-rw-r--r-- | usr/src/man/man7d/zen_udf.7d | 36 | ||||
-rw-r--r-- | usr/src/pkg/manifests/driver-developer-amd-zen.mf | 4 | ||||
-rw-r--r-- | usr/src/uts/intel/Makefile.files | 1 | ||||
-rw-r--r-- | usr/src/uts/intel/Makefile.intel | 2 | ||||
-rw-r--r-- | usr/src/uts/intel/io/amdzen/amdzen.c | 70 | ||||
-rw-r--r-- | usr/src/uts/intel/io/amdzen/amdzen.h | 3 | ||||
-rw-r--r-- | usr/src/uts/intel/io/amdzen/amdzen_client.h | 4 | ||||
-rw-r--r-- | usr/src/uts/intel/io/amdzen/zen_udf.c | 286 | ||||
-rw-r--r-- | usr/src/uts/intel/io/amdzen/zen_udf.h | 44 | ||||
-rw-r--r-- | usr/src/uts/intel/zen_udf/Makefile | 41 |
17 files changed, 611 insertions, 10 deletions
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile index 2f35ac9412..dee86627e5 100644 --- a/usr/src/cmd/Makefile +++ b/usr/src/cmd/Makefile @@ -489,6 +489,7 @@ i386_SUBDIRS= \ acpihpd \ addbadsec \ ahciem \ + amdzen \ bhyve \ bhyvectl \ biosdev \ @@ -499,7 +500,6 @@ i386_SUBDIRS= \ rdmsr \ rtc \ ucodeadm \ - usmn \ xhci \ xvm diff --git a/usr/src/cmd/usmn/Makefile b/usr/src/cmd/amdzen/Makefile index 4fc6e17bfe..c9f8b7778e 100644 --- a/usr/src/cmd/usmn/Makefile +++ b/usr/src/cmd/amdzen/Makefile @@ -13,7 +13,7 @@ # Copyright 2020 Oxide Computer Company # -PROG= usmn +PROG= usmn udf include ../Makefile.cmd diff --git a/usr/src/cmd/amdzen/udf.c b/usr/src/cmd/amdzen/udf.c new file mode 100644 index 0000000000..604e0b4802 --- /dev/null +++ b/usr/src/cmd/amdzen/udf.c @@ -0,0 +1,118 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2020 Oxide Computer Company + */ + +/* + * Facilitate access to the AMD Zen data fabric + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <err.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <strings.h> +#include <zen_udf.h> + +static void +udf_readone(int fd, uint8_t inst, uint8_t func, uint16_t reg, boolean_t do64) +{ + int ret; + zen_udf_io_t zui; + + bzero(&zui, sizeof (zui)); + zui.zui_inst = inst; + zui.zui_func = func; + zui.zui_reg = reg; + + ret = ioctl(fd, do64 ? ZEN_UDF_READ64 : ZEN_UDF_READ32, &zui); + if (ret != 0) { + err(EXIT_FAILURE, "failed to issue read ioctl"); + } + + (void) printf("ifr %x/%x/%x: 0x%" PRIx64 "\n", + inst, func, reg, zui.zui_data); +} + +int +main(int argc, char *argv[]) +{ + int c, fd; + const char *device = NULL; + const char *funcstr = NULL; + const char *inststr = NULL; + const char *regstr = NULL; + uint8_t func, inst; + uint16_t reg; + unsigned long lval; + char *eptr; + boolean_t do64 = B_FALSE; + + while ((c = getopt(argc, argv, "d:f:i:r:l")) != -1) { + switch (c) { + case 'd': + device = optarg; + break; + case 'f': + funcstr = optarg; + break; + case 'i': + inststr = optarg; + break; + case 'l': + do64 = B_TRUE; + break; + case 'r': + regstr = optarg; + break; + } + } + + if (device == NULL || funcstr == NULL || inststr == NULL || + regstr == NULL) { + warnx("missing required arguments"); + (void) fprintf(stderr, "Usage: udf [-l] -d device -f func -i " + "inst -r reg\n"); + } + + errno = 0; + lval = strtoul(funcstr, &eptr, 0); + if (errno != 0 || lval > UINT8_MAX || *eptr != '\0') { + errx(EXIT_FAILURE, "failed to parse -f: %s", funcstr); + } + func = (uint8_t)lval; + + lval = strtoul(inststr, &eptr, 0); + if (errno != 0 || lval > UINT8_MAX || *eptr != '\0') { + errx(EXIT_FAILURE, "failed to parse -i: %s", inststr); + } + inst = (uint8_t)lval; + + lval = strtoul(regstr, &eptr, 0); + if (errno != 0 || lval > UINT16_MAX || *eptr != '\0') { + errx(EXIT_FAILURE, "failed to parse -r: %s", regstr); + } + reg = (uint16_t)lval; + + if ((fd = open(device, O_RDONLY)) < 0) { + err(EXIT_FAILURE, "failed to open %s", device); + } + + udf_readone(fd, inst, func, reg, do64); + (void) close(fd); + return (0); +} diff --git a/usr/src/cmd/usmn/usmn.c b/usr/src/cmd/amdzen/usmn.c index 3b9998f021..3b9998f021 100644 --- a/usr/src/cmd/usmn/usmn.c +++ b/usr/src/cmd/amdzen/usmn.c diff --git a/usr/src/man/man7d/Makefile b/usr/src/man/man7d/Makefile index d8bbaaa77b..9da7d4b205 100644 --- a/usr/src/man/man7d/Makefile +++ b/usr/src/man/man7d/Makefile @@ -245,6 +245,7 @@ i386_MANFILES= ahci.7d \ virtio.7d \ wpi.7d \ xhci.7d \ + zen_udf.7d \ zyd.7d _MANLINKS= 1394.7d \ diff --git a/usr/src/man/man7d/amdzen.7d b/usr/src/man/man7d/amdzen.7d index 0b0c531a99..171d36b0d6 100644 --- a/usr/src/man/man7d/amdzen.7d +++ b/usr/src/man/man7d/amdzen.7d @@ -45,4 +45,6 @@ drivers are limited to .Sy x86 platforms with AMD Family 17h processors. .Sh SEE ALSO -.Xr smntemp 7D +.Xr smntemp 7D , +.Xr usmn 7D , +.Xr zen_udf 7D diff --git a/usr/src/man/man7d/usmn.7d b/usr/src/man/man7d/usmn.7d index 016c85276c..b36da78be4 100644 --- a/usr/src/man/man7d/usmn.7d +++ b/usr/src/man/man7d/usmn.7d @@ -33,4 +33,5 @@ This driver is intended strictly for facilitating platform development and is not recommended for systems that aren't doing kernel development on AMD Zen platforms. .Sh SEE ALSO -.Xr amdzen 7D +.Xr amdzen 7D , +.Xr zen_udf 7D diff --git a/usr/src/man/man7d/zen_udf.7d b/usr/src/man/man7d/zen_udf.7d new file mode 100644 index 0000000000..a2243ef67f --- /dev/null +++ b/usr/src/man/man7d/zen_udf.7d @@ -0,0 +1,36 @@ +.\" +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.0 of the CDDL. +.\" +.\" A full copy of the text of the CDDL should have accompanied this +.\" source. A copy of the CDDL is also available via the Internet at +.\" http://www.illumos.org/license/CDDL. +.\" +.\" +.\" Copyright 2020 Oxide Computer Company +.\" +.Dd October 7, 2020 +.Dt ZEN_UDF 7D +.Os +.Sh NAME +.Nm zen_udf +.Nd AMD data fabric user access driver +.Sh SYNOPSIS +.Pa /devices/pseudo/amdzen@0/zen_udf@3:zen_udf.* +.Sh DESCRIPTION +The +.Nm +driver provides the ability to read data from the AMD data fabric +.Pq DF +on AMD Family 17h +.Pq Zen, Zen+, and Zen 2 +processors. +.Pp +This driver is intended strictly for facilitating platform development +and is not recommended for systems that aren't doing kernel development +on AMD Zen platforms. +.Sh SEE ALSO +.Xr amdzen 7D , +.Xr usmn 7D diff --git a/usr/src/pkg/manifests/driver-developer-amd-zen.mf b/usr/src/pkg/manifests/driver-developer-amd-zen.mf index 27d46083e5..7df997705f 100644 --- a/usr/src/pkg/manifests/driver-developer-amd-zen.mf +++ b/usr/src/pkg/manifests/driver-developer-amd-zen.mf @@ -27,7 +27,11 @@ dir path=usr/lib dir path=usr/share/man dir path=usr/share/man/man7d driver name=usmn +driver name=zen_udf file path=kernel/drv/$(ARCH64)/usmn group=sys +file path=kernel/drv/$(ARCH64)/zen_udf group=sys +file path=usr/lib/udf mode=0555 file path=usr/lib/usmn mode=0555 file path=usr/share/man/man7d/usmn.7d +file path=usr/share/man/man7d/zen_udf.7d license lic_CDDL license=lic_CDDL diff --git a/usr/src/uts/intel/Makefile.files b/usr/src/uts/intel/Makefile.files index f6d2efc34c..336c25d739 100644 --- a/usr/src/uts/intel/Makefile.files +++ b/usr/src/uts/intel/Makefile.files @@ -350,3 +350,4 @@ AMDZEN_OBJS = amdzen.o AMDZEN_STUB_OBJS = amdzen_stub.o SMNTEMP_OBJS = smntemp.o USMN_OBJS = usmn.o +ZEN_UDF_OBJS = zen_udf.o diff --git a/usr/src/uts/intel/Makefile.intel b/usr/src/uts/intel/Makefile.intel index f24c591288..64e027fe15 100644 --- a/usr/src/uts/intel/Makefile.intel +++ b/usr/src/uts/intel/Makefile.intel @@ -776,4 +776,4 @@ DRV_KMODS += smntemp # DRV_KMODS += amdzen DRV_KMODS += amdzen_stub -DRV_KMODS += usmn +DRV_KMODS += usmn zen_udf diff --git a/usr/src/uts/intel/io/amdzen/amdzen.c b/usr/src/uts/intel/io/amdzen/amdzen.c index 17a3c69b9a..25e38ee988 100644 --- a/usr/src/uts/intel/io/amdzen/amdzen.c +++ b/usr/src/uts/intel/io/amdzen/amdzen.c @@ -157,7 +157,8 @@ typedef struct { static const amdzen_child_data_t amdzen_children[] = { { "smntemp", AMDZEN_C_SMNTEMP }, - { "usmn", AMDZEN_C_USMN } + { "usmn", AMDZEN_C_USMN }, + { "zen_udf", AMDZEN_C_ZEN_UDF } }; static uint32_t @@ -166,6 +167,12 @@ amdzen_stub_get32(amdzen_stub_t *stub, off_t reg) return (pci_config_get32(stub->azns_cfgspace, reg)); } +static uint64_t +amdzen_stub_get64(amdzen_stub_t *stub, off_t reg) +{ + return (pci_config_get64(stub->azns_cfgspace, reg)); +} + static void amdzen_stub_put32(amdzen_stub_t *stub, off_t reg, uint32_t val) { @@ -189,6 +196,24 @@ amdzen_df_read32(amdzen_t *azn, amdzen_df_t *df, uint8_t inst, uint8_t func, return (amdzen_stub_get32(df->adf_funcs[4], AMDZEN_DF_F4_FICAD_LO)); } +/* + * Perform a targeted 64-bit indirect read to a specific instance and function. + */ +static uint64_t +amdzen_df_read64(amdzen_t *azn, amdzen_df_t *df, uint8_t inst, uint8_t func, + uint16_t reg) +{ + uint32_t val; + + VERIFY(MUTEX_HELD(&azn->azn_mutex)); + val = AMDZEN_DF_F4_FICAA_TARG_INST | AMDZEN_DF_F4_FICAA_SET_REG(reg) | + AMDZEN_DF_F4_FICAA_SET_FUNC(func) | + AMDZEN_DF_F4_FICAA_SET_INST(inst) | AMDZEN_DF_F4_FICAA_SET_64B; + amdzen_stub_put32(df->adf_funcs[4], AMDZEN_DF_F4_FICAA, val); + return (amdzen_stub_get64(df->adf_funcs[4], AMDZEN_DF_F4_FICAD_LO)); +} + + static uint32_t amdzen_smn_read32(amdzen_t *azn, amdzen_df_t *df, uint32_t reg) { @@ -260,6 +285,45 @@ amdzen_c_df_count(void) return (ret); } +int +amdzen_c_df_read32(uint_t dfno, uint8_t inst, uint8_t func, + uint16_t reg, uint32_t *valp) +{ + amdzen_df_t *df; + amdzen_t *azn = amdzen_data; + + mutex_enter(&azn->azn_mutex); + df = amdzen_df_find(azn, dfno); + if (df == NULL) { + mutex_exit(&azn->azn_mutex); + return (ENOENT); + } + + *valp = amdzen_df_read32(azn, df, inst, func, reg); + mutex_exit(&azn->azn_mutex); + + return (0); +} + +int +amdzen_c_df_read64(uint_t dfno, uint8_t inst, uint8_t func, + uint16_t reg, uint64_t *valp) +{ + amdzen_df_t *df; + amdzen_t *azn = amdzen_data; + + mutex_enter(&azn->azn_mutex); + df = amdzen_df_find(azn, dfno); + if (df == NULL) { + mutex_exit(&azn->azn_mutex); + return (ENOENT); + } + + *valp = amdzen_df_read64(azn, df, inst, func, reg); + mutex_exit(&azn->azn_mutex); + + return (0); +} static boolean_t amdzen_create_child(amdzen_t *azn, const amdzen_child_data_t *acd) @@ -269,14 +333,14 @@ amdzen_create_child(amdzen_t *azn, const amdzen_child_data_t *acd) if (ndi_devi_alloc(azn->azn_dip, acd->acd_name, (pnode_t)DEVI_SID_NODEID, &child) != NDI_SUCCESS) { - dev_err(azn->azn_dip, CE_WARN, "failed to allocate child " + dev_err(azn->azn_dip, CE_WARN, "!failed to allocate child " "dip for %s", acd->acd_name); return (B_FALSE); } ddi_set_parent_data(child, (void *)acd); if ((ret = ndi_devi_online(child, 0)) != NDI_SUCCESS) { - dev_err(azn->azn_dip, CE_WARN, "failed to online child " + dev_err(azn->azn_dip, CE_WARN, "!failed to online child " "dip %s: %d", acd->acd_name, ret); return (B_FALSE); } diff --git a/usr/src/uts/intel/io/amdzen/amdzen.h b/usr/src/uts/intel/io/amdzen/amdzen.h index 79b0bc38f4..8150495911 100644 --- a/usr/src/uts/intel/io/amdzen/amdzen.h +++ b/usr/src/uts/intel/io/amdzen/amdzen.h @@ -289,7 +289,8 @@ typedef struct amdzen { typedef enum { AMDZEN_C_SMNTEMP = 1, - AMDZEN_C_USMN + AMDZEN_C_USMN, + AMDZEN_C_ZEN_UDF } amdzen_child_t; /* diff --git a/usr/src/uts/intel/io/amdzen/amdzen_client.h b/usr/src/uts/intel/io/amdzen/amdzen_client.h index ebb942c40b..41ca3e8afd 100644 --- a/usr/src/uts/intel/io/amdzen/amdzen_client.h +++ b/usr/src/uts/intel/io/amdzen/amdzen_client.h @@ -26,8 +26,10 @@ extern "C" { #endif -extern int amdzen_c_smn_read32(uint_t df, uint32_t reg, uint32_t *); +extern int amdzen_c_smn_read32(uint_t, uint32_t, uint32_t *); extern uint_t amdzen_c_df_count(void); +extern int amdzen_c_df_read32(uint_t, uint8_t, uint8_t, uint16_t, uint32_t *); +extern int amdzen_c_df_read64(uint_t, uint8_t, uint8_t, uint16_t, uint64_t *); #ifdef __cplusplus } diff --git a/usr/src/uts/intel/io/amdzen/zen_udf.c b/usr/src/uts/intel/io/amdzen/zen_udf.c new file mode 100644 index 0000000000..61d1e79774 --- /dev/null +++ b/usr/src/uts/intel/io/amdzen/zen_udf.c @@ -0,0 +1,286 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2020 Oxide Computer Company + */ + +/* + * A companion to zen_udf(7D) that allows user access to read the data fabric + * for development purposes. + */ + +#include <sys/types.h> +#include <sys/file.h> +#include <sys/errno.h> +#include <sys/open.h> +#include <sys/cred.h> +#include <sys/ddi.h> +#include <sys/sunddi.h> +#include <sys/stat.h> +#include <sys/conf.h> +#include <sys/devops.h> +#include <sys/cmn_err.h> +#include <sys/policy.h> +#include <amdzen_client.h> + +#include <zen_udf.h> + +typedef struct zen_udf { + dev_info_t *zudf_dip; + uint_t zudf_ndfs; +} zen_udf_t; + +static zen_udf_t zen_udf_data; + +static int +zen_udf_open(dev_t *devp, int flags, int otype, cred_t *credp) +{ + minor_t m; + zen_udf_t *zen_udf = &zen_udf_data; + + if (crgetzoneid(credp) != GLOBAL_ZONEID || + secpolicy_hwmanip(credp) != 0) { + return (EPERM); + } + + if ((flags & (FEXCL | FNDELAY | FNONBLOCK)) != 0) { + return (EINVAL); + } + + if (otype != OTYP_CHR) { + return (EINVAL); + } + + m = getminor(*devp); + if (m >= zen_udf->zudf_ndfs) { + return (ENXIO); + } + + return (0); +} + +static int +zen_udf_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, + int *rvalp) +{ + uint_t dfno; + zen_udf_t *zen_udf = &zen_udf_data; + zen_udf_io_t zui; + + if (cmd != ZEN_UDF_READ32 && cmd != ZEN_UDF_READ64) { + return (ENOTTY); + } + + dfno = getminor(dev); + if (dfno >= zen_udf->zudf_ndfs) { + return (ENXIO); + } + + if (crgetzoneid(credp) != GLOBAL_ZONEID || + secpolicy_hwmanip(credp) != 0) { + return (EPERM); + } + + if (ddi_copyin((void *)arg, &zui, sizeof (zui), mode & FKIOCTL) != 0) { + return (EFAULT); + } + + if (cmd == ZEN_UDF_READ32) { + int ret; + uint32_t data; + + ret = amdzen_c_df_read32(dfno, zui.zui_inst, zui.zui_func, + zui.zui_reg, &data); + if (ret != 0) { + return (ret); + } + + zui.zui_data = data; + } else { + int ret; + + ret = amdzen_c_df_read64(dfno, zui.zui_inst, zui.zui_func, + zui.zui_reg, &zui.zui_data); + if (ret != 0) { + return (ret); + } + } + + if (ddi_copyout(&zui, (void *)arg, sizeof (zui), mode & FKIOCTL) != 0) { + return (EFAULT); + } + + return (0); +} + +static int +zen_udf_close(dev_t dev, int flag, int otyp, cred_t *credp) +{ + return (0); +} + +static void +zen_udf_cleanup(zen_udf_t *zen_udf) +{ + ddi_remove_minor_node(zen_udf->zudf_dip, NULL); + zen_udf->zudf_ndfs = 0; + zen_udf->zudf_dip = NULL; +} + +static int +zen_udf_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) +{ + zen_udf_t *zen_udf = &zen_udf_data; + + if (cmd == DDI_RESUME) { + return (DDI_SUCCESS); + } else if (cmd != DDI_ATTACH) { + return (DDI_FAILURE); + } + + if (zen_udf->zudf_dip != NULL) { + dev_err(dip, CE_WARN, "!zen_udf is already attached to a " + "dev_info_t: %p", zen_udf->zudf_dip); + return (DDI_FAILURE); + } + + zen_udf->zudf_dip = dip; + zen_udf->zudf_ndfs = amdzen_c_df_count(); + for (uint_t i = 0; i < zen_udf->zudf_ndfs; i++) { + char buf[32]; + + (void) snprintf(buf, sizeof (buf), "zen_udf.%u", i); + if (ddi_create_minor_node(dip, buf, S_IFCHR, i, DDI_PSEUDO, + 0) != DDI_SUCCESS) { + dev_err(dip, CE_WARN, "!failed to create minor %s", + buf); + goto err; + } + } + + return (DDI_SUCCESS); + +err: + zen_udf_cleanup(zen_udf); + return (DDI_FAILURE); +} + +static int +zen_udf_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp) +{ + zen_udf_t *zen_udf = &zen_udf_data; + minor_t m; + + switch (cmd) { + case DDI_INFO_DEVT2DEVINFO: + m = getminor((dev_t)arg); + if (m >= zen_udf->zudf_ndfs) { + return (DDI_FAILURE); + } + *resultp = (void *)zen_udf->zudf_dip; + break; + case DDI_INFO_DEVT2INSTANCE: + m = getminor((dev_t)arg); + if (m >= zen_udf->zudf_ndfs) { + return (DDI_FAILURE); + } + *resultp = (void *)(uintptr_t)ddi_get_instance( + zen_udf->zudf_dip); + break; + default: + return (DDI_FAILURE); + } + return (DDI_SUCCESS); +} + +static int +zen_udf_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) +{ + zen_udf_t *zen_udf = &zen_udf_data; + + if (cmd == DDI_SUSPEND) { + return (DDI_SUCCESS); + } else if (cmd != DDI_DETACH) { + return (DDI_FAILURE); + } + + if (zen_udf->zudf_dip != dip) { + dev_err(dip, CE_WARN, "!asked to detach zen_udf, but dip " + "doesn't match"); + return (DDI_FAILURE); + } + + zen_udf_cleanup(zen_udf); + return (DDI_SUCCESS); +} + +static struct cb_ops zen_udf_cb_ops = { + .cb_open = zen_udf_open, + .cb_close = zen_udf_close, + .cb_strategy = nodev, + .cb_print = nodev, + .cb_dump = nodev, + .cb_read = nodev, + .cb_write = nodev, + .cb_ioctl = zen_udf_ioctl, + .cb_devmap = nodev, + .cb_mmap = nodev, + .cb_segmap = nodev, + .cb_chpoll = nochpoll, + .cb_prop_op = ddi_prop_op, + .cb_flag = D_MP, + .cb_rev = CB_REV, + .cb_aread = nodev, + .cb_awrite = nodev +}; + +static struct dev_ops zen_udf_dev_ops = { + .devo_rev = DEVO_REV, + .devo_refcnt = 0, + .devo_getinfo = zen_udf_getinfo, + .devo_identify = nulldev, + .devo_probe = nulldev, + .devo_attach = zen_udf_attach, + .devo_detach = zen_udf_detach, + .devo_reset = nodev, + .devo_quiesce = ddi_quiesce_not_needed, + .devo_cb_ops = &zen_udf_cb_ops +}; + +static struct modldrv zen_udf_modldrv = { + .drv_modops = &mod_driverops, + .drv_linkinfo = "AMD User DF Access", + .drv_dev_ops = &zen_udf_dev_ops +}; + +static struct modlinkage zen_udf_modlinkage = { + .ml_rev = MODREV_1, + .ml_linkage = { &zen_udf_modldrv, NULL } +}; + +int +_init(void) +{ + return (mod_install(&zen_udf_modlinkage)); +} + +int +_info(struct modinfo *modinfop) +{ + return (mod_info(&zen_udf_modlinkage, modinfop)); +} + +int +_fini(void) +{ + return (mod_remove(&zen_udf_modlinkage)); +} diff --git a/usr/src/uts/intel/io/amdzen/zen_udf.h b/usr/src/uts/intel/io/amdzen/zen_udf.h new file mode 100644 index 0000000000..ef5a3184d5 --- /dev/null +++ b/usr/src/uts/intel/io/amdzen/zen_udf.h @@ -0,0 +1,44 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2020 Oxide Computer Company + */ + +#ifndef _ZEN_UDF_H +#define _ZEN_UDF_H + +/* + * Private ioctls for interfacing with the zen_udf driver. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZEN_UDF_IOCTL (('u' << 24) | ('d' << 16) | ('f' << 8)) + +#define ZEN_UDF_READ32 (ZEN_UDF_IOCTL | 0x01) +#define ZEN_UDF_READ64 (ZEN_UDF_IOCTL | 0x02) + +typedef struct zen_udf_io { + uint8_t zui_inst; + uint8_t zui_func; + uint16_t zui_reg; + uint32_t zui_pad; + uint64_t zui_data; +} zen_udf_io_t; + +#ifdef __cplusplus +} +#endif + +#endif /* _ZEN_UDF_H */ diff --git a/usr/src/uts/intel/zen_udf/Makefile b/usr/src/uts/intel/zen_udf/Makefile new file mode 100644 index 0000000000..5b312d7013 --- /dev/null +++ b/usr/src/uts/intel/zen_udf/Makefile @@ -0,0 +1,41 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2020 Oxide Computer Company +# + +UTSBASE = ../.. + +MODULE = zen_udf +OBJECTS = $(ZEN_UDF_OBJS:%=$(OBJS_DIR)/%) +ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) + +include $(UTSBASE)/intel/Makefile.intel + +ALL_TARGET = $(BINARY) +INSTALL_TARGET = $(BINARY) $(ROOTMODULE) +CPPFLAGS += -I$(UTSBASE)/intel/io/amdzen +LDFLAGS += -dy -Ndrv/amdzen + +.KEEP_STATE: + +def: $(DEF_DEPS) + +all: $(ALL_DEPS) + +clean: $(CLEAN_DEPS) + +clobber: $(CLOBBER_DEPS) + +install: $(INSTALL_DEPS) + +include $(UTSBASE)/intel/Makefile.targ |