Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void nvme_io_wait(uint32_t *iocqb_copy)
- {
- uint32_t val;
- do{
- val = *iocqb_copy;
- }while(val == 0);
- display("iocq: status field plus phase tag value: {p}\n", (void *) *(uint16_t *) ((char *) iocqb_copy + 2));
- *iocqb_copy = 0; // Overwrite the old entry
- }
- void nvme_io_savetail(uint32_t io_tail_val, volatile char* nvme_iotail, uint32_t old_tail_val)
- {
- char *iocqb_copy = nvme_iocqb;
- *nvme_iotail = io_tail_val; // Save the tail for the next command
- *((volatile uint32_t *) ((char *) nvme_base + 0x1008)) = io_tail_val; // Write the new tail value
- // Check completion queue
- old_tail_val = old_tail_val * 16; // Each entry is 16 bytes
- old_tail_val = old_tail_val + 12; // Add 12 for DW3
- iocqb_copy += old_tail_val;
- nvme_io_wait(iocqb_copy);
- }
- /*
- * copy data from ssd partition to the partition data buffer
- */
- char *copy_data_from_ssd_partition(uint32_t starting_sector, uint32_t num_blocks)
- {
- uint32_t cdw0 = 0x00000002; // CDW0 CID 0, PRP used (15:14 clear), FUSE normal (bits 9:8 clear), command read (0x02)
- uint32_t cdw1 = 1; // CDW1 NSID
- uint32_t cdw10_11 = starting_sector; // CDW10_11
- uint32_t cdw12 = num_blocks - 1; /* number of logical blocks to be read */
- char *nvme_iosqb_ptr = nvme_iosqb;
- uint32_t tmp, io_tail_val = 0;
- // Build the command at the expected location in the Submission ring
- io_tail_val = *nvme_iotail; // Get the current io tail value
- io_tail_val *= 64; // Quick multiply by 64
- nvme_iosqb_ptr += io_tail_val;
- // Build the structure
- *(uint32_t *) nvme_iosqb_ptr = cdw0; // CDW0
- *(uint32_t *) (nvme_iosqb_ptr + 4) = cdw1; // CDW1
- *(uint32_t *) (nvme_iosqb_ptr + 8) = 0; // CDW2
- *(uint32_t *) (nvme_iosqb_ptr + 12) = 0; // CDW3
- *(uint64_t *) (nvme_iosqb_ptr + 16) = 0; // CDW4-5
- *(uint64_t *) (nvme_iosqb_ptr + 24) = (uint64_t) partition_data_buffer; // CDW6-7
- *(uint64_t *) (nvme_iosqb_ptr + 32) = 0; // CDW8-9
- *(uint64_t *) (nvme_iosqb_ptr + 40) = cdw10_11; // CDW10_11
- *(uint32_t *) (nvme_iosqb_ptr + 48) = cdw12; // CDW12
- *(uint32_t *) (nvme_iosqb_ptr + 52) = 0; // CDW13
- *(uint32_t *) (nvme_iosqb_ptr + 56) = 0; // CDW14
- *(uint32_t *) (nvme_iosqb_ptr + 60) = 0; // CDW15
- // Start the read command by updating the tail doorbell
- io_tail_val = *nvme_iotail; // Get the current io tail value
- tmp = io_tail_val; // Save the old io tail value for reading from the completion ring
- io_tail_val++; // Add 1 to it
- if(io_tail_val>= 64)
- io_tail_val = 0;
- nvme_io_savetail(io_tail_val, nvme_iotail, tmp);
- return partition_data_buffer;
- }
- /*
- * paste data from the partition data buffer into the ssd partition.
- */
- void paste_data_into_ssd_partition(uint32_t starting_sector, uint32_t num_blocks)
- {
- uint32_t cdw0 = 0x00000001; // CDW0 CID 0, PRP used (15:14 clear), FUSE normal (bits 9:8 clear), command write (0x01)
- uint32_t cdw1 = 1; // CDW1 NSID
- uint32_t cdw10_11 = starting_sector; // CDW10_11
- uint32_t cdw12 = num_blocks - 1; /* number of logical blocks to be written */
- char *nvme_iosqb_ptr = nvme_iosqb;
- uint32_t tmp, io_tail_val = 0;
- // Build the command at the expected location in the Submission ring
- io_tail_val = *nvme_iotail; // Get the current io tail value
- io_tail_val *= 64; // Quick multiply by 64
- //
- nvme_iosqb_ptr += io_tail_val;
- // Build the structure
- *(uint32_t *) nvme_iosqb_ptr = cdw0; // CDW0
- *(uint32_t *) (nvme_iosqb_ptr + 4) = cdw1; // CDW1
- *(uint32_t *) (nvme_iosqb_ptr + 8) = 0; // CDW2
- *(uint32_t *) (nvme_iosqb_ptr + 12) = 0; // CDW3
- *(uint64_t *) (nvme_iosqb_ptr + 16) = 0; // CDW4-5
- *(uint64_t *) (nvme_iosqb_ptr + 24) = (uint64_t) partition_data_buffer; // CDW6-7
- *(uint64_t *) (nvme_iosqb_ptr + 32) = 0; // CDW8-9
- *(uint64_t *) (nvme_iosqb_ptr + 40) = cdw10_11; // CDW10_11
- *(uint32_t *) (nvme_iosqb_ptr + 48) = cdw12; // CDW12
- *(uint32_t *) (nvme_iosqb_ptr + 52) = 0; // CDW13
- *(uint32_t *) (nvme_iosqb_ptr + 56) = 0; // CDW14
- *(uint32_t *) (nvme_iosqb_ptr + 60) = 0; // CDW15
- //
- // Start the write command by updating the tail doorbell
- io_tail_val = 0;
- io_tail_val = *nvme_iotail; // Get the current io tail value
- tmp = io_tail_val; // Save the old io tail value for reading from the completion ring
- io_tail_val++; // Add 1 to it
- if(io_tail_val>= 64)
- io_tail_val = 0;
- nvme_io_savetail(io_tail_val, nvme_iotail, tmp);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement