PS2SDK
PS2 Homebrew Libraries
hdproatad.c
1 /*
2  Copyright 2011, jimmikaelkael
3  Licenced under Academic Free License version 3.0
4 
5  ATA Driver for the HD Pro Kit, based on original & updated ATAD from ps2sdk:
6 
7  Copyright (c) 2003 Marcus R. Brown <mrbrown@0xd6.org>
8  Licenced under Academic Free License version 2.0
9  Review ps2sdk README & LICENSE files for further details.
10 
11  ATA device driver.
12 */
13 
14 #include <types.h>
15 #include <defs.h>
16 #include <irx.h>
17 #include <loadcore.h>
18 #include <intrman.h>
19 #include <thbase.h>
20 #include <thevent.h>
21 #include <stdio.h>
22 #include <sysclib.h>
23 #include <atad.h>
24 
25 #include <atahw.h>
26 
27 #define MODNAME "hdcombo_driver"
28 IRX_ID(MODNAME, 1, 1);
29 
30 #define M_PRINTF(format, args...) \
31  printf(MODNAME ": " format, ##args)
32 
33 #define BANNER "ATA device driver for HD Pro Kit %s\n"
34 #define VERSION "v1.0"
35 
36 #define ATA_XFER_MODE_PIO 0x08
37 
38 #define ATA_EV_TIMEOUT 1
39 #define ATA_EV_COMPLETE 2 // Unused as there is no completion interrupt
40 
41 // HD Pro Kit is mapping the 1st word in ROM0 seg as a main ATA controller,
42 // The pseudo ATA controller registers are accessed (input/ouput) by writing
43 // an id to the main ATA controller (id specific to HDpro, see registers id below).
44 #define HDPROreg_IO8 (*(vu8 *)0xBFC00000)
45 #define HDPROreg_IO32 (*(vu32 *)0xBFC00000)
46 
47 #define CDVDreg_STATUS (*(vu8 *)0xBF40200A)
48 
49 // Pseudo ATA controller registers id - Output
50 #define ATAreg_CONTROL_RD 0x68
51 #define ATAreg_SELECT_RD 0x70
52 #define ATAreg_STATUS_RD 0xf0
53 #define ATAreg_ERROR_RD 0x90
54 #define ATAreg_NSECTOR_RD 0x50
55 #define ATAreg_SECTOR_RD 0xd0
56 #define ATAreg_LCYL_RD 0x30
57 #define ATAreg_HCYL_RD 0xb0
58 #define ATAreg_DATA_RD 0x41
59 
60 // Pseudo ATA controller registers id - Input
61 #define ATAreg_CONTROL_WR 0x6a
62 #define ATAreg_SELECT_WR 0x72
63 #define ATAreg_COMMAND_WR 0xf2
64 #define ATAreg_FEATURE_WR 0x92
65 #define ATAreg_NSECTOR_WR 0x52
66 #define ATAreg_SECTOR_WR 0xd2
67 #define ATAreg_LCYL_WR 0x32
68 #define ATAreg_HCYL_WR 0xb2
69 #define ATAreg_DATA_WR 0x12
70 
71 static int ata_devinfo_init = 0;
72 static int ata_evflg = -1;
73 
74 /* Local device info kept for drives 0 and 1. */
75 static ata_devinfo_t atad_devinfo[2];
76 
77 /* Data returned from DEVICE IDENTIFY is kept here. Also, this is used by the
78  security commands to set and unlock the password. */
79 static u16 ata_param[256];
80 
81 /* ATA command info. */
82 typedef struct _ata_cmd_info
83 {
84  u8 command;
85  u8 type;
87 
88 // DMA commands have been removed, since there is no support for DMA.
89 static const ata_cmd_info_t ata_cmd_table[] = {
90  {ATA_C_NOP, 1},
91  {ATA_C_CFA_REQUEST_EXTENDED_ERROR_CODE, 1},
92  {ATA_C_DEVICE_RESET, 5},
93  {ATA_C_READ_SECTOR, 2},
94  {ATA_C_READ_SECTOR_EXT, 0x82},
95  {ATA_C_WRITE_SECTOR, 3},
96  {ATA_C_WRITE_LONG, 8},
97  {ATA_C_WRITE_SECTOR_EXT, 0x83},
98  {ATA_C_CFA_WRITE_SECTORS_WITHOUT_ERASE, 3},
99  {ATA_C_READ_VERIFY_SECTOR, 1},
100  {ATA_C_READ_VERIFY_SECTOR_EXT, 0x81},
101  {ATA_C_SEEK, 1},
102  {ATA_C_CFA_TRANSLATE_SECTOR, 2},
103  {ATA_C_SCE_SECURITY_CONTROL, 7},
104  {ATA_C_EXECUTE_DEVICE_DIAGNOSTIC, 6},
105  {ATA_C_INITIALIZE_DEVICE_PARAMETERS, 1},
106  {ATA_C_DOWNLOAD_MICROCODE, 3},
107  {ATA_C_IDENTIFY_PACKET_DEVICE, 2},
108  {ATA_C_SMART, 7},
109  {ATA_C_CFA_ERASE_SECTORS, 1},
110  {ATA_C_READ_MULTIPLE, 2},
111  {ATA_C_WRITE_MULTIPLE, 3},
112  {ATA_C_SET_MULTIPLE_MODE, 1},
113  {ATA_C_CFA_WRITE_MULTIPLE_WITHOUT_ERASE, 3},
114  {ATA_C_GET_MEDIA_STATUS, 1},
115  {ATA_C_MEDIA_LOCK, 1},
116  {ATA_C_MEDIA_UNLOCK, 1},
117  {ATA_C_STANDBY_IMMEDIATE, 1},
118  {ATA_C_IDLE_IMMEDIATE, 1},
119  {ATA_C_STANDBY, 1},
120  {ATA_C_IDLE, 1},
121  {ATA_C_READ_BUFFER, 2},
122  {ATA_C_CHECK_POWER_MODE, 1},
123  {ATA_C_SLEEP, 1},
124  {ATA_C_FLUSH_CACHE, 1},
125  {ATA_C_WRITE_BUFFER, 3},
126  {ATA_C_FLUSH_CACHE_EXT, 1},
127  {ATA_C_IDENTIFY_DEVICE, 2},
128  {ATA_C_MEDIA_EJECT, 1},
129  {ATA_C_SET_FEATURES, 1},
130  {ATA_C_SECURITY_SET_PASSWORD, 3},
131  {ATA_C_SECURITY_UNLOCK, 3},
132  {ATA_C_SECURITY_ERASE_PREPARE, 1},
133  {ATA_C_SECURITY_ERASE_UNIT, 3},
134  {ATA_C_SECURITY_FREEZE_LOCK, 1},
135  {ATA_C_SECURITY_DISABLE_PASSWORD, 3},
136  {ATA_C_READ_NATIVE_MAX_ADDRESS, 1},
137  {ATA_C_SET_MAX_ADDRESS, 1}};
138 #define ATA_CMD_TABLE_SIZE (sizeof ata_cmd_table / sizeof(ata_cmd_info_t))
139 
140 static const ata_cmd_info_t smart_cmd_table[] = {
141  {ATA_S_SMART_READ_DATA, 2},
142  {ATA_S_SMART_ENABLE_DISABLE_AUTOSAVE, 1},
143  {ATA_S_SMART_SAVE_ATTRIBUTE_VALUES, 1},
144  {ATA_S_SMART_EXECUTE_OFF_LINE, 1},
145  {ATA_S_SMART_READ_LOG, 2},
146  {ATA_S_SMART_WRITE_LOG, 3},
147  {ATA_S_SMART_ENABLE_OPERATIONS, 1},
148  {ATA_S_SMART_DISABLE_OPERATIONS, 1},
149  {ATA_S_SMART_RETURN_STATUS, 1}};
150 #define SMART_CMD_TABLE_SIZE (sizeof smart_cmd_table / sizeof(ata_cmd_info_t))
151 
152 /* This is the state info tracked between sceAtaExecCmd() and sceAtaWaitResult(). */
153 typedef struct _ata_cmd_state
154 {
155  s32 type; /* The ata_cmd_info_t type field. */
156  union
157  {
158  void *buf;
159  u8 *buf8;
160  u16 *buf16;
161  };
162  u32 blkcount; /* The number of 512-byte blocks (sectors) to transfer. */
164 
165 static ata_cmd_state_t atad_cmd_state;
166 
167 static int hdpro_io_active = 0;
168 static int intr_suspended = 0;
169 static int intr_state;
170 
171 static int hdpro_io_start(void);
172 static int hdpro_io_finish(void);
173 static void hdpro_io_write(u8 cmd, u16 val);
174 static int hdpro_io_read(u8 cmd);
175 static int ata_bus_reset(void);
176 static int ata_init_devices(ata_devinfo_t *devinfo);
177 static int gen_ata_wait_busy(int bits);
178 
179 extern struct irx_export_table _exp_atad;
180 
181 static unsigned int ata_alarm_cb(void *unused)
182 {
183  (void)unused;
184 
185  iSetEventFlag(ata_evflg, ATA_EV_TIMEOUT);
186  return 0;
187 }
188 
189 static void suspend_intr(void)
190 {
191  if (!intr_suspended) {
192  CpuSuspendIntr(&intr_state);
193 
194  intr_suspended = 1;
195  }
196 }
197 
198 static void resume_intr(void)
199 {
200  if (intr_suspended) {
201  CpuResumeIntr(intr_state);
202 
203  intr_suspended = 0;
204  }
205 }
206 
207 static int ata_create_event_flag(void)
208 {
210 
211  event.attr = EA_SINGLE; // In v1.04, EA_MULTI was specified.
212  event.bits = 0;
213  return CreateEventFlag(&event);
214 }
215 
216 int _start(int argc, char *argv[])
217 {
218  int res = MODULE_NO_RESIDENT_END;
219 
220  (void)argc;
221  (void)argv;
222 
223  printf(BANNER, VERSION);
224 
225  if (!hdpro_io_start()) {
226  M_PRINTF("Failed to detect HD Pro, exiting.\n");
227  goto out;
228  }
229 
230  hdpro_io_finish();
231 
232  if ((ata_evflg = ata_create_event_flag()) < 0) {
233  M_PRINTF("Couldn't create event flag, exiting.\n");
234  goto out;
235  }
236 
237  if (RegisterLibraryEntries(&_exp_atad) != 0) {
238  M_PRINTF("Library is already registered, exiting.\n");
239  goto out;
240  }
241 
242  res = MODULE_RESIDENT_END;
243  M_PRINTF("Driver loaded.\n");
244 
245 out:
246  return res;
247 }
248 
249 int shutdown(void)
250 {
251  return 0;
252 }
253 
254 /* Export 8 */
255 int sceAtaGetError(void)
256 {
257  return hdpro_io_read(ATAreg_ERROR_RD) & 0xff;
258 }
259 
260 #define ATA_WAIT_BUSY 0x80
261 #define ATA_WAIT_BUSBUSY 0x88
262 
263 #define ata_wait_busy() gen_ata_wait_busy(ATA_WAIT_BUSY)
264 #define ata_wait_bus_busy() gen_ata_wait_busy(ATA_WAIT_BUSBUSY)
265 
266 /* 0x80 for busy, 0x88 for bus busy.
267  In the original ATAD, the busy and bus-busy functions were separate, but similar. */
268 static int gen_ata_wait_busy(int bits)
269 {
270  int i, didx, delay;
271  int res = 0;
272 
273  for (i = 0; i < 80; i++) {
274 
275  hdpro_io_start();
276 
277  u16 r_control = hdpro_io_read(ATAreg_CONTROL_RD);
278 
279  hdpro_io_finish();
280 
281  if (r_control == 0xffff) // Differs from the normal ATAD here.
282  return ATA_RES_ERR_TIMEOUT;
283 
284  if (!(r_control & bits))
285  goto out;
286 
287  didx = i / 10;
288  switch (didx) {
289  case 0:
290  continue;
291  case 1:
292  delay = 100;
293  break;
294  case 2:
295  delay = 1000;
296  break;
297  case 3:
298  delay = 10000;
299  break;
300  case 4:
301  delay = 100000;
302  break;
303  default:
304  delay = 1000000;
305  }
306 
307  DelayThread(delay);
308  }
309 
310  res = ATA_RES_ERR_TIMEOUT;
311  M_PRINTF("Timeout while waiting on busy (0x%02x).\n", bits);
312 
313 out:
314  hdpro_io_start();
315 
316  return res;
317 }
318 
319 // Must be called before any I/O is done with HDPro
320 static int hdpro_io_start(void)
321 {
322  if (hdpro_io_active)
323  return 0;
324 
325  hdpro_io_active = 0;
326 
327  suspend_intr();
328 
329  // HD Pro IO start commands sequence
330  HDPROreg_IO8 = 0x72;
331  CDVDreg_STATUS = 0;
332  HDPROreg_IO8 = 0x34;
333  CDVDreg_STATUS = 0;
334  HDPROreg_IO8 = 0x61;
335  CDVDreg_STATUS = 0;
336  unsigned int res = HDPROreg_IO8;
337  CDVDreg_STATUS = 0;
338 
339  resume_intr();
340 
341  // check result
342  if ((res & 0xff) == 0xe7)
343  hdpro_io_active = 1;
344 
345  return hdpro_io_active;
346 }
347 
348 // Must be called after I/O is done with HDPro
349 static int hdpro_io_finish(void)
350 {
351  if (!hdpro_io_active)
352  return 0;
353 
354  suspend_intr();
355 
356  // HD Pro IO finish commands sequence
357  HDPROreg_IO8 = 0xf3;
358  CDVDreg_STATUS = 0;
359 
360  resume_intr();
361 
362  DelayThread(200);
363 
364  if (HDPROreg_IO32 == 0x401a7800) // check the 1st in ROM0 seg get
365  hdpro_io_active = 0; // back to it's original state
366 
367  return hdpro_io_active ^ 1;
368 }
369 
370 static void hdpro_io_write(u8 cmd, u16 val)
371 {
372  suspend_intr();
373 
374  // IO write to HD Pro
375  HDPROreg_IO8 = cmd;
376  CDVDreg_STATUS = 0;
377  HDPROreg_IO8 = val;
378  CDVDreg_STATUS = 0;
379  HDPROreg_IO8 = (val & 0xffff) >> 8;
380  CDVDreg_STATUS = 0;
381 
382  resume_intr();
383 }
384 
385 static int hdpro_io_read(u8 cmd)
386 {
387  suspend_intr();
388 
389  // IO read from HD Pro
390  HDPROreg_IO8 = cmd;
391  CDVDreg_STATUS = 0;
392  unsigned int res0 = HDPROreg_IO8;
393  CDVDreg_STATUS = 0;
394  unsigned int res1 = HDPROreg_IO8;
395  CDVDreg_STATUS = 0;
396  res0 = (res0 & 0xff) | (res1 << 8);
397 
398  resume_intr();
399 
400  return res0 & 0xffff;
401 }
402 
403 /* Reset the ATA controller/bus. */
404 static int ata_bus_reset(void)
405 {
406  suspend_intr();
407 
408  // HD Pro IO initialization commands sequence
409  HDPROreg_IO8 = 0x13;
410  CDVDreg_STATUS = 0;
411  HDPROreg_IO8 = 0x00;
412  CDVDreg_STATUS = 0;
413 
414  resume_intr();
415 
416  DelayThread(100);
417 
418  suspend_intr();
419 
420  HDPROreg_IO8 = 0x13;
421  CDVDreg_STATUS = 0;
422  HDPROreg_IO8 = 0x01;
423  CDVDreg_STATUS = 0;
424 
425  resume_intr();
426 
427  DelayThread(3000);
428 
429  return ata_wait_busy();
430 }
431 
432 static int ata_device_select(int device)
433 {
434  int res;
435 
436  if ((res = ata_wait_bus_busy()) < 0)
437  return res;
438 
439  /* If the device was already selected, nothing to do. */
440  if (((hdpro_io_read(ATAreg_SELECT_RD) >> 4) & 1) == device)
441  return 0;
442 
443  /* Select the device. */
444  hdpro_io_write(ATAreg_SELECT_WR, (device & 1) << 4);
445  (void)(hdpro_io_read(ATAreg_CONTROL_RD));
446 
447  return ata_wait_bus_busy();
448 }
449 
450 /* Export 6 */
451 int sceAtaExecCmd(void *buf, u32 blkcount, u16 feature, u16 nsector, u16 sector, u16 lcyl, u16 hcyl, u16 select, u16 command)
452 {
453  iop_sys_clock_t cmd_timeout;
454  const ata_cmd_info_t *cmd_table;
455  int i, res, type, cmd_table_size;
456  int using_timeout, device = (select >> 4) & 1;
457  u8 searchcmd;
458 
459  ClearEventFlag(ata_evflg, 0);
460 
461  if (!atad_devinfo[device].exists)
462  return ATA_RES_ERR_NODEV;
463 
464  if ((res = ata_device_select(device)) != 0)
465  return res;
466 
467  /* For the SMART commands, we need to search on the subcommand
468  specified in the feature register. */
469  if (command == ATA_C_SMART) {
470  cmd_table = smart_cmd_table;
471  cmd_table_size = SMART_CMD_TABLE_SIZE;
472  searchcmd = feature;
473  } else {
474  cmd_table = ata_cmd_table;
475  cmd_table_size = ATA_CMD_TABLE_SIZE;
476  searchcmd = command & 0xff;
477  }
478 
479  type = 0;
480  for (i = 0; i < cmd_table_size; i++) {
481  if (searchcmd == cmd_table[i].command) {
482  type = cmd_table[i].type;
483  break;
484  }
485  }
486 
487  if (!(atad_cmd_state.type = type & 0x7F))
488  return ATA_RES_ERR_CMD;
489 
490  atad_cmd_state.buf = buf;
491  atad_cmd_state.blkcount = blkcount;
492 
493  /* Check that the device is ready if this the appropiate command. */
494  if (!(hdpro_io_read(ATAreg_CONTROL_RD) & 0x40)) {
495  switch (command) {
496  case ATA_C_DEVICE_RESET:
497  case ATA_C_EXECUTE_DEVICE_DIAGNOSTIC:
498  case ATA_C_INITIALIZE_DEVICE_PARAMETERS:
499  case ATA_C_PACKET:
500  case ATA_C_IDENTIFY_PACKET_DEVICE:
501  break;
502  default:
503  M_PRINTF("Error: Device %d is not ready.\n", device);
504  return ATA_RES_ERR_NOTREADY;
505  }
506  }
507 
508  /* Does this command need a timeout? */
509  using_timeout = 0;
510  switch (type & 0x7F) {
511  case 1:
512  case 6:
513  using_timeout = 1;
514  break;
515  // Support for DMA commands (type = 4) is removed because HDPro cannot support DMA. The original HDPro driver still had code for it though.
516  }
517 
518  if (using_timeout) {
519  cmd_timeout.lo = 0x41eb0000;
520  cmd_timeout.hi = 0;
521 
522  if ((res = SetAlarm(&cmd_timeout, &ata_alarm_cb, NULL)) < 0)
523  return res;
524  }
525 
526  /* Enable the command completion interrupt. */
527  suspend_intr();
528  HDPROreg_IO8 = 0x21;
529  CDVDreg_STATUS = 0;
530  (void)(HDPROreg_IO8);
531  CDVDreg_STATUS = 0;
532  resume_intr();
533 
534  /* Finally! We send off the ATA command with arguments. */
535  hdpro_io_write(ATAreg_CONTROL_WR, (using_timeout == 0) << 1);
536 
537  if (type & 0x80) { // For the sake of achieving improved performance, write the registers twice only if required!
538  /* 48-bit LBA requires writing to the address registers twice,
539  24 bits of the LBA address is written each time.
540  Writing to registers twice does not affect 28-bit LBA since
541  only the latest data stored in address registers is used. */
542  hdpro_io_write(ATAreg_FEATURE_WR, (feature & 0xffff) >> 8);
543  hdpro_io_write(ATAreg_NSECTOR_WR, (nsector & 0xffff) >> 8);
544  hdpro_io_write(ATAreg_SECTOR_WR, (sector & 0xffff) >> 8);
545  hdpro_io_write(ATAreg_LCYL_WR, (lcyl & 0xffff) >> 8);
546  hdpro_io_write(ATAreg_HCYL_WR, (hcyl & 0xffff) >> 8);
547  }
548 
549  hdpro_io_write(ATAreg_FEATURE_WR, feature & 0xff);
550  hdpro_io_write(ATAreg_NSECTOR_WR, nsector & 0xff);
551  hdpro_io_write(ATAreg_SECTOR_WR, sector & 0xff);
552  hdpro_io_write(ATAreg_LCYL_WR, lcyl & 0xff);
553  hdpro_io_write(ATAreg_HCYL_WR, hcyl & 0xff);
554 
555  hdpro_io_write(ATAreg_SELECT_WR, (select | ATA_SEL_LBA) & 0xff); // In v1.04, LBA was enabled in the sceAtaDmaTransfer function.
556  hdpro_io_write(ATAreg_COMMAND_WR, command & 0xff);
557 
558  return 0;
559 }
560 
561 /* Do a PIO transfer, to or from the device. */
562 static int ata_pio_transfer(ata_cmd_state_t *cmd_state)
563 {
564  u16 *buf16;
565  int i, type;
566  int res = 0, chk = 0;
567  u16 status = hdpro_io_read(ATAreg_STATUS_RD);
568 
569  if (status & ATA_STAT_ERR) {
570  M_PRINTF("Error: Command error: status 0x%02x, error 0x%02x.\n", status, sceAtaGetError());
571  return ATA_RES_ERR_IO;
572  }
573 
574  /* DRQ must be set (data request). */
575  if (!(status & ATA_STAT_DRQ))
576  return ATA_RES_ERR_NODATA;
577 
578  type = cmd_state->type;
579 
580  if (type == 3 || type == 8) {
581  /* PIO data out */
582  buf16 = cmd_state->buf16;
583 
584  HDPROreg_IO8 = 0x43;
585  CDVDreg_STATUS = 0;
586 
587  for (i = 0; i < 256; i++) {
588  u16 r_data = *buf16;
589  hdpro_io_write(ATAreg_DATA_WR, r_data);
590  chk ^= r_data + i;
591  cmd_state->buf = ++buf16;
592  }
593 
594  u16 out = hdpro_io_read(ATAreg_DATA_RD) & 0xffff;
595  if (out != (chk & 0xffff))
596  return ATA_RES_ERR_IO;
597 
598  if (cmd_state->type == 8) {
599  u8 *buf8;
600 
601  buf8 = cmd_state->buf8;
602  for (i = 0; i < 4; i++) {
603  hdpro_io_write(ATAreg_DATA_WR, *buf8);
604  cmd_state->buf = ++buf8;
605  }
606  }
607 
608  } else if (type == 2) {
609  /* PIO data in */
610  buf16 = cmd_state->buf16;
611 
612  suspend_intr();
613 
614  HDPROreg_IO8 = 0x53;
615  CDVDreg_STATUS = 0;
616  CDVDreg_STATUS = 0;
617 
618  for (i = 0; i < 256; i++) {
619 
620  unsigned int res0 = HDPROreg_IO8;
621  CDVDreg_STATUS = 0;
622  unsigned int res1 = HDPROreg_IO8;
623  CDVDreg_STATUS = 0;
624 
625  res0 = (res0 & 0xff) | (res1 << 8);
626  chk ^= res0 + i;
627 
628  *buf16 = res0 & 0xffff;
629  cmd_state->buf16 = ++buf16;
630  }
631 
632  HDPROreg_IO8 = 0x51;
633  CDVDreg_STATUS = 0;
634  CDVDreg_STATUS = 0;
635 
636  resume_intr();
637 
638  u16 r_data = hdpro_io_read(ATAreg_DATA_RD) & 0xffff;
639  if (r_data != (chk & 0xffff))
640  return ATA_RES_ERR_IO;
641  }
642 
643  return res;
644 }
645 
646 /* Export 5 */
647 int sceAtaSoftReset(void)
648 {
649  if (hdpro_io_read(ATAreg_CONTROL_RD) & 0x80)
650  return ATA_RES_ERR_NOTREADY;
651 
652  /* Disables device interrupt assertion and asserts SRST. */
653  hdpro_io_write(ATAreg_CONTROL_WR, 6);
654  DelayThread(100);
655 
656  /* Disable ATA interrupts. */
657  hdpro_io_write(ATAreg_CONTROL_WR, 2);
658  DelayThread(3000);
659 
660  return ata_wait_busy();
661 }
662 
663 /* Export 11 */
664 int sceAtaSecurityUnLock(int device, void *password)
665 { // Device can always be unlocked.
666  (void)device;
667  (void)password;
668  return 0;
669 }
670 
671 static void ata_device_probe(ata_devinfo_t *devinfo)
672 {
673  u16 nsector, lcyl, hcyl, sector;
674 
675  devinfo->exists = 0;
676  devinfo->has_packet = 2;
677 
678  if (hdpro_io_read(ATAreg_CONTROL_RD) & 0x88)
679  return;
680 
681  nsector = hdpro_io_read(ATAreg_NSECTOR_RD) & 0xff;
682  sector = hdpro_io_read(ATAreg_SECTOR_RD) & 0xff;
683  lcyl = hdpro_io_read(ATAreg_LCYL_RD) & 0xff;
684  hcyl = hdpro_io_read(ATAreg_HCYL_RD) & 0xff;
685  (void)(hdpro_io_read(ATAreg_SELECT_RD) & 0xff);
686 
687  /* The original HDPro driver did not check sector.
688  However, by the ATA-4 specification (9.1), sector should be 1.
689  So it should be perfectly fine to check. */
690  if ((nsector != 1) || (sector != 1))
691  return;
692  devinfo->exists = 1;
693 
694  if ((lcyl == 0x00) && (hcyl == 0x00))
695  devinfo->has_packet = 0;
696  else if ((lcyl == 0x14) && (hcyl == 0xeb))
697  devinfo->has_packet = 1;
698 
699  /* Seems to be for ensuring that there is a device connected.
700  Not sure why this has to be done, but is present in v2.4. */
701  hdpro_io_write(ATAreg_LCYL_WR, 0x55);
702  hdpro_io_write(ATAreg_HCYL_WR, 0xaa);
703  lcyl = hdpro_io_read(ATAreg_LCYL_RD) & 0xff;
704  hcyl = hdpro_io_read(ATAreg_HCYL_RD) & 0xff;
705 
706  if ((lcyl != 0x55) || (hcyl != 0xaa))
707  devinfo->exists = 0;
708 }
709 
710 /* Export 17 */
711 int sceAtaFlushCache(int device)
712 {
713  int res;
714 
715  if (!hdpro_io_start())
716  return -1;
717 
718  if (!(res = sceAtaExecCmd(NULL, 1, 0, 0, 0, 0, 0, (device << 4) & 0xffff, atad_devinfo[device].lba48 ? ATA_C_FLUSH_CACHE_EXT : ATA_C_FLUSH_CACHE)))
719  res = sceAtaWaitResult();
720 
721  if (!hdpro_io_finish())
722  return -2;
723 
724  return res;
725 }
726 
727 /* Export 13 */
728 int ata_device_idle(int device, int period)
729 {
730  int res;
731 
732  res = sceAtaExecCmd(NULL, 1, 0, period & 0xff, 0, 0, 0, (device << 4) & 0xffff, ATA_C_IDLE);
733  if (res)
734  return res;
735 
736  return sceAtaWaitResult();
737 }
738 
739 /* Set features - set transfer mode. */
740 static int ata_device_set_transfer_mode(int device, int type, int mode)
741 {
742  int res;
743 
744  res = sceAtaExecCmd(NULL, 1, 3, (type | mode) & 0xff, 0, 0, 0, (device << 4) & 0xffff, ATA_C_SET_FEATURES);
745  if (res)
746  return res;
747 
748  res = sceAtaWaitResult();
749  if (res)
750  return res;
751 
752  return 0;
753 }
754 
755 static int ata_device_identify(int device, void *info)
756 {
757  int res;
758 
759  res = sceAtaExecCmd(info, 1, 0, 0, 0, 0, 0, (device << 4) & 0xffff, ATA_C_IDENTIFY_DEVICE);
760  if (res)
761  return res;
762 
763  return sceAtaWaitResult();
764 }
765 
766 static int ata_device_smart_enable(int device)
767 {
768  int res;
769 
770  if (!(res = sceAtaExecCmd(NULL, 1, ATA_S_SMART_ENABLE_OPERATIONS, 0, 0, 0x4f, 0xc2, (device << 4) & 0xffff, ATA_C_SMART)))
771  res = sceAtaWaitResult();
772 
773  return res;
774 }
775 
776 static int ata_init_devices(ata_devinfo_t *devinfo)
777 {
778  int i, res;
779 
780  if ((res = sceAtaSoftReset()) != 0)
781  return res;
782 
783  ata_device_probe(&devinfo[0]);
784  if (!devinfo[0].exists) {
785  M_PRINTF("Error: Unable to detect HDD 0.\n");
786  devinfo[1].exists = 0;
787  return ATA_RES_ERR_NODEV; // Returns 0 in v1.04.
788  }
789 
790  /* If there is a device 1, grab it's info too. */
791  if ((res = ata_device_select(1)) != 0)
792  return res;
793  if (hdpro_io_read(ATAreg_CONTROL_RD) & 0xff)
794  ata_device_probe(&devinfo[1]);
795  else
796  devinfo[1].exists = 0;
797 
798  for (i = 0; i < 2; i++) {
799  if (!devinfo[i].exists)
800  continue;
801 
802  /* Send the IDENTIFY DEVICE command. if it doesn't succeed
803  devinfo is disabled. */
804  if (!devinfo[i].has_packet) {
805  res = ata_device_identify(i, ata_param);
806  devinfo[i].exists = (res == 0);
807  } else if (devinfo[i].has_packet == 1) {
808  /* If it's a packet device, send the IDENTIFY PACKET
809  DEVICE command. */
810  /* Packet devices are not supported:
811 
812  The original HDPro driver issues the IDENTIFY PACKET DEVICE command,
813  but does not export sceAtaExecCmd and sceAtaWaitResult.
814  This makes packet device support impossible. */
815  res = -1;
816  devinfo[i].exists = (res == 0);
817  }
818  /* Otherwise, do nothing if has_packet = 2. */
819 
820  /* This next section is HDD-specific: if no device or it's a
821  packet (ATAPI) device, we're done. */
822  if (!devinfo[i].exists || devinfo[i].has_packet)
823  continue;
824 
825  /* This section is to detect whether the HDD supports 48-bit LBA
826  (IDENITFY DEVICE bit 10 word 83) and get the total sectors from
827  either words(61:60) for 28-bit or words(103:100) for 48-bit. */
828  if (ata_param[ATA_ID_COMMAND_SETS_SUPPORTED] & 0x0400) {
829  atad_devinfo[i].lba48 = 1;
830  /* I don't think anyone would use a >2TB HDD but just in case. */
831  if (ata_param[ATA_ID_48BIT_SECTOTAL_HI]) {
832  devinfo[i].total_sectors = 0xffffffff;
833  } else {
834  devinfo[i].total_sectors =
835  (ata_param[ATA_ID_48BIT_SECTOTAL_MI] << 16) |
836  ata_param[ATA_ID_48BIT_SECTOTAL_LO];
837  }
838  } else {
839  atad_devinfo[i].lba48 = 0;
840  devinfo[i].total_sectors = (ata_param[ATA_ID_SECTOTAL_HI] << 16) |
841  ata_param[ATA_ID_SECTOTAL_LO];
842  }
843  devinfo[i].security_status = ata_param[ATA_ID_SECURITY_STATUS];
844 
845  /* PIO mode 0 (flow control). */
846  ata_device_set_transfer_mode(i, ATA_XFER_MODE_PIO, 0);
847  ata_device_smart_enable(i);
848  /* Disable idle timeout. */
849  ata_device_idle(i, 0);
850  }
851  return 0;
852 }
853 
854 /* Export 7 */
855 int sceAtaWaitResult(void)
856 {
857  ata_cmd_state_t *cmd_state = &atad_cmd_state;
858  u32 bits;
859  int res = 0, type = cmd_state->type;
860  u16 stat;
861 
862  if (type == 1 || type == 6) { /* Non-data commands. */
863 
864  // Unlike ATAD, poll until the device either completes its command or times out. There is no completion interrupt.
865  while (1) {
866  suspend_intr();
867 
868  HDPROreg_IO8 = 0x21;
869  CDVDreg_STATUS = 0;
870  unsigned int ret = HDPROreg_IO8;
871  CDVDreg_STATUS = 0;
872 
873  resume_intr();
874 
875  if (((ret & 0xff) & 1) != 0) {
876  // Command completed.
877  break;
878  }
879 
880  /* The original did not check on the return value of PollEventFlag,
881  but PollEventFlag does not seem to return the event flag's bits if the wait condition is not satisfied. */
882  if (PollEventFlag(ata_evflg, ATA_EV_TIMEOUT | ATA_EV_COMPLETE, WEF_CLEAR | WEF_OR, &bits) == 0) {
883  if (bits & ATA_EV_TIMEOUT) { /* Timeout. */
884  M_PRINTF("Error: ATA timeout on a non-data command.\n");
885  return ATA_RES_ERR_TIMEOUT;
886  }
887  }
888 
889  DelayThread(500);
890  }
891 
892  /* Support for DMA commands (type = 4) is removed because HDPro cannot support DMA.
893  The original would return ATA_RES_ERR_TIMEOUT for type = 4. */
894  } else { /* PIO transfers. */
895  stat = hdpro_io_read(ATAreg_CONTROL_RD);
896  if ((res = ata_wait_busy()) < 0)
897  goto finish;
898 
899  /* Transfer each PIO data block. */
900  while ((int)(--cmd_state->blkcount) != -1) {
901  if ((res = ata_pio_transfer(cmd_state)) < 0)
902  goto finish;
903  if ((res = ata_wait_busy()) < 0)
904  goto finish;
905  }
906  }
907 
908  if (res)
909  goto finish;
910 
911  /* Wait until the device isn't busy. */
912  if (hdpro_io_read(ATAreg_STATUS_RD) & ATA_STAT_BUSY)
913  res = ata_wait_busy();
914  if ((stat = hdpro_io_read(ATAreg_STATUS_RD)) & ATA_STAT_ERR) {
915  M_PRINTF("Error: Command error: status 0x%02x, error 0x%02x.\n", stat, sceAtaGetError());
916  res = ATA_RES_ERR_IO;
917  }
918 
919 finish:
920  /* The command has completed (with an error or not), so clean things up. */
921  CancelAlarm(&ata_alarm_cb, NULL);
922 
923  return res;
924 }
925 
926 /* Export 9 */
927 int sceAtaDmaTransfer(int device, void *buf, u32 lba, u32 nsectors, int dir)
928 {
929  int res = 0;
930  u16 sector, lcyl, hcyl, select, command, len;
931 
932  if (!hdpro_io_start())
933  return -1;
934 
935  while (nsectors) {
936  len = (nsectors > 256) ? 256 : nsectors;
937 
938  /* Variable lba is only 32 bits so no change for lcyl and hcyl. */
939  lcyl = (lba >> 8) & 0xff;
940  hcyl = (lba >> 16) & 0xff;
941 
942  if (atad_devinfo[device].lba48) {
943  /* Setup for 48-bit LBA. */
944  /* Combine bits 24-31 and bits 0-7 of lba into sector. */
945  sector = ((lba >> 16) & 0xff00) | (lba & 0xff);
946  /* In v1.04, LBA was enabled here. */
947  select = (device << 4) & 0xffff;
948  command = (dir == 1) ? ATA_C_WRITE_SECTOR_EXT : ATA_C_READ_SECTOR_EXT;
949  } else {
950  /* Setup for 28-bit LBA. */
951  sector = lba & 0xff;
952  /* In v1.04, LBA was enabled here. */
953  select = ((device << 4) | ((lba >> 24) & 0xf)) & 0xffff;
954  command = (dir == 1) ? ATA_C_WRITE_SECTOR : ATA_C_READ_SECTOR;
955  }
956 
957  // Unlike ATAD, retry indefinitely until the I/O operation succeeds.
958  if ((res = sceAtaExecCmd(buf, len, 0, len, sector, lcyl,
959  hcyl, select, command)) != 0)
960  continue;
961  if ((res = sceAtaWaitResult()) != 0)
962  continue;
963 
964  buf = (void *)((u8 *)buf + len * 512);
965  lba += len;
966  nsectors -= len;
967  }
968 
969  if (!hdpro_io_finish())
970  return -2;
971 
972  return res;
973 }
974 
975 /* Export 4 */
976 ata_devinfo_t *sceAtaInit(int device)
977 {
978  if (!ata_devinfo_init) {
979  ata_devinfo_init = 1;
980 
981  if (!hdpro_io_start())
982  return NULL;
983 
984  HDPROreg_IO8 = 0xe3;
985  CDVDreg_STATUS = 0;
986 
987  if ((ata_bus_reset() != 0) || (ata_init_devices(atad_devinfo) != 0) || (!hdpro_io_finish()))
988  return NULL;
989  }
990 
991  return &atad_devinfo[device];
992 }
thbase.h
_ata_devinfo::has_packet
s32 has_packet
Definition: xatapi.c:42
_ata_devinfo
Definition: xatapi.c:39
sysclib.h
s_info
Definition: xprintf.c:78
atad.h
_ata_cmd_state
Definition: xatapi.c:21
CpuSuspendIntr
int CpuSuspendIntr(int *state)
Definition: intrman.c:195
event
Definition: thcommon.h:71
loadcore.h
_ata_devinfo::security_status
u32 security_status
Definition: xatapi.c:44
_ata_devinfo::exists
s32 exists
Definition: xatapi.c:41
_ata_cmd_info
Definition: ps2atad.c:87
irx.h
irx_export_table
Definition: irx.h:90
stdio.h
CpuResumeIntr
int CpuResumeIntr(int state)
Definition: intrman.c:217
_ata_devinfo::total_sectors
u32 total_sectors
Definition: xatapi.c:43
atahw.h
defs.h
_ata_devinfo::lba48
u32 lba48
Definition: xatapi.c:45
intrman.h
iop_event_t
Definition: thevent.h:37
EA_SINGLE
#define EA_SINGLE
Definition: thevent.h:33
thevent.h
_iop_sys_clock
Definition: thbase.h:87