LibXenon
Bare-metal Xbox 360 homebrew library
Loading...
Searching...
No Matches
ata.c
Go to the documentation of this file.
1/* modified to fit in libxenon */
2
3/* ata.c - ATA disk access. */
4/*
5 * GRUB -- GRand Unified Bootloader
6 * Copyright (C) 2007 Free Software Foundation, Inc.
7 *
8 * GRUB is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * GRUB is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <stdint.h>
23#include <string.h>
24#include <stdio.h>
25#include <assert.h>
26#include <time/time.h>
27#include <ppc/cache.h>
28#include <malloc.h>
29#include "ata.h"
30
31#include <debug.h>
32#include <byteswap.h>
33
34#define MAX(a,b) (((a)>(b))?(a):(b))
35#define MIN(a,b) (((a)<(b))?(a):(b))
36
37//No printf
38//#define printf(...)
39
40#define USE_DMA
41
44
45static inline void
46xenon_ata_regset(struct xenon_ata_device *dev, int reg, uint8_t val) {
47 *(volatile uint8_t*)(dev->ioaddress + reg) = val;
48}
49
50static inline uint8_t
51xenon_ata_regget(struct xenon_ata_device *dev, int reg) {
52 return *(volatile uint8_t*)(dev->ioaddress + reg);
53}
54
55static inline void
56xenon_ata_regset2(struct xenon_ata_device *dev, int reg, int val) {
57 *(volatile uint8_t*)(dev->ioaddress2 + reg) = val;
58}
59
60static inline int
61xenon_ata_regget2(struct xenon_ata_device *dev, int reg) {
62 return *(volatile uint8_t*)(dev->ioaddress2 + reg);
63}
64
65static inline uint32_t
66xenon_ata_read_data(struct xenon_ata_device *dev, int reg) {
67 return *(volatile uint32_t*)(dev->ioaddress + reg);
68}
69
70static inline void
71xenon_ata_write_data(struct xenon_ata_device *dev, int reg, uint32_t val) {
72 *(volatile uint32_t*)(dev->ioaddress + reg) = val;
73}
74
75static inline void
76xenon_ata_write_data2(struct xenon_ata_device *dev, int reg, uint32_t val) {
77 *(volatile uint32_t*)(dev->ioaddress2 + reg) = val;
78}
79
80static inline void
81xenon_ata_wait_busy(struct xenon_ata_device *dev) {
82 while ((xenon_ata_regget(dev, XENON_ATA_REG_STATUS) & 0x80));
83}
84
85static inline void
86xenon_ata_wait_drq(struct xenon_ata_device *dev) {
87 while (!(xenon_ata_regget(dev, XENON_ATA_REG_STATUS) & 0x08));
88}
89
90static inline void
91xenon_ata_wait_ready(struct xenon_ata_device *dev) {
92 while ((xenon_ata_regget(dev, XENON_ATA_REG_STATUS) & 0xC0) != 0x40);
93}
94
95static inline void
96xenon_ata_wait() {
97 mdelay(50);
98}
99
100static int
101xenon_ata_pio_read(struct xenon_ata_device *dev, char *buf, int size) {
102 uint32_t *buf32 = (uint32_t *) buf;
103 unsigned int i;
104
105 if (xenon_ata_regget(dev, XENON_ATA_REG_STATUS) & 1)
106 return xenon_ata_regget(dev, XENON_ATA_REG_ERROR);
107
108 /* Wait until the data is available. */
109 xenon_ata_wait_drq(dev);
110
111 /* Read in the data, word by word. */
112 if (size & 0xf) {
113 for (i = 0; i < size / 4; i++)
114 buf32[i] = xenon_ata_read_data(dev, XENON_ATA_REG_DATA);
115 } else {
116 volatile uint32_t* reg_data = (volatile uint32_t*)(dev->ioaddress + XENON_ATA_REG_DATA);
117 for (i = 0; i < size / 16; ++i) {
118 *buf32++ = *reg_data;
119 *buf32++ = *reg_data;
120 *buf32++ = *reg_data;
121 *buf32++ = *reg_data;
122 }
123 }
124
125 if (xenon_ata_regget(dev, XENON_ATA_REG_STATUS) & 1)
126 return xenon_ata_regget(dev, XENON_ATA_REG_ERROR);
127
128 return 0;
129}
130
131static int
132xenon_ata_pio_write(struct xenon_ata_device *dev, char *buf, int size) {
133 uint32_t *buf32 = (uint32_t *) buf;
134 unsigned int i;
135
136 /* Wait until the device is ready to write. */
137 xenon_ata_wait_drq(dev);
138
139 /* Write the data, word by word. */
140 for (i = 0; i < size / 4; i++)
141 xenon_ata_write_data(dev, XENON_ATA_REG_DATA, buf32[i]);
142
143 if (xenon_ata_regget(dev, XENON_ATA_REG_STATUS) & 1)
144 return xenon_ata_regget(dev, XENON_ATA_REG_ERROR);
145
146 return 0;
147}
148
149static int
150xenon_ata_dma_read(struct xenon_ata_device *dev, char *buf, int size) {
151
152 assert(!((uint32_t) buf & 3));
153
154 uint32_t i, b;
155 int s, ss;
156
157 if (xenon_ata_regget(dev, XENON_ATA_REG_STATUS) & 1)
158 return xenon_ata_regget(dev, XENON_ATA_REG_ERROR);
159
160 // printf("ATA DMA %p %d\n",buf,size);
161
162 /* build PRDs */
163
164 i = 0;
165 s = size;
166 b = ((uint32_t) buf)&0x7fffffff;
167 while (s > 0) {
168 dev->prds[i].address = __builtin_bswap32(b);
169
170 ss = MIN(s, 0x10000 - (b & 0xffff)); // a PRD buffer mustn't cross a 64k boundary
171 s -= ss;
172 b += ss;
173
174 dev->prds[i].size_flags = __builtin_bswap32((ss & 0xffff) | (s > 0 ? 0 : 0x80000000));
175
176 // printf("PRD %08x %d\n",b,ss);
177
178 ++i;
179 if (i >= MAX_PRDS && s > 0) {
180 printf("ATA DMA transfer too big\n");
181 return -1;
182 }
183 }
184
185 memdcbst(dev->prds, MAX_PRDS * sizeof (struct xenon_ata_dma_prd));
186
187 /* setup DMA regs */
188
189 xenon_ata_write_data2(dev, XENON_ATA_DMA_TABLE_OFS, __builtin_bswap32((uint32_t) dev->prds & 0x7fffffff));
190 xenon_ata_regset2(dev, XENON_ATA_DMA_CMD, XENON_ATA_DMA_WR);
191 xenon_ata_regset2(dev, XENON_ATA_DMA_STATUS, 0);
192
193 /* flush buffer from cache */
194
195 memdcbf(buf, size);
196
197 /* start DMA */
198
199 xenon_ata_regset2(dev, XENON_ATA_DMA_CMD, XENON_ATA_DMA_WR | XENON_ATA_DMA_START);
200
201 /* wait for DMA end */
202
203 while (xenon_ata_regget2(dev, XENON_ATA_DMA_STATUS) & XENON_ATA_DMA_ACTIVE);
204
205 /* stop DMA ctrlr */
206
207 xenon_ata_regset2(dev, XENON_ATA_DMA_CMD, 0);
208
209 if (xenon_ata_regget2(dev, XENON_ATA_DMA_STATUS) & XENON_ATA_DMA_ERR) {
210 printf("ATA DMA transfer error\n");
211 return -1;
212 }
213
214 if (xenon_ata_regget(dev, XENON_ATA_REG_STATUS) & 1)
215 return xenon_ata_regget(dev, XENON_ATA_REG_ERROR);
216
217 /* reload buffer into cache */
218
219 memdcbt(buf, size);
220
221 return 0;
222};
223
224static void
225xenon_ata_dumpinfo(struct xenon_ata_device *dev, char *info) {
226 char text[41];
227 char data[0x80];
228 int i;
229
230 for (i = 0; i<sizeof (data); i += 2) {
231 data[i] = info[i + 1];
232 data[i + 1] = info[i];
233 }
234
235 /* The device information was read, dump it for debugging. */
236 strncpy(text, data + 20, 20);
237 text[20] = 0;
238 printf(" * Serial: %s\n", text);
239
240 strncpy(dev->rev, data + 46, 8);
241 dev->rev[8] = 0;
242 printf(" * Firmware: %s\n", dev->rev);
243
244 strncpy(dev->model, data + 54, 40);
245 dev->model[40] = 0;
246 printf(" * Model: %s\n", dev->model);
247
248 if (!dev->atapi) {
249 printf(" * Addressing mode: %d\n", dev->addressing_mode);
250 printf(" * #cylinders: %d\n", (int) dev->cylinders);
251 printf(" * #heads: %d\n", (int) dev->heads);
252 printf(" * #sectors: %d\n", (int) dev->size);
253 }
254}
255
256static void
257xenon_ata_setlba(struct xenon_ata_device *dev, int sector, int size) {
258 xenon_ata_regset(dev, XENON_ATA_REG_SECTORS, size);
259 xenon_ata_regset(dev, XENON_ATA_REG_LBALOW, sector & 0xFF);
260 xenon_ata_regset(dev, XENON_ATA_REG_LBAMID, (sector >> 8) & 0xFF);
261 xenon_ata_regset(dev, XENON_ATA_REG_LBAHIGH, (sector >> 16) & 0xFF);
262}
263
264static int
265xenon_ata_setaddress(struct xenon_ata_device *dev, int sector, int size) {
266 xenon_ata_wait_busy(dev);
267
268 switch (dev->addressing_mode) {
269 case XENON_ATA_CHS:
270 {
271 unsigned int cylinder;
272 unsigned int head;
273 unsigned int sect;
274
275 /* Calculate the sector, cylinder and head to use. */
276 sect = ((uint32_t) sector % dev->sectors_per_track) + 1;
277 cylinder = (((uint32_t) sector / dev->sectors_per_track)
278 / dev->heads);
279 head = ((uint32_t) sector / dev->sectors_per_track) % dev->heads;
280
281 if (sect > dev->sectors_per_track
282 || cylinder > dev->cylinders
283 || head > dev->heads) {
284 printf("sector %d can not be addressed "
285 "using CHS addressing", sector);
286 return -1;
287 }
288
289 xenon_ata_regset(dev, XENON_ATA_REG_SECTNUM, sect);
290 xenon_ata_regset(dev, XENON_ATA_REG_CYLLSB, cylinder & 0xFF);
291 xenon_ata_regset(dev, XENON_ATA_REG_CYLMSB, cylinder >> 8);
292 xenon_ata_regset(dev, XENON_ATA_REG_DISK, head);
293
294 break;
295 }
296
297 case XENON_ATA_LBA:
298 if (size == 256)
299 size = 0;
300 xenon_ata_setlba(dev, sector, size);
301 xenon_ata_regset(dev, XENON_ATA_REG_DISK,
302 0xE0 | ((sector >> 24) & 0x0F));
303 break;
304
305 case XENON_ATA_LBA48:
306 if (size == 65536)
307 size = 0;
308
309 /* Set "Previous". */
310 xenon_ata_setlba(dev, sector >> 24, size >> 8);
311 /* Set "Current". */
312 xenon_ata_setlba(dev, sector, size);
313 xenon_ata_regset(dev, XENON_ATA_REG_DISK, 0xE0);
314
315 break;
316
317 default:
318 return -1;
319 }
320 return 0;
321}
322
323static int
324xenon_ata_read_sectors(sec_t start_sector, sec_t sector_size, void *buf) {
325 //struct xenon_ata_device *dev = bdev->ctx;
326 struct xenon_ata_device *dev = &ata;
327
328 //start_sector += bdev->offset;
329
330 xenon_ata_setaddress(dev, start_sector, sector_size);
331
332 /* Read sectors. */
333#ifndef USE_DMA
334 unsigned int sect = 0;
336 xenon_ata_wait_ready(dev);
337 for (sect = 0; sect < sector_size; sect++) {
338 if (xenon_ata_pio_read(dev, buf, XENON_DISK_SECTOR_SIZE)) {
339 asm volatile ("sync");
340 printf("ATA read error\n");
341 return -1;
342 }
344 }
345 asm volatile ("sync");
346 return sect;
347#else
348 xenon_ata_regset(dev, XENON_ATA_REG_CMD, XENON_ATA_CMD_READ_DMA_EXT);
349 xenon_ata_wait_ready(dev);
350
351 if (xenon_ata_dma_read(dev, buf, sector_size * XENON_DISK_SECTOR_SIZE)) {
352 printf("ATA DMA read error\n");
353 asm volatile ("sync");
354 return -1;
355 }
356 asm volatile ("sync");
357 return sector_size;
358#endif
359}
360
361static int
362//xenon_ata_write_sectors(struct bdev *bdev, const void *buf, lba_t start_sector, int sector_size) {
363xenon_ata_write_sectors(lba_t start_sector, int sector_size, const void *buf) {
364 unsigned int sect;
365 // struct xenon_ata_device *dev = bdev->ctx;
366 struct xenon_ata_device *dev = &ata;
367
368 //start_sector += bdev->offset;
369
370 xenon_ata_setaddress(dev, start_sector, sector_size);
371
372 /* Read sectors. */
374 xenon_ata_wait_ready(dev);
375 for (sect = 0; sect < sector_size; sect++) {
376 if (xenon_ata_pio_write(dev, (void *) buf, XENON_DISK_SECTOR_SIZE)) {
377 printf("ATA write error\n");
378 return -1;
379 }
381 }
382
383 return sect;
384}
385
386__attribute__((unused)) static int
387xenon_atapi_identify(struct xenon_ata_device *dev) {
388
389 char info[XENON_DISK_SECTOR_SIZE];
390 xenon_ata_wait_busy(dev);
391
392 xenon_ata_regset(dev, XENON_ATA_REG_DISK, 0xE0);
393 xenon_ata_regset(dev, XENON_ATA_REG_CMD,
395 xenon_ata_wait_ready(dev);
396
397 xenon_ata_pio_read(dev, info, sizeof (info));
398
399 dev->atapi = 1;
400
401 xenon_ata_dumpinfo(dev, info);
402
403 return 0;
404}
405
406static int
407xenon_atapi_packet(struct xenon_ata_device *dev, char *packet, int dma) {
408
409 xenon_ata_regset(dev, XENON_ATA_REG_DISK, 0);
410 xenon_ata_regset(dev, XENON_ATA_REG_FEATURES, dma ? 1 : 0);
411 xenon_ata_regset(dev, XENON_ATA_REG_SECTORS, 0);
412 xenon_ata_regset(dev, XENON_ATA_REG_LBAHIGH, 0xff);
413 xenon_ata_regset(dev, XENON_ATA_REG_LBAMID, 0xff);
414 xenon_ata_regset(dev, XENON_ATA_REG_CMD, XENON_ATA_CMD_PACKET);
415 xenon_ata_wait_ready(dev);
416
417 xenon_ata_pio_write(dev, packet, 12);
418
419 return 0;
420}
421
422#define SK(sense)((sense>>16) & 0xFF)
423#define ASC(sense)((sense>>8) & 0xFF)
424#define ASCQ(sense)((sense>>0) & 0xFF)
425
426int
428 char cdb[12] = {0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
430 char buf[24];
431 memset(buf, 0, sizeof (buf));
432
433 cdb[4] = sizeof (buf);
434
435 xenon_atapi_packet(dev, cdb, 0);
436 xenon_ata_wait_ready(dev);
437 if (xenon_ata_pio_read(dev, buf, sizeof (buf))) {
438 printf("ATAPI request sense failed\n");
439 return -1;
440 };
441
442 return (buf[2] << 16) | (buf[12] << 8) | buf[13];
443}
444
445static int
446xenon_atapi_inquiry_model(struct xenon_ata_device *dev) {
447
448 char cdb[12] = {0x12, 0x00, 0x00, 0x00, 0x24, 0xC0,
449 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
450 char buf[0x24];
451 memset(buf, 0, sizeof (buf));
452
453 xenon_atapi_packet(dev, cdb, 0);
454 xenon_ata_wait_ready(dev);
455 if (xenon_ata_pio_read(dev, buf, sizeof (buf))) {
456 printf("ATAPI inquiry failed\n");
457 return -1;
458 };
459
460 memcpy(dev->model, &buf[8], 24);
461 dev->model[24] = '\0';
462
463 memcpy(dev->rev, &buf[32], 4);
464 dev->rev[4] = '\0';
465
466 printf("ATAPI inquiry model: %s %s\n", dev->model, dev->rev);
467
468 return 0;
469}
470
471void
473 struct xenon_ata_device *dev = &atapi;
474
475 char buf[0x30];
476 memset(buf, 0, sizeof (buf));
477
478 char cdb[12] = {0xE7, 0x48, 0x49, 0x54, 0x30, 0x90,
479 0x90, 0xd0, 0x01, 0x00, 0x00, 0x00};
480
481 xenon_atapi_packet(dev, cdb, 0);
482 xenon_ata_wait_ready(dev);
483 if (xenon_ata_pio_read(dev, buf, sizeof (buf))) {
484 printf("DVD set mode b failed\n");
485 }
486}
487
488int
489xenon_atapi_get_dvd_key_tsh943a(unsigned char *dvdkey) {
490 struct xenon_ata_device *dev = &atapi;
491
492 // create mode page buffer
493 char buf[0x10];
494 memset(buf, 0, sizeof (buf));
495
496 char cdb[12] = {0xFF, 0x08, 0x05, 0x00, 0x05, 0x01,
497 0x03, 0x00, 0x04, 0x07, 0x00, 0x00};
498
499 xenon_atapi_packet(dev, cdb, 0);
500 xenon_ata_wait_ready(dev);
501 if (xenon_ata_pio_read(dev, buf, sizeof (buf))) {
502 int sense = xenon_atapi_request_sense(dev);
503 printf("DVD drive key read failed with sense: %06x\n", sense);
504 return -1;
505 };
506
507 memcpy(dvdkey, buf, 0x10);
508 return 0;
509}
510
511int
512xenon_atapi_set_dvd_key(unsigned char *dvdkey) {
513 struct xenon_ata_device *dev = &atapi;
514
515 // create mode page buffer
516 char buf[0x3A];
517 memset(buf, 0, 0x3A);
518
519 // Mode parameter header(mode select 10) start
520 buf[0] = 0x00; // MODE DATA LENGTH MSB
521 buf[1] = 0x38; // MODE DATA LENGTH LSB
522 // Mode parameter header(mode select 10) end
523 buf[8] = 0xBB; // mode page code (vendor specific, page format required)
524 buf[9] = 0x30; // page length (16 bytes drive key + 32 bytes 0x00 following after mode page code)
525
526 // set drive key in mode page to 0xFF
527 memset(buf + 0x0A, 0xFF, 0x10);
528
529 char cdb[12] = {0x55, 0x00, 0x00, 0x00, 0x00, 0x00,
530 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00};
531
532
533 xenon_atapi_packet(dev, cdb, 0);
534 xenon_ata_wait_ready(dev);
535 if (xenon_ata_pio_write(dev, buf, sizeof (buf))) {
536 int sense = xenon_atapi_request_sense(dev);
537 printf(" ! DVD drive key erase failed with sense: %06x\n", sense);
538 return -1;
539 };
540
541 //set the key into the buffer
542 memcpy(buf + 0x0A, dvdkey, 0x10);
543
544 xenon_atapi_packet(dev, cdb, 0);
545 xenon_ata_wait_ready(dev);
546 if (xenon_ata_pio_write(dev, buf, sizeof (buf))) {
547 int sense = xenon_atapi_request_sense(dev);
548 printf("DVD drive key set failed with sense: %06x\n", sense);
549 return -1;
550 };
551
552 return 0;
553}
554
555static int
556xenon_atapi_read_sectors(sec_t start_sector, sec_t sector_size, void *buf) {
557 int maxretries = 20;
558 //struct xenon_ata_device *dev = bdev->ctx;
559 struct xenon_ata_device *dev = &atapi;
560 struct xenon_atapi_read readcmd;
561
562 readcmd.code = 0x28;
563 readcmd.lba = start_sector;
564 readcmd.length = sector_size;
565
566 // Wait for the drive to become ready before we attempt to read sectors
567 // Hitachi 3120L and DL10N drives are picky and hang if we don't wait
568 xenon_ata_wait_ready(dev);
569
570#ifndef USE_DMA
571 unsigned int sect = 0;
572 void * bufpos = buf;
573retry:
574 xenon_atapi_packet(dev, (char *) &readcmd, 0);
575 xenon_ata_wait_ready(dev);
576 for (sect = 0; sect < sector_size; sect++) {
577 if (xenon_ata_pio_read(dev, bufpos, XENON_CDROM_SECTOR_SIZE)) {
578 int sense = xenon_atapi_request_sense(dev);
579
580 // no media
581 if (SK(sense) == 0x02 && ASC(sense) == 0x3a) {
583 }
584
585 // becoming ready
586 if ((SK(sense) == 0x02 && ASC(sense) == 0x4) || SK(sense) == 0x6) {
587 if (!maxretries) return -1;
588 mdelay(500);
589 maxretries--;
590 goto retry;
591 }
592
593 printf("ATAPI read error\n");
594 return -1;
595 }
596 bufpos += XENON_CDROM_SECTOR_SIZE;
597 }
598#else
599retry:
600 xenon_atapi_packet(dev, (char *) &readcmd, 1);
601 xenon_ata_wait_ready(dev);
602
603 if (xenon_ata_dma_read(dev, buf, sector_size * XENON_CDROM_SECTOR_SIZE)) {
604 int sense = xenon_atapi_request_sense(dev);
605
606 // no media
607 if (SK(sense) == 0x02 && ASC(sense) == 0x3a) {
609 }
610
611 // becoming ready
612 if ((SK(sense) == 0x02 && ASC(sense) == 0x4) || SK(sense) == 0x6) {
613 if (!maxretries) return -1;
614 mdelay(500);
615 maxretries--;
616 goto retry;
617 }
618
619 printf("ATAPI DMA read error\n");
620 return -1;
621 }
622#endif
623
624 return sector_size;
625}
626
627static int
628xenon_ata_identify(struct xenon_ata_device *dev) {
629 char info[XENON_DISK_SECTOR_SIZE];
630 uint16_t *info16 = (uint16_t *) info;
631 xenon_ata_wait_busy(dev);
632
633 xenon_ata_regset(dev, XENON_ATA_REG_DISK, 0xE0);
634 xenon_ata_regset(dev, XENON_ATA_REG_CMD, XENON_ATA_CMD_IDENTIFY_DEVICE);
635 xenon_ata_wait_ready(dev);
636
637 int val = xenon_ata_pio_read(dev, info, XENON_DISK_SECTOR_SIZE);
638 if (val & 4)
639 return xenon_atapi_inquiry_model(dev);
640 else if (val)
641 return -1;
642
643 /* Now it is certain that this is not an ATAPI device. */
644 dev->atapi = 0;
645
646 /* CHS is always supported. */
648 /* Check if LBA is supported. */
649 if (bswap_16(info16[49]) & (1 << 9)) {
650 /* Check if LBA48 is supported. */
651 if (bswap_16(info16[83]) & (1 << 10))
653 else
655 }
656
657 /* Determine the amount of sectors. */
659 dev->size = __builtin_bswap32(*((uint32_t *) & info16[60]));
660 else
661 dev->size = __builtin_bswap32(*((uint32_t *) & info16[100]));
662
663 /* Read CHS information. */
664 dev->cylinders = bswap_16(info16[1]);
665 dev->heads = bswap_16(info16[3]);
666 dev->sectors_per_track = bswap_16(info16[6]);
667
668 xenon_ata_dumpinfo(dev, info);
669
670 return 0;
671}
672
673int
674xenon_ata_init1(struct xenon_ata_device *dev, uint32_t ioaddress, uint32_t ioaddress2) {
675
676 memset(dev, 0, sizeof (struct xenon_ata_device));
677 dev->ioaddress = ioaddress;
678 dev->ioaddress2 = ioaddress2;
679
680 dev->prds = memalign(0x10000, MAX_PRDS * sizeof (struct xenon_ata_dma_prd));
681
682 xenon_ata_identify(dev);
683
684 /* Try to detect if the port is in use by writing to it,
685 waiting for a while and reading it again. If the value
686 was preserved, there is a device connected. */
687 xenon_ata_regset(dev, XENON_ATA_REG_DISK, 0);
688 xenon_ata_wait();
689 xenon_ata_regset(dev, XENON_ATA_REG_LBALOW, 0x5A);
690 xenon_ata_wait();
691 if (xenon_ata_regget(dev, XENON_ATA_REG_LBALOW) != 0x5A) {
692 printf("no ata device connected.\n");
693 return -1;
694 }
695
696 /* Issue a reset. */
697 xenon_ata_regset2(dev, XENON_ATA_REG2_CONTROL, 6);
698 xenon_ata_wait();
699 xenon_ata_regset2(dev, XENON_ATA_REG2_CONTROL, 2);
700 xenon_ata_regget2(dev, XENON_ATA_REG2_CONTROL);
701 xenon_ata_regget2(dev, XENON_ATA_REG2_CONTROL);
702 xenon_ata_regget2(dev, XENON_ATA_REG2_CONTROL);
703 xenon_ata_regget2(dev, XENON_ATA_REG2_CONTROL);
704
705 xenon_ata_regset(dev, XENON_ATA_REG_DISK, 0);
706 xenon_ata_regget2(dev, XENON_ATA_REG2_CONTROL);
707 xenon_ata_regget2(dev, XENON_ATA_REG2_CONTROL);
708 xenon_ata_regget2(dev, XENON_ATA_REG2_CONTROL);
709 xenon_ata_regget2(dev, XENON_ATA_REG2_CONTROL);
710
711 printf("SATA device at %08lx\n", dev->ioaddress);
712
713 return 0;
714}
715
716static int ata_ready = 0;
717static int atapi_ready = 0;
718
719static bool atapi_inserted() {
720 return atapi_ready;
721}
722
723static bool ata_startup(void){
724 return true;
725}
726static bool ata_inserted(void) {
727 return ata_ready;
728}
729static bool ata_readsectors(sec_t sector, sec_t numSectors, void* buffer) {
730 if(xenon_ata_read_sectors(sector,numSectors,buffer))
731 return true;
732 return false;
733}
734static bool atapi_readsectors(sec_t sector, sec_t numSectors, void* buffer) {
735 if(xenon_atapi_read_sectors(sector,numSectors,buffer))
736 return true;
737 return false;
738}
739static bool ata_writesectors(sec_t sector, sec_t numSectors, const void* buffer){
740 if(xenon_ata_write_sectors(sector,numSectors,buffer))
741 return true;
742 else
743 return false;
744}
745static bool ata_clearstatus(void){
747 return true;
748}
749static bool ata_shutdown(void){
751 return true;
752}
753
754static s32 ata_sectors(void)
755{
756 struct xenon_ata_device *dev = &ata;
757 return dev->size;
758}
759
760static s32 atapi_sectors(void)
761{
762 struct xenon_ata_device *dev = &atapi;
763 return dev->size;
764}
765
767 .sectors = (FN_MEDIUM_DEVSECTORS) & ata_sectors,
768 .readSectors = (FN_MEDIUM_READSECTORS) & ata_readsectors,
769 .writeSectors = (FN_MEDIUM_WRITESECTORS) & ata_writesectors,
770 .clearStatus = (FN_MEDIUM_CLEARSTATUS) & ata_clearstatus,
771 .shutdown = (FN_MEDIUM_SHUTDOWN) & ata_shutdown,
772 .isInserted = (FN_MEDIUM_ISINSERTED) & ata_inserted,
773 .startup = (FN_MEDIUM_STARTUP) & ata_startup,
774 .ioType = FEATURE_XENON_ATA,
776};
777
779 .sectors = (FN_MEDIUM_DEVSECTORS) & atapi_sectors,
780 .readSectors = (FN_MEDIUM_READSECTORS) & atapi_readsectors,
781 .clearStatus = (FN_MEDIUM_CLEARSTATUS) & ata_clearstatus,
782 .shutdown = (FN_MEDIUM_SHUTDOWN) & ata_shutdown,
783 .isInserted = (FN_MEDIUM_ISINSERTED) & atapi_inserted,
784 .startup = (FN_MEDIUM_STARTUP) & ata_startup,
785 .ioType = FEATURE_XENON_ATAPI,
787};
788
789int
791 //preinit (start from scratch)
792 *(volatile uint32_t*)0xd0110060 = __builtin_bswap32(0x112400);
793 *(volatile uint32_t*)0xd0110080 = __builtin_bswap32(0x407231BE);
794 *(volatile uint32_t*)0xea001318 &= __builtin_bswap32(0xFFFFFFF0);
795 mdelay(1000);
796
797 struct xenon_ata_device *dev = &ata;
798 memset(dev, 0, sizeof (struct xenon_ata_device));
799 int err = xenon_ata_init1(dev, 0xea001300, 0xea001320);
800 if (!err)
801 ata_ready = 1;
802 return err;
803}
804
805int
807 //preinit (start from scratch)
808 *(volatile uint32_t*)0xd0108060 = __builtin_bswap32(0x112400);
809 *(volatile uint32_t*)0xd0108080 = __builtin_bswap32(0x407231BE);
810 *(volatile uint32_t*)0xea001218 &= __builtin_bswap32(0xFFFFFFF0);
811 mdelay(200);
812
813 struct xenon_ata_device *dev = &atapi;
814 memset(dev, 0, sizeof (struct xenon_ata_device));
815 int err = xenon_ata_init1(dev, 0xea001200, 0xea001220);
816 if (!err)
817 atapi_ready = 1;
818 return err;
819}
int xenon_atapi_init()
Definition: ata.c:806
#define SK(sense)
Definition: ata.c:422
struct xenon_ata_device ata
Definition: ata.c:42
DISC_INTERFACE xenon_ata_ops
Definition: ata.c:766
int xenon_ata_init1(struct xenon_ata_device *dev, uint32_t ioaddress, uint32_t ioaddress2)
Definition: ata.c:674
#define MIN(a, b)
Definition: ata.c:35
#define ASC(sense)
Definition: ata.c:423
void xenon_atapi_set_modeb(void)
Definition: ata.c:472
DISC_INTERFACE xenon_atapi_ops
Definition: ata.c:778
int xenon_atapi_set_dvd_key(unsigned char *dvdkey)
Definition: ata.c:512
struct xenon_ata_device atapi
Definition: ata.c:43
int xenon_atapi_request_sense(struct xenon_ata_device *dev)
Definition: ata.c:427
int xenon_ata_init()
Definition: ata.c:790
int xenon_atapi_get_dvd_key_tsh943a(unsigned char *dvdkey)
Definition: ata.c:489
@ XENON_ATA_CHS
Definition: ata.h:41
@ XENON_ATA_LBA
Definition: ata.h:42
@ XENON_ATA_LBA48
Definition: ata.h:43
#define XENON_ATA_REG_CYLLSB
Definition: ata.h:15
#define XENON_ATA_REG_CYLMSB
Definition: ata.h:16
#define MAX_PRDS
Definition: ata.h:60
#define XENON_ATA_REG_CMD
Definition: ata.h:21
#define XENON_ATA_REG_ERROR
Definition: ata.h:11
#define XENON_ATA_REG_STATUS
Definition: ata.h:22
#define XENON_ATA_REG_DISK
Definition: ata.h:20
#define XENON_ATA_REG_DATA
Definition: ata.h:10
#define XENON_CDROM_SECTOR_SIZE
Definition: ata.h:47
#define XENON_ATA_REG_LBAHIGH
Definition: ata.h:19
#define XENON_ATA_REG_SECTORS
Definition: ata.h:13
#define XENON_ATA_REG_LBALOW
Definition: ata.h:17
#define XENON_ATA_REG_LBAMID
Definition: ata.h:18
#define XENON_ATA_REG2_CONTROL
Definition: ata.h:24
#define XENON_ATA_REG_SECTNUM
Definition: ata.h:14
#define XENON_DISK_SECTOR_SIZE
Definition: ata.h:46
@ XENON_ATA_CMD_IDENTIFY_DEVICE
Definition: ata.h:34
@ XENON_ATA_CMD_WRITE_SECTORS_EXT
Definition: ata.h:33
@ XENON_ATA_CMD_PACKET
Definition: ata.h:36
@ XENON_ATA_CMD_READ_SECTORS_EXT
Definition: ata.h:30
@ XENON_ATA_CMD_IDENTIFY_PACKET_DEVICE
Definition: ata.h:35
@ XENON_ATA_CMD_READ_DMA_EXT
Definition: ata.h:31
@ XENON_ATA_DMA_ACTIVE
Definition: ata.h:57
@ XENON_ATA_DMA_ERR
Definition: ata.h:56
@ XENON_ATA_DMA_CMD
Definition: ata.h:52
@ XENON_ATA_DMA_START
Definition: ata.h:54
@ XENON_ATA_DMA_TABLE_OFS
Definition: ata.h:50
@ XENON_ATA_DMA_STATUS
Definition: ata.h:51
@ XENON_ATA_DMA_WR
Definition: ata.h:53
#define XENON_ATA_REG_FEATURES
Definition: ata.h:12
#define FEATURE_XENON_ATA
Definition: disc_io.h:41
bool(* FN_MEDIUM_STARTUP)(void)
Definition: disc_io.h:47
bool(* FN_MEDIUM_CLEARSTATUS)(void)
Definition: disc_io.h:51
#define FEATURE_MEDIUM_CANREAD
Definition: disc_io.h:39
s32(* FN_MEDIUM_DEVSECTORS)(void)
Definition: disc_io.h:53
bool(* FN_MEDIUM_SHUTDOWN)(void)
Definition: disc_io.h:52
#define DISKIO_ERROR_NO_MEDIA
Definition: disc_io.h:37
#define FEATURE_XENON_ATAPI
Definition: disc_io.h:42
bool(* FN_MEDIUM_READSECTORS)(sec_t sector, sec_t numSectors, void *buffer)
Definition: disc_io.h:49
bool(* FN_MEDIUM_WRITESECTORS)(sec_t sector, sec_t numSectors, const void *buffer)
Definition: disc_io.h:50
#define FEATURE_MEDIUM_CANWRITE
Definition: disc_io.h:40
uint32_t sec_t
Definition: disc_io.h:45
bool(* FN_MEDIUM_ISINSERTED)(void)
Definition: disc_io.h:48
void memdcbf(void *addr, int len)
void memdcbst(void *addr, int len)
void memdcbt(void *addr, int len)
static uint32_t val
Definition: io.h:17
u32 size
Definition: iso9660.c:537
u32 uint32_t
Definition: libfdt_env.h:11
u16 uint16_t
Definition: libfdt_env.h:10
u8 uint8_t
Definition: libfdt_env.h:9
unsigned int __mf_uintptr_t __attribute__((__mode__(__pointer__)))
Definition: mf-runtime.h:34
FN_MEDIUM_DEVSECTORS sectors
Definition: disc_io.h:64
char rev[9]
Definition: ata.h:85
uint32_t ioaddress
Definition: ata.h:68
int addressing_mode
Definition: ata.h:73
char model[0x30]
Definition: ata.h:84
int atapi
Definition: ata.h:71
uint32_t size
Definition: ata.h:79
uint16_t sectors_per_track
Definition: ata.h:77
struct xenon_ata_dma_prd * prds
Definition: ata.h:82
uint16_t heads
Definition: ata.h:76
uint16_t cylinders
Definition: ata.h:75
uint32_t ioaddress2
Definition: ata.h:69
uint32_t address
Definition: ata.h:63
uint32_t size_flags
Definition: ata.h:64
uint8_t code
Definition: ata.h:89
void mdelay(int u)
Definition: time.c:17
u8 features
Definition: xenos_edid.h:15
union @15 data
unsigned long long lba_t
Definition: xetypes.h:44
int32_t s32
32bit signed integer
Definition: xetypes.h:19