add extra info
[libreriscv.git] / overloadable_opcodes.mdwn
index 64f24b8d9f052fd66d3d7dcea136bec0e15eada8..ed05873e2d69d51ed347b39da40d5cb0c939ec97 100644 (file)
@@ -1,7 +1,11 @@
 # Overloadable opcodes. 
 
-The xext proposal defines a small number N (e.g. N= 8) standardised R-type instructions 
-xcmd0, xcmd1, ...xcmd[N-1], preferably in the brownfield opcode space. 
+The overloadable opcode (or xext) proposal allows a non standard extension to use a documented 20 + 3 bit   (or 52 + 3 bit on RV64) UUID identifier for an instruction for _software_ to use. At runtime, a cpu translates the UUID to a small implementation defined 12 + 3 bit bit identifier for _hardware_ to use. It also defines a fallback mechanism for the UUID's of instructions the cpu does not recognise.  
+
+Tl;DR see below for a C description of how this is supposed to work. 
+
+It defines a small number N  standardised R-type instructions 
+xcmd0, xcmd1, ...xcmd[N-1], preferably in the brownfield opcode space. We usually assume N = 8 (aka log2(8) = 3 in the + 3 above).  
 Each xcmd takes (in rs1) a 12 bit "logical unit" (lun) identifying a (sub)device on the cpu 
 that implements some "extension interface" (xintf) together with some additional data. 
 Extension devices may be implemented in any convenient form, e.g. non standard extensions 
@@ -36,7 +40,6 @@ arbitrary number of commands. Organising related commands in xintfs, helps avoid
 pollution, and allows to amortise the (small) cost of UUID to lun translation if related 
 commands are used in combination.
  
-Tl;DR see below for a C description of how this is supposed to work. 
  
 == Description of the instructions ==
 
@@ -296,9 +299,9 @@ probabilities. On RV64 the UUID can also be extended to 52 bits (> 10^15).
     short cpu__lookup_lun(const struct uuid_device_priv2lun* lun_map, uuid_dev_t uuid_dev, enum privilege priv, lun_t on_notfound);
 
 
-#define org_RiscV__Trap__lun           ((lun_t)0)
-#define org_RiscV__Fallback__ReturnZero__lun     ((lun_t)1)
-#define org_RiscV__Fallback__ReturnMinusOne__lun ((lun_t)2)
+     #define org_RiscV__Trap__lun           ((lun_t)0)
+     #define org_RiscV__Fallback__ReturnZero__lun     ((lun_t)1)
+     #define org_RiscV__Fallback__ReturnMinusOne__lun ((lun_t)2)
 
      lun_data_t xext(uuid_dev_t rs1, long rs2)
      {
@@ -366,10 +369,11 @@ probabilities. On RV64 the UUID can also be extended to 52 bits (> 10^15).
      }
 
 Example:
+
+     // Fake UUID's
      #define com_bigbucks__Frobate__uuid 0xABCDE
      #define org_tinker_tinker__RocknRoll__uuid 0x12345
-     #define org_tinker_tinker__Jazz__uuid 0xD0B0D
+     #define org_tinker_tinker__Jazz__uuid 0xBEB0B
      /*
      com.bigbucks:Frobate{
          uuid: com_bigbucks__Frobate__uuid
@@ -384,11 +388,16 @@ Example:
          roll rd rs1 rs2: cmd1 rd rs1 rs2
      }
 
+     /* 
+        Device 1 implements com.bigbucks::Frobate and org.tinker.tinker interfaces, uses 
+        a special command for the machine level implementation.  
+     */
+
      long com_bigbucks__device1(short  subdevice_xcmd, lun_data_t rs1, long rs2)
      {
         switch(subdevice_xcmd) {
         case 0 | 0 << 12  /* com.bigbucks:Frobate:frobate */     : return device1_frobate(rs1, rs2);
-        case 42| 0 << 12  /* com.bigbucks:FrobateMach:frobate    : return device1_frobate_machine_level(rs1, rs2);
+        case 0 | 7 << 12  /* com.bigbucks:Frobate:frobate */     : return device1_frobate_machine_level(rs1, rs2);
         case 0 | 1 << 12  /* com.bigbucks:Frobate:foo */         : return device1_foo(rs1, rs2);
         case 0 | 2 << 12  /* com.bigbucks:Frobate:bar */         : return device1_bar(rs1, rs2);
         case 1 | 0 << 12  /* org.tinker.tinker:RocknRoll:rock */ : return device1_rock(rs1, rs2);
@@ -404,6 +413,7 @@ Example:
      }
      */
 
+     /* Device 2 implements Frobate and Jazz interfaces */
      long org_tinker_tinker__device2(short subdevice_xcmd,  lun_data_t rs1, long rs2)
      {
         switch(dev_cmd.interfId){
@@ -415,6 +425,7 @@ Example:
         }
      }
 
+     /* cpu assigns luns to the interfaces at different privilege levels on device1 and 2 to luns at manufacturing or boot up time */
      #define cpu__Device1__Frobate__lun   ((lun_t)32)
      #define cpu__Device1__RocknRoll__lun ((lun_t)33)
      #define cpu__Device2__Frobate__lun   ((lun_t)34)
@@ -444,9 +455,10 @@ Example:
             {{.uuid_devId = {org_tinker_tinker__RocknRoll__uuid, 0},        .priv = hyper}, .lun = cpu__Device2__Jazz__lun},
        }
    
+     /* cpu maps luns + privilege level to busaddress of device and particular subdevice according to spec of the device.*/
      /* struct lun2dev_subdevice_map[] */
         dev_subdevice_map = {
-//             .lun = 0,  will trap 
+    //         .lun = 0,  will trap 
              {{.lun = org_RiscV__Fallback__ReturnZero__lun,     .priv = user},  .devAddr_interfId = {fallback,    1 /* ReturnZero  */}},
              {{.lun = org_RiscV__Fallback__ReturnZero__lun,     .priv = super}, .devAddr_interfId = {fallback,    1 /* ReturnZero  */}},
              {{.lun = org_RiscV__Fallback__ReturnZero__lun,     .priv = hyper}, .devAddr_interfId = {fallback,    1 /* ReturnZero  */}},
@@ -457,7 +469,7 @@ Example:
              {{.lun = org_RiscV__Fallback__ReturnMinusOne__lun, .priv = mach},  .devAddr_interfId = {fallback,    2 /* ReturnMinusOne*/}},
      //       .lun = 3 .. 7  reserved for other fallback RV interfaces
      //       .lun = 8 .. 30 reserved as error numbers, c.li t1 31; bltu rd t1 L_fail tests errors
-     //      .lun = 31  reserved out of caution 
+     //       .lun = 31  reserved out of caution 
              {{.lun = cpu__Device1__Frobate__lun,               .priv = user},  .devAddr_interfId = {device1, 0 /* Frobate  interface */}},
              {{.lun = cpu__Device1__Frobate__lun,               .priv = super}, .devAddr_interfId = {device1, 0 /* Frobate  interface */}},
              {{.lun = cpu__Device1__Frobate__lun,               .priv = hyper}, .devAddr_interfId = {device1, 0 /* Frobate  interface */}},