Advertisement
Guest User

Untitled

a guest
Oct 25th, 2024
40
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.33 KB | None | 0 0
  1. void nvme_io_wait(uint32_t *iocqb_copy)
  2. {
  3.     uint32_t val;
  4.  
  5.     do{
  6.         val = *iocqb_copy;
  7.     }while(val == 0);
  8.  
  9.     display("iocq: status field plus phase tag value: {p}\n", (void *) *(uint16_t *) ((char *) iocqb_copy + 2));
  10.    
  11.     *iocqb_copy = 0; // Overwrite the old entry
  12. }  
  13.  
  14. void nvme_io_savetail(uint32_t io_tail_val, volatile char* nvme_iotail, uint32_t old_tail_val)
  15. {
  16.     char *iocqb_copy = nvme_iocqb;
  17.  
  18.     *nvme_iotail = io_tail_val; // Save the tail for the next command
  19.  
  20.     *((volatile uint32_t *) ((char *) nvme_base + 0x1008)) = io_tail_val; // Write the new tail value
  21.    
  22.     // Check completion queue
  23.     old_tail_val = old_tail_val * 16;   // Each entry is 16 bytes
  24.     old_tail_val = old_tail_val + 12;   // Add 12 for DW3
  25.    
  26.     iocqb_copy += old_tail_val;
  27.  
  28.     nvme_io_wait(iocqb_copy);
  29. }
  30.  
  31. /*
  32.  * copy data from ssd partition to the partition data buffer
  33.  */
  34. char *copy_data_from_ssd_partition(uint32_t starting_sector, uint32_t num_blocks)
  35. {
  36.     uint32_t cdw0 = 0x00000002; // CDW0 CID 0, PRP used (15:14 clear), FUSE normal (bits 9:8 clear), command read (0x02)
  37.     uint32_t cdw1 = 1;  // CDW1 NSID
  38.     uint32_t cdw10_11 = starting_sector;        // CDW10_11
  39.     uint32_t cdw12 = num_blocks - 1;    /* number of logical blocks to be read */
  40.  
  41.     char *nvme_iosqb_ptr = nvme_iosqb;
  42.     uint32_t tmp, io_tail_val = 0;
  43.  
  44.     // Build the command at the expected location in the Submission ring
  45.     io_tail_val = *nvme_iotail; // Get the current io tail value
  46.  
  47.     io_tail_val *= 64;          // Quick multiply by 64
  48.  
  49.     nvme_iosqb_ptr += io_tail_val;
  50.  
  51.     // Build the structure
  52.     *(uint32_t *) nvme_iosqb_ptr = cdw0;    // CDW0
  53.     *(uint32_t *) (nvme_iosqb_ptr + 4) = cdw1;  // CDW1
  54.     *(uint32_t *) (nvme_iosqb_ptr + 8) = 0; // CDW2
  55.     *(uint32_t *) (nvme_iosqb_ptr + 12) = 0;    // CDW3
  56.     *(uint64_t *) (nvme_iosqb_ptr + 16) = 0;    // CDW4-5
  57.     *(uint64_t *) (nvme_iosqb_ptr + 24) = (uint64_t) partition_data_buffer; // CDW6-7
  58.     *(uint64_t *) (nvme_iosqb_ptr + 32) = 0;    // CDW8-9
  59.     *(uint64_t *) (nvme_iosqb_ptr + 40) = cdw10_11; // CDW10_11
  60.     *(uint32_t *) (nvme_iosqb_ptr + 48) = cdw12;    // CDW12
  61.     *(uint32_t *) (nvme_iosqb_ptr + 52) = 0;    // CDW13
  62.     *(uint32_t *) (nvme_iosqb_ptr + 56) = 0;    // CDW14
  63.     *(uint32_t *) (nvme_iosqb_ptr + 60) = 0;    // CDW15
  64.    
  65.  
  66.     // Start the read command by updating the tail doorbell
  67.     io_tail_val = *nvme_iotail; // Get the current io tail value
  68.     tmp = io_tail_val;  // Save the old io tail value for reading from the completion ring
  69.     io_tail_val++;          // Add 1 to it
  70.    
  71.     if(io_tail_val>= 64)
  72.         io_tail_val = 0;
  73.  
  74.     nvme_io_savetail(io_tail_val, nvme_iotail, tmp);
  75.  
  76.     return partition_data_buffer;
  77. }
  78.  
  79. /*
  80.  * paste data from the partition data buffer into the ssd partition.
  81.  */
  82. void paste_data_into_ssd_partition(uint32_t starting_sector, uint32_t num_blocks)
  83. {
  84.     uint32_t cdw0 = 0x00000001; // CDW0 CID 0, PRP used (15:14 clear), FUSE normal (bits 9:8 clear), command write (0x01)
  85.     uint32_t cdw1 = 1;  // CDW1 NSID
  86.     uint32_t cdw10_11 = starting_sector;        // CDW10_11
  87.     uint32_t cdw12 = num_blocks - 1;    /* number of logical blocks to be written */
  88.  
  89.  
  90.     char *nvme_iosqb_ptr = nvme_iosqb;
  91.     uint32_t tmp, io_tail_val = 0;
  92.  
  93.     // Build the command at the expected location in the Submission ring
  94.     io_tail_val = *nvme_iotail; // Get the current io tail value
  95.  
  96.     io_tail_val *= 64;          // Quick multiply by 64
  97.                             //
  98.     nvme_iosqb_ptr += io_tail_val;
  99.  
  100.     // Build the structure
  101.     *(uint32_t *) nvme_iosqb_ptr = cdw0;    // CDW0
  102.     *(uint32_t *) (nvme_iosqb_ptr + 4) = cdw1;  // CDW1
  103.     *(uint32_t *) (nvme_iosqb_ptr + 8) = 0; // CDW2
  104.     *(uint32_t *) (nvme_iosqb_ptr + 12) = 0;    // CDW3
  105.     *(uint64_t *) (nvme_iosqb_ptr + 16) = 0;    // CDW4-5
  106.     *(uint64_t *) (nvme_iosqb_ptr + 24) = (uint64_t) partition_data_buffer; // CDW6-7
  107.     *(uint64_t *) (nvme_iosqb_ptr + 32) = 0;    // CDW8-9
  108.     *(uint64_t *) (nvme_iosqb_ptr + 40) = cdw10_11; // CDW10_11
  109.     *(uint32_t *) (nvme_iosqb_ptr + 48) = cdw12;    // CDW12
  110.     *(uint32_t *) (nvme_iosqb_ptr + 52) = 0;    // CDW13
  111.     *(uint32_t *) (nvme_iosqb_ptr + 56) = 0;    // CDW14
  112.     *(uint32_t *) (nvme_iosqb_ptr + 60) = 0;    // CDW15
  113.                                 //
  114.    
  115.     // Start the write command by updating the tail doorbell
  116.     io_tail_val = 0;
  117.     io_tail_val = *nvme_iotail; // Get the current io tail value
  118.     tmp = io_tail_val;  // Save the old io tail value for reading from the completion ring
  119.     io_tail_val++;          // Add 1 to it
  120.    
  121.     if(io_tail_val>= 64)
  122.         io_tail_val = 0;
  123.  
  124.     nvme_io_savetail(io_tail_val, nvme_iotail, tmp);
  125. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement