Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openbios / drivers / esp.c
1 /*
2  *   OpenBIOS ESP driver
3  *
4  *   Copyright (C) 2004 Jens Axboe <axboe@suse.de>
5  *   Copyright (C) 2005 Stefan Reinauer <stepan@openbios.org>
6  *
7  *   Credit goes to Hale Landis for his excellent ata demo software
8  *   OF node handling and some fixes by Stefan Reinauer
9  *
10  *   This program is free software; you can redistribute it and/or
11  *   modify it under the terms of the GNU General Public License
12  *   version 2
13  *
14  */
15
16 #include "config.h"
17 #include "libopenbios/bindings.h"
18 #include "kernel/kernel.h"
19 #include "libc/byteorder.h"
20 #include "libc/vsprintf.h"
21
22 #include "drivers/drivers.h"
23 #include "asm/io.h"
24 #include "scsi.h"
25 #include "asm/dma.h"
26 #include "esp.h"
27 #include "libopenbios/ofmem.h"
28
29 #define BUFSIZE         4096
30
31 #ifdef CONFIG_DEBUG_ESP
32 #define DPRINTF(fmt, args...)                   \
33     do { printk(fmt , ##args); } while (0)
34 #else
35 #define DPRINTF(fmt, args...)
36 #endif
37
38 struct esp_dma {
39     volatile struct sparc_dma_registers *regs;
40     enum dvma_rev revision;
41 };
42
43 typedef struct sd_private {
44     unsigned int bs;
45     const char *media_str[2];
46     uint32_t sectors;
47     uint8_t media;
48     uint8_t id;
49     uint8_t present;
50     char model[40];
51 } sd_private_t;
52
53 struct esp_regs {
54     unsigned char regs[ESP_REG_SIZE];
55 };
56
57 typedef struct esp_private {
58     volatile struct esp_regs *ll;
59     uint32_t buffer_dvma;
60     unsigned int irq;        /* device IRQ number    */
61     struct esp_dma espdma;
62     unsigned char *buffer;
63     sd_private_t sd[8];
64 } esp_private_t;
65
66 static esp_private_t *global_esp;
67
68 /* DECLARE data structures for the nodes.  */
69 DECLARE_UNNAMED_NODE(ob_sd, INSTALL_OPEN, sizeof(sd_private_t *));
70 DECLARE_UNNAMED_NODE(ob_esp, INSTALL_OPEN, sizeof(esp_private_t *));
71
72 #ifdef CONFIG_DEBUG_ESP
73 static void dump_drive(sd_private_t *drive)
74 {
75     printk("SCSI DRIVE @%lx:\n", (unsigned long)drive);
76     printk("id: %d\n", drive->id);
77     printk("media: %s\n", drive->media_str[0]);
78     printk("media: %s\n", drive->media_str[1]);
79     printk("model: %s\n", drive->model);
80     printk("sectors: %d\n", drive->sectors);
81     printk("present: %d\n", drive->present);
82     printk("bs: %d\n", drive->bs);
83 }
84 #endif
85
86 static int
87 do_command(esp_private_t *esp, sd_private_t *sd, int cmdlen, int replylen)
88 {
89     int status;
90
91     // Set SCSI target
92     esp->ll->regs[ESP_BUSID] = sd->id & 7;
93     // Set DMA address
94     esp->espdma.regs->st_addr = esp->buffer_dvma;
95     // Set DMA length
96     esp->ll->regs[ESP_TCLOW] = cmdlen & 0xff;
97     esp->ll->regs[ESP_TCMED] = (cmdlen >> 8) & 0xff;
98     // Set DMA direction and enable DMA
99     esp->espdma.regs->cond_reg = DMA_ENABLE;
100     // Set ATN, issue command
101     esp->ll->regs[ESP_CMD] = ESP_CMD_SELA | ESP_CMD_DMA;
102     // Wait for DMA to complete. Can this fail?
103     while ((esp->espdma.regs->cond_reg & DMA_HNDL_INTR) == 0) /* no-op */;
104     // Check status
105     status = esp->ll->regs[ESP_STATUS];
106     // Clear interrupts to avoid guests seeing spurious interrupts
107     (void)esp->ll->regs[ESP_INTRPT];
108
109     DPRINTF("do_command: id %d, cmd[0] 0x%x, status 0x%x\n", sd->id, esp->buffer[1], status);
110
111     /* Target didn't want all command data? */
112     if ((status & ESP_STAT_TCNT) != ESP_STAT_TCNT) {
113         return status;
114     }
115     if (replylen == 0) {
116         return 0;
117     }
118     /* Target went to status phase instead of data phase? */
119     if ((status & ESP_STAT_PMASK) == ESP_STATP) {
120         return status;
121     }
122
123     // Get reply
124     // Set DMA address
125     esp->espdma.regs->st_addr = esp->buffer_dvma;
126     // Set DMA length
127     esp->ll->regs[ESP_TCLOW] = replylen & 0xff;
128     esp->ll->regs[ESP_TCMED] = (replylen >> 8) & 0xff;
129     // Set DMA direction
130     esp->espdma.regs->cond_reg = DMA_ST_WRITE | DMA_ENABLE;
131     // Transfer
132     esp->ll->regs[ESP_CMD] = ESP_CMD_TI | ESP_CMD_DMA;
133     // Wait for DMA to complete
134     while ((esp->espdma.regs->cond_reg & DMA_HNDL_INTR) == 0) /* no-op */;
135     // Check status
136     status = esp->ll->regs[ESP_STATUS];
137     // Clear interrupts to avoid guests seeing spurious interrupts
138     (void)esp->ll->regs[ESP_INTRPT];
139
140     DPRINTF("do_command_reply: status 0x%x\n", status);
141
142     if ((status & ESP_STAT_TCNT) != ESP_STAT_TCNT)
143         return status;
144     else
145         return 0; // OK
146 }
147
148 // offset is in sectors
149 static int
150 ob_sd_read_sector(esp_private_t *esp, sd_private_t *sd, int offset)
151 {
152     DPRINTF("ob_sd_read_sector id %d sector=%d\n",
153             sd->id, offset);
154
155     // Setup command = Read(10)
156     memset(esp->buffer, 0, 11);
157     esp->buffer[0] = 0x80;
158     esp->buffer[1] = READ_10;
159
160     esp->buffer[3] = (offset >> 24) & 0xff;
161     esp->buffer[4] = (offset >> 16) & 0xff;
162     esp->buffer[5] = (offset >> 8) & 0xff;
163     esp->buffer[6] = offset & 0xff;
164
165     esp->buffer[8] = 0;
166     esp->buffer[9] = 1;
167
168     if (do_command(esp, sd, 11, sd->bs))
169         return 0;
170
171     return 0;
172 }
173
174 static unsigned int
175 read_capacity(esp_private_t *esp, sd_private_t *sd)
176 {
177     // Setup command = Read Capacity
178     memset(esp->buffer, 0, 11);
179     esp->buffer[0] = 0x80;
180     esp->buffer[1] = READ_CAPACITY;
181
182     if (do_command(esp, sd, 11, 8)) {
183         sd->sectors = 0;
184         sd->bs = 0;
185         DPRINTF("read_capacity id %d failed\n", sd->id);
186         return 0;
187     }
188     sd->bs = (esp->buffer[4] << 24) | (esp->buffer[5] << 16) | (esp->buffer[6] << 8) | esp->buffer[7];
189     sd->sectors = ((esp->buffer[0] << 24) | (esp->buffer[1] << 16) | (esp->buffer[2] << 8) | esp->buffer[3]) * (sd->bs / 512);
190
191     DPRINTF("read_capacity id %d bs %d sectors %d\n", sd->id, sd->bs,
192             sd->sectors);
193     return 1;
194 }
195
196 static unsigned int
197 test_unit_ready(esp_private_t *esp, sd_private_t *sd)
198 {
199     /* Setup command = Test Unit Ready */
200     memset(esp->buffer, 0, 7);
201     esp->buffer[0] = 0x80;
202     esp->buffer[1] = TEST_UNIT_READY;
203
204     if (do_command(esp, sd, 7, 0)) {
205         DPRINTF("test_unit_ready id %d failed\n", sd->id);
206         return 0;
207     }
208
209     DPRINTF("test_unit_ready id %d success\n", sd->id);
210     return 1;
211 }
212
213 static unsigned int
214 inquiry(esp_private_t *esp, sd_private_t *sd)
215 {
216     const char *media[2] = { "UNKNOWN", "UNKNOWN"};
217
218     // Setup command = Inquiry
219     memset(esp->buffer, 0, 7);
220     esp->buffer[0] = 0x80;
221     esp->buffer[1] = INQUIRY;
222
223     esp->buffer[5] = 36;
224
225     if (do_command(esp, sd, 7, 36)) {
226         sd->present = 0;
227         sd->media = -1;
228         return 0;
229     }
230     sd->present = 1;
231     sd->media = esp->buffer[0];
232
233     switch (sd->media) {
234     case TYPE_DISK:
235         media[0] = "disk";
236         media[1] = "hd";
237         break;
238     case TYPE_ROM:
239         media[0] = "cdrom";
240         media[1] = "cd";
241         break;
242     }
243     sd->media_str[0] = media[0];
244     sd->media_str[1] = media[1];
245     memcpy(sd->model, &esp->buffer[16], 16);
246     sd->model[17] = '\0';
247
248     return 1;
249 }
250
251
252 static void
253 ob_sd_read_blocks(sd_private_t **sd)
254 {
255     cell n = POP(), cnt = n;
256     ucell blk = POP();
257     char *dest = (char*)POP();
258     int pos, spb, sect_offset;
259
260     DPRINTF("ob_sd_read_blocks id %d %lx block=%d n=%d\n", (*sd)->id, (unsigned long)dest, blk, n );
261
262     if ((*sd)->bs == 0) {
263         PUSH(0);
264         return;
265     }
266     spb = (*sd)->bs / 512;
267     while (n) {
268         sect_offset = blk / spb;
269         pos = (blk - sect_offset * spb) * 512;
270
271         if (ob_sd_read_sector(global_esp, *sd, sect_offset)) {
272             DPRINTF("ob_sd_read_blocks: error\n");
273             RET(0);
274         }
275         while (n && pos < spb * 512) {
276             memcpy(dest, global_esp->buffer + pos, 512);
277             pos += 512;
278             dest += 512;
279             n--;
280             blk++;
281         }
282     }
283     PUSH(cnt);
284 }
285
286 static void
287 ob_sd_block_size(__attribute__((unused))sd_private_t **sd)
288 {
289     PUSH(512);
290 }
291
292 static void
293 ob_sd_open(__attribute__((unused))sd_private_t **sd)
294 {
295     int ret = 1, id;
296     phandle_t ph;
297
298     fword("my-unit");
299     id = POP();
300     POP(); // unit id is 2 ints but we only need one.
301     *sd = &global_esp->sd[id];
302
303 #ifdef CONFIG_DEBUG_ESP
304     {
305         char *args;
306
307         fword("my-args");
308         args = pop_fstr_copy();
309         DPRINTF("opening drive %d args %s\n", id, args);
310         free(args);
311     }
312 #endif
313
314     selfword("open-deblocker");
315
316     /* interpose disk-label */
317     ph = find_dev("/packages/disk-label");
318     fword("my-args");
319     PUSH_ph( ph );
320     fword("interpose");
321
322     RET ( -ret );
323 }
324
325 static void
326 ob_sd_close(__attribute__((unused)) sd_private_t **sd)
327 {
328     selfword("close-deblocker");
329 }
330
331 NODE_METHODS(ob_sd) = {
332     { "open",           ob_sd_open },
333     { "close",          ob_sd_close },
334     { "read-blocks",    ob_sd_read_blocks },
335     { "block-size",     ob_sd_block_size },
336 };
337
338
339 static int
340 espdma_init(unsigned int slot, uint64_t base, unsigned long offset,
341             struct esp_dma *espdma)
342 {
343     espdma->regs = (void *)ofmem_map_io(base + (uint64_t)offset, 0x10);
344
345     if (espdma->regs == NULL) {
346         DPRINTF("espdma_init: cannot map registers\n");
347         return -1;
348     }
349
350     DPRINTF("dma1: ");
351
352     switch ((espdma->regs->cond_reg) & DMA_DEVICE_ID) {
353     case DMA_VERS0:
354         espdma->revision = dvmarev0;
355         DPRINTF("Revision 0 ");
356         break;
357     case DMA_ESCV1:
358         espdma->revision = dvmaesc1;
359         DPRINTF("ESC Revision 1 ");
360         break;
361     case DMA_VERS1:
362         espdma->revision = dvmarev1;
363         DPRINTF("Revision 1 ");
364         break;
365     case DMA_VERS2:
366         espdma->revision = dvmarev2;
367         DPRINTF("Revision 2 ");
368         break;
369     case DMA_VERHME:
370         espdma->revision = dvmahme;
371         DPRINTF("HME DVMA gate array ");
372         break;
373     case DMA_VERSPLUS:
374         espdma->revision = dvmarevplus;
375         DPRINTF("Revision 1 PLUS ");
376         break;
377     default:
378         DPRINTF("unknown dma version %x",
379                (espdma->regs->cond_reg) & DMA_DEVICE_ID);
380         /* espdma->allocated = 1; */
381         break;
382     }
383     DPRINTF("\n");
384
385     push_str("/iommu/sbus/espdma");
386     fword("find-device");
387
388     /* set reg */
389     PUSH(slot);
390     fword("encode-int");
391     PUSH(offset);
392     fword("encode-int");
393     fword("encode+");
394     PUSH(0x00000010);
395     fword("encode-int");
396     fword("encode+");
397     push_str("reg");
398     fword("property");
399
400     return 0;
401 }
402
403 static void
404 ob_esp_initialize(__attribute__((unused)) esp_private_t **esp)
405 {
406     phandle_t ph = get_cur_dev();
407
408     set_int_property(ph, "#address-cells", 2);
409     set_int_property(ph, "#size-cells", 0);
410
411     /* set device type */
412     push_str("scsi");
413     fword("device-type");
414
415     /* QEMU's ESP emulation does not support mixing DMA and FIFO messages. By
416        setting this attribute, we prevent the Solaris ESP kernel driver from
417        trying to use this feature when booting a disk image (and failing) */
418     PUSH(0x58);
419     fword("encode-int");
420     push_str("scsi-options");
421     fword("property");
422
423     PUSH(0x24);
424     fword("encode-int");
425     PUSH(0);
426     fword("encode-int");
427     fword("encode+");
428     push_str("intr");
429     fword("property");
430 }
431
432 static void
433 ob_esp_decodeunit(__attribute__((unused)) esp_private_t **esp)
434 {
435     fword("decode-unit-scsi");
436 }
437
438
439 static void
440 ob_esp_encodeunit(__attribute__((unused)) esp_private_t **esp)
441 {
442     fword("encode-unit-scsi");
443 }
444
445 NODE_METHODS(ob_esp) = {
446     { NULL,             ob_esp_initialize },
447     { "decode-unit",    ob_esp_decodeunit },
448     { "encode-unit",    ob_esp_encodeunit },
449 };
450
451 static void
452 add_alias(const char *device, const char *alias)
453 {
454     DPRINTF("add_alias dev \"%s\" = alias \"%s\"\n", device, alias);
455     push_str("/aliases");
456     fword("find-device");
457     push_str(device);
458     fword("encode-string");
459     push_str(alias);
460     fword("property");
461 }
462
463 int
464 ob_esp_init(unsigned int slot, uint64_t base, unsigned long espoffset,
465             unsigned long dmaoffset)
466 {
467     int id, diskcount = 0, cdcount = 0, *counter_ptr;
468     char nodebuff[256], aliasbuff[256];
469     esp_private_t *esp;
470     unsigned int i;
471
472     DPRINTF("Initializing SCSI...");
473
474     esp = malloc(sizeof(esp_private_t));
475     if (!esp) {
476         DPRINTF("Can't allocate ESP private structure\n");
477         return -1;
478     }
479
480     global_esp = esp;
481
482     if (espdma_init(slot, base, dmaoffset, &esp->espdma) != 0) {
483         return -1;
484     }
485     /* Get the IO region */
486     esp->ll = (void *)ofmem_map_io(base + (uint64_t)espoffset,
487                              sizeof(struct esp_regs));
488     if (esp->ll == NULL) {
489         DPRINTF("Can't map ESP registers\n");
490         return -1;
491     }
492
493     esp->buffer = (void *)dvma_alloc(BUFSIZE, &esp->buffer_dvma);
494     if (!esp->buffer || !esp->buffer_dvma) {
495         DPRINTF("Can't get a DVMA buffer\n");
496         return -1;
497     }
498
499     // Chip reset
500     esp->ll->regs[ESP_CMD] = ESP_CMD_RC;
501
502     DPRINTF("ESP at 0x%lx, buffer va 0x%lx dva 0x%lx\n", (unsigned long)esp,
503             (unsigned long)esp->buffer, (unsigned long)esp->buffer_dvma);
504     DPRINTF("done\n");
505     DPRINTF("Initializing SCSI devices...");
506
507     for (id = 0; id < 8; id++) {
508         esp->sd[id].id = id;
509         if (!inquiry(esp, &esp->sd[id])) {
510             DPRINTF("Unit %d not present\n", id);
511             continue;
512         }
513         /* Clear Unit Attention condition from reset */
514         for (i = 0; i < 5; i++) {
515             if (test_unit_ready(esp, &esp->sd[id])) {
516                 break;
517             }
518         }
519         if (i == 5) {
520             DPRINTF("Unit %d present but won't become ready\n", id);
521             continue;
522         }
523         DPRINTF("Unit %d present\n", id);
524         read_capacity(esp, &esp->sd[id]);
525
526 #ifdef CONFIG_DEBUG_ESP
527         dump_drive(&esp->sd[id]);
528 #endif
529     }
530
531     REGISTER_NAMED_NODE(ob_esp, "/iommu/sbus/espdma/esp");
532     device_end();
533     /* set reg */
534     push_str("/iommu/sbus/espdma/esp");
535     fword("find-device");
536     PUSH(slot);
537     fword("encode-int");
538     PUSH(espoffset);
539     fword("encode-int");
540     fword("encode+");
541     PUSH(0x00000010);
542     fword("encode-int");
543     fword("encode+");
544     push_str("reg");
545     fword("property");
546
547     PUSH(0x02625a00);
548     fword("encode-int");
549     push_str("clock-frequency");
550     fword("property");
551
552     for (id = 0; id < 8; id++) {
553         if (!esp->sd[id].present)
554             continue;
555         push_str("/iommu/sbus/espdma/esp");
556         fword("find-device");
557         fword("new-device");
558         push_str("sd");
559         fword("device-name");
560         push_str("block");
561         fword("device-type");
562         fword("is-deblocker");
563         PUSH(id);
564         fword("encode-int");
565         PUSH(0);
566         fword("encode-int");
567         fword("encode+");
568         push_str("reg");
569         fword("property");
570         fword("finish-device");
571         snprintf(nodebuff, sizeof(nodebuff), "/iommu/sbus/espdma/esp/sd@%d,0",
572                  id);
573         REGISTER_NODE_METHODS(ob_sd, nodebuff);
574         if (esp->sd[id].media == TYPE_ROM) {
575             counter_ptr = &cdcount;
576         } else {
577             counter_ptr = &diskcount;
578         }
579         if (*counter_ptr == 0) {
580             add_alias(nodebuff, esp->sd[id].media_str[0]);
581             add_alias(nodebuff, esp->sd[id].media_str[1]);
582         }
583         snprintf(aliasbuff, sizeof(aliasbuff), "%s%d",
584                  esp->sd[id].media_str[0], *counter_ptr);
585         add_alias(nodebuff, aliasbuff);
586         snprintf(aliasbuff, sizeof(aliasbuff), "%s%d",
587                  esp->sd[id].media_str[1], *counter_ptr);
588         add_alias(nodebuff, aliasbuff);
589         snprintf(aliasbuff, sizeof(aliasbuff), "sd(0,%d,0)", id);
590         add_alias(nodebuff, aliasbuff);
591         snprintf(aliasbuff, sizeof(aliasbuff), "sd(0,%d,0)@0,0", id);
592         add_alias(nodebuff, aliasbuff);
593         (*counter_ptr)++;
594     }
595     DPRINTF("done\n");
596
597     return 0;
598 }