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