@Vengineerの戯言 : Twitter
SystemVerilogの世界へようこそ、すべては、SystemC v0.9公開から始まった
Edge TPUのデバイスドライバのソースコードは公開されていないとTweetしましたが、
— Vengineer@アマゾンプライムで映画三昧 (@Vengineer) 2020年6月10日
実は、Google Pixel4に搭載されている Neural Video Core内のEdge TPUのデバイスドライバ(Apex)は公開されているんですよね。
Linux の中にあるんですよ。https://t.co/qe7P5CiMBt
libedgetpu の中にもApexとあります https://t.co/UFXwrTKLvA
ということで、Linuxでは、Apex ドライバとして登録されています。
でこのファイルの中の割り込み関連部分、
/* Gasket device interrupts enums must be dense (i.e., no empty slots). */
enum apex_interrupt {
APEX_INTERRUPT_INSTR_QUEUE = 0,
APEX_INTERRUPT_INPUT_ACTV_QUEUE = 1,
APEX_INTERRUPT_PARAM_QUEUE = 2,
APEX_INTERRUPT_OUTPUT_ACTV_QUEUE = 3,
APEX_INTERRUPT_SC_HOST_0 = 4,
APEX_INTERRUPT_SC_HOST_1 = 5,
APEX_INTERRUPT_SC_HOST_2 = 6,
APEX_INTERRUPT_SC_HOST_3 = 7,
APEX_INTERRUPT_TOP_LEVEL_0 = 8,
APEX_INTERRUPT_TOP_LEVEL_1 = 9,
APEX_INTERRUPT_TOP_LEVEL_2 = 10,
APEX_INTERRUPT_TOP_LEVEL_3 = 11,
APEX_INTERRUPT_FATAL_ERR = 12,
APEX_INTERRUPT_COUNT = 13,
};
と libedgetpu の 割り込みハンドラのヘッダ部分 のこの部分、
// Interrupt identifiers.
enum Interrupt {
DW_INTERRUPT_INSTR_QUEUE = 0,
DW_INTERRUPT_INPUT_ACTV_QUEUE = 1,
DW_INTERRUPT_PARAM_QUEUE = 2,
DW_INTERRUPT_OUTPUT_ACTV_QUEUE = 3,
DW_INTERRUPT_SC_HOST_0 = 4,
DW_INTERRUPT_SC_HOST_1 = 5,
DW_INTERRUPT_SC_HOST_2 = 6,
DW_INTERRUPT_SC_HOST_3 = 7,
DW_INTERRUPT_TOP_LEVEL_0 = 8,
DW_INTERRUPT_TOP_LEVEL_1 = 9,
DW_INTERRUPT_TOP_LEVEL_2 = 10,
DW_INTERRUPT_TOP_LEVEL_3 = 11,
DW_INTERRUPT_FATAL_ERR = 12,
DW_INTERRUPT_COUNT = 13,// Aliases.
DW_INTERRUPT_SC_HOST_BASE = DW_INTERRUPT_SC_HOST_0,
DW_INTERRUPT_TOP_LEVEL_BASE = DW_INTERRUPT_TOP_LEVEL_0,
};
同じですよ。
ということで、この2つを組み合わせて解析すれば、かなりのことが分かりそう。
#define APEX_IOCTL_GATE_CLOCK \
_IOW(APEX_IOCTL_BASE, 0, struct apex_gate_clock_ioctl)
libedgetpu 側には、linux_gasket_ioctrl.h の中にたくさんあります。
Linux の gasket に対して、下記の3つが追加されたっぽい。
/*
* [Loopbacks only] Requests that the loopback device send the specified
* interrupt to the host. The (ulong) argument is the number of the interrupt to
* send.
*/
#define GASKET_IOCTL_LOOPBACK_INTERRUPT \
_IOW(GASKET_IOCTL_BASE, 3, unsigned long) // NOLINT/*
* Tells the kernel to map size bytes at host_address to device_address in
* page_table_index page table. Passes flags to indicate additional attribute
* requests for the mapped memory.
*/
#define GASKET_IOCTL_MAP_BUFFER_FLAGS \
_IOW(GASKET_IOCTL_BASE, 12, struct gasket_page_table_ioctl_flags)/*
* Tells the kernel to map/unmap dma-buf with fd to device_address in
* page_table_index page table.
*/
#define GASKET_IOCTL_MAP_DMABUF \
_IOW(GASKET_IOCTL_BASE, 13, struct gasket_page_table_ioctl_dmabuf)