update
[libreriscv.git] / isa_conflict_resolution / ioctl.mdwn
index 22c693c7b16c58fe1872a26c1c9d9209bc5b1cb9..e7ea56d0680b076282e3414ff80433931fe61ab8 100644 (file)
@@ -1,236 +1,2 @@
-# ioctl-like
-
-==RB===
-
-This proposal adds a standardised extension interface to the RV
-instruction set by introducing a fixed small number (e.g. 8) of
-"overloadable" R-type opcodes ext_ctl0, .. ext_ctl7. Each takes a process
-local interface cookie in rs1. Based on the cookie, the CPU routes the
-"overloaded" instructions to a "device" on or off the CPU that implements
-the actual semantics.
-
-The cookie is "opened" with an additional r-type instruction ext_open that
-takes a 20 bit identifier and "closed" with an  ext_close instruction. The
-implementing hardware device can use the cookie to reference internal
-state. Thus, interfaces may be statefull.
-
-CPU's and devices may implement several interfaces, indeed, are expected
-to. E.g. a single hardware device might expose a functional interface with
-6 overloaded instructions, expose configuration with two highly device
-specific management interfaces with 8 resp. 4 overloaded instructions,
-and respond to a standardised save state interface with 4 overloaded
-instructions.
-
-Having a standardised overloadable interface simply avoids much of the
-need for isa extensions for hardware with non standard interfaces and
-semantics. This is analogous to the way that the standardised overloadable
-ioctl interface of the kernel almost completely avoids the need for
-extending the kernel with syscalls for the myriad of hardware devices
-with their specific interfaces and semantics.
-
-Since the rs1 input of the overloaded  ext_ctl instruction's are taken
-by the interface cookie, they are restricted in use compared to a normal
-R-type instruction (it is possible to pass 12 bits of additional info by
-or ing it with the cookie). Delegation is also expected to come at a small
-additional performance price compared to a "native" instruction. This
-should be an acceptable tradeoff in most cases.
-
-The expanded flexibility comes at the cost: the standard can specify the
-semantics of the delegation mechanism and the interfacing with the rest
-of the cpu, but the actual semantics of the overloaded instructions can
-only be defined by the designer of the interface. Likewise, a device
-can be conforming as far as delegation and interaction with the CPU
-is concerned, but whether the hardware is conforming to the semantics
-of the interface is outside the scope of spec. Being able to specify
-that semantics using the methods used for RV itself is clearly very
-valuable. One impetus for doing that is using it for purposes of its own,
-effectively freeing opcode space for other purposes. Also, some interfaces
-may become de facto or de jure standards themselves, necessitating
-hardware to implement competing interfaces. I.e., facilitating a free
-for all, may lead to standards proliferation. C'est la vie.
-
-The only "ISA-collisions" that can still occur are in the 20 bit (~10^6)
-interface identifier space, with 12 more bits to identify a device on
-a hart that implements the interface. One suggestion is setting aside
-2^19 id's that are handed out for a small fee by a central (automated)
-registration (making sure the space is not just claimed), while the
-remaining 2^19 are used as a good hash on a long, plausibly globally
-unique human readable interface name. This gives implementors the choice
-between a guaranteed private identifier paying a fee, or relying on low
-probabilities. The interface identifier could also easily be extended
-to 42 bits on RV64.
-
-
-====End RB==
-
-This proposal basically mirrors the concept of POSIX ioctls, providing
-(arbitrarily) 8 functions (opcodes) whose meaning may be over-ridden
-in an object-orientated fashion by calling an "open handle" (and close)
-function (instruction) that switches (redirects) the 8 functions over to
-different opcodes.
-
-
-The "open handle" opcode takes a GUID (globally-unique identifier)
-and an ioctl number, and stores the UUID in a table indexed by the
-ioctl number:
-
-    handle_global_state[8] # stores UUID or index of same
-
-    def open_handle(uuid, ioctl_num):
-          handle_global_state[ioctl_num] = uuid
-
-    def close_handle(ioctl_num):
-          handle_global_state[ioctl_num] = -1 # clear table entry
-
-
-"Ioctls" (arbitrarily 8 separate R-type opcodes) then perform a redirect
-based on what the global state for that numbered "ioctl" has been set to:
-
-    def ioctl_fn0(funct7, rs2, rs1, funct3, rd): # all r-type bits
-        if handle_global_state[0] == CUSTOMEXT1UUID:
-           CUSTEXT1_FN0(funct7, rs2, rs1, funct3, rd) # all r-type bits
-        elif handle_global_state[0] == CUSTOMEXT2UUID:
-           CUSTEXT2_FN0(funct7, rs2, rs1, funct3, rd, opcode) # all r-type bits
-        else:
-            raise Exception("undefined opcode")
-
-Note that the "ioctl" receives all r-type bits (31:7) with the exception of the
-opcode (6:0).
-
-=== RB ==
-
-not quite I think. It is more like
-
-// Hardware, implementing interface with UUID 0xABCD
-
-    def A_shutdown(cookie, data):
-       ...
-
-    def A_init(data)
-
-    def A_do_stuff(cookie, data):
-       ...
-
-    def A_do_more_stuff(cookie, data):
-       ...
-
-    interfaceA = {
-                  "shutdown": A_shutdown,
-                  "init":     A_init,
-                  "ctl0":     A_do_stuff,
-                  "ctl1":     A_do_more_stuff
-                 }
-
-// hardware implementing interface with UUID = 0x1234
-
-    def B_do_things(cookie, data):
-       ...
-    def B_shutdown(cookie, data)
-       ...
-
-    interfaceB = {
-                  "shutdown": B_shutdown,
-                  "ctl0":     B_do_things
-                 }
-
-
-// The CPU being wired to the devices
-
-    cpu_interfaces = {
-                  0xABCD: interfaceA,
-                  0x1234: interfaceB
-                 }
-
-// The functionality that the CPU must implement to use the extension interface
-
-    cpu_open_handles = {}
-
-    __handleId = 0
-    def new_unused_handle_id()
-        __handleId = __handleId + 1
-        return __handleId
-
-    def ext_open(uuid, data):
-        interface = cpu_interface[uuid]
-        if interface == NIL:
-            raise Exception("No such interface")
-
-        handleId = new_unused_handle_id()
-        cpu_open_handles[handleId] = (interface,
-                                      CurrentVirtualMemoryAddressSpace)
-
-        cookie = A_init(data)                      # Here device takes over
-
-        return (handle_id, cookie)
-
-    def ext_close(handle, data):
-        (handleId, cookie) = handle
-        intf_VMA = cpu_open_handles[handleId]
-        if intf_VMA == NIL:
-             return -1
-
-        (interface, VMA) = intf_VMA
-        if VMA != CurrentVirtualMemoryAddressSpace:
-             return -1
-        assert(interface != NIL)
-        shutdown = interface["shutdown"]
-        if shutdown != NIL:
-
-             err = interface.shutdown(cookie, data)  # Here device takes over
-
-             if err != 0:
-                 return err
-        cpu_open_handles[handleId] = NIL
-        return 0
-
-    def ext_ctl0(handle, data):
-        (handleId, cookie) = handle
-        intf_VMA = cpu_open_handles[handleId]
-        if intf_VMA == NIL:
-             raise Exception("No such interface")
-
-        (interface, VMA) = intf_VMA
-        if VMA != CurrentVirtualMemoryAddressSpace:
-             raise Exception("No such interface")  # Disclosing that the
-                                                   # interface exists in 
-                                                   # different address is 
-                                                   # security hole
-
-        assert(interface != NIL)
-        ctl0 = interface["ctl0"]
-        if ctl0 == NIL:
-            raise Exception("No such Instruction")
-
-        return ctl0(cookie, data)                  # Here device takes over
-
-
-The other ext_ctl's are similar.
-
-==End RB==
-
-
-
-
-The proposal is functionally near-identical to that of the mvendor/march-id
-except extended down to individual opcodes.  As such it could hypothetically
-be proposed as an independent Standard Extension in its own right that extends
-the Custom Opcode space *or* fits into the brownfield spaces within the
-existing ISA opcode space *or* is used as the basis of an independent
-Custom Extension in its own right.
-
-==RB==
-I really think it should be in browncode
-==RB==
-
-One of the reasons for seeking an extension of the Custom opcode space is
-that the Custom opcode space is severely limited: only 2 opcodes are free
-within the 32-bit space, and only four total remain in the 48 and 64-bit
-space.
-
-Despite the proposal (which is still undergoing clarification)
-being worthwhile in its own right, and standing on its own merits and
-thus definitely worthwhile pursuing, it is non-trivial and much more
-invasive than the mvendor/march-id WARL concept.
-
-
+The ioctls proposal was a precursor of the [[overloadable opcodes]] proposal. Please see there.