NVMe controller returns fatal error flag in CSTS register after submitting first command

0

I'm trying to initialize an NVMe SSD on a 32-bit PowerPC board just enough to issue the identity command. I don't have an operating system.
These are the steps I've taken:

  • Disable dcache
  • Find the SDD
  • Get bar0, strip off the last nybble, and use that as the control area address (a volatile struct)
  • Allocate some memory for the admin completion and submission queues: 16*64 bytes for submission, 256 bytes for completion. That's 16 entries for both
  • Set AQA in the control area to ENDIAN_FLIP((16<<16)|16) because I have 16 entries for each
  • Zero out the queues with memset
  • Set ASQ and ACQ to their respective addresses (Endian flipped)
  • Ensure EN in CSTS is not enabled by comparing it bitwise with 0x01000000
  • Enable controller by setting CC to 0x01000000
  • Wait for CSTS to notify it's enabled. This works so far
  • Ensure CSTS doesn't contain fatal error flag. Works
  • Allocate a 4096kb memory block for identify controller response
  • Form submission entry from struct:
    • .cdw0 = ENDIAN_FLIP(0x00000006)//identify command
    • .prp1 = ENDIAN_FLIP(block_address_32bit)//loading 32-bit address into 64-bit space
    • .cdw10 = ENDIAN_FLIP(0x00000001)//identify controller
  • Copy struct to submission queue[0]
  • Increment tail doorbell register locally (from 0 to 1)
  • set tail doorbell register in NVMe control area to ENDIAN_FLIP(local_tail_doorbell_counter)
  • Check that CSTS doesn't have fatal flag. FAILS HERE: CSTS returns 0x03000000, which means NVMe controller is enabled and a fatal error has occurred

Is there any idea on what's gone wrong, or what I could do to find better error information?
I've been reading the spec, and it seems like I'm doing everything right :/

powerpc
bare-metal
nvme
asked on Stack Overflow Jan 6, 2021 by SunshineToast

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0