VirtualBox

source: vbox/trunk/src/VBox/Devices/PC/BIOS/virtio.c@ 81899

Last change on this file since 81899 was 81407, checked in by vboxsync, 6 years ago

PC/BIOS/virtio.c: Updates

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 34.4 KB
Line 
1/* $Id: virtio.c 81407 2019-10-21 13:08:46Z vboxsync $ */
2/** @file
3 * VirtIO-SCSI host adapter driver to boot from disks.
4 */
5
6/*
7 * Copyright (C) 2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include <stdint.h>
19#include <string.h>
20#include "biosint.h"
21#include "ebda.h"
22#include "inlines.h"
23#include "pciutil.h"
24#include "vds.h"
25#include "scsi.h"
26
27#define DEBUG_VIRTIO 1
28#if DEBUG_VIRTIO
29# define DBG_VIRTIO(...) BX_INFO(__VA_ARGS__)
30#else
31# define DBG_VIRTIO(...)
32#endif
33
34#define VBSCSI_MAX_DEVICES 16 /* Maximum number of devices a SCSI device currently supported. */
35
36/* The maximum CDB size. */
37#define VIRTIO_SCSI_CDB_SZ 16
38/** Maximum sense data to return. */
39#define VIRTIO_SCSI_SENSE_SZ 32
40
41#define VIRTIO_SCSI_RING_ELEM 3
42
43/**
44 * VirtIO queue descriptor.
45 */
46typedef struct
47{
48 /** 64bit guest physical address of the buffer, split into high and low part because we work in real mode. */
49 uint32_t GCPhysBufLow;
50 uint32_t GCPhysBufHigh;
51 /** Length of the buffer in bytes. */
52 uint32_t cbBuf;
53 /** Flags for the buffer. */
54 uint16_t fFlags;
55 /** Next field where the buffer is continued if _NEXT flag is set. */
56 uint16_t idxNext;
57} virtio_q_desc_t;
58
59#define VIRTIO_Q_DESC_F_NEXT 0x1
60#define VIRTIO_Q_DESC_F_WRITE 0x2
61#define VIRTIO_Q_DESC_F_INDIRECT 0x4
62
63/**
64 * VirtIO available ring.
65 */
66typedef struct
67{
68 /** Flags. */
69 uint16_t fFlags;
70 /** Next index to write an available buffer by the driver. */
71 uint16_t idxNextFree;
72 /** The ring - we only provide one entry. */
73 uint16_t au16Ring[VIRTIO_SCSI_RING_ELEM];
74 /** Used event index. */
75 uint16_t u16EvtUsed;
76} virtio_q_avail_t;
77
78/**
79 * VirtIO queue used element.
80 */
81typedef struct
82{
83 /** Index of the start of the descriptor chain. */
84 uint32_t u32Id;
85 /** Number of bytes used in the descriptor chain. */
86 uint32_t cbUsed;
87} virtio_q_used_elem_t;
88
89/**
90 * VirtIo used ring.
91 */
92typedef struct
93{
94 /** Flags. */
95 volatile uint16_t fFlags;
96 /** Index where the next entry would be written by the device. */
97 volatile uint16_t idxNextUsed;
98 /** The used ring. */
99 virtio_q_used_elem_t aRing[VIRTIO_SCSI_RING_ELEM];
100} virtio_q_used_t;
101
102/**
103 * VirtIO queue structure we are using, needs to be aligned on a 16byte boundary.
104 */
105typedef struct
106{
107 /** The descriptor table, using 4 max. */
108 virtio_q_desc_t aDescTbl[4];
109 /** Available ring. */
110 virtio_q_avail_t AvailRing;
111 /** Used ring. */
112 virtio_q_used_t UsedRing;
113 /** The notification offset for the queue. */
114 uint32_t offNotify;
115} virtio_q_t;
116
117/**
118 * VirtIO SCSI request structure passed in the queue.
119 */
120typedef struct
121{
122 /** The LUN to address. */
123 uint8_t au8Lun[8];
124 /** Request ID - split into low and high part. */
125 uint32_t u32IdLow;
126 uint32_t u32IdHigh;
127 /** Task attributes. */
128 uint8_t u8TaskAttr;
129 /** Priority. */
130 uint8_t u8Prio;
131 /** CRN value, usually 0. */
132 uint8_t u8Crn;
133 /** The CDB. */
134 uint8_t abCdb[VIRTIO_SCSI_CDB_SZ];
135} virtio_scsi_req_hdr_t;
136
137/**
138 * VirtIO SCSI status structure filled by the device.
139 */
140typedef struct
141{
142 /** Returned sense length. */
143 uint32_t cbSense;
144 /** Residual amount of bytes left. */
145 uint32_t cbResidual;
146 /** Status qualifier. */
147 uint16_t u16StatusQual;
148 /** Status code. */
149 uint8_t u8Status;
150 /** Response code. */
151 uint8_t u8Response;
152 /** Sense data. */
153 uint8_t abSense[VIRTIO_SCSI_SENSE_SZ];
154} virtio_scsi_req_sts_t;
155
156/**
157 * VirtIO config for the different data structures.
158 */
159typedef struct
160{
161 /** BAR where to find it. */
162 uint8_t u8Bar;
163 /** Padding. */
164 uint8_t abPad[3];
165 /** Offset within the bar. */
166 uint32_t u32Offset;
167 /** Length of the structure in bytes. */
168 uint32_t u32Length;
169} virtio_bar_cfg_t;
170
171/**
172 * VirtIO PCI capability structure.
173 */
174typedef struct
175{
176 /** Capability typem should always be PCI_CAP_ID_VNDR*/
177 uint8_t u8PciCapId;
178 /** Offset where to find the next capability or 0 if last capability. */
179 uint8_t u8PciCapNext;
180 /** Size of the capability in bytes. */
181 uint8_t u8PciCapLen;
182 /** VirtIO capability type. */
183 uint8_t u8VirtIoCfgType;
184 /** BAR where to find it. */
185 uint8_t u8Bar;
186 /** Padding. */
187 uint8_t abPad[3];
188 /** Offset within the bar. */
189 uint32_t u32Offset;
190 /** Length of the structure in bytes. */
191 uint32_t u32Length;
192} virtio_pci_cap_t;
193
194/**
195 * VirtIO-SCSI controller data.
196 */
197typedef struct
198{
199 /** The queue used - must be first for alignment reasons. */
200 virtio_q_t Queue;
201 /** The BAR configs read from the PCI configuration space, see VIRTIO_PCI_CAP_*_CFG,
202 * only use 4 because VIRTIO_PCI_CAP_PCI_CFG is not part of this. */
203 virtio_bar_cfg_t aBarCfgs[4];
204 /** The start offset in the PCI configuration space where to find the VIRTIO_PCI_CAP_PCI_CFG
205 * capability for the alternate access method to the registers. */
206 uint8_t u8PciCfgOff;
207 /** The notification offset multiplier. */
208 uint32_t u32NotifyOffMult;
209 /** PCI bus where the device is located. */
210 uint8_t u8Bus;
211 /** Device/Function number. */
212 uint8_t u8DevFn;
213 /** Saved high bits of EAX. */
214 uint16_t saved_eax_hi;
215 /** The current executed command structure. */
216 virtio_scsi_req_hdr_t ScsiReqHdr;
217 virtio_scsi_req_sts_t ScsiReqSts;
218} virtio_t;
219
220/* The VirtIO specific data must fit into 1KB (statically allocated). */
221ct_assert(sizeof(virtio_t) <= 1024);
222
223/** PCI configuration fields. */
224#define PCI_CONFIG_CAP 0x34
225
226#define PCI_CAP_ID_VNDR 0x09
227#define VBOX_VIRTIO_NO_DEVICE 0xffff
228
229#define VBOX_VIRTIO_NIL_CFG 0xff
230
231#define VIRTIO_PCI_CAP_COMMON_CFG 0x01
232#define VIRTIO_PCI_CAP_NOTIFY_CFG 0x02
233#define VIRTIO_PCI_CAP_ISR_CFG 0x03
234#define VIRTIO_PCI_CAP_DEVICE_CFG 0x04
235#define VIRTIO_PCI_CAP_PCI_CFG 0x05
236
237#define RT_BIT_32(bit) ((uint32_t)(1L << (bit)))
238
239#define VIRTIO_COMMON_REG_DEV_FEAT_SLCT 0x00
240#define VIRTIO_COMMON_REG_DEV_FEAT 0x04
241# define VIRTIO_CMN_REG_DEV_FEAT_SCSI_INOUT 0x01
242#define VIRTIO_COMMON_REG_DRV_FEAT_SLCT 0x08
243#define VIRTIO_COMMON_REG_DRV_FEAT 0x0c
244#define VIRTIO_COMMON_REG_MSIX_CFG 0x10
245#define VIRTIO_COMMON_REG_NUM_QUEUES 0x12
246#define VIRTIO_COMMON_REG_DEV_STS 0x14
247# define VIRTIO_CMN_REG_DEV_STS_F_RST 0x00
248# define VIRTIO_CMN_REG_DEV_STS_F_ACK 0x01
249# define VIRTIO_CMN_REG_DEV_STS_F_DRV 0x02
250# define VIRTIO_CMN_REG_DEV_STS_F_DRV_OK 0x04
251# define VIRTIO_CMN_REG_DEV_STS_F_FEAT_OK 0x08
252# define VIRTIO_CMN_REG_DEV_STS_F_DEV_RST 0x40
253# define VIRTIO_CMN_REG_DEV_STS_F_FAILED 0x80
254#define VIRTIO_COMMON_REG_CFG_GEN 0x15
255
256#define VIRTIO_COMMON_REG_Q_SELECT 0x16
257#define VIRTIO_COMMON_REG_Q_SIZE 0x18
258#define VIRTIO_COMMON_REG_Q_MSIX_VEC 0x1a
259#define VIRTIO_COMMON_REG_Q_ENABLE 0x1c
260#define VIRTIO_COMMON_REG_Q_NOTIFY_OFF 0x1e
261#define VIRTIO_COMMON_REG_Q_DESC 0x20
262#define VIRTIO_COMMON_REG_Q_DRIVER 0x28
263#define VIRTIO_COMMON_REG_Q_DEVICE 0x30
264
265#define VIRTIO_DEV_CFG_REG_Q_NUM 0x00
266#define VIRTIO_DEV_CFG_REG_SEG_MAX 0x04
267#define VIRTIO_DEV_CFG_REG_SECT_MAX 0x08
268#define VIRTIO_DEV_CFG_REG_CMD_PER_LUN 0x0c
269#define VIRTIO_DEV_CFG_REG_EVT_INFO_SZ 0x10
270#define VIRTIO_DEV_CFG_REG_SENSE_SZ 0x14
271#define VIRTIO_DEV_CFG_REG_CDB_SZ 0x18
272#define VIRTIO_DEV_CFG_REG_MAX_CHANNEL 0x1c
273#define VIRTIO_DEV_CFG_REG_MAX_TGT 0x1e
274#define VIRTIO_DEV_CFG_REG_MAX_LUN 0x20
275
276#define VIRTIO_SCSI_Q_CONTROL 0x00
277#define VIRTIO_SCSI_Q_EVENT 0x01
278#define VIRTIO_SCSI_Q_REQUEST 0x02
279
280/* Machinery to save/restore high bits of EAX. 32-bit port I/O needs to use
281 * EAX, but saving/restoring EAX around each port access would be inefficient.
282 * Instead, each externally callable routine must save the high bits before
283 * modifying them and restore the high bits before exiting.
284 */
285
286/* Note: Reading high EAX bits destroys them - *must* be restored later. */
287uint16_t eax_hi_rd(void);
288#pragma aux eax_hi_rd = \
289 ".386" \
290 "shr eax, 16" \
291 value [ax] modify nomemory;
292
293void eax_hi_wr(uint16_t);
294#pragma aux eax_hi_wr = \
295 ".386" \
296 "shl eax, 16" \
297 parm [ax] modify nomemory;
298
299void inline high_bits_save(virtio_t __far *virtio)
300{
301 virtio->saved_eax_hi = eax_hi_rd();
302}
303
304void inline high_bits_restore(virtio_t __far *virtio)
305{
306 eax_hi_wr(virtio->saved_eax_hi);
307}
308
309static void virtio_reg_set_bar_offset_length(virtio_t __far *virtio, uint8_t u8Bar, uint32_t offReg, uint32_t cb)
310{
311 pci_write_config_byte(virtio->u8Bus, virtio->u8DevFn, virtio->u8PciCfgOff + 4, u8Bar);
312 pci_write_config_dword(virtio->u8Bus, virtio->u8DevFn, virtio->u8PciCfgOff + 8, offReg);
313 pci_write_config_dword(virtio->u8Bus, virtio->u8DevFn, virtio->u8PciCfgOff + 12, cb);
314}
315
316static void virtio_reg_common_access_prepare(virtio_t __far *virtio, uint16_t offReg, uint32_t cbAcc)
317{
318 virtio_reg_set_bar_offset_length(virtio,
319 virtio->aBarCfgs[VIRTIO_PCI_CAP_COMMON_CFG - 1].u8Bar,
320 virtio->aBarCfgs[VIRTIO_PCI_CAP_COMMON_CFG - 1].u32Offset + offReg,
321 cbAcc);
322}
323
324static void virtio_reg_dev_access_prepare(virtio_t __far *virtio, uint16_t offReg, uint32_t cbAcc)
325{
326 virtio_reg_set_bar_offset_length(virtio,
327 virtio->aBarCfgs[VIRTIO_PCI_CAP_DEVICE_CFG - 1].u8Bar,
328 virtio->aBarCfgs[VIRTIO_PCI_CAP_DEVICE_CFG - 1].u32Offset + offReg,
329 cbAcc);
330}
331
332static void virtio_reg_notify_access_prepare(virtio_t __far *virtio, uint16_t offReg, uint32_t cbAcc)
333{
334 virtio_reg_set_bar_offset_length(virtio,
335 virtio->aBarCfgs[VIRTIO_PCI_CAP_NOTIFY_CFG - 1].u8Bar,
336 virtio->aBarCfgs[VIRTIO_PCI_CAP_NOTIFY_CFG - 1].u32Offset + offReg,
337 cbAcc);
338}
339
340static uint8_t virtio_reg_common_read_u8(virtio_t __far *virtio, uint16_t offReg)
341{
342 virtio_reg_common_access_prepare(virtio, offReg, sizeof(uint8_t));
343 return pci_read_config_byte(virtio->u8Bus, virtio->u8DevFn, virtio->u8PciCfgOff + sizeof(virtio_pci_cap_t));
344}
345
346static void virtio_reg_common_write_u8(virtio_t __far *virtio, uint16_t offReg, uint8_t u8Val)
347{
348 virtio_reg_common_access_prepare(virtio, offReg, sizeof(uint8_t));
349 pci_write_config_byte(virtio->u8Bus, virtio->u8DevFn, virtio->u8PciCfgOff + sizeof(virtio_pci_cap_t), u8Val);
350}
351
352static uint16_t virtio_reg_common_read_u16(virtio_t __far *virtio, uint16_t offReg)
353{
354 virtio_reg_common_access_prepare(virtio, offReg, sizeof(uint16_t));
355 return pci_read_config_word(virtio->u8Bus, virtio->u8DevFn, virtio->u8PciCfgOff + sizeof(virtio_pci_cap_t));
356}
357
358static void virtio_reg_common_write_u16(virtio_t __far *virtio, uint16_t offReg, uint16_t u16Val)
359{
360 virtio_reg_common_access_prepare(virtio, offReg, sizeof(uint16_t));
361 pci_write_config_word(virtio->u8Bus, virtio->u8DevFn, virtio->u8PciCfgOff + sizeof(virtio_pci_cap_t), u16Val);
362}
363
364static uint32_t virtio_reg_common_read_u32(virtio_t __far *virtio, uint16_t offReg)
365{
366 virtio_reg_common_access_prepare(virtio, offReg, sizeof(uint32_t));
367 return pci_read_config_dword(virtio->u8Bus, virtio->u8DevFn, virtio->u8PciCfgOff + sizeof(virtio_pci_cap_t));
368}
369
370static void virtio_reg_common_write_u32(virtio_t __far *virtio, uint16_t offReg, uint32_t u32Val)
371{
372 virtio_reg_common_access_prepare(virtio, offReg, sizeof(uint32_t));
373 pci_write_config_dword(virtio->u8Bus, virtio->u8DevFn, virtio->u8PciCfgOff + sizeof(virtio_pci_cap_t), u32Val);
374}
375
376static uint16_t virtio_reg_dev_cfg_read_u16(virtio_t __far *virtio, uint16_t offReg)
377{
378 virtio_reg_dev_access_prepare(virtio, offReg, sizeof(uint16_t));
379 return pci_read_config_word(virtio->u8Bus, virtio->u8DevFn, virtio->u8PciCfgOff + sizeof(virtio_pci_cap_t));
380}
381
382static uint32_t virtio_reg_dev_cfg_read_u32(virtio_t __far *virtio, uint16_t offReg)
383{
384 virtio_reg_dev_access_prepare(virtio, offReg, sizeof(uint32_t));
385 return pci_read_config_dword(virtio->u8Bus, virtio->u8DevFn, virtio->u8PciCfgOff + sizeof(virtio_pci_cap_t));
386}
387
388static void virtio_reg_dev_cfg_write_u32(virtio_t __far *virtio, uint16_t offReg, uint32_t u32Val)
389{
390 virtio_reg_dev_access_prepare(virtio, offReg, sizeof(uint32_t));
391 pci_write_config_dword(virtio->u8Bus, virtio->u8DevFn, virtio->u8PciCfgOff + sizeof(virtio_pci_cap_t), u32Val);
392}
393
394static void virtio_reg_notify_write_u16(virtio_t __far *virtio, uint16_t offReg, uint16_t u16Val)
395{
396 virtio_reg_notify_access_prepare(virtio, offReg, sizeof(uint16_t));
397 pci_write_config_word(virtio->u8Bus, virtio->u8DevFn, virtio->u8PciCfgOff + sizeof(virtio_pci_cap_t), u16Val);
398}
399
400/**
401 * Allocates 1K of conventional memory.
402 */
403static uint16_t virtio_mem_alloc(void)
404{
405 uint16_t base_mem_kb;
406 uint16_t virtio_seg;
407
408 base_mem_kb = read_word(0x00, 0x0413);
409
410 DBG_VIRTIO("VirtIO: %dK of base mem\n", base_mem_kb);
411
412 if (base_mem_kb == 0)
413 return 0;
414
415 base_mem_kb--; /* Allocate one block. */
416 virtio_seg = (((uint32_t)base_mem_kb * 1024) >> 4); /* Calculate start segment. */
417
418 write_word(0x00, 0x0413, base_mem_kb);
419
420 return virtio_seg;
421}
422
423/**
424 * Converts a segment:offset pair into a 32bit physical address.
425 */
426static uint32_t virtio_addr_to_phys(void __far *ptr)
427{
428 return ((uint32_t)FP_SEG(ptr) << 4) + FP_OFF(ptr);
429}
430
431int virtio_scsi_cmd_data_in(virtio_t __far *virtio, uint8_t idTgt, uint8_t __far *aCDB,
432 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length)
433{
434 uint16_t idxUsedOld = virtio->Queue.UsedRing.idxNextUsed;
435 uint64_t idxNext = virtio->Queue.AvailRing.idxNextFree;
436
437 _fmemset(&virtio->ScsiReqHdr, 0, sizeof(virtio->ScsiReqHdr));
438 _fmemset(&virtio->ScsiReqSts, 0, sizeof(virtio->ScsiReqSts));
439
440 virtio->ScsiReqHdr.au8Lun[0] = 0x1;
441 virtio->ScsiReqHdr.au8Lun[1] = idTgt;
442 virtio->ScsiReqHdr.au8Lun[2] = 0;
443 virtio->ScsiReqHdr.au8Lun[3] = 0;
444 _fmemcpy(&virtio->ScsiReqHdr.abCdb[0], aCDB, cbCDB);
445
446 /* Fill in the descriptors. */
447 virtio->Queue.aDescTbl[0].GCPhysBufLow = virtio_addr_to_phys(&virtio->ScsiReqHdr);
448 virtio->Queue.aDescTbl[0].GCPhysBufHigh = 0;
449 virtio->Queue.aDescTbl[0].cbBuf = sizeof(virtio->ScsiReqHdr);
450 virtio->Queue.aDescTbl[0].fFlags = VIRTIO_Q_DESC_F_NEXT;
451 virtio->Queue.aDescTbl[0].idxNext = 1;
452
453 /* No data out buffer, the status comes right after this in the next descriptor. */
454 virtio->Queue.aDescTbl[1].GCPhysBufLow = virtio_addr_to_phys(&virtio->ScsiReqSts);
455 virtio->Queue.aDescTbl[1].GCPhysBufHigh = 0;
456 virtio->Queue.aDescTbl[1].cbBuf = sizeof(virtio->ScsiReqSts);
457 virtio->Queue.aDescTbl[1].fFlags = VIRTIO_Q_DESC_F_WRITE | VIRTIO_Q_DESC_F_NEXT;
458 virtio->Queue.aDescTbl[1].idxNext = 2;
459
460 virtio->Queue.aDescTbl[2].GCPhysBufLow = virtio_addr_to_phys(buffer);
461 virtio->Queue.aDescTbl[2].GCPhysBufHigh = 0;
462 virtio->Queue.aDescTbl[2].cbBuf = length;
463 virtio->Queue.aDescTbl[2].fFlags = VIRTIO_Q_DESC_F_WRITE; /* End of chain. */
464 virtio->Queue.aDescTbl[2].idxNext = 0;
465
466 /* Put it into the queue. */
467 virtio->Queue.AvailRing.au16Ring[virtio->Queue.AvailRing.idxNextFree] = 0;
468 virtio->Queue.AvailRing.idxNextFree++;
469 virtio->Queue.AvailRing.idxNextFree %= VIRTIO_SCSI_RING_ELEM;
470
471 /* Notify the device about the new command. */
472 DBG_VIRTIO("VirtIO: Submitting new request, Queue.offNotify=0x%x\n", virtio->Queue.offNotify);
473 virtio_reg_notify_write_u16(virtio, virtio->Queue.offNotify, idxNext);
474
475 /* Wait for it to complete. */
476 while (idxUsedOld == virtio->Queue.UsedRing.idxNextUsed);
477
478 DBG_VIRTIO("VirtIO: Request complete\n");
479
480 return 0;
481}
482
483static int virtio_scsi_detect_devices(virtio_t __far *virtio)
484{
485 int i;
486 uint8_t buffer[0x0200];
487 bio_dsk_t __far *bios_dsk;
488
489 bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
490
491 /* Go through target devices. */
492 for (i = 0; i < VBSCSI_MAX_DEVICES; i++)
493 {
494 uint8_t rc;
495 uint8_t aCDB[16];
496 uint8_t hd_index, devcount_scsi;
497
498 aCDB[0] = SCSI_INQUIRY;
499 aCDB[1] = 0;
500 aCDB[2] = 0;
501 aCDB[3] = 0;
502 aCDB[4] = 5; /* Allocation length. */
503 aCDB[5] = 0;
504
505 rc = virtio_scsi_cmd_data_in(virtio, i, aCDB, 6, buffer, 5);
506 if (rc != 0)
507 BX_PANIC("%s: SCSI_INQUIRY failed\n", __func__);
508
509 devcount_scsi = bios_dsk->scsi_devcount;
510
511 /* Check the attached device. */
512 if ( ((buffer[0] & 0xe0) == 0)
513 && ((buffer[0] & 0x1f) == 0x00))
514 {
515 DBG_VIRTIO("%s: Disk detected at %d\n", __func__, i);
516
517 /* We add the disk only if the maximum is not reached yet. */
518 if (devcount_scsi < BX_MAX_SCSI_DEVICES)
519 {
520 uint64_t sectors, t;
521 uint32_t sector_size, cylinders;
522 uint16_t heads, sectors_per_track;
523 uint8_t hdcount;
524 uint8_t cmos_base;
525
526 /* Issue a read capacity command now. */
527 _fmemset(aCDB, 0, sizeof(aCDB));
528 aCDB[0] = SCSI_SERVICE_ACT;
529 aCDB[1] = SCSI_READ_CAP_16;
530 aCDB[13] = 32; /* Allocation length. */
531
532 rc = virtio_scsi_cmd_data_in(virtio, i, aCDB, 16, buffer, 32);
533 if (rc != 0)
534 BX_PANIC("%s: SCSI_READ_CAPACITY failed\n", __func__);
535
536 /* The value returned is the last addressable LBA, not
537 * the size, which what "+ 1" is for.
538 */
539 sectors = swap_64(*(uint64_t *)buffer) + 1;
540
541 sector_size = ((uint32_t)buffer[8] << 24)
542 | ((uint32_t)buffer[9] << 16)
543 | ((uint32_t)buffer[10] << 8)
544 | ((uint32_t)buffer[11]);
545
546 /* We only support the disk if sector size is 512 bytes. */
547 if (sector_size != 512)
548 {
549 /* Leave a log entry. */
550 BX_INFO("Disk %d has an unsupported sector size of %u\n", i, sector_size);
551 continue;
552 }
553
554 /* Get logical CHS geometry. */
555 switch (devcount_scsi)
556 {
557 case 0:
558 cmos_base = 0x90;
559 break;
560 case 1:
561 cmos_base = 0x98;
562 break;
563 case 2:
564 cmos_base = 0xA0;
565 break;
566 case 3:
567 cmos_base = 0xA8;
568 break;
569 default:
570 cmos_base = 0;
571 }
572
573 if (cmos_base && inb_cmos(cmos_base + 7))
574 {
575 /* If provided, grab the logical geometry from CMOS. */
576 cylinders = inb_cmos(cmos_base + 0) + (inb_cmos(cmos_base + 1) << 8);
577 heads = inb_cmos(cmos_base + 2);
578 sectors_per_track = inb_cmos(cmos_base + 7);
579 }
580 else
581 {
582 /* Calculate default logical geometry. NB: Very different
583 * from default ATA/SATA logical geometry!
584 */
585 if (sectors >= (uint32_t)4 * 1024 * 1024)
586 {
587 heads = 255;
588 sectors_per_track = 63;
589 /* Approximate x / (255 * 63) using shifts */
590 t = (sectors >> 6) + (sectors >> 12);
591 cylinders = (t >> 8) + (t >> 16);
592 }
593 else if (sectors >= (uint32_t)2 * 1024 * 1024)
594 {
595 heads = 128;
596 sectors_per_track = 32;
597 cylinders = sectors >> 12;
598 }
599 else
600 {
601 heads = 64;
602 sectors_per_track = 32;
603 cylinders = sectors >> 11;
604 }
605 }
606
607 /* Calculate index into the generic disk table. */
608 hd_index = devcount_scsi + BX_MAX_ATA_DEVICES;
609
610 //bios_dsk->scsidev[devcount_scsi].io_base = io_base;
611 bios_dsk->scsidev[devcount_scsi].target_id = i;
612 bios_dsk->devices[hd_index].type = DSK_TYPE_SCSI;
613 bios_dsk->devices[hd_index].device = DSK_DEVICE_HD;
614 bios_dsk->devices[hd_index].removable = 0;
615 bios_dsk->devices[hd_index].lock = 0;
616 bios_dsk->devices[hd_index].blksize = sector_size;
617 bios_dsk->devices[hd_index].translation = GEO_TRANSLATION_LBA;
618
619 /* Write LCHS/PCHS values. */
620 bios_dsk->devices[hd_index].lchs.heads = heads;
621 bios_dsk->devices[hd_index].lchs.spt = sectors_per_track;
622 bios_dsk->devices[hd_index].pchs.heads = heads;
623 bios_dsk->devices[hd_index].pchs.spt = sectors_per_track;
624
625 if (cylinders > 1024) {
626 bios_dsk->devices[hd_index].lchs.cylinders = 1024;
627 bios_dsk->devices[hd_index].pchs.cylinders = 1024;
628 } else {
629 bios_dsk->devices[hd_index].lchs.cylinders = (uint16_t)cylinders;
630 bios_dsk->devices[hd_index].pchs.cylinders = (uint16_t)cylinders;
631 }
632
633 BX_INFO("SCSI %d-ID#%d: LCHS=%lu/%u/%u 0x%llx sectors\n", devcount_scsi,
634 i, (uint32_t)cylinders, heads, sectors_per_track, sectors);
635
636 bios_dsk->devices[hd_index].sectors = sectors;
637
638 /* Store the id of the disk in the ata hdidmap. */
639 hdcount = bios_dsk->hdcount;
640 bios_dsk->hdidmap[hdcount] = devcount_scsi + BX_MAX_ATA_DEVICES;
641 hdcount++;
642 bios_dsk->hdcount = hdcount;
643
644 /* Update hdcount in the BDA. */
645 hdcount = read_byte(0x40, 0x75);
646 hdcount++;
647 write_byte(0x40, 0x75, hdcount);
648
649 devcount_scsi++;
650 }
651 else
652 {
653 /* We reached the maximum of SCSI disks we can boot from. We can quit detecting. */
654 break;
655 }
656 }
657 else if ( ((buffer[0] & 0xe0) == 0)
658 && ((buffer[0] & 0x1f) == 0x05))
659 {
660 uint8_t cdcount;
661 uint8_t removable;
662
663 BX_INFO("SCSI %d-ID#%d: CD/DVD-ROM\n", devcount_scsi, i);
664
665 /* Calculate index into the generic device table. */
666 hd_index = devcount_scsi + BX_MAX_ATA_DEVICES;
667
668 removable = buffer[1] & 0x80 ? 1 : 0;
669
670 //bios_dsk->scsidev[devcount_scsi].io_base = io_base;
671 bios_dsk->scsidev[devcount_scsi].target_id = i;
672 bios_dsk->devices[hd_index].type = DSK_TYPE_SCSI;
673 bios_dsk->devices[hd_index].device = DSK_DEVICE_CDROM;
674 bios_dsk->devices[hd_index].removable = removable;
675 bios_dsk->devices[hd_index].blksize = 2048;
676 bios_dsk->devices[hd_index].translation = GEO_TRANSLATION_NONE;
677
678 /* Store the ID of the device in the BIOS cdidmap. */
679 cdcount = bios_dsk->cdcount;
680 bios_dsk->cdidmap[cdcount] = devcount_scsi + BX_MAX_ATA_DEVICES;
681 cdcount++;
682 bios_dsk->cdcount = cdcount;
683
684 devcount_scsi++;
685 }
686 else
687 DBG_VIRTIO("%s: No supported device detected at %d\n", __func__, i);
688
689 bios_dsk->scsi_devcount = devcount_scsi;
690 }
691}
692
693/**
694 * Initializes the VirtIO SCSI HBA and detects attached devices.
695 */
696static int virtio_scsi_hba_init(uint8_t u8Bus, uint8_t u8DevFn, uint8_t u8PciCapOffVirtIo)
697{
698 uint8_t u8PciCapOff;
699 uint16_t ebda_seg;
700 uint16_t virtio_seg;
701 uint32_t fFeatures;
702 uint8_t u8DevStat;
703 bio_dsk_t __far *bios_dsk;
704 virtio_t __far *virtio;
705
706 ebda_seg = read_word(0x0040, 0x000E);
707 bios_dsk = ebda_seg :> &EbdaData->bdisk;
708
709 /* Allocate 1K of base memory. */
710 virtio_seg = virtio_mem_alloc();
711 if (virtio_seg == 0)
712 {
713 DBG_VIRTIO("VirtIO: Could not allocate 1K of memory, can't boot from controller\n");
714 return 0;
715 }
716 DBG_VIRTIO("VirtIO: virtio_seg=%04x, size=%04x, pointer at EBDA:%04x (EBDA size=%04x)\n",
717 virtio_seg, sizeof(virtio_t), (uint16_t)&EbdaData->bdisk.virtio_seg, sizeof(ebda_data_t));
718
719 bios_dsk->virtio_seg = virtio_seg;
720 bios_dsk->virtio_devcnt = 0;
721
722 virtio = virtio_seg :> 0;
723 virtio->u8Bus = u8Bus;
724 virtio->u8DevFn = u8DevFn;
725
726 /*
727 * Go through the config space again, read the complete config capabilities
728 * this time and fill in the data.
729 */
730 u8PciCapOff = u8PciCapOffVirtIo;
731 while (u8PciCapOff != 0)
732 {
733 uint8_t u8PciCapId = pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff);
734 uint8_t cbPciCap = pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff + 2); /* Capability length. */
735
736 DBG_VIRTIO("Capability ID 0x%x at 0x%x\n", u8PciCapId, u8PciCapOff);
737
738 if ( u8PciCapId == PCI_CAP_ID_VNDR
739 && cbPciCap >= sizeof(virtio_pci_cap_t))
740 {
741 /* Read in the config type and see what we got. */
742 uint8_t u8PciVirtioCfg = pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff + 3);
743
744 DBG_VIRTIO("VirtIO: CFG ID 0x%x\n", u8PciVirtioCfg);
745 switch (u8PciVirtioCfg)
746 {
747 case VIRTIO_PCI_CAP_COMMON_CFG:
748 case VIRTIO_PCI_CAP_NOTIFY_CFG:
749 case VIRTIO_PCI_CAP_ISR_CFG:
750 case VIRTIO_PCI_CAP_DEVICE_CFG:
751 {
752 virtio_bar_cfg_t __far *pBarCfg = &virtio->aBarCfgs[u8PciVirtioCfg - 1];
753
754 pBarCfg->u8Bar = pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff + 4);
755 pBarCfg->u32Offset = pci_read_config_dword(u8Bus, u8DevFn, u8PciCapOff + 8);
756 pBarCfg->u32Length = pci_read_config_dword(u8Bus, u8DevFn, u8PciCapOff + 12);
757 if (u8PciVirtioCfg == VIRTIO_PCI_CAP_NOTIFY_CFG)
758 {
759 virtio->u32NotifyOffMult = pci_read_config_dword(u8Bus, u8DevFn, u8PciCapOff + 16);
760 DBG_VIRTIO("VirtIO: u32NotifyOffMult 0x%x\n", virtio->u32NotifyOffMult);
761 }
762 break;
763 }
764 case VIRTIO_PCI_CAP_PCI_CFG:
765 virtio->u8PciCfgOff = u8PciCapOff;
766 DBG_VIRTIO("VirtIO PCI CAP window offset: %x\n", u8PciCapOff);
767 break;
768 default:
769 DBG_VIRTIO("VirtIO SCSI HBA with unknown PCI capability type 0x%x\n", u8PciVirtioCfg);
770 }
771 }
772
773 u8PciCapOff = pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff + 1);
774 }
775
776 /* Reset the device. */
777 u8DevStat = VIRTIO_CMN_REG_DEV_STS_F_RST;
778 virtio_reg_common_write_u8(virtio, VIRTIO_COMMON_REG_DEV_STS, u8DevStat);
779 /* Acknowledge presence. */
780 u8DevStat |= VIRTIO_CMN_REG_DEV_STS_F_ACK;
781 virtio_reg_common_write_u8(virtio, VIRTIO_COMMON_REG_DEV_STS, u8DevStat);
782 /* Our driver knows how to operate the device. */
783 u8DevStat |= VIRTIO_CMN_REG_DEV_STS_F_DRV;
784 virtio_reg_common_write_u8(virtio, VIRTIO_COMMON_REG_DEV_STS, u8DevStat);
785
786#if 0
787 /* Read the feature bits and only program the VIRTIO_CMN_REG_DEV_FEAT_SCSI_INOUT bit if available. */
788 fFeatures = virtio_reg_common_read_u32(virtio, VIRTIO_COMMON_REG_DEV_FEAT);
789 fFeatures &= VIRTIO_CMN_REG_DEV_FEAT_SCSI_INOUT;
790#endif
791
792 /* Check that the device is sane. */
793 if ( virtio_reg_dev_cfg_read_u32(virtio, VIRTIO_DEV_CFG_REG_Q_NUM) < 1
794 || virtio_reg_dev_cfg_read_u32(virtio, VIRTIO_DEV_CFG_REG_CDB_SZ) < 16
795 || virtio_reg_dev_cfg_read_u32(virtio, VIRTIO_DEV_CFG_REG_SENSE_SZ) < 32
796 || virtio_reg_dev_cfg_read_u32(virtio, VIRTIO_DEV_CFG_REG_SECT_MAX) < 1)
797 {
798 DBG_VIRTIO("VirtIO-SCSI: Invalid SCSI device configuration, ignoring device\n");
799 return 0;
800 }
801
802 virtio_reg_common_write_u32(virtio, VIRTIO_COMMON_REG_DRV_FEAT, VIRTIO_CMN_REG_DEV_FEAT_SCSI_INOUT);
803
804 /* Set the features OK bit. */
805 u8DevStat |= VIRTIO_CMN_REG_DEV_STS_F_FEAT_OK;
806 virtio_reg_common_write_u8(virtio, VIRTIO_COMMON_REG_DEV_STS, u8DevStat);
807
808 /* Read again and check the the okay bit is still set. */
809 if (!(virtio_reg_common_read_u8(virtio, VIRTIO_COMMON_REG_DEV_STS) & VIRTIO_CMN_REG_DEV_STS_F_FEAT_OK))
810 {
811 DBG_VIRTIO("VirtIO-SCSI: Device doesn't accept our feature set, ignoring device\n");
812 return 0;
813 }
814
815 /* Disable event and control queue. */
816 virtio_reg_common_write_u16(virtio, VIRTIO_COMMON_REG_Q_SELECT, VIRTIO_SCSI_Q_CONTROL);
817 virtio_reg_common_write_u16(virtio, VIRTIO_COMMON_REG_Q_SIZE, 0);
818 virtio_reg_common_write_u16(virtio, VIRTIO_COMMON_REG_Q_ENABLE, 0);
819
820 virtio_reg_common_write_u16(virtio, VIRTIO_COMMON_REG_Q_SELECT, VIRTIO_SCSI_Q_EVENT);
821 virtio_reg_common_write_u16(virtio, VIRTIO_COMMON_REG_Q_SIZE, 0);
822 virtio_reg_common_write_u16(virtio, VIRTIO_COMMON_REG_Q_ENABLE, 0);
823
824 /* Setup the request queue. */
825 virtio_reg_common_write_u16(virtio, VIRTIO_COMMON_REG_Q_SELECT, VIRTIO_SCSI_Q_REQUEST);
826 virtio_reg_common_write_u16(virtio, VIRTIO_COMMON_REG_Q_SIZE, VIRTIO_SCSI_RING_ELEM);
827 virtio_reg_common_write_u16(virtio, VIRTIO_COMMON_REG_Q_ENABLE, 1);
828
829 /* Set queue area addresses (only low part, leave high part 0). */
830 virtio_reg_common_write_u32(virtio, VIRTIO_COMMON_REG_Q_DESC, virtio_addr_to_phys(&virtio->Queue.aDescTbl[0]));
831 virtio_reg_common_write_u32(virtio, VIRTIO_COMMON_REG_Q_DESC + 4, 0);
832
833 virtio_reg_common_write_u32(virtio, VIRTIO_COMMON_REG_Q_DRIVER, virtio_addr_to_phys(&virtio->Queue.AvailRing));
834 virtio_reg_common_write_u32(virtio, VIRTIO_COMMON_REG_Q_DRIVER + 4, 0);
835
836 virtio_reg_common_write_u32(virtio, VIRTIO_COMMON_REG_Q_DEVICE, virtio_addr_to_phys(&virtio->Queue.UsedRing));
837 virtio_reg_common_write_u32(virtio, VIRTIO_COMMON_REG_Q_DEVICE + 4, 0);
838
839 virtio_reg_dev_cfg_write_u32(virtio, VIRTIO_DEV_CFG_REG_CDB_SZ, VIRTIO_SCSI_CDB_SZ);
840 virtio_reg_dev_cfg_write_u32(virtio, VIRTIO_DEV_CFG_REG_SENSE_SZ, VIRTIO_SCSI_SENSE_SZ);
841
842 DBG_VIRTIO("VirtIO: Q notify offset 0x%x\n", virtio_reg_common_read_u16(virtio, VIRTIO_COMMON_REG_Q_NOTIFY_OFF));
843 virtio->Queue.offNotify = virtio_reg_common_read_u16(virtio, VIRTIO_COMMON_REG_Q_NOTIFY_OFF) * virtio->u32NotifyOffMult;
844
845 /* Bring the device into operational mode. */
846 u8DevStat |= VIRTIO_CMN_REG_DEV_STS_F_DRV_OK;
847 virtio_reg_common_write_u8(virtio, VIRTIO_COMMON_REG_DEV_STS, u8DevStat);
848
849 return virtio_scsi_detect_devices(virtio);
850}
851
852/**
853 * Init the VirtIO SCSI driver and detect attached disks.
854 */
855void BIOSCALL virtio_scsi_init(void)
856{
857 uint16_t busdevfn;
858
859 busdevfn = pci_find_device(0x1af4, 0x1048);
860 if (busdevfn != VBOX_VIRTIO_NO_DEVICE)
861 {
862 uint8_t u8Bus, u8DevFn;
863 uint8_t u8PciCapOff;
864 uint8_t u8PciCapOffVirtIo = VBOX_VIRTIO_NIL_CFG;
865 uint8_t u8PciCapVirtioSeen = 0;
866
867 u8Bus = (busdevfn & 0xff00) >> 8;
868 u8DevFn = busdevfn & 0x00ff;
869
870 DBG_VIRTIO("VirtIO SCSI HBA at Bus %u DevFn 0x%x (raw 0x%x)\n", u8Bus, u8DevFn, busdevfn);
871
872 /* Examine the capability list and search for the VirtIO specific capabilities. */
873 u8PciCapOff = pci_read_config_byte(u8Bus, u8DevFn, PCI_CONFIG_CAP);
874
875 while (u8PciCapOff != 0)
876 {
877 uint8_t u8PciCapId = pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff);
878 uint8_t cbPciCap = pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff + 2); /* Capability length. */
879
880 DBG_VIRTIO("Capability ID 0x%x at 0x%x\n", u8PciCapId, u8PciCapOff);
881
882 if ( u8PciCapId == PCI_CAP_ID_VNDR
883 && cbPciCap >= sizeof(virtio_pci_cap_t))
884 {
885 /* Read in the config type and see what we got. */
886 uint8_t u8PciVirtioCfg = pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff + 3);
887
888 if (u8PciCapOffVirtIo == VBOX_VIRTIO_NIL_CFG)
889 u8PciCapOffVirtIo = u8PciCapOff;
890
891 DBG_VIRTIO("VirtIO: CFG ID 0x%x\n", u8PciVirtioCfg);
892 switch (u8PciVirtioCfg)
893 {
894 case VIRTIO_PCI_CAP_COMMON_CFG:
895 case VIRTIO_PCI_CAP_NOTIFY_CFG:
896 case VIRTIO_PCI_CAP_ISR_CFG:
897 case VIRTIO_PCI_CAP_DEVICE_CFG:
898 case VIRTIO_PCI_CAP_PCI_CFG:
899 u8PciCapVirtioSeen |= 1 << (u8PciVirtioCfg - 1);
900 break;
901 default:
902 DBG_VIRTIO("VirtIO SCSI HBA with unknown PCI capability type 0x%x\n", u8PciVirtioCfg);
903 }
904 }
905
906 u8PciCapOff = pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff + 1);
907 }
908
909 /* Initialize the controller if all required PCI capabilities where found. */
910 if ( u8PciCapOffVirtIo != VBOX_VIRTIO_NIL_CFG
911 && u8PciCapVirtioSeen == 0x1f)
912 {
913 int rc;
914
915 DBG_VIRTIO("VirtIO SCSI HBA with all required capabilities at 0x%x\n", u8PciCapOffVirtIo);
916
917 /* Enable PCI memory, I/O, bus mastering access in command register. */
918 pci_write_config_word(u8Bus, u8DevFn, 4, 0x7);
919
920 rc = virtio_scsi_hba_init(u8Bus, u8DevFn, u8PciCapOffVirtIo);
921 }
922 else
923 DBG_VIRTIO("VirtIO SCSI HBA with no usable PCI config access!\n");
924 }
925 else
926 DBG_VIRTIO("No VirtIO SCSI HBA!\n");
927}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette