Advertisement
Guest User

Untitled

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