Vengineerの妄想

人生を妄想しています。

Google Edge TPUのlibedgetpuの中とApexデバイスドライバの関係

@Vengineerの戯言 : Twitter
SystemVerilogの世界へようこそすべては、SystemC v0.9公開から始まった 

 ということで、Linuxでは、Apex ドライバとして登録されています。

github.com

でこのファイルの中の割り込み関連部分

/* 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つを組み合わせて解析すれば、かなりのことが分かりそう。

 

LinuxのApexのIOCTLには、

#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)