FPGA 管理器¶
概述¶
FPGA 管理器核心匯出了一組用於使用映像程式設計 FPGA 的函式。該 API 與製造商無關。 所有制造商的特殊性都隱藏在底層驅動程式中,該驅動程式向核心註冊一組操作。 FPGA 映像資料本身非常特定於製造商,但就我們的目的而言,它只是二進位制資料。 FPGA 管理器核心不會解析它。
要程式設計的 FPGA 映像可以在散佈/聚集列表中、單個連續緩衝區中或韌體檔案中。 因為應避免為緩衝區分配連續的核心記憶體,因此建議使用者儘可能改用散佈/聚集列表。
程式設計映像的詳細資訊顯示在一個結構體 (struct fpga_image_info) 中。 此結構體包含諸如指向 FPGA 映像的指標以及映像特定的詳細資訊(例如映像是為完全還是部分重新配置而構建的)之類的引數。
如何支援新的 FPGA 裝置¶
要新增另一個 FPGA 管理器,請編寫一個實現一組操作的驅動程式。 probe 函式呼叫 fpga_mgr_register() 或 fpga_mgr_register_full(),例如
static const struct fpga_manager_ops socfpga_fpga_ops = {
.write_init = socfpga_fpga_ops_configure_init,
.write = socfpga_fpga_ops_configure_write,
.write_complete = socfpga_fpga_ops_configure_complete,
.state = socfpga_fpga_ops_state,
};
static int socfpga_fpga_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct socfpga_fpga_priv *priv;
struct fpga_manager *mgr;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
/*
* do ioremaps, get interrupts, etc. and save
* them in priv
*/
mgr = fpga_mgr_register(dev, "Altera SOCFPGA FPGA Manager",
&socfpga_fpga_ops, priv);
if (IS_ERR(mgr))
return PTR_ERR(mgr);
platform_set_drvdata(pdev, mgr);
return 0;
}
static int socfpga_fpga_remove(struct platform_device *pdev)
{
struct fpga_manager *mgr = platform_get_drvdata(pdev);
fpga_mgr_unregister(mgr);
return 0;
}
或者,probe 函式可以呼叫資源管理的註冊函式之一 devm_fpga_mgr_register() 或 devm_fpga_mgr_register_full()。 使用這些函式時,引數語法相同,但應刪除對 fpga_mgr_unregister() 的呼叫。 在上面的示例中,不需要 socfpga_fpga_remove() 函式。
這些操作將實現所需的任何裝置特定暫存器寫入,以執行此特定 FPGA 的程式設計序列。 這些操作成功時返回 0,否則返回負錯誤程式碼。
- 程式設計序列為:
.parse_header(可選,可以呼叫一次或多次)
.write_init
.write 或 .write_sg(可以呼叫一次或多次)
.write_complete
.parse_header 函式會將 header_size 和 data_size 設定為 struct fpga_image_info。 在 parse_header 呼叫之前,header_size 會使用 initial_header_size 初始化。 如果 fpga_manager_ops 的標誌 skip_header 為 true,則 .write 函式將獲取從頭 header_size 偏移量開始的映像緩衝區。 如果設定了 data_size,則 .write 函式將獲取映像緩衝區的 data_size 個位元組,否則 .write 將獲取資料直到映像緩衝區的末尾。 這不會影響 .write_sg,.write_sg 仍將以 sg_table 形式獲取整個映像。 如果 FPGA 映像已對映為單個連續緩衝區,則整個緩衝區將傳遞到 .parse_header。 如果映像採用散佈-聚集形式,則核心程式碼將在第一次呼叫 .parse_header 之前緩衝至少 .initial_header_size,如果這不夠,則 .parse_header 應將所需大小設定為 info->header_size 並返回 -EAGAIN,然後將再次使用輸入端上的較大映像緩衝區呼叫它。
.write_init 函式將準備 FPGA 以接收映像資料。 傳遞到 .write_init 的緩衝區將至少為 info->header_size 位元組長;如果整個位元流不可立即使用,則核心程式碼將在啟動之前緩衝至少這麼多。
.write 函式將緩衝區寫入 FPGA。 該緩衝區可能包含整個 FPGA 映像,也可能包含 FPGA 映像的較小塊。 在後一種情況下,會為連續塊多次呼叫此函式。 此介面適用於使用 PIO 的驅動程式。
.write_sg 版本的行為與 .write 相同,只是輸入是 sg_table 散佈列表。 此介面適用於使用 DMA 的驅動程式。
.write_complete 函式在所有映像都已寫入後呼叫,以使 FPGA 進入執行模式。
這些操作包括一個 .state 函式,該函式將確定 FPGA 所處的狀態,並返回 enum fpga_mgr_states 型別的程式碼。 它不會導致狀態更改。
用於實現新的 FPGA 管理器驅動程式的 API¶
fpga_mgr_states- fpga_manager->state 的值。struct fpga_manager- FPGA 管理器結構體struct fpga_manager_ops- 底層 FPGA 管理器驅動程式操作struct fpga_manager_info- fpga_mgr_register_full() 的引數結構體__fpga_mgr_register_full()- 建立並註冊 FPGA 管理器,使用 fpga_mgr_info 結構體來提供選項的全部靈活性__fpga_mgr_register()- 建立並註冊 FPGA 管理器,使用標準引數__devm_fpga_mgr_register_full()-__fpga_mgr_register_full()的資源管理版本fpga_mgr_unregister()- 登出 FPGA 管理器
輔助宏 fpga_mgr_register_full()、fpga_mgr_register()、devm_fpga_mgr_register_full() 和 devm_fpga_mgr_register() 可用於簡化註冊。
-
enum fpga_mgr_states¶
fpga 框架狀態
常量
FPGA_MGR_STATE_UNKNOWN無法確定狀態
FPGA_MGR_STATE_POWER_OFFFPGA 電源已關閉
FPGA_MGR_STATE_POWER_UPFPGA 報告電源已開啟
FPGA_MGR_STATE_RESETFPGA 處於復位狀態
FPGA_MGR_STATE_FIRMWARE_REQ韌體請求正在進行中
FPGA_MGR_STATE_FIRMWARE_REQ_ERR韌體請求失敗
FPGA_MGR_STATE_PARSE_HEADER解析 FPGA 映像標頭
FPGA_MGR_STATE_PARSE_HEADER_ERRPARSE_HEADER 階段期間出錯
FPGA_MGR_STATE_WRITE_INIT準備 FPGA 進行程式設計
FPGA_MGR_STATE_WRITE_INIT_ERRWRITE_INIT 階段期間出錯
FPGA_MGR_STATE_WRITE將映像寫入 FPGA
FPGA_MGR_STATE_WRITE_ERR寫入 FPGA 時出錯
FPGA_MGR_STATE_WRITE_COMPLETE執行程式設計後步驟
FPGA_MGR_STATE_WRITE_COMPLETE_ERRWRITE_COMPLETE 期間出錯
FPGA_MGR_STATE_OPERATINGFPGA 已程式設計並正在執行
-
struct fpga_manager¶
fpga 管理器結構體
定義:
struct fpga_manager {
const char *name;
struct device dev;
struct mutex ref_mutex;
enum fpga_mgr_states state;
struct fpga_compat_id *compat_id;
const struct fpga_manager_ops *mops;
struct module *mops_owner;
void *priv;
};
成員
name底層 fpga 管理器的名稱
devfpga 管理器裝置
ref_mutex僅允許對 fpga 管理器的一個引用
statefpga 管理器的狀態
compat_id用於相容性檢查的 FPGA 管理器 ID。
mops指向 fpga 管理器操作結構體的指標
mops_owner包含 mops 的模組
priv底層驅動程式私有日期
-
struct fpga_manager_ops¶
底層 fpga 管理器驅動程式的操作
定義:
struct fpga_manager_ops {
size_t initial_header_size;
bool skip_header;
enum fpga_mgr_states (*state)(struct fpga_manager *mgr);
u64 (*status)(struct fpga_manager *mgr);
int (*parse_header)(struct fpga_manager *mgr,struct fpga_image_info *info, const char *buf, size_t count);
int (*write_init)(struct fpga_manager *mgr,struct fpga_image_info *info, const char *buf, size_t count);
int (*write)(struct fpga_manager *mgr, const char *buf, size_t count);
int (*write_sg)(struct fpga_manager *mgr, struct sg_table *sgt);
int (*write_complete)(struct fpga_manager *mgr, struct fpga_image_info *info);
void (*fpga_remove)(struct fpga_manager *mgr);
const struct attribute_group **groups;
};
成員
initial_header_size應傳遞到 parse_header 和 write_init 的最小位元組數。
skip_headerbool 標誌,用於告訴 fpga-mgr 核心在呼叫寫入回撥時是否應跳過映像開頭的 info->header_size 部分。
state返回 FPGA 狀態的列舉值
status返回 FPGA 的狀態,包括重新配置錯誤程式碼
parse_header解析 FPGA 映像標頭以設定 info->header_size 和 info->data_size。 如果輸入緩衝區不夠大,請將所需大小設定為 info->header_size 並返回 -EAGAIN。
write_init準備 FPGA 以接收配置資料
write將 count 個位元組的配置資料寫入 FPGA
write_sg將配置資料的散佈列表寫入 FPGA
write_complete寫入完成後,將 FPGA 設定為執行狀態
fpga_remove可選:在驅動程式移除期間將 FPGA 設定為特定狀態
groups可選的屬性組。
描述
fpga_manager_ops 是由特定的 fpga 管理器驅動程式實現的底層函式。 可選的函式在呼叫之前會測試是否為 NULL,因此省略它們是可以的。
-
struct fpga_manager_info¶
FPGA 管理器的引數集合
定義:
struct fpga_manager_info {
const char *name;
struct fpga_compat_id *compat_id;
const struct fpga_manager_ops *mops;
void *priv;
};
成員
namefpga 管理器名稱
compat_id用於相容性檢查的 FPGA 管理器 ID。
mops指向 fpga 管理器操作結構體的指標
privfpga 管理器私有資料
描述
fpga_manager_info 包含 register_full 函式的引數。 這些引數被分成一個 info 結構體,因為它們中的一些是可選的,而其他的可能會在將來被新增。 info 結構體有助於維護穩定的 API。
-
struct fpga_manager *__fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info, struct module *owner)¶
建立並註冊 FPGA 管理器裝置
引數
struct device *parent來自 pdev 的 fpga 管理器裝置
const struct fpga_manager_info *infofpga 管理器的引數
struct module *owner包含操作的 owner 模組
描述
此函式的呼叫者負責呼叫 fpga_mgr_unregister()。 建議改用 devm_fpga_mgr_register_full()。
返回
指向 struct fpga_manager 指標的指標,或者 ERR_PTR()
-
struct fpga_manager *__fpga_mgr_register(struct device *parent, const char *name, const struct fpga_manager_ops *mops, void *priv, struct module *owner)¶
建立並註冊 FPGA 管理器裝置
引數
struct device *parent來自 pdev 的 fpga 管理器裝置
const char *namefpga 管理器名稱
const struct fpga_manager_ops *mops指向 fpga 管理器操作結構體的指標
void *privfpga 管理器私有資料
struct module *owner包含操作的 owner 模組
描述
此函式的呼叫者負責呼叫 fpga_mgr_unregister()。 建議改用 devm_fpga_mgr_register()。 此簡單版本的註冊函式應足以滿足大多數使用者的需求。 fpga_mgr_register_full() 函式可用於需要傳遞其他可選引數的使用者。
返回
指向 struct fpga_manager 指標的指標,或者 ERR_PTR()
-
struct fpga_manager *__devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info, struct module *owner)¶
fpga_mgr_register() 的資源管理變體
引數
struct device *parent來自 pdev 的 fpga 管理器裝置
const struct fpga_manager_info *infofpga 管理器的引數
struct module *owner包含操作的 owner 模組
返回
成功時返回 FPGA 管理器指標,否則返回負的錯誤程式碼。
描述
這是 fpga_mgr_register_full() 的 devres 變體,當管理裝置分離時,將自動呼叫登出函式。
-
struct fpga_manager *__devm_fpga_mgr_register(struct device *parent, const char *name, const struct fpga_manager_ops *mops, void *priv, struct module *owner)¶
fpga_mgr_register() 的資源管理變體
引數
struct device *parent來自 pdev 的 fpga 管理器裝置
const char *namefpga 管理器名稱
const struct fpga_manager_ops *mops指向 fpga 管理器操作結構體的指標
void *privfpga 管理器私有資料
struct module *owner包含操作的 owner 模組
返回
成功時返回 FPGA 管理器指標,否則返回負的錯誤程式碼。
描述
這是 fpga_mgr_register() 的 devres 變體,當管理裝置分離時,將自動呼叫登出函式。
-
void fpga_mgr_unregister(struct fpga_manager *mgr)¶
登出一個 FPGA 管理器
引數
struct fpga_manager *mgrFPGA 管理器結構體
描述
此函式旨在用於 FPGA 管理器驅動程式的 remove 函式中。