i^sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextEnglish}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget /userspace-api/accelerators/ocxlmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget3/translations/zh_TW/userspace-api/accelerators/ocxlmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget3/translations/it_IT/userspace-api/accelerators/ocxlmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget3/translations/ja_JP/userspace-api/accelerators/ocxlmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget3/translations/ko_KR/userspace-api/accelerators/ocxlmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hPortuguese (Brazilian)}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget3/translations/pt_BR/userspace-api/accelerators/ocxlmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget3/translations/sp_SP/userspace-api/accelerators/ocxlmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageChinese (Simplified)uh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhh`/var/lib/git/docbuild/linux/Documentation/translations/zh_CN/userspace-api/accelerators/ocxl.rsthKubhnote)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]h paragraph)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hh5Documentation/translations/zh_CN/disclaimer-zh_CN.rsthKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh field_list)}(hhh](hfield)}(hhh](h field_name)}(hOriginalh]hOriginal}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhKubh field_body)}(h2Documentation/userspace-api/accelerators/ocxl.rst h]h)}(h1Documentation/userspace-api/accelerators/ocxl.rsth]h1Documentation/userspace-api/accelerators/ocxl.rst}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h翻译h]h翻译}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhKubj)}(h李睿 Rui Li h]h)}(h李睿 Rui Li h](h李睿 Rui Li <}(hj4hhhNhNubh reference)}(h me@lirui.orgh]h me@lirui.org}(hj>hhhNhNubah}(h]h ]h"]h$]h&]refurimailto:me@lirui.orguh1j<hj4ubh>}(hj4hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj0ubah}(h]h ]h"]h$]h&]uh1hhjubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubeh}(h]h ]h"]h$]h&]uh1hhhhhhhhKubhsection)}(hhh](htitle)}(h3OpenCAPI (开放相干加速器处理器接口)h]h3OpenCAPI (开放相干加速器处理器接口)}(hjqhhhNhNubah}(h]h ]h"]h$]h&]uh1johjlhhhhhK ubh)}(h9*OpenCAPI: Open Coherent Accelerator Processor Interface*h]hemphasis)}(hjh]h7OpenCAPI: Open Coherent Accelerator Processor Interface}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhKhjlhhubh)}(hOpenCAPI是处理器和加速器之间的一个接口,致力于达到低延迟和高带宽。该规范 由 `OpenCAPI Consortium `_ 开发。h](hmOpenCAPI是处理器和加速器之间的一个接口,致力于达到低延迟和高带宽。该规范 由 }(hjhhhNhNubj=)}(h-`OpenCAPI Consortium `_h]hOpenCAPI Consortium}(hjhhhNhNubah}(h]h ]h"]h$]h&]nameOpenCAPI Consortiumrefurihttp://opencapi.org/uh1j<hjubhtarget)}(h h]h}(h]opencapi-consortiumah ]h"]opencapi consortiumah$]h&]refurijuh1j referencedKhjubh 开发。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjlhhubh)}(h它允许加速器(可以是FPGA、ASIC等)使用虚拟地址连贯地访问主机内存。一个OpenCAPI 设备也可以托管它自己的内存,并可以由主机访问。h]h它允许加速器(可以是FPGA、ASIC等)使用虚拟地址连贯地访问主机内存。一个OpenCAPI 设备也可以托管它自己的内存,并可以由主机访问。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjlhhubh)}(hOpenCAPI在Linux中称为“ocxl”,它作为“cxl”(用于powerpc的IBM CAPI接口的驱动)的 开放、处理器无关的演进,这么命名是为了避免与ISDN CAPI子系统相混淆。h]hOpenCAPI在Linux中称为“ocxl”,它作为“cxl”(用于powerpc的IBM CAPI接口的驱动)的 开放、处理器无关的演进,这么命名是为了避免与ISDN CAPI子系统相混淆。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjlhhubjk)}(hhh](jp)}(h 高层视角h]h 高层视角}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhKubh)}(hOpenCAPI定义了一个在物理链路层上实现的数据链路层(TL)和传输层(TL)。任何 实现DL和TL的处理器或者设备都可以开始共享内存。h]hOpenCAPI定义了一个在物理链路层上实现的数据链路层(TL)和传输层(TL)。任何 实现DL和TL的处理器或者设备都可以开始共享内存。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh literal_block)}(hXX+-----------+ +-------------+ | | | | | | | Accelerated | | Processor | | Function | | | +--------+ | Unit | +--------+ | |--| Memory | | (AFU) |--| Memory | | | +--------+ | | +--------+ +-----------+ +-------------+ | | +-----------+ +-------------+ | TL | | TLX | +-----------+ +-------------+ | | +-----------+ +-------------+ | DL | | DLX | +-----------+ +-------------+ | | | PHY | +---------------------------------------+ Processor:处理器 Memory:内存 Accelerated Function Unit:加速功能单元h]hXX+-----------+ +-------------+ | | | | | | | Accelerated | | Processor | | Function | | | +--------+ | Unit | +--------+ | |--| Memory | | (AFU) |--| Memory | | | +--------+ | | +--------+ +-----------+ +-------------+ | | +-----------+ +-------------+ | TL | | TLX | +-----------+ +-------------+ | | +-----------+ +-------------+ | DL | | DLX | +-----------+ +-------------+ | | | PHY | +---------------------------------------+ Processor:处理器 Memory:内存 Accelerated Function Unit:加速功能单元}hj sbah}(h]h ]h"]h$]h&]hhuh1jhhhK"hjhhubeh}(h]id1ah ]h"] 高层视角ah$]h&]uh1jjhjlhhhhhKubjk)}(hhh](jp)}(h 设备发现h]h 设备发现}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhK=ubh)}(hOpenCAPI依赖一个在设备上实现的与PCI类似的配置空间。因此主机可以通过查询 配置空间来发现AFU。h]hOpenCAPI依赖一个在设备上实现的与PCI类似的配置空间。因此主机可以通过查询 配置空间来发现AFU。}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK?hjhhubh)}(hXPOpenCAPI设备在Linux中被当作类PCI设备(有一些注意事项)。固件需要对硬件进行 抽象,就好像它是一个PCI链路。许多已有的PCI架构被重用:在模拟标准PCI时, 设备被扫描并且BAR(基址寄存器)被分配。像“lspci”的命令因此可以被用于查看 哪些设备可用。h]hXPOpenCAPI设备在Linux中被当作类PCI设备(有一些注意事项)。固件需要对硬件进行 抽象,就好像它是一个PCI链路。许多已有的PCI架构被重用:在模拟标准PCI时, 设备被扫描并且BAR(基址寄存器)被分配。像“lspci”的命令因此可以被用于查看 哪些设备可用。}(hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKBhjhhubh)}(h配置空间定义了可以在物理适配器上可以被找到的AFU,比如它的名字、支持多少内 存上下文、内存映射IO(MMIO)区域的大小等。h]h配置空间定义了可以在物理适配器上可以被找到的AFU,比如它的名字、支持多少内 存上下文、内存映射IO(MMIO)区域的大小等。}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKGhjhhubeh}(h]id2ah ]h"] 设备发现ah$]h&]uh1jjhjlhhhhhK=ubjk)}(hhh](jp)}(hMMIOh]hMMIO}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1johjbhhhhhKMubh)}(h0OpenCAPI为每个AFU定义了两个MMIO区域:h]h0OpenCAPI为每个AFU定义了两个MMIO区域:}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKOhjbhhubh bullet_list)}(hhh](h list_item)}(h:全局MMIO区域,保存和整个AFU相关的寄存器。h]h)}(hjh]h:全局MMIO区域,保存和整个AFU相关的寄存器。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKQhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hC每个进程的MMIO区域,对于每个上下文固定大小。 h]h)}(h@每个进程的MMIO区域,对于每个上下文固定大小。h]h@每个进程的MMIO区域,对于每个上下文固定大小。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKRhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]bullet*uh1jhhhKQhjbhhubeh}(h]mmioah ]h"]mmioah$]h&]uh1jjhjlhhhhhKMubjk)}(hhh](jp)}(h AFU中断h]h AFU中断}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhKWubh)}(hOpenCAPI拥有AFU向主机进程发送中断的可能性。它通过定义在传输层的“intrp_req” 来完成,指定一个定义中断的64位对象句柄。h]hOpenCAPI拥有AFU向主机进程发送中断的可能性。它通过定义在传输层的“intrp_req” 来完成,指定一个定义中断的64位对象句柄。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKYhjhhubh)}(hV驱动允许一个进程分配中断并获取可以传递给AFU的64位对象句柄。h]hV驱动允许一个进程分配中断并获取可以传递给AFU的64位对象句柄。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK\hjhhubeh}(h]afuah ]h"] afu中断ah$]h&]uh1jjhjlhhhhhKWubjk)}(hhh](jp)}(h 字符设备h]h 字符设备}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhKaubh)}(h驱动为每个在物理设备上发现的AFU创建一个字符设备。一个物理设备可能拥有多个 功能,一个功能可以拥有多个AFU。不过编写这篇文档之时,只对导出一个AFU的设备 测试过。h]h驱动为每个在物理设备上发现的AFU创建一个字符设备。一个物理设备可能拥有多个 功能,一个功能可以拥有多个AFU。不过编写这篇文档之时,只对导出一个AFU的设备 测试过。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKchjhhubh)}(hh字符设备可以在 /dev/ocxl/ 中被找到,其命名为: /dev/ocxl/.<位置>.<索引>h]hh字符设备可以在 /dev/ocxl/ 中被找到,其命名为: /dev/ocxl/.<位置>.<索引>}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKghjhhubh)}(hX( 是一个最长20个字符的名称,和在AFU配置空间中找到的相同。 <位置>由驱动添加,可在系统有不止一个相同的OpenCAPI设备时帮助区分设备。 <索引>也是为了在少见情况下帮助区分AFU,即设备携带多个同样的AFU副本时。h]hX( 是一个最长20个字符的名称,和在AFU配置空间中找到的相同。 <位置>由驱动添加,可在系统有不止一个相同的OpenCAPI设备时帮助区分设备。 <索引>也是为了在少见情况下帮助区分AFU,即设备携带多个同样的AFU副本时。}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKjhjhhubeh}(h]id3ah ]h"] 字符设备ah$]h&]uh1jjhjlhhhhhKaubjk)}(hhh](jp)}(hSysfs类h]hSysfs类}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1johj?hhhhhKqubh)}(hx添加了代表AFU的ocxl类。查看/sys/class/ocxl。布局在 Documentation/ABI/testing/sysfs-class-ocxl 中描述。h]hx添加了代表AFU的ocxl类。查看/sys/class/ocxl。布局在 Documentation/ABI/testing/sysfs-class-ocxl 中描述。}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKshj?hhubeh}(h]sysfsah ]h"]sysfs类ah$]h&]uh1jjhjlhhhhhKqubjk)}(hhh](jp)}(h 用户APIh]h 用户API}(hjihhhNhNubah}(h]h ]h"]h$]h&]uh1johjfhhhhhKyubjk)}(hhh](jp)}(h打开h]h打开}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1johjwhhhhhK|ubh)}(h基于在配置空间中找到的AFU定义,AFU可能支持在多个内存上下文中工作,这种情况 下相关的字符设备可以被不同进程多次打开。h]h基于在配置空间中找到的AFU定义,AFU可能支持在多个内存上下文中工作,这种情况 下相关的字符设备可以被不同进程多次打开。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK~hjwhhubeh}(h]id4ah ]h"]打开ah$]h&]uh1jjhjfhhhhhK|ubjk)}(hhh](jp)}(hioctlh]hioctl}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhKubh)}(hOCXL_IOCTL_ATTACH:h]hOCXL_IOCTL_ATTACH:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh block_quote)}(hL附加调用进程的内存上下文到AFU,以允许AFU访问其内存。 h]h)}(hK附加调用进程的内存上下文到AFU,以允许AFU访问其内存。h]hK附加调用进程的内存上下文到AFU,以允许AFU访问其内存。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhhhKhjhhubh)}(hOCXL_IOCTL_IRQ_ALLOC:h]hOCXL_IOCTL_IRQ_ALLOC:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(h%分配AFU中断,返回标识符。 h]h)}(h$分配AFU中断,返回标识符。h]h$分配AFU中断,返回标识符。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhhhKhjhhubh)}(hOCXL_IOCTL_IRQ_FREE:h]hOCXL_IOCTL_IRQ_FREE:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(h"释放之前分配的AFU中断。 h]h)}(h!释放之前分配的AFU中断。h]h!释放之前分配的AFU中断。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1jhhhKhjhhubh)}(hOCXL_IOCTL_IRQ_SET_FD:h]hOCXL_IOCTL_IRQ_SET_FD:}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(hq将一个事件文件描述符和AFU中断关联,因此用户进程可以在AFU发送中断时收到通 知。 h]h)}(hp将一个事件文件描述符和AFU中断关联,因此用户进程可以在AFU发送中断时收到通 知。h]hp将一个事件文件描述符和AFU中断关联,因此用户进程可以在AFU发送中断时收到通 知。}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj1ubah}(h]h ]h"]h$]h&]uh1jhhhKhjhhubh)}(hOCXL_IOCTL_GET_METADATA:h]hOCXL_IOCTL_GET_METADATA:}(hjIhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(h从卡中获取配置信息,比如内存映射IO区域的大小、AFU版本和当前上下文的进程 地址空间ID(PASID)。 h]h)}(h从卡中获取配置信息,比如内存映射IO区域的大小、AFU版本和当前上下文的进程 地址空间ID(PASID)。h]h从卡中获取配置信息,比如内存映射IO区域的大小、AFU版本和当前上下文的进程 地址空间ID(PASID)。}(hj[hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjWubah}(h]h ]h"]h$]h&]uh1jhhhKhjhhubh)}(hOCXL_IOCTL_ENABLE_P9_WAIT:h]hOCXL_IOCTL_ENABLE_P9_WAIT:}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(h允许AFU唤醒执行“等待”的用户空间进程。返回信息给用户空间,允许其配置AFU。 注意这只在POWER9上可用。 h]h)}(h允许AFU唤醒执行“等待”的用户空间进程。返回信息给用户空间,允许其配置AFU。 注意这只在POWER9上可用。h]h允许AFU唤醒执行“等待”的用户空间进程。返回信息给用户空间,允许其配置AFU。 注意这只在POWER9上可用。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj}ubah}(h]h ]h"]h$]h&]uh1jhhhKhjhhubh)}(hOCXL_IOCTL_GET_FEATURES:h]hOCXL_IOCTL_GET_FEATURES:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(h:报告用户空间可用的影响OpenCAPI的CPU特性。 h]h)}(h8报告用户空间可用的影响OpenCAPI的CPU特性。h]h8报告用户空间可用的影响OpenCAPI的CPU特性。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhhhKhjhhubeh}(h]ioctlah ]h"]ioctlah$]h&]uh1jjhjfhhhhhKubjk)}(hhh](jp)}(hmmaph]hmmap}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhKubh)}(hA一个进程可以mmap每个进程的MMIO区域来和AFU交互。h]hA一个进程可以mmap每个进程的MMIO区域来和AFU交互。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]mmapah ]h"]mmapah$]h&]uh1jjhjfhhhhhKubeh}(h]apiah ]h"] 用户apiah$]h&]uh1jjhjlhhhhhKyubeh}(h]opencapiah ]h"]3opencapi (开放相干加速器处理器接口)ah$]h&]uh1jjhhhhhhhK ubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(joN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourcehnj _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(jjjjjjj_j\jjjjj<j9jcj`jjjjjjjju nametypes}(jjjj_jjj<jcjjjjuh}(jjljjjjj\jjjbjjj9jj`j?jjfjjwjjjju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}j+KsRparse_messages]transform_messages] transformerN include_log]DDocumentation/translations/zh_CN/userspace-api/accelerators/ocxl.rst(NNNNta decorationNhhub.