X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=isa_conflict_resolution%2Fioctl.mdwn;h=e7ea56d0680b076282e3414ff80433931fe61ab8;hb=f53181cba2b2bfb2aef5e18fc71fea94ce5011f8;hp=f2c0f110ac73553fb75a5b7f486cca556b42dc58;hpb=31028b7e8f26472b9c551d70e3cff28216c388a7;p=libreriscv.git diff --git a/isa_conflict_resolution/ioctl.mdwn b/isa_conflict_resolution/ioctl.mdwn index f2c0f110a..e7ea56d06 100644 --- a/isa_conflict_resolution/ioctl.mdwn +++ b/isa_conflict_resolution/ioctl.mdwn @@ -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.