34#define MAX(a,b) (((a)>(b))?(a):(b))
35#define MIN(a,b) (((a)<(b))?(a):(b))
109 xenon_ata_wait_drq(dev);
113 for (i = 0; i <
size / 4; i++)
117 for (i = 0; i <
size / 16; ++i) {
118 *buf32++ = *reg_data;
119 *buf32++ = *reg_data;
120 *buf32++ = *reg_data;
121 *buf32++ = *reg_data;
137 xenon_ata_wait_drq(dev);
140 for (i = 0; i <
size / 4; i++)
170 ss =
MIN(s, 0x10000 - (b & 0xffff));
174 dev->
prds[i].
size_flags = __builtin_bswap32((ss & 0xffff) | (s > 0 ? 0 : 0x80000000));
180 printf(
"ATA DMA transfer too big\n");
210 printf(
"ATA DMA transfer error\n");
230 for (i = 0; i<
sizeof (
data); i += 2) {
231 data[i] = info[i + 1];
232 data[i + 1] = info[i];
236 strncpy(text,
data + 20, 20);
238 printf(
" * Serial: %s\n", text);
239 strncpy(text,
data + 46, 8);
241 printf(
" * Firmware: %s\n", text);
242 strncpy(text,
data + 54, 40);
244 printf(
" * Model: %s\n", text);
248 printf(
" * #cylinders: %d\n", (
int) dev->
cylinders);
249 printf(
" * #heads: %d\n", (
int) dev->
heads);
250 printf(
" * #sectors: %d\n", (
int) dev->
size);
264 xenon_ata_wait_busy(dev);
269 unsigned int cylinder;
281 || head > dev->
heads) {
282 printf(
"sector %d can not be addressed "
283 "using CHS addressing", sector);
298 xenon_ata_setlba(dev, sector,
size);
300 0xE0 | ((sector >> 24) & 0x0F));
308 xenon_ata_setlba(dev, sector >> 24,
size >> 8);
310 xenon_ata_setlba(dev, sector,
size);
322xenon_ata_read_sectors(
sec_t start_sector,
sec_t sector_size,
void *buf) {
328 xenon_ata_setaddress(dev, start_sector, sector_size);
332 unsigned int sect = 0;
334 xenon_ata_wait_ready(dev);
335 for (sect = 0; sect < sector_size; sect++) {
337 asm volatile (
"sync");
338 printf(
"ATA read error\n");
343 asm volatile (
"sync");
347 xenon_ata_wait_ready(dev);
350 printf(
"ATA DMA read error\n");
351 asm volatile (
"sync");
354 asm volatile (
"sync");
361xenon_ata_write_sectors(
lba_t start_sector,
int sector_size,
const void *buf) {
368 xenon_ata_setaddress(dev, start_sector, sector_size);
372 xenon_ata_wait_ready(dev);
373 for (sect = 0; sect < sector_size; sect++) {
375 printf(
"ATA write error\n");
388 xenon_ata_wait_busy(dev);
393 xenon_ata_wait_ready(dev);
395 xenon_ata_pio_read(dev, info,
sizeof (info));
399 xenon_ata_dumpinfo(dev, info);
413 xenon_ata_wait_ready(dev);
415 xenon_ata_pio_write(dev, packet, 12);
420#define SK(sense)((sense>>16) & 0xFF)
421#define ASC(sense)((sense>>8) & 0xFF)
422#define ASCQ(sense)((sense>>0) & 0xFF)
426 char cdb[12] = {0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
427 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
429 memset(buf, 0,
sizeof (buf));
431 cdb[4] =
sizeof (buf);
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");
440 return (buf[2] << 16) | (buf[12] << 8) | buf[13];
446 char cdb[12] = {0x12, 0x00, 0x00, 0x00, 0x24, 0xC0,
447 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
449 memset(buf, 0,
sizeof (buf));
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");
459 printf(
"ATAPI inquiry model: %s\n", &buf[8]);
469 memset(buf, 0,
sizeof (buf));
471 char cdb[12] = {0xE7, 0x48, 0x49, 0x54, 0x30, 0x90,
472 0x90, 0xd0, 0x01, 0x00, 0x00, 0x00};
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");
487 memset(buf, 0,
sizeof (buf));
489 char cdb[12] = {0xFF, 0x08, 0x05, 0x00, 0x05, 0x01,
490 0x03, 0x00, 0x04, 0x07, 0x00, 0x00};
492 xenon_atapi_packet(dev, cdb, 0);
493 xenon_ata_wait_ready(dev);
494 if (xenon_ata_pio_read(dev, buf,
sizeof (buf))) {
496 printf(
"DVD drive key read failed with sense: %06x\n", sense);
500 memcpy(dvdkey, buf, 0x10);
510 memset(buf, 0, 0x3A);
520 memset(buf + 0x0A, 0xFF, 0x10);
522 char cdb[12] = {0x55, 0x00, 0x00, 0x00, 0x00, 0x00,
523 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00};
526 xenon_atapi_packet(dev, cdb, 0);
527 xenon_ata_wait_ready(dev);
528 if (xenon_ata_pio_write(dev, buf,
sizeof (buf))) {
530 printf(
" ! DVD drive key erase failed with sense: %06x\n", sense);
535 memcpy(buf + 0x0A, dvdkey, 0x10);
537 xenon_atapi_packet(dev, cdb, 0);
538 xenon_ata_wait_ready(dev);
539 if (xenon_ata_pio_write(dev, buf,
sizeof (buf))) {
541 printf(
"DVD drive key set failed with sense: %06x\n", sense);
549xenon_atapi_read_sectors(
sec_t start_sector,
sec_t sector_size,
void *buf) {
556 readcmd.lba = start_sector;
557 readcmd.length = sector_size;
560 unsigned int sect = 0;
563 xenon_atapi_packet(dev, (
char *) &readcmd, 0);
564 xenon_ata_wait_ready(dev);
565 for (sect = 0; sect < sector_size; sect++) {
570 if (
SK(sense) == 0x02 &&
ASC(sense) == 0x3a) {
575 if ((
SK(sense) == 0x02 &&
ASC(sense) == 0x4) ||
SK(sense) == 0x6) {
576 if (!maxretries)
return -1;
582 printf(
"ATAPI read error\n");
589 xenon_atapi_packet(dev, (
char *) &readcmd, 1);
590 xenon_ata_wait_ready(dev);
596 if (
SK(sense) == 0x02 &&
ASC(sense) == 0x3a) {
601 if ((
SK(sense) == 0x02 &&
ASC(sense) == 0x4) ||
SK(sense) == 0x6) {
602 if (!maxretries)
return -1;
608 printf(
"ATAPI DMA read error\n");
620 xenon_ata_wait_busy(dev);
624 xenon_ata_wait_ready(dev);
628 return xenon_atapi_inquiry_model(dev);
638 if (bswap_16(info16[49]) & (1 << 9)) {
640 if (bswap_16(info16[83]) & (1 << 10))
648 dev->
size = __builtin_bswap32(*((
uint32_t *) & info16[60]));
650 dev->
size = __builtin_bswap32(*((
uint32_t *) & info16[100]));
654 dev->
heads = bswap_16(info16[3]);
657 xenon_ata_dumpinfo(dev, info);
671 xenon_ata_identify(dev);
681 printf(
"no ata device connected.\n");
700 printf(
"SATA device at %08lx\n", dev->
ioaddress);
705static int ata_ready = 0;
706static int atapi_ready = 0;
708static bool atapi_inserted() {
712static bool ata_startup(
void){
715static bool ata_inserted(
void) {
718static bool ata_readsectors(
sec_t sector,
sec_t numSectors,
void* buffer) {
719 if(xenon_ata_read_sectors(sector,numSectors,buffer))
723static bool atapi_readsectors(
sec_t sector,
sec_t numSectors,
void* buffer) {
724 if(xenon_atapi_read_sectors(sector,numSectors,buffer))
728static bool ata_writesectors(
sec_t sector,
sec_t numSectors,
const void* buffer){
729 if(xenon_ata_write_sectors(sector,numSectors,buffer))
734static bool ata_clearstatus(
void){
738static bool ata_shutdown(
void){
743static s32 ata_sectors(
void)
749static s32 atapi_sectors(
void)
781 *(
volatile uint32_t*)0xd0110060 = __builtin_bswap32(0x112400);
782 *(
volatile uint32_t*)0xd0110080 = __builtin_bswap32(0x407231BE);
783 *(
volatile uint32_t*)0xea001318 &= __builtin_bswap32(0xFFFFFFF0);
797 *(
volatile uint32_t*)0xd0108060 = __builtin_bswap32(0x112400);
798 *(
volatile uint32_t*)0xd0108080 = __builtin_bswap32(0x407231BE);
799 *(
volatile uint32_t*)0xea001218 &= __builtin_bswap32(0xFFFFFFF0);
struct xenon_ata_device ata
DISC_INTERFACE xenon_ata_ops
int xenon_ata_init1(struct xenon_ata_device *dev, uint32_t ioaddress, uint32_t ioaddress2)
void xenon_atapi_set_modeb(void)
DISC_INTERFACE xenon_atapi_ops
int xenon_atapi_set_dvd_key(unsigned char *dvdkey)
struct xenon_ata_device atapi
int xenon_atapi_request_sense(struct xenon_ata_device *dev)
int xenon_atapi_get_dvd_key_tsh943a(unsigned char *dvdkey)
#define XENON_ATA_REG_CYLLSB
#define XENON_ATA_REG_CYLMSB
#define XENON_ATA_REG_CMD
#define XENON_ATA_REG_ERROR
#define XENON_ATA_REG_STATUS
#define XENON_ATA_REG_DISK
#define XENON_ATA_REG_DATA
#define XENON_CDROM_SECTOR_SIZE
#define XENON_ATA_REG_LBAHIGH
#define XENON_ATA_REG_SECTORS
#define XENON_ATA_REG_LBALOW
#define XENON_ATA_REG_LBAMID
#define XENON_ATA_REG2_CONTROL
#define XENON_ATA_REG_SECTNUM
#define XENON_DISK_SECTOR_SIZE
@ XENON_ATA_CMD_IDENTIFY_DEVICE
@ XENON_ATA_CMD_WRITE_SECTORS_EXT
@ XENON_ATA_CMD_READ_SECTORS_EXT
@ XENON_ATA_CMD_IDENTIFY_PACKET_DEVICE
@ XENON_ATA_CMD_READ_DMA_EXT
@ XENON_ATA_DMA_TABLE_OFS
#define XENON_ATA_REG_FEATURES
#define FEATURE_XENON_ATA
bool(* FN_MEDIUM_STARTUP)(void)
bool(* FN_MEDIUM_CLEARSTATUS)(void)
#define FEATURE_MEDIUM_CANREAD
s32(* FN_MEDIUM_DEVSECTORS)(void)
bool(* FN_MEDIUM_SHUTDOWN)(void)
#define DISKIO_ERROR_NO_MEDIA
#define FEATURE_XENON_ATAPI
bool(* FN_MEDIUM_READSECTORS)(sec_t sector, sec_t numSectors, void *buffer)
bool(* FN_MEDIUM_WRITESECTORS)(sec_t sector, sec_t numSectors, const void *buffer)
#define FEATURE_MEDIUM_CANWRITE
bool(* FN_MEDIUM_ISINSERTED)(void)
void memdcbf(void *addr, int len)
void memdcbst(void *addr, int len)
void memdcbt(void *addr, int len)
unsigned int __mf_uintptr_t __attribute__((__mode__(__pointer__)))
FN_MEDIUM_DEVSECTORS sectors
uint16_t sectors_per_track
struct xenon_ata_dma_prd * prds
int32_t s32
32bit signed integer