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 strncpy(text, data + 46, 8);
240 text[8] = 0;
241 printf(" * Firmware: %s\n", text);
242 strncpy(text, data + 54, 40);
243 text[40] = 0;
244 printf(" * Model: %s\n", text);
245
246 if (!dev->atapi) {
247 printf(" * Addressing mode: %d\n", dev->addressing_mode);
248 printf(" * #cylinders: %d\n", (int) dev->cylinders);
249 printf(" * #heads: %d\n", (int) dev->heads);
250 printf(" * #sectors: %d\n", (int) dev->size);
251 }
252}
253
254static void
255xenon_ata_setlba(struct xenon_ata_device *dev, int sector, int size) {
256 xenon_ata_regset(dev, XENON_ATA_REG_SECTORS, size);
257 xenon_ata_regset(dev, XENON_ATA_REG_LBALOW, sector & 0xFF);
258 xenon_ata_regset(dev, XENON_ATA_REG_LBAMID, (sector >> 8) & 0xFF);
259 xenon_ata_regset(dev, XENON_ATA_REG_LBAHIGH, (sector >> 16) & 0xFF);
260}
261
262static int
263xenon_ata_setaddress(struct xenon_ata_device *dev, int sector, int size) {
264 xenon_ata_wait_busy(dev);
265
266 switch (dev->addressing_mode) {
267 case XENON_ATA_CHS:
268 {
269 unsigned int cylinder;
270 unsigned int head;
271 unsigned int sect;
272
273 /* Calculate the sector, cylinder and head to use. */
274 sect = ((uint32_t) sector % dev->sectors_per_track) + 1;
275 cylinder = (((uint32_t) sector / dev->sectors_per_track)
276 / dev->heads);
277 head = ((uint32_t) sector / dev->sectors_per_track) % dev->heads;
278
279 if (sect > dev->sectors_per_track
280 || cylinder > dev->cylinders
281 || head > dev->heads) {
282 printf("sector %d can not be addressed "
283 "using CHS addressing", sector);
284 return -1;
285 }
286
287 xenon_ata_regset(dev, XENON_ATA_REG_SECTNUM, sect);
288 xenon_ata_regset(dev, XENON_ATA_REG_CYLLSB, cylinder & 0xFF);
289 xenon_ata_regset(dev, XENON_ATA_REG_CYLMSB, cylinder >> 8);
290 xenon_ata_regset(dev, XENON_ATA_REG_DISK, head);
291
292 break;
293 }
294
295 case XENON_ATA_LBA:
296 if (size == 256)
297 size = 0;
298 xenon_ata_setlba(dev, sector, size);
299 xenon_ata_regset(dev, XENON_ATA_REG_DISK,
300 0xE0 | ((sector >> 24) & 0x0F));
301 break;
302
303 case XENON_ATA_LBA48:
304 if (size == 65536)
305 size = 0;
306
307 /* Set "Previous". */
308 xenon_ata_setlba(dev, sector >> 24, size >> 8);
309 /* Set "Current". */
310 xenon_ata_setlba(dev, sector, size);
311 xenon_ata_regset(dev, XENON_ATA_REG_DISK, 0xE0);
312
313 break;
314
315 default:
316 return -1;
317 }
318 return 0;
319}
320
321static int
322xenon_ata_read_sectors(sec_t start_sector, sec_t sector_size, void *buf) {
323 //struct xenon_ata_device *dev = bdev->ctx;
324 struct xenon_ata_device *dev = &ata;
325
326 //start_sector += bdev->offset;
327
328 xenon_ata_setaddress(dev, start_sector, sector_size);
329
330 /* Read sectors. */
331#ifndef USE_DMA
332 unsigned int sect = 0;
334 xenon_ata_wait_ready(dev);
335 for (sect = 0; sect < sector_size; sect++) {
336 if (xenon_ata_pio_read(dev, buf, XENON_DISK_SECTOR_SIZE)) {
337 asm volatile ("sync");
338 printf("ATA read error\n");
339 return -1;
340 }
342 }
343 asm volatile ("sync");
344 return sect;
345#else
346 xenon_ata_regset(dev, XENON_ATA_REG_CMD, XENON_ATA_CMD_READ_DMA_EXT);
347 xenon_ata_wait_ready(dev);
348
349 if (xenon_ata_dma_read(dev, buf, sector_size * XENON_DISK_SECTOR_SIZE)) {
350 printf("ATA DMA read error\n");
351 asm volatile ("sync");
352 return -1;
353 }
354 asm volatile ("sync");
355 return sector_size;
356#endif
357}
358
359static int
360//xenon_ata_write_sectors(struct bdev *bdev, const void *buf, lba_t start_sector, int sector_size) {
361xenon_ata_write_sectors(lba_t start_sector, int sector_size, const void *buf) {
362 unsigned int sect;
363 // struct xenon_ata_device *dev = bdev->ctx;
364 struct xenon_ata_device *dev = &ata;
365
366 //start_sector += bdev->offset;
367
368 xenon_ata_setaddress(dev, start_sector, sector_size);
369
370 /* Read sectors. */
372 xenon_ata_wait_ready(dev);
373 for (sect = 0; sect < sector_size; sect++) {
374 if (xenon_ata_pio_write(dev, (void *) buf, XENON_DISK_SECTOR_SIZE)) {
375 printf("ATA write error\n");
376 return -1;
377 }
379 }
380
381 return sect;
382}
383
384__attribute__((unused)) static int
385xenon_atapi_identify(struct xenon_ata_device *dev) {
386
387 char info[XENON_DISK_SECTOR_SIZE];
388 xenon_ata_wait_busy(dev);
389
390 xenon_ata_regset(dev, XENON_ATA_REG_DISK, 0xE0);
391 xenon_ata_regset(dev, XENON_ATA_REG_CMD,
393 xenon_ata_wait_ready(dev);
394
395 xenon_ata_pio_read(dev, info, sizeof (info));
396
397 dev->atapi = 1;
398
399 xenon_ata_dumpinfo(dev, info);
400
401 return 0;
402}
403
404static int
405xenon_atapi_packet(struct xenon_ata_device *dev, char *packet, int dma) {
406
407 xenon_ata_regset(dev, XENON_ATA_REG_DISK, 0);
408 xenon_ata_regset(dev, XENON_ATA_REG_FEATURES, dma ? 1 : 0);
409 xenon_ata_regset(dev, XENON_ATA_REG_SECTORS, 0);
410 xenon_ata_regset(dev, XENON_ATA_REG_LBAHIGH, 0xff);
411 xenon_ata_regset(dev, XENON_ATA_REG_LBAMID, 0xff);
412 xenon_ata_regset(dev, XENON_ATA_REG_CMD, XENON_ATA_CMD_PACKET);
413 xenon_ata_wait_ready(dev);
414
415 xenon_ata_pio_write(dev, packet, 12);
416
417 return 0;
418}
419
420#define SK(sense)((sense>>16) & 0xFF)
421#define ASC(sense)((sense>>8) & 0xFF)
422#define ASCQ(sense)((sense>>0) & 0xFF)
423
424int
426 char cdb[12] = {0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
427 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
428 char buf[24];
429 memset(buf, 0, sizeof (buf));
430
431 cdb[4] = sizeof (buf);
432
433 xenon_atapi_packet(dev, cdb, 0);
434 xenon_ata_wait_ready(dev);
435 if (xenon_ata_pio_read(dev, buf, sizeof (buf))) {
436 printf("ATAPI request sense failed\n");
437 return -1;
438 };
439
440 return (buf[2] << 16) | (buf[12] << 8) | buf[13];
441}
442
443static int
444xenon_atapi_inquiry_model(struct xenon_ata_device *dev) {
445
446 char cdb[12] = {0x12, 0x00, 0x00, 0x00, 0x24, 0xC0,
447 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
448 char buf[0x24];
449 memset(buf, 0, sizeof (buf));
450
451 xenon_atapi_packet(dev, cdb, 0);
452 xenon_ata_wait_ready(dev);
453 if (xenon_ata_pio_read(dev, buf, sizeof (buf))) {
454 printf("ATAPI inquiry failed\n");
455 return -1;
456 };
457
458 buf[8 + 24] = '\0';
459 printf("ATAPI inquiry model: %s\n", &buf[8]);
460
461 return 0;
462}
463
464void
466 struct xenon_ata_device *dev = &atapi;
467
468 char buf[0x30];
469 memset(buf, 0, sizeof (buf));
470
471 char cdb[12] = {0xE7, 0x48, 0x49, 0x54, 0x30, 0x90,
472 0x90, 0xd0, 0x01, 0x00, 0x00, 0x00};
473
474 xenon_atapi_packet(dev, cdb, 0);
475 xenon_ata_wait_ready(dev);
476 if (xenon_ata_pio_read(dev, buf, sizeof (buf))) {
477 printf("DVD set mode b failed\n");
478 }
479}
480
481int
482xenon_atapi_get_dvd_key_tsh943a(unsigned char *dvdkey) {
483 struct xenon_ata_device *dev = &atapi;
484
485 // create mode page buffer
486 char buf[0x10];
487 memset(buf, 0, sizeof (buf));
488
489 char cdb[12] = {0xFF, 0x08, 0x05, 0x00, 0x05, 0x01,
490 0x03, 0x00, 0x04, 0x07, 0x00, 0x00};
491
492 xenon_atapi_packet(dev, cdb, 0);
493 xenon_ata_wait_ready(dev);
494 if (xenon_ata_pio_read(dev, buf, sizeof (buf))) {
495 int sense = xenon_atapi_request_sense(dev);
496 printf("DVD drive key read failed with sense: %06x\n", sense);
497 return -1;
498 };
499
500 memcpy(dvdkey, buf, 0x10);
501 return 0;
502}
503
504int
505xenon_atapi_set_dvd_key(unsigned char *dvdkey) {
506 struct xenon_ata_device *dev = &atapi;
507
508 // create mode page buffer
509 char buf[0x3A];
510 memset(buf, 0, 0x3A);
511
512 // Mode parameter header(mode select 10) start
513 buf[0] = 0x00; // MODE DATA LENGTH MSB
514 buf[1] = 0x38; // MODE DATA LENGTH LSB
515 // Mode parameter header(mode select 10) end
516 buf[8] = 0xBB; // mode page code (vendor specific, page format required)
517 buf[9] = 0x30; // page length (16 bytes drive key + 32 bytes 0x00 following after mode page code)
518
519 // set drive key in mode page to 0xFF
520 memset(buf + 0x0A, 0xFF, 0x10);
521
522 char cdb[12] = {0x55, 0x00, 0x00, 0x00, 0x00, 0x00,
523 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00};
524
525
526 xenon_atapi_packet(dev, cdb, 0);
527 xenon_ata_wait_ready(dev);
528 if (xenon_ata_pio_write(dev, buf, sizeof (buf))) {
529 int sense = xenon_atapi_request_sense(dev);
530 printf(" ! DVD drive key erase failed with sense: %06x\n", sense);
531 return -1;
532 };
533
534 //set the key into the buffer
535 memcpy(buf + 0x0A, dvdkey, 0x10);
536
537 xenon_atapi_packet(dev, cdb, 0);
538 xenon_ata_wait_ready(dev);
539 if (xenon_ata_pio_write(dev, buf, sizeof (buf))) {
540 int sense = xenon_atapi_request_sense(dev);
541 printf("DVD drive key set failed with sense: %06x\n", sense);
542 return -1;
543 };
544
545 return 0;
546}
547
548static int
549xenon_atapi_read_sectors(sec_t start_sector, sec_t sector_size, void *buf) {
550 int maxretries = 20;
551 //struct xenon_ata_device *dev = bdev->ctx;
552 struct xenon_ata_device *dev = &atapi;
553 struct xenon_atapi_read readcmd;
554
555 readcmd.code = 0x28;
556 readcmd.lba = start_sector;
557 readcmd.length = sector_size;
558
559#ifndef USE_DMA
560 unsigned int sect = 0;
561 void * bufpos = buf;
562retry:
563 xenon_atapi_packet(dev, (char *) &readcmd, 0);
564 xenon_ata_wait_ready(dev);
565 for (sect = 0; sect < sector_size; sect++) {
566 if (xenon_ata_pio_read(dev, bufpos, XENON_CDROM_SECTOR_SIZE)) {
567 int sense = xenon_atapi_request_sense(dev);
568
569 // no media
570 if (SK(sense) == 0x02 && ASC(sense) == 0x3a) {
572 }
573
574 // becoming ready
575 if ((SK(sense) == 0x02 && ASC(sense) == 0x4) || SK(sense) == 0x6) {
576 if (!maxretries) return -1;
577 mdelay(500);
578 maxretries--;
579 goto retry;
580 }
581
582 printf("ATAPI read error\n");
583 return -1;
584 }
585 bufpos += XENON_CDROM_SECTOR_SIZE;
586 }
587#else
588retry:
589 xenon_atapi_packet(dev, (char *) &readcmd, 1);
590 xenon_ata_wait_ready(dev);
591
592 if (xenon_ata_dma_read(dev, buf, sector_size * XENON_CDROM_SECTOR_SIZE)) {
593 int sense = xenon_atapi_request_sense(dev);
594
595 // no media
596 if (SK(sense) == 0x02 && ASC(sense) == 0x3a) {
598 }
599
600 // becoming ready
601 if ((SK(sense) == 0x02 && ASC(sense) == 0x4) || SK(sense) == 0x6) {
602 if (!maxretries) return -1;
603 mdelay(500);
604 maxretries--;
605 goto retry;
606 }
607
608 printf("ATAPI DMA read error\n");
609 return -1;
610 }
611#endif
612
613 return sector_size;
614}
615
616static int
617xenon_ata_identify(struct xenon_ata_device *dev) {
618 char info[XENON_DISK_SECTOR_SIZE];
619 uint16_t *info16 = (uint16_t *) info;
620 xenon_ata_wait_busy(dev);
621
622 xenon_ata_regset(dev, XENON_ATA_REG_DISK, 0xE0);
623 xenon_ata_regset(dev, XENON_ATA_REG_CMD, XENON_ATA_CMD_IDENTIFY_DEVICE);
624 xenon_ata_wait_ready(dev);
625
626 int val = xenon_ata_pio_read(dev, info, XENON_DISK_SECTOR_SIZE);
627 if (val & 4)
628 return xenon_atapi_inquiry_model(dev);
629 else if (val)
630 return -1;
631
632 /* Now it is certain that this is not an ATAPI device. */
633 dev->atapi = 0;
634
635 /* CHS is always supported. */
637 /* Check if LBA is supported. */
638 if (bswap_16(info16[49]) & (1 << 9)) {
639 /* Check if LBA48 is supported. */
640 if (bswap_16(info16[83]) & (1 << 10))
642 else
644 }
645
646 /* Determine the amount of sectors. */
648 dev->size = __builtin_bswap32(*((uint32_t *) & info16[60]));
649 else
650 dev->size = __builtin_bswap32(*((uint32_t *) & info16[100]));
651
652 /* Read CHS information. */
653 dev->cylinders = bswap_16(info16[1]);
654 dev->heads = bswap_16(info16[3]);
655 dev->sectors_per_track = bswap_16(info16[6]);
656
657 xenon_ata_dumpinfo(dev, info);
658
659 return 0;
660}
661
662int
663xenon_ata_init1(struct xenon_ata_device *dev, uint32_t ioaddress, uint32_t ioaddress2) {
664
665 memset(dev, 0, sizeof (struct xenon_ata_device));
666 dev->ioaddress = ioaddress;
667 dev->ioaddress2 = ioaddress2;
668
669 dev->prds = memalign(0x10000, MAX_PRDS * sizeof (struct xenon_ata_dma_prd));
670
671 xenon_ata_identify(dev);
672
673 /* Try to detect if the port is in use by writing to it,
674 waiting for a while and reading it again. If the value
675 was preserved, there is a device connected. */
676 xenon_ata_regset(dev, XENON_ATA_REG_DISK, 0);
677 xenon_ata_wait();
678 xenon_ata_regset(dev, XENON_ATA_REG_LBALOW, 0x5A);
679 xenon_ata_wait();
680 if (xenon_ata_regget(dev, XENON_ATA_REG_LBALOW) != 0x5A) {
681 printf("no ata device connected.\n");
682 return -1;
683 }
684
685 /* Issue a reset. */
686 xenon_ata_regset2(dev, XENON_ATA_REG2_CONTROL, 6);
687 xenon_ata_wait();
688 xenon_ata_regset2(dev, XENON_ATA_REG2_CONTROL, 2);
689 xenon_ata_regget2(dev, XENON_ATA_REG2_CONTROL);
690 xenon_ata_regget2(dev, XENON_ATA_REG2_CONTROL);
691 xenon_ata_regget2(dev, XENON_ATA_REG2_CONTROL);
692 xenon_ata_regget2(dev, XENON_ATA_REG2_CONTROL);
693
694 xenon_ata_regset(dev, XENON_ATA_REG_DISK, 0);
695 xenon_ata_regget2(dev, XENON_ATA_REG2_CONTROL);
696 xenon_ata_regget2(dev, XENON_ATA_REG2_CONTROL);
697 xenon_ata_regget2(dev, XENON_ATA_REG2_CONTROL);
698 xenon_ata_regget2(dev, XENON_ATA_REG2_CONTROL);
699
700 printf("SATA device at %08lx\n", dev->ioaddress);
701
702 return 0;
703}
704
705static int ata_ready = 0;
706static int atapi_ready = 0;
707
708static bool atapi_inserted() {
709 return atapi_ready;
710}
711
712static bool ata_startup(void){
713 return true;
714}
715static bool ata_inserted(void) {
716 return ata_ready;
717}
718static bool ata_readsectors(sec_t sector, sec_t numSectors, void* buffer) {
719 if(xenon_ata_read_sectors(sector,numSectors,buffer))
720 return true;
721 return false;
722}
723static bool atapi_readsectors(sec_t sector, sec_t numSectors, void* buffer) {
724 if(xenon_atapi_read_sectors(sector,numSectors,buffer))
725 return true;
726 return false;
727}
728static bool ata_writesectors(sec_t sector, sec_t numSectors, const void* buffer){
729 if(xenon_ata_write_sectors(sector,numSectors,buffer))
730 return true;
731 else
732 return false;
733}
734static bool ata_clearstatus(void){
736 return true;
737}
738static bool ata_shutdown(void){
740 return true;
741}
742
743static s32 ata_sectors(void)
744{
745 struct xenon_ata_device *dev = &ata;
746 return dev->size;
747}
748
749static s32 atapi_sectors(void)
750{
751 struct xenon_ata_device *dev = &atapi;
752 return dev->size;
753}
754
756 .sectors = (FN_MEDIUM_DEVSECTORS) & ata_sectors,
757 .readSectors = (FN_MEDIUM_READSECTORS) & ata_readsectors,
758 .writeSectors = (FN_MEDIUM_WRITESECTORS) & ata_writesectors,
759 .clearStatus = (FN_MEDIUM_CLEARSTATUS) & ata_clearstatus,
760 .shutdown = (FN_MEDIUM_SHUTDOWN) & ata_shutdown,
761 .isInserted = (FN_MEDIUM_ISINSERTED) & ata_inserted,
762 .startup = (FN_MEDIUM_STARTUP) & ata_startup,
763 .ioType = FEATURE_XENON_ATA,
765};
766
768 .sectors = (FN_MEDIUM_DEVSECTORS) & atapi_sectors,
769 .readSectors = (FN_MEDIUM_READSECTORS) & atapi_readsectors,
770 .clearStatus = (FN_MEDIUM_CLEARSTATUS) & ata_clearstatus,
771 .shutdown = (FN_MEDIUM_SHUTDOWN) & ata_shutdown,
772 .isInserted = (FN_MEDIUM_ISINSERTED) & atapi_inserted,
773 .startup = (FN_MEDIUM_STARTUP) & ata_startup,
774 .ioType = FEATURE_XENON_ATAPI,
776};
777
778int
780 //preinit (start from scratch)
781 *(volatile uint32_t*)0xd0110060 = __builtin_bswap32(0x112400);
782 *(volatile uint32_t*)0xd0110080 = __builtin_bswap32(0x407231BE);
783 *(volatile uint32_t*)0xea001318 &= __builtin_bswap32(0xFFFFFFF0);
784 mdelay(1000);
785
786 struct xenon_ata_device *dev = &ata;
787 memset(dev, 0, sizeof (struct xenon_ata_device));
788 int err = xenon_ata_init1(dev, 0xea001300, 0xea001320);
789 if (!err)
790 ata_ready = 1;
791 return err;
792}
793
794int
796 //preinit (start from scratch)
797 *(volatile uint32_t*)0xd0108060 = __builtin_bswap32(0x112400);
798 *(volatile uint32_t*)0xd0108080 = __builtin_bswap32(0x407231BE);
799 *(volatile uint32_t*)0xea001218 &= __builtin_bswap32(0xFFFFFFF0);
800 mdelay(200);
801
802 struct xenon_ata_device *dev = &atapi;
803 memset(dev, 0, sizeof (struct xenon_ata_device));
804 int err = xenon_ata_init1(dev, 0xea001200, 0xea001220);
805 if (!err)
806 atapi_ready = 1;
807 return err;
808}
int xenon_atapi_init()
Definition: ata.c:795
#define SK(sense)
Definition: ata.c:420
struct xenon_ata_device ata
Definition: ata.c:42
DISC_INTERFACE xenon_ata_ops
Definition: ata.c:755
int xenon_ata_init1(struct xenon_ata_device *dev, uint32_t ioaddress, uint32_t ioaddress2)
Definition: ata.c:663
#define MIN(a, b)
Definition: ata.c:35
#define ASC(sense)
Definition: ata.c:421
void xenon_atapi_set_modeb(void)
Definition: ata.c:465
DISC_INTERFACE xenon_atapi_ops
Definition: ata.c:767
int xenon_atapi_set_dvd_key(unsigned char *dvdkey)
Definition: ata.c:505
struct xenon_ata_device atapi
Definition: ata.c:43
int xenon_atapi_request_sense(struct xenon_ata_device *dev)
Definition: ata.c:425
int xenon_ata_init()
Definition: ata.c:779
int xenon_atapi_get_dvd_key_tsh943a(unsigned char *dvdkey)
Definition: ata.c:482
@ 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
uint32_t ioaddress
Definition: ata.h:68
int addressing_mode
Definition: ata.h:73
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:86
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