NVMeDriver
----------

Communication with NVMe devices

Parameters at start
-------------------

None

SWIs
----
0x05a5c0 - ControllerEnumerate
           In

           R0 - 0 or Controller Handle
           R1 - Flags
                 Bits
                 0      Filter by NVMe type
                 8 - 15 Filter type

           Out

           R0 - Controller Handle or -1 if there is no information
           R1 - Pointer to NVN subsystem name (Unicode UTF-8.
                Zero terminated)
           R2 - Controller ID
           R3 - Domain ID
           R4 - NMVe controller type
           R5 - Next controller handle or -1 to indicate end
           R6 - Name set ID
           R7 - Number of namespaces
           R8 - Controller type
                0 - PCIe
                1 - TCP (over Fabrics. Not implemented yet)

0x05a5c1 - ControllerAccessInfo
           In

           R0 - Controller Handle

           Out

           R1 - Number of Queues
           R2 - Data Memory Information
                0 - PCI
                1 - System Memory
           R3 - Memory page size
           R4 - Maximal size of data for transfer

0x05a5c2 - Transfer
           In

           R0 - Controller Handle
           R1 - Various
                Bits
                0 - 15 Queue (0 Admin)
                24 - 27 Completion type (CT)
                        0 - No action
                        1 - Service Call
                        2 - Callback procedure (generic veneer at C)
                        3 - GetResult
                        4 - Block
                        5 - Service Call system
                        6 - Callback procedure system (generic veneer at C)
                28 - 31 Type of data memory
                         0 - PCI
                         1 - System Memory
                         2 - Application Memory

                         In case that transfer uses application memory but
                         PCI is required data is copied automatically and
                         addresses are adapted accordingly.
                         Easy to handle but quite slow.
           R2 - Pointer to 64 Bytes NVM Command. Referred data memory must be
                valid until end of request.
           R3 - Pointer to 16 Bytes result. D3 will be cleared at beginning
                to allow recognition of completion. Must be valid until end
                of request.

                On Input:
                D0 - Caller handle (CT 1, 2, 5, 6)
                D1 - Callback procedure address (CT 2, 6)
                D2 - Callback procedure workspace (CT 1, 2, 5, 6)
           R4 - Size of MPTR buffer in case of temporary memory buffering.
                If not used set to zero.
           R5 - Reserved. Must be set to zero (intended for access
                protection)

           Out

           R3 - Completion Identifier (unique for all uncompleted requests)
                Required in Service Call because caller handles may be not
                unique and also in GetResult

           Starts a NVMe transfer. Completion status can be obtained by
           using NVMeDriver_GetResult or by examining D3 inside result
           to be non zero.

           See section Others below.

           Applications and components which are using no PCI memory at
           transfer requests may only use the NVMe PRP memory address scheme.
           This limitation may be perhaps removed later.
           If using PRP addresses and no PCI memory the two lowest Bits of
           a PRP address must be used because they are used nor by RISC OS
           neither by NVMe. To avoid implementation of the whole NVM command
           logic into the NVMeDriver module the caller must help NVMeDriver
           to map the memory into NVMeDrivers own memory world. The two Bits
           are having the following meaning:

           Bits
           1 0
           ---
           0 0 - End of PRP list (no meaning inside command because
                 unchanged).
                 Must be a NULL Pointer else IO information would be
                 missing.
           0 1 - Input from view of caller
           1 0 - Output from view of Caller
           1 1 - Is a reference to a PRP list

           In case that there is remapping necessary as e.g. in case of
           system memory to system memory these Bits will automatically
           cleared by NVMeDriver inside caller memory because NVMe
           controllers might return errors in other cases (but this is not
           mandatory and depends on the controller)

           Important: MPTR and DPTR must be always set to NULL if they
           are unused. NVMeDriver doesn't know whether this fields are
           used inside a particular command and therefore can't handle
           this information properly without this convention.

           MPTR also uses Bits 1 and 0. But here only the Bit combinations
           01 and 10 are allowed.

           Register usage at completion depending on completion type:

           Completion type
           1,5 - ServiceCall
                 R2 - Caller Handle
                 R3 - Workspace (unique caller identification)
                 R4 - Completion Identifier
           2,6 - APCS Call
                 R0  - Caller Handle
                 R1  - Completion Identifier
                 R12 - Workspace

0x05a5c3 - GetResult
           In

           R1 - Flags
                Bits
                0 - Return only result
                1 - Queue operation completion identifier (not
                    implemented yet)
           R3 - Completion Identifier

           Out

           R0 -  0 - completed
                 1 - unfinished
                -1 - Failure

           Only for usage by applications. Returns either the information
           that transfer or queue operation (not implemented yet) is still
           unfinished or will fill the internally stored results into the
           memory pass at Transfer.

0x05a5c4 - SetSpecialPRPinfo -> Not implemented yet
0x05a5c5 - QueueReset -> Not implemented yet
0x05a5c6 - ControllerInfo
           In

           R0 - Controller Handle
           R1 - Type of information returned in R2
                0 - model number (ASCII, Zero terminated)
                1 - serial number (ASCII, Zero terminated)
                2 - firmware revision (ASCII, Zero terminated)
                3 - NVM subsystem name (UTF-8, Zero terminated)

           Out

           R2 - Pointer to string

Service Calls
-------------

Evaluated:
- None

Launched:
- 0x811C0 NVMeDriverStarted
- 0x811C1 NVMeDriverDying
- 0x811C2 NVMeDriverTransferDone -> See SWI Transfer above

Commands
--------

- NVMeDevices lists information about all devices which the
  driver is handling in the moment

Other
-----

Memory issues:
            Caller
            PCI     SYSTEM    APPLICATION
Controller
PCI         Note 1  Note 2    Note 2
SYSTEM      Note 1  Note 3    Note 4 <- PCI and SYSTEM must be checked in
                                        case that NVMe over Fabrics is
                                        implemented. Perhaps Bits 1:0 may be
                                        required in this case also.

Note 1: Caller must not use Bits 1:0 in PRP. SGL may be used.
Note 2: Claim temporary PCI memory. PRP must be used. Adjust PRP references.
Note 3: SGL may be used. If PRP is used NVMeDriver will clear Bits 1:0
        references to ensure that no problems are occurring in case that the
        caller isn't distinguishing between Controller memory types.
        PTR1 and PTR2 are always purged. In case that Bits 1:0 of PRP2 are
        1 1 this indicates a pointer to a PRP list and clearing is
        continued for the whole list. In other cases either the caller
        isn't making usage of Bits 1:0 or there is no list.
Note 4: Claim temporary SYSTEM memory. PRP must be used. Adjust PRP
        references.

Note that callers using system memory must examine controller memory type to
decide whether SGL may be used.

Differences between completion types 1,2 and 5,6:
In general NVMeDriver will try to delay evaluation of NVMe device interrupts
into a RISC OS callback. However this isn't helpful in case that the caller
is e.g. a module in e.g. SVC mode. NVMeDriver will get the interrupt from the
device and will put it to callback. Meanwhile the caller module waits in SVC
mode for the reply of NVMeDriver for eternity as the system will never
achieve callback status and so the interrupt is not evaluated. To overcome
this situation modes 5 and 6 are enforcing an immediate evaluation of the
interrupt. This isn't playing a role at type 0. Type 4 implies immediate
evaluation and type 3 can rely on the fact that a callback will happen
before calling application gets control again.
