1 // SPDX-License-Identifier: BSD-3-Clause
3 * Libpayload NVMe device driver
4 * Copyright (C) 2019 secunet Security Networks AG
12 #include <libpayload.h>
13 #include <storage/storage.h>
14 #include <storage/nvme.h>
16 #define NVME_CC_EN (1 << 0)
17 #define NVME_CC_CSS (0 << 4)
18 #define NVME_CC_MPS (0 << 7)
19 #define NVME_CC_AMS (0 << 11)
20 #define NVME_CC_SHN (0 << 14)
21 #define NVME_CC_IOSQES (6 << 16)
22 #define NVME_CC_IOCQES (4 << 20)
24 #define NVME_QUEUE_SIZE 2
25 #define NVME_SQ_ENTRY_SIZE 64
26 #define NVME_CQ_ENTRY_SIZE 16
29 storage_dev_t storage_dev
;
36 uint16_t idx
; // bool pos 0 or 1
37 uint16_t round
; // bool round 0 or 1+0xd
44 struct nvme_s_queue_entry
{
48 struct nvme_c_queue_entry
{
61 static storage_poll_t
nvme_poll(struct storage_dev
*dev
)
63 return POLL_MEDIUM_PRESENT
;
67 struct nvme_dev
*nvme
, enum nvme_queue q
, const struct nvme_s_queue_entry
*cmd
)
71 void *s_entry
= nvme
->queue
[sq
].base
+ (nvme
->queue
[sq
].idx
* NVME_SQ_ENTRY_SIZE
);
72 memcpy(s_entry
, cmd
, NVME_SQ_ENTRY_SIZE
);
73 nvme
->queue
[sq
].idx
= (nvme
->queue
[sq
].idx
+ 1) & (NVME_QUEUE_SIZE
- 1);
74 write32(nvme
->queue
[sq
].bell
, nvme
->queue
[sq
].idx
);
76 struct nvme_c_queue_entry
*c_entry
= nvme
->queue
[cq
].base
+
77 (nvme
->queue
[cq
].idx
* NVME_CQ_ENTRY_SIZE
);
78 while (((read32(&c_entry
->dw
[3]) >> 16) & 0x1) == nvme
->queue
[cq
].round
)
80 nvme
->queue
[cq
].idx
= (nvme
->queue
[cq
].idx
+ 1) & (NVME_QUEUE_SIZE
- 1);
81 write32(nvme
->queue
[cq
].bell
, nvme
->queue
[cq
].idx
);
82 if (nvme
->queue
[cq
].idx
== 0)
83 nvme
->queue
[cq
].round
= (nvme
->queue
[cq
].round
+ 1) & 1;
84 return c_entry
->dw
[3] >> 17;
87 static int delete_io_submission_queue(struct nvme_dev
*nvme
)
89 const struct nvme_s_queue_entry e
= {
94 int res
= nvme_cmd(nvme
, NVME_ADMIN_QUEUE
, &e
);
96 free(nvme
->queue
[ios
].base
);
97 nvme
->queue
[ios
].base
= NULL
;
98 nvme
->queue
[ios
].bell
= NULL
;
99 nvme
->queue
[ios
].idx
= 0;
103 static int delete_io_completion_queue(struct nvme_dev
*nvme
)
105 const struct nvme_s_queue_entry e
= {
110 int res
= nvme_cmd(nvme
, NVME_ADMIN_QUEUE
, &e
);
111 free(nvme
->queue
[ioc
].base
);
113 nvme
->queue
[ioc
].base
= NULL
;
114 nvme
->queue
[ioc
].bell
= NULL
;
115 nvme
->queue
[ioc
].idx
= 0;
116 nvme
->queue
[ioc
].round
= 0;
120 static int delete_admin_queues(struct nvme_dev
*nvme
)
122 if (nvme
->queue
[ios
].base
|| nvme
->queue
[ioc
].base
)
123 printf("NVMe ERROR: IO queues still active.\n");
125 free(nvme
->queue
[ads
].base
);
126 nvme
->queue
[ads
].base
= NULL
;
127 nvme
->queue
[ads
].bell
= NULL
;
128 nvme
->queue
[ads
].idx
= 0;
130 free(nvme
->queue
[adc
].base
);
131 nvme
->queue
[adc
].base
= NULL
;
132 nvme
->queue
[adc
].bell
= NULL
;
133 nvme
->queue
[adc
].idx
= 0;
134 nvme
->queue
[adc
].round
= 0;
139 static void nvme_detach_device(struct storage_dev
*dev
)
141 struct nvme_dev
*nvme
= (struct nvme_dev
*)dev
;
143 if (delete_io_submission_queue(nvme
))
144 printf("NVMe ERROR: Failed to delete io submission queue\n");
145 if (delete_io_completion_queue(nvme
))
146 printf("NVME ERROR: Failed to delete io completion queue\n");
147 if (delete_admin_queues(nvme
))
148 printf("NVME ERROR: Failed to delete admin queues\n");
150 write32(nvme
->config
+ 0x14, 0);
152 int status
, timeout
= (read64(nvme
->config
) >> 24 & 0xff) * 500;
154 status
= read32(nvme
->config
+ 0x1c) & 0x3;
156 printf("NVMe ERROR: Failed to disable controller. FATAL ERROR\n");
160 printf("NVMe ERROR: Failed to disable controller. Timeout.\n");
165 } while (status
!= 0x0);
167 uint16_t command
= pci_read_config16(nvme
->pci_dev
, PCI_COMMAND
);
168 pci_write_config16(nvme
->pci_dev
, PCI_COMMAND
, command
& ~PCI_COMMAND_MASTER
);
170 free(nvme
->prp_list
);
173 static int nvme_read(struct nvme_dev
*nvme
, unsigned char *buffer
, uint64_t base
, uint16_t count
)
175 if (count
== 0 || count
> 512)
178 struct nvme_s_queue_entry e
= {
181 .dw
[6] = virt_to_phys(buffer
),
183 .dw
[11] = base
>> 32,
187 const unsigned int start_page
= (uintptr_t)buffer
>> 12;
188 const unsigned int end_page
= ((uintptr_t)buffer
+ count
* 512 - 1) >> 12;
189 if (end_page
== start_page
) {
190 /* No page crossing, PRP2 is reserved */
191 } else if (end_page
== start_page
+ 1) {
192 /* Crossing exactly one page boundary, PRP2 is second page */
193 e
.dw
[8] = virt_to_phys(buffer
+ 0x1000) & ~0xfff;
195 /* Use a single page as PRP list, PRP2 points to the list */
197 for (i
= 0; i
< end_page
- start_page
; ++i
) {
199 nvme
->prp_list
[i
] = virt_to_phys(buffer
) & ~0xfff;
201 e
.dw
[8] = virt_to_phys(nvme
->prp_list
);
204 return nvme_cmd(nvme
, ios
, &e
);
207 static ssize_t
nvme_read_blocks512(
208 struct storage_dev
*const dev
,
209 const lba_t start
, const size_t count
, unsigned char *const buf
)
211 unsigned int off
= 0;
212 while (off
< count
) {
213 const unsigned int blocks
= MIN(count
- off
, 512);
214 if (nvme_read((struct nvme_dev
*)dev
, buf
+ (off
* 512), start
+ off
, blocks
))
221 static int create_io_submission_queue(struct nvme_dev
*nvme
)
223 void *sq_buffer
= memalign(0x1000, NVME_SQ_ENTRY_SIZE
* NVME_QUEUE_SIZE
);
225 printf("NVMe ERROR: Failed to allocate memory for io submission queue.\n");
228 memset(sq_buffer
, 0, NVME_SQ_ENTRY_SIZE
* NVME_QUEUE_SIZE
);
230 struct nvme_s_queue_entry e
= {
232 .dw
[6] = virt_to_phys(sq_buffer
),
233 .dw
[10] = ((NVME_QUEUE_SIZE
- 1) << 16) | ios
>> 1,
234 .dw
[11] = (1 << 16) | 1,
237 int res
= nvme_cmd(nvme
, NVME_ADMIN_QUEUE
, &e
);
239 printf("NVMe ERROR: nvme_cmd returned with %i.\n", res
);
244 uint8_t cap_dstrd
= (read64(nvme
->config
) >> 32) & 0xf;
245 nvme
->queue
[ios
].base
= sq_buffer
;
246 nvme
->queue
[ios
].bell
= nvme
->config
+ 0x1000 + (ios
* (4 << cap_dstrd
));
247 nvme
->queue
[ios
].idx
= 0;
251 static int create_io_completion_queue(struct nvme_dev
*nvme
)
253 void *const cq_buffer
= memalign(0x1000, NVME_CQ_ENTRY_SIZE
* NVME_QUEUE_SIZE
);
255 printf("NVMe ERROR: Failed to allocate memory for io completion queue.\n");
258 memset(cq_buffer
, 0, NVME_CQ_ENTRY_SIZE
* NVME_QUEUE_SIZE
);
260 const struct nvme_s_queue_entry e
= {
262 .dw
[6] = virt_to_phys(cq_buffer
),
263 .dw
[10] = ((NVME_QUEUE_SIZE
- 1) << 16) | ioc
>> 1,
267 int res
= nvme_cmd(nvme
, NVME_ADMIN_QUEUE
, &e
);
269 printf("NVMe ERROR: nvme_cmd returned with %i.\n", res
);
274 uint8_t cap_dstrd
= (read64(nvme
->config
) >> 32) & 0xf;
275 nvme
->queue
[ioc
].base
= cq_buffer
;
276 nvme
->queue
[ioc
].bell
= nvme
->config
+ 0x1000 + (ioc
* (4 << cap_dstrd
));
277 nvme
->queue
[ioc
].idx
= 0;
278 nvme
->queue
[ioc
].round
= 0;
283 static int create_admin_queues(struct nvme_dev
*nvme
)
285 uint8_t cap_dstrd
= (read64(nvme
->config
) >> 32) & 0xf;
286 write32(nvme
->config
+ 0x24, (NVME_QUEUE_SIZE
- 1) << 16 | (NVME_QUEUE_SIZE
- 1));
288 void *sq_buffer
= memalign(0x1000, NVME_SQ_ENTRY_SIZE
* NVME_QUEUE_SIZE
);
290 printf("NVMe ERROR: Failed to allocated memory for admin submission queue\n");
293 memset(sq_buffer
, 0, NVME_SQ_ENTRY_SIZE
* NVME_QUEUE_SIZE
);
294 write64(nvme
->config
+ 0x28, virt_to_phys(sq_buffer
));
296 nvme
->queue
[ads
].base
= sq_buffer
;
297 nvme
->queue
[ads
].bell
= nvme
->config
+ 0x1000 + (ads
* (4 << cap_dstrd
));
298 nvme
->queue
[ads
].idx
= 0;
300 void *cq_buffer
= memalign(0x1000, NVME_CQ_ENTRY_SIZE
* NVME_QUEUE_SIZE
);
302 printf("NVMe ERROR: Failed to allocate memory for admin completion queue\n");
306 memset(cq_buffer
, 0, NVME_CQ_ENTRY_SIZE
* NVME_QUEUE_SIZE
);
307 write64(nvme
->config
+ 0x30, virt_to_phys(cq_buffer
));
309 nvme
->queue
[adc
].base
= cq_buffer
;
310 nvme
->queue
[adc
].bell
= nvme
->config
+ 0x1000 + (adc
* (4 << cap_dstrd
));
311 nvme
->queue
[adc
].idx
= 0;
312 nvme
->queue
[adc
].round
= 0;
317 static void nvme_init(pcidev_t dev
)
319 printf("NVMe init (Device %02x:%02x.%02x)\n",
320 PCI_BUS(dev
), PCI_SLOT(dev
), PCI_FUNC(dev
));
322 void *pci_bar0
= phys_to_virt(pci_read_config32(dev
, 0x10) & ~0x3ff);
324 if (!(read64(pci_bar0
) >> 37 & 0x01)) {
325 printf("NVMe ERROR: PCIe device does not support the NVMe command set\n");
328 struct nvme_dev
*nvme
= malloc(sizeof(*nvme
));
330 printf("NVMe ERROR: Failed to allocate buffer for nvme driver struct\n");
333 nvme
->storage_dev
.port_type
= PORT_TYPE_NVME
;
334 nvme
->storage_dev
.poll
= nvme_poll
;
335 nvme
->storage_dev
.read_blocks512
= nvme_read_blocks512
;
336 nvme
->storage_dev
.write_blocks512
= NULL
;
337 nvme
->storage_dev
.detach_device
= nvme_detach_device
;
339 nvme
->config
= pci_bar0
;
340 nvme
->prp_list
= memalign(0x1000, 0x1000);
342 if (!nvme
->prp_list
) {
343 printf("NVMe ERROR: Failed to allocate buffer for PRP list\n");
347 const uint32_t cc
= NVME_CC_EN
| NVME_CC_CSS
| NVME_CC_MPS
| NVME_CC_AMS
| NVME_CC_SHN
348 | NVME_CC_IOSQES
| NVME_CC_IOCQES
;
350 write32(nvme
->config
+ 0x14, 0);
352 int status
, timeout
= (read64(nvme
->config
) >> 24 & 0xff) * 500;
354 status
= read32(nvme
->config
+ 0x1c) & 0x3;
356 printf("NVMe ERROR: Failed to disable controller. FATAL ERROR\n");
360 printf("NVMe ERROR: Failed to disable controller. Timeout.\n");
365 } while (status
!= 0x0);
366 if (create_admin_queues(nvme
))
368 write32(nvme
->config
+ 0x14, cc
);
370 timeout
= (read64(nvme
->config
) >> 24 & 0xff) * 500;
372 status
= read32(nvme
->config
+ 0x1c) & 0x3;
374 goto _delete_admin_abort
;
376 goto _delete_admin_abort
;
379 } while (status
!= 0x1);
381 uint16_t command
= pci_read_config16(dev
, PCI_COMMAND
);
382 pci_write_config16(dev
, PCI_COMMAND
, command
| PCI_COMMAND_MASTER
);
383 if (create_io_completion_queue(nvme
))
384 goto _delete_admin_abort
;
385 if (create_io_submission_queue(nvme
))
386 goto _delete_completion_abort
;
387 storage_attach_device((storage_dev_t
*)nvme
);
388 printf("NVMe init done.\n");
391 _delete_completion_abort
:
392 delete_io_completion_queue(nvme
);
394 delete_admin_queues(nvme
);
396 free(nvme
->prp_list
);
398 printf("NVMe init failed.\n");
401 void nvme_initialize(struct pci_dev
*dev
)
403 nvme_init(PCI_DEV(dev
->bus
, dev
->dev
, dev
->func
));