fwctl cxl 驅動程式¶
- 作者:
Dave Jiang
概述¶
CXL 規範定義了一組可以傳送到 CXL 裝置或交換機的郵箱的命令。它還為傳送到郵箱的供應商特定命令留出了空間。 fwctl 提供了一條路徑,用於從使用者空間向裝置發出由核心驅動程式調節的一組允許的郵箱命令。
以下 3 個命令將用於支援 CXL 特性: CXL 規範 r3.1 8.2.9.6.1 獲取支援的特性(操作碼 0500h) CXL 規範 r3.1 8.2.9.6.2 獲取特性(操作碼 0501h) CXL 規範 r3.1 8.2.9.6.3 設定特性(操作碼 0502h)
“獲取支援的特性”返回的資料可能會被核心驅動程式過濾,以刪除核心禁止的或核心獨佔使用的任何特性。驅動程式會將“獲取支援的特性支援的特性條目”的“設定特性大小”設定為 0,以表明該特性無法修改。“獲取支援的特性”命令和“獲取特性”屬於 FWCTL_RPC_CONFIGURATION 的 fwctl 策略。
對於“設定特性”命令,訪問策略目前分為兩類,具體取決於裝置報告的“設定特性”效果。如果“設定特性”將導致裝置立即更改,則 fwctl 訪問策略必須為 FWCTL_RPC_DEBUG_WRITE_FULL。此級別的效果是用於設定效果掩碼的“立即配置更改”、“立即資料更改”、“立即策略更改”或“立即日誌更改”。如果效果是“帶有冷重置的配置更改”或“帶有傳統重置的配置更改”,則 fwctl 訪問策略必須為 FWCTL_RPC_DEBUG_WRITE 或更高。
fwctl cxl 使用者 API¶
-
struct fwctl_rpc_cxl¶
用於 CXL 的 ioctl(FWCTL_RPC) 輸入
定義:
struct fwctl_rpc_cxl {
__u32 opcode;
__u32 flags;
__u32 op_size;
__u32 reserved1;
union {
struct cxl_mbox_get_sup_feats_in get_sup_feats_in;
struct cxl_mbox_get_feat_in get_feat_in;
struct cxl_mbox_set_feat_in set_feat_in;
};
};
成員
opcodeCXL 郵箱命令操作碼
flags命令的標誌(輸入)。
op_size輸入負載的大小。
reserved1已保留。必須為 0。
{unnamed_union}anonymous
get_sup_feats_in獲取支援的特性輸入
get_feat_in獲取特性輸入
set_feat_in設定特性輸入
-
struct fwctl_rpc_cxl_out¶
用於 CXL 的 ioctl(FWCTL_RPC) 輸出
定義:
struct fwctl_rpc_cxl_out {
__u32 size;
__u32 retval;
union {
struct cxl_mbox_get_sup_feats_out get_sup_feats_out;
__u8 payload[];
};
};
成員
size輸出負載的大小
retval來自裝置的返回值
{unnamed_union}anonymous
get_sup_feats_out獲取支援的特性輸出
payload負載的原始位元組流
1. 驅動程式資訊查詢¶
應用程式的第一步是發出 ioctl(FWCTL_CMD_INFO)。ioctl 的成功呼叫意味著“特性”功能正在執行,並返回一個全零的 32 位負載。需要使用設定為 FWCTL_DEVICE_TYPE_CXL 的 fwctl_info.out_device_type 填充 struct fwctl_info。返回的資料應為包含保留的 32 位欄位(應全部為零)的 struct fwctl_info_cxl。
2. 傳送硬體命令¶
下一步是透過 ioctl(FWCTL_RPC) 從使用者空間向驅動程式傳送“獲取支援的特性”命令。 struct fwctl_rpc_cxl 由 fwctl_rpc.in 指向。 struct fwctl_rpc_cxl.in_payload 指向 CXL 規範定義的硬體輸入結構。 fwctl_rpc.out 指向包含一個內聯作為 fwctl_rpc_cxl_out.payload 的硬體輸出資料的 struct fwctl_rpc_cxl_out 的緩衝區。此命令被呼叫兩次。第一次是為了檢索支援的特性數量。第二次是為了檢索作為輸出資料的特定特性詳細資訊。
獲取特定特性詳細資訊後,可以適當程式設計併發送“獲取/設定特性”命令。對於“設定特性”命令,檢索到的特性資訊包含一個效果欄位,該欄位詳細說明了將觸發的“設定特性”命令的結果。這將告知使用者系統是否已配置為允許“設定特性”命令。
“獲取特性”的程式碼示例¶
static int cxl_fwctl_rpc_get_test_feature(int fd, struct test_feature *feat_ctx,
const uint32_t expected_data)
{
struct cxl_mbox_get_feat_in *feat_in;
struct fwctl_rpc_cxl_out *out;
struct fwctl_rpc rpc = {0};
struct fwctl_rpc_cxl *in;
size_t out_size, in_size;
uint32_t val;
void *data;
int rc;
in_size = sizeof(*in) + sizeof(*feat_in);
rc = posix_memalign((void **)&in, 16, in_size);
if (rc)
return -ENOMEM;
memset(in, 0, in_size);
feat_in = &in->get_feat_in;
uuid_copy(feat_in->uuid, feat_ctx->uuid);
feat_in->count = feat_ctx->get_size;
out_size = sizeof(*out) + feat_ctx->get_size;
rc = posix_memalign((void **)&out, 16, out_size);
if (rc)
goto free_in;
memset(out, 0, out_size);
in->opcode = CXL_MBOX_OPCODE_GET_FEATURE;
in->op_size = sizeof(*feat_in);
rpc.size = sizeof(rpc);
rpc.scope = FWCTL_RPC_CONFIGURATION;
rpc.in_len = in_size;
rpc.out_len = out_size;
rpc.in = (uint64_t)(uint64_t *)in;
rpc.out = (uint64_t)(uint64_t *)out;
rc = send_command(fd, &rpc, out);
if (rc)
goto free_all;
data = out->payload;
val = le32toh(*(__le32 *)data);
if (memcmp(&val, &expected_data, sizeof(val)) != 0) {
rc = -ENXIO;
goto free_all;
}
free_all:
free(out);
free_in:
free(in);
return rc;
}
檢視 CXL CLI 測試目錄 <https://github.com/pmem/ndctl/tree/main/test/fwctl.c> 以獲取有關如何執行此路徑的詳細使用者程式碼示例。
fwctl cxl 核心 API¶
-
int devm_cxl_setup_features(struct cxl_dev_state *cxlds)¶
分配和初始化特性上下文
引數
struct cxl_dev_state *cxldsCXL 裝置上下文
描述
成功時返回 0,失敗時返回 -errno。
-
struct cxl_features_state¶
裝置的特性狀態
定義:
struct cxl_features_state {
struct cxl_dev_state *cxlds;
struct cxl_feat_entries {
int num_features;
int num_user_features;
struct cxl_feat_entry ent[] ;
} *entries;
};
成員
cxlds指向 CXL 裝置狀態的指標
entriesCXl 特性條目上下文