.. _falcon-xfer: ======================================= Code/data xfers to/from external memory ======================================= .. contents:: Introduction ============ The falcon has a builtin DMA controller that allows running asynchronous copies beteween falcon data/code segments and external memory. An xfer request consists of the following: - mode: code load [external -> falcon code], data load [external -> falcon data], or data store [falcon data -> external] - external port: 0-7. Specifies which external memory space the xfer should use. - external base: 0-0xffffffff. Shifted left by 8 bits to obtain the base address of the transfer in external memory. - external offset: 0-0xffffffff. Offset in external memory, and for v3+ code segments, virtual address that code should be loaded at. - local address: 0-0xffff. Offset in falcon code/data segment where data should be transferred. Physical address for code xfers. - xfer size: 0-6 for data xfers, ignored for code xfers [always effectively 6]. The xfer copies (4<`_ for GF100 PGRAPH CTXCTLs, :ref:`falcon-memif` for the other engines. .. _falcon-isa-xfer: Submitting xfer requests: xcld, xdld, xdst ========================================== These instruction submit xfer requests of the relevant type. ext_base and port are taken from $xdbase/$xcbase and $xtargets special registers. ext_offset is taken from first operand, local_address is taken from low 16 bits of second operand, and size [for data xfers] is taken from bits 16-18 of the second operand. Secret flag is taken from $cauth bit 16. Instructions: ==== =========== ========= Name Description Subopcode ==== =========== ========= xcld code load 4 xdld data load 5 xdst data store 6 ==== =========== ========= Instruction class: unsized Operands: SRC1, SRC2 Forms: ====== ====== Form Opcode ====== ====== R2, R1 fa ====== ====== Operation: :: if (op == xcld) XFER(mode=code_load, port=$xtargets[0:2], ext_base=$xcbase, ext_offset=SRC1, local_address=(SRC2&0xffff), secret=($cauth[16:16])); else if (op == xdld) XFER(mode=data_load, port=$xtargets[8:10], ext_base=$xdbase, ext_offset=SRC1, local_address=(SRC2&0xffff), size=(SRC2>>16)); else // xdst XFER(mode=data_store, port=$xtargets[12:14], ext_base=$xdbase, ext_offset=SRC1, local_address=(SRC2&0xffff), size=(SRC2>>16)); .. _falcon-isa-xwait: Waiting for xfer completion: xcwait, xdwait =========================================== These instructions wait until all xfers of the relevant type have finished. Instructions: ====== ======================================== ========= Name Description Subopcode ====== ======================================== ========= xdwait wait for all data loads/stores to finish 3 xcwait wait for all code loads to finish 7 ====== ======================================== ========= Instruction class: unsized Operands: [none] Forms: ============= ====== Form Opcode ============= ====== [no operands] f8 ============= ====== Operation: :: if (op == xcwait) while (XFER_ACTIVE(mode=code_load)); else while (XFER_ACTIVE(mode=data_load) || XFER_ACTIVE(mode=data_store)); .. _falcon-io-xfer: Submitting xfer requests via IO space ===================================== There are 4 IO registers that can be used to manually submit xfer reuqests. The request is sent out by writing XFER_CTRL register, other registers have to be set beforehand. MMIO 0x110 / I[0x04400]: XFER_EXT_BASE Specifies the ext_base for the xfer that will be launched by XFER_CTRL. MMIO 0x114 / I[0x04500]: XFER_LOCAL_ADDRESS Specifies the local_address for the xfer that will be launched by XFER_CTRL. MMIO 0x118 / I[0x04600]: XFER_CTRL Writing requests a new xfer with given params, reading shows the last value written + two status flags - bit 0: pending [RO]: The last write to XFER_CTRL is still waiting for place in the queue. XFER_CTRL shouldn't be written until this bit clears. - bit 1: ??? [RO] - bit 2: secret flag [secret engines only] - bit 3: ??? [secret engines only] - bits 4-5: mode - 0: data load - 1: code load - 2: data store - bits 8-10: size - bits 12-14: port .. todo:: figure out bit 1. Related to 0x10c? MMIO 0x11c / I[0x04700]: XFER_EXT_OFFSET Specifies the ext_offset for the xfer that will be launched by XFER_CTRL. .. todo:: how to wait for xfer finish using only IO? .. _falcon-io-xfer-status: xfer queue status registers =========================== The status of the xfer queue can be read out through an IO register: MMIO 0x120 / I[0x04800]: XFER_STATUS - bit 1: busy. 1 if any data xfer is pending. - bits 4-5: ??? writable - bits 16-18: number of data stores pending - bits 24-26: number of data loads pending .. todo:: bits 4-5 .. todo:: RE and document this stuff, find if there's status for code xfers