Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / seabios / src / hw / pvscsi.c
1 // QEMU VMWARE Paravirtualized SCSI boot support.
2 //
3 // Copyright (c) 2013 Ravello Systems LTD (http://ravellosystems.com)
4 //
5 // Authors:
6 //  Evgeny Budilovsky <evgeny.budilovsky@ravellosystems.com>
7 //
8 // This file may be distributed under the terms of the GNU LGPLv3 license.
9
10 #include "block.h" // struct drive_s
11 #include "blockcmd.h" // scsi_drive_setup
12 #include "config.h" // CONFIG_*
13 #include "malloc.h" // free
14 #include "output.h" // dprintf
15 #include "pci.h" // foreachpci
16 #include "pci_ids.h" // PCI_DEVICE_ID_VMWARE_PVSCSI
17 #include "pci_regs.h" // PCI_VENDOR_ID
18 #include "pvscsi.h" // pvscsi_setup
19 #include "std/disk.h" // DISK_RET_SUCCESS
20 #include "string.h" // memset
21 #include "util.h" // usleep
22 #include "virtio-ring.h" // PAGE_SHIFT, virt_to_phys
23 #include "x86.h" // writel
24
25 #define MASK(n) ((1 << (n)) - 1)
26
27 #define SIMPLE_QUEUE_TAG 0x20
28
29 #define PVSCSI_INTR_CMPL_0                 (1 << 0)
30 #define PVSCSI_INTR_CMPL_1                 (1 << 1)
31 #define PVSCSI_INTR_CMPL_MASK              MASK(2)
32
33 #define PVSCSI_INTR_MSG_0                  (1 << 2)
34 #define PVSCSI_INTR_MSG_1                  (1 << 3)
35 #define PVSCSI_INTR_MSG_MASK               (MASK(2) << 2)
36 #define PVSCSI_INTR_ALL_SUPPORTED          MASK(4)
37
38 #define PVSCSI_FLAG_CMD_WITH_SG_LIST       (1 << 0)
39 #define PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB    (1 << 1)
40 #define PVSCSI_FLAG_CMD_DIR_NONE           (1 << 2)
41 #define PVSCSI_FLAG_CMD_DIR_TOHOST         (1 << 3)
42 #define PVSCSI_FLAG_CMD_DIR_TODEVICE       (1 << 4)
43
44 enum PVSCSIRegOffset {
45     PVSCSI_REG_OFFSET_COMMAND        =    0x0,
46     PVSCSI_REG_OFFSET_COMMAND_DATA   =    0x4,
47     PVSCSI_REG_OFFSET_COMMAND_STATUS =    0x8,
48     PVSCSI_REG_OFFSET_LAST_STS_0     =  0x100,
49     PVSCSI_REG_OFFSET_LAST_STS_1     =  0x104,
50     PVSCSI_REG_OFFSET_LAST_STS_2     =  0x108,
51     PVSCSI_REG_OFFSET_LAST_STS_3     =  0x10c,
52     PVSCSI_REG_OFFSET_INTR_STATUS    = 0x100c,
53     PVSCSI_REG_OFFSET_INTR_MASK      = 0x2010,
54     PVSCSI_REG_OFFSET_KICK_NON_RW_IO = 0x3014,
55     PVSCSI_REG_OFFSET_DEBUG          = 0x3018,
56     PVSCSI_REG_OFFSET_KICK_RW_IO     = 0x4018,
57 };
58
59 enum PVSCSICommands {
60     PVSCSI_CMD_FIRST             = 0,
61     PVSCSI_CMD_ADAPTER_RESET     = 1,
62     PVSCSI_CMD_ISSUE_SCSI        = 2,
63     PVSCSI_CMD_SETUP_RINGS       = 3,
64     PVSCSI_CMD_RESET_BUS         = 4,
65     PVSCSI_CMD_RESET_DEVICE      = 5,
66     PVSCSI_CMD_ABORT_CMD         = 6,
67     PVSCSI_CMD_CONFIG            = 7,
68     PVSCSI_CMD_SETUP_MSG_RING    = 8,
69     PVSCSI_CMD_DEVICE_UNPLUG     = 9,
70     PVSCSI_CMD_LAST              = 10
71 };
72
73 #define PVSCSI_SETUP_RINGS_MAX_NUM_PAGES        32
74 struct PVSCSICmdDescSetupRings {
75     u32    reqRingNumPages;
76     u32    cmpRingNumPages;
77     u64    ringsStatePPN;
78     u64    reqRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
79     u64    cmpRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
80 } PACKED;
81
82 struct PVSCSIRingCmpDesc {
83     u64    context;
84     u64    dataLen;
85     u32    senseLen;
86     u16    hostStatus;
87     u16    scsiStatus;
88     u32    pad[2];
89 } PACKED;
90
91 struct PVSCSIRingsState {
92     u32    reqProdIdx;
93     u32    reqConsIdx;
94     u32    reqNumEntriesLog2;
95
96     u32    cmpProdIdx;
97     u32    cmpConsIdx;
98     u32    cmpNumEntriesLog2;
99
100     u8     pad[104];
101
102     u32    msgProdIdx;
103     u32    msgConsIdx;
104     u32    msgNumEntriesLog2;
105 } PACKED;
106
107 struct PVSCSIRingReqDesc {
108     u64    context;
109     u64    dataAddr;
110     u64    dataLen;
111     u64    senseAddr;
112     u32    senseLen;
113     u32    flags;
114     u8     cdb[16];
115     u8     cdbLen;
116     u8     lun[8];
117     u8     tag;
118     u8     bus;
119     u8     target;
120     u8     vcpuHint;
121     u8     unused[59];
122 } PACKED;
123
124 struct pvscsi_ring_dsc_s {
125     struct PVSCSIRingsState *ring_state;
126     struct PVSCSIRingReqDesc *ring_reqs;
127     struct PVSCSIRingCmpDesc *ring_cmps;
128 };
129
130 struct pvscsi_lun_s {
131     struct drive_s drive;
132     void *iobase;
133     u8 target;
134     u8 lun;
135     struct pvscsi_ring_dsc_s *ring_dsc;
136 };
137
138 static void
139 pvscsi_write_cmd_desc(void *iobase, u32 cmd, const void *desc, size_t len)
140 {
141     const u32 *ptr = desc;
142     size_t i;
143
144     len /= sizeof(*ptr);
145     writel(iobase + PVSCSI_REG_OFFSET_COMMAND, cmd);
146     for (i = 0; i < len; i++)
147         writel(iobase + PVSCSI_REG_OFFSET_COMMAND_DATA, ptr[i]);
148 }
149
150 static void
151 pvscsi_kick_rw_io(void *iobase)
152 {
153     writel(iobase + PVSCSI_REG_OFFSET_KICK_RW_IO, 0);
154 }
155
156 static void
157 pvscsi_wait_intr_cmpl(void *iobase)
158 {
159     while (!(readl(iobase + PVSCSI_REG_OFFSET_INTR_STATUS) & PVSCSI_INTR_CMPL_MASK))
160         usleep(5);
161     writel(iobase + PVSCSI_REG_OFFSET_INTR_STATUS, PVSCSI_INTR_CMPL_MASK);
162 }
163
164 static void
165 pvscsi_init_rings(void *iobase, struct pvscsi_ring_dsc_s **ring_dsc)
166 {
167     struct PVSCSICmdDescSetupRings cmd = {0,};
168
169     struct pvscsi_ring_dsc_s *dsc = memalign_low(sizeof(*dsc), PAGE_SIZE);
170     if (!dsc) {
171         warn_noalloc();
172         return;
173     }
174
175     dsc->ring_state =
176         (struct PVSCSIRingsState *)memalign_low(PAGE_SIZE, PAGE_SIZE);
177     dsc->ring_reqs =
178         (struct PVSCSIRingReqDesc *)memalign_low(PAGE_SIZE, PAGE_SIZE);
179     dsc->ring_cmps =
180         (struct PVSCSIRingCmpDesc *)memalign_low(PAGE_SIZE, PAGE_SIZE);
181     if (!dsc->ring_state || !dsc->ring_reqs || !dsc->ring_cmps) {
182         warn_noalloc();
183         return;
184     }
185     memset(dsc->ring_state, 0, PAGE_SIZE);
186     memset(dsc->ring_reqs, 0, PAGE_SIZE);
187     memset(dsc->ring_cmps, 0, PAGE_SIZE);
188
189     cmd.reqRingNumPages = 1;
190     cmd.cmpRingNumPages = 1;
191     cmd.ringsStatePPN = virt_to_phys(dsc->ring_state) >> PAGE_SHIFT;
192     cmd.reqRingPPNs[0] = virt_to_phys(dsc->ring_reqs) >> PAGE_SHIFT;
193     cmd.cmpRingPPNs[0] = virt_to_phys(dsc->ring_cmps) >> PAGE_SHIFT;
194
195     pvscsi_write_cmd_desc(iobase, PVSCSI_CMD_SETUP_RINGS,
196                           &cmd, sizeof(cmd));
197     *ring_dsc = dsc;
198 }
199
200 static void pvscsi_fill_req(struct PVSCSIRingsState *s,
201                             struct PVSCSIRingReqDesc *req,
202                             u16 target, u16 lun, void *cdbcmd, u16 blocksize,
203                             struct disk_op_s *op)
204 {
205     req->bus = 0;
206     req->target = target;
207     memset(req->lun, 0, sizeof(req->lun));
208     req->lun[1] = lun;
209     req->senseLen = 0;
210     req->senseAddr = 0;
211     req->cdbLen = 16;
212     req->vcpuHint = 0;
213     memcpy(req->cdb, cdbcmd, 16);
214     req->tag = SIMPLE_QUEUE_TAG;
215     req->flags = cdb_is_read(cdbcmd, blocksize) ?
216         PVSCSI_FLAG_CMD_DIR_TOHOST : PVSCSI_FLAG_CMD_DIR_TODEVICE;
217
218     req->dataLen = op->count * blocksize;
219     req->dataAddr = (u32)op->buf_fl;
220     s->reqProdIdx = s->reqProdIdx + 1;
221 }
222
223 static u32
224 pvscsi_get_rsp(struct PVSCSIRingsState *s,
225                struct PVSCSIRingCmpDesc *rsp)
226 {
227     u32 status = rsp->hostStatus;
228     s->cmpConsIdx = s->cmpConsIdx + 1;
229     return status;
230 }
231
232 static int
233 pvscsi_cmd(struct pvscsi_lun_s *plun, struct disk_op_s *op,
234            void *cdbcmd, u16 target, u16 lun, u16 blocksize)
235 {
236     struct pvscsi_ring_dsc_s *ring_dsc = plun->ring_dsc;
237     struct PVSCSIRingsState *s = ring_dsc->ring_state;
238     u32 req_entries = s->reqNumEntriesLog2;
239     u32 cmp_entries = s->cmpNumEntriesLog2;
240     struct PVSCSIRingReqDesc *req;
241     struct PVSCSIRingCmpDesc *rsp;
242     u32 status;
243
244     if (s->reqProdIdx - s->cmpConsIdx >= 1 << req_entries) {
245         dprintf(1, "pvscsi: ring full: reqProdIdx=%d cmpConsIdx=%d\n",
246                 s->reqProdIdx, s->cmpConsIdx);
247         return DISK_RET_EBADTRACK;
248     }
249
250     req = ring_dsc->ring_reqs + (s->reqProdIdx & MASK(req_entries));
251     pvscsi_fill_req(s, req, target, lun, cdbcmd, blocksize, op);
252
253     pvscsi_kick_rw_io(plun->iobase);
254     pvscsi_wait_intr_cmpl(plun->iobase);
255
256     rsp = ring_dsc->ring_cmps + (s->cmpConsIdx & MASK(cmp_entries));
257     status = pvscsi_get_rsp(s, rsp);
258
259     return status == 0 ? DISK_RET_SUCCESS : DISK_RET_EBADTRACK;
260 }
261
262 int
263 pvscsi_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize)
264 {
265     if (!CONFIG_PVSCSI)
266         return DISK_RET_EBADTRACK;
267
268     struct pvscsi_lun_s *plun =
269         container_of(op->drive_gf, struct pvscsi_lun_s, drive);
270
271     return pvscsi_cmd(plun, op, cdbcmd, plun->target, plun->lun, blocksize);
272 }
273
274 static int
275 pvscsi_add_lun(struct pci_device *pci, void *iobase,
276                struct pvscsi_ring_dsc_s *ring_dsc, u8 target, u8 lun)
277 {
278     struct pvscsi_lun_s *plun = malloc_fseg(sizeof(*plun));
279     if (!plun) {
280         warn_noalloc();
281         return -1;
282     }
283     memset(plun, 0, sizeof(*plun));
284     plun->drive.type = DTYPE_PVSCSI;
285     plun->drive.cntl_id = pci->bdf;
286     plun->target = target;
287     plun->lun = lun;
288     plun->iobase = iobase;
289     plun->ring_dsc = ring_dsc;
290
291     char *name = znprintf(16, "pvscsi %02x:%02x.%x %d:%d",
292                           pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
293                           pci_bdf_to_fn(pci->bdf), target, lun);
294     int prio = bootprio_find_scsi_device(pci, target, lun);
295     int ret = scsi_drive_setup(&plun->drive, name, prio);
296     free(name);
297     if (ret)
298         goto fail;
299     return 0;
300
301 fail:
302     free(plun);
303     return -1;
304 }
305
306 static void
307 pvscsi_scan_target(struct pci_device *pci, void *iobase,
308                    struct pvscsi_ring_dsc_s *ring_dsc, u8 target)
309 {
310     /* TODO: send REPORT LUNS.  For now, only LUN 0 is recognized.  */
311     pvscsi_add_lun(pci, iobase, ring_dsc, target, 0);
312 }
313
314 static void
315 init_pvscsi(struct pci_device *pci)
316 {
317     struct pvscsi_ring_dsc_s *ring_dsc = NULL;
318     int i;
319     u16 bdf = pci->bdf;
320     void *iobase = (void*)(pci_config_readl(pci->bdf, PCI_BASE_ADDRESS_0)
321                            & PCI_BASE_ADDRESS_MEM_MASK);
322
323     pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER);
324
325     dprintf(1, "found pvscsi at %02x:%02x.%x, io @ %p\n",
326             pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf),
327             pci_bdf_to_fn(bdf), iobase);
328
329     pvscsi_write_cmd_desc(iobase, PVSCSI_CMD_ADAPTER_RESET, NULL, 0);
330
331     pvscsi_init_rings(iobase, &ring_dsc);
332     for (i = 0; i < 7; i++)
333         pvscsi_scan_target(pci, iobase, ring_dsc, i);
334
335     return;
336 }
337
338 void
339 pvscsi_setup(void)
340 {
341     ASSERT32FLAT();
342     if (! CONFIG_PVSCSI)
343         return;
344
345     dprintf(3, "init pvscsi\n");
346
347     struct pci_device *pci;
348     foreachpci(pci) {
349         if (pci->vendor != PCI_VENDOR_ID_VMWARE
350             || pci->device != PCI_DEVICE_ID_VMWARE_PVSCSI)
351             continue;
352         init_pvscsi(pci);
353     }
354 }