4 * Open Hack'Ware BIOS bloc devices management
6 * Copyright (c) 2004-2005 Jocelyn Mayer
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License V2
10 * as published by the Free Software Foundation
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #define DPRINTF(fmt, args...) do { } while (0)
29 struct bloc_device_t
{
44 int (*init
)(bloc_device_t
*bd
, int device
);
45 int (*read_sector
)(bloc_device_t
*bd
, void *buffer
, int secnum
);
46 int (*ioctl
)(bloc_device_t
*bd
, int func
, void *args
);
52 #ifdef USE_OPENFIRMWARE
56 part_t
*parts
, *bparts
;
63 static bloc_device_t
*bd_list
;
65 static int fdc_initialize (bloc_device_t
*bd
, int device
);
66 static int fdc_read_sector (bloc_device_t
*bd
, void *buffer
, int secnum
);
68 static int ide_initialize (bloc_device_t
*bd
, int device
);
69 static int ide_read_sector (bloc_device_t
*bd
, void *buffer
, int secnum
);
70 static int ide_reset (bloc_device_t
*bd
);
72 static int mem_initialize (bloc_device_t
*bd
, int device
);
73 static int mem_read_sector (bloc_device_t
*bd
, void *buffer
, int secnum
);
74 static int mem_ioctl (bloc_device_t
*bd
, int func
, void *args
);
76 bloc_device_t
*bd_open (int device
)
84 bd
= malloc(sizeof(bloc_device_t
));
91 bd
->init
= &fdc_initialize
;
92 bd
->read_sector
= &fdc_read_sector
;
96 bd
->init
= &fdc_initialize
;
97 bd
->read_sector
= &fdc_read_sector
;
101 bd
->init
= &ide_initialize
;
102 bd
->read_sector
= &ide_read_sector
;
106 bd
->init
= &ide_initialize
;
107 bd
->read_sector
= &ide_read_sector
;
111 bd
->init
= &ide_initialize
;
112 bd
->read_sector
= &ide_read_sector
;
116 bd
->init
= &ide_initialize
;
117 bd
->read_sector
= &ide_read_sector
;
121 bd
->init
= &mem_initialize
;
122 bd
->read_sector
= &mem_read_sector
;
123 bd
->ioctl
= &mem_ioctl
;
129 if ((*bd
->init
)(bd
, num
) < 0) {
133 bd
->buffer
= malloc(bd
->seclen
);
134 if (bd
->buffer
== NULL
) {
143 int bd_seek (bloc_device_t
*bd
, uint32_t bloc
, uint32_t pos
)
147 maxbloc
= bd_maxbloc(bd
);
148 if (bloc
> maxbloc
) {
149 DPRINTF("%p bloc: %d maxbloc: %d C: %d H: %d S: %d\n",
150 bd
, bloc
, maxbloc
, bd
->trks
, bd
->heads
, bd
->sects
);
155 DPRINTF("%s: %p %08x %08x %08x %08x %08x\n", __func__
, bd
, bloc
, pos
,
156 bd
->bloc
, bd
->vbloc
, bd
->vpos
);
161 int bd_read (bloc_device_t
*bd
, void *buffer
, int len
)
165 for (total
= 0; len
> 0; total
+= clen
) {
166 if (bd
->vbloc
!= bd
->bloc
) {
167 /* Do physical seek */
169 DPRINTF("Read sector %d\n", bd
->vbloc
);
171 if ((*bd
->read_sector
)(bd
, bd
->buffer
, bd
->vbloc
) < 0) {
172 printf("Error reading bloc %d\n", bd
->vbloc
);
175 bd
->bloc
= bd
->vbloc
;
177 clen
= bd
->seclen
- bd
->vpos
;
180 memcpy(buffer
, bd
->buffer
+ bd
->vpos
, clen
);
182 DPRINTF("%s: %p copy %d bytes (%08x %08x %08x) %08x %08x %08x %08x\n",
183 __func__
, bd
, clen
, bd
->bloc
, bd
->vbloc
, bd
->vpos
,
184 ((uint32_t *)buffer
)[0], ((uint32_t *)buffer
)[1],
185 ((uint32_t *)buffer
)[2], ((uint32_t *)buffer
)[3]);
188 if (bd
->vpos
== bd
->seclen
) {
199 int bd_write (unused bloc_device_t
*bd
,
200 unused
const void *buffer
, unused
int len
)
205 int bd_ioctl (bloc_device_t
*bd
, int func
, void *args
)
207 if (bd
->ioctl
== NULL
)
210 return (*bd
->ioctl
)(bd
, func
, args
);
213 void bd_close (unused bloc_device_t
*bd
)
217 void bd_reset_all(void)
220 for (bd
= bd_list
; bd
!= NULL
; bd
= bd
->next
) {
221 if (bd
->init
== &ide_initialize
) {
222 /* reset IDE drive because Darwin wants all IDE devices to be reset */
228 uint32_t bd_seclen (bloc_device_t
*bd
)
233 uint32_t bd_maxbloc (bloc_device_t
*bd
)
235 return bd_CHS2sect(bd
, bd
->trks
, 0, 1);
238 /* XXX: to be suppressed */
239 void bd_set_boot_part (bloc_device_t
*bd
, part_t
*partition
, int partnum
)
241 dprintf("%s: part %p (%p) %d\n", __func__
, partition
, bd
->boot_part
, partnum
);
242 if (bd
->boot_part
== NULL
) {
243 bd
->boot_part
= partition
;
244 bd
->bpartnum
= partnum
;
248 part_t
**_bd_parts (bloc_device_t
*bd
)
253 part_t
**_bd_bparts (bloc_device_t
*bd
)
258 void bd_set_boot_device (bloc_device_t
*bd
)
260 #if defined (USE_OPENFIRMWARE)
261 OF_blockdev_set_boot_device(bd
->OF_private
, bd
->bpartnum
, "\\\\ofwboot");
265 part_t
*bd_probe (int boot_device
)
267 char devices
[] = { /*'a', 'b',*/ 'c', 'd', 'e', 'f', 'm', '\0', };
268 bloc_device_t
*bd
, **cur
;
269 part_t
*boot_part
, *tmp
;
273 /* Probe bloc devices */
274 for (i
= 0; devices
[i
] != '\0'; i
++) {
275 if (devices
[i
] == 'm' && boot_device
!= 'm')
277 bd
= bd_open(devices
[i
]);
279 DPRINTF("New bloc device %c: %p\n", devices
[i
], bd
);
280 for (cur
= &bd_list
; *cur
!= NULL
; cur
= &(*cur
)->next
)
284 DPRINTF("No bloc device %c\n", devices
[i
]);
287 /* Probe partitions for each bloc device found */
288 for (bd
= bd_list
; bd
!= NULL
; bd
= bd
->next
) {
289 dprintf("Probe partitions for device %c\n", bd
->device
);
290 if (bd
->device
== 'm')
294 tmp
= part_probe(bd
, force_raw
);
295 if (boot_device
== bd
->device
) {
297 bd_set_boot_device(bd
);
304 bloc_device_t
*bd_get (int device
)
308 for (cur
= bd_list
; cur
!= NULL
; cur
= cur
->next
) {
309 if (cur
->device
== device
) {
310 DPRINTF("%s: found device %c: %p\n", __func__
, device
, cur
);
318 void bd_put (unused bloc_device_t
*bd
)
322 void bd_sect2CHS (bloc_device_t
*bd
, uint32_t secnum
,
323 int *cyl
, int *head
, int *sect
)
327 tmp
= secnum
/ bd
->sects
;
328 *sect
= secnum
- (tmp
* bd
->sects
) + 1;
329 *cyl
= tmp
/ bd
->heads
;
330 *head
= tmp
- (*cyl
* bd
->heads
);
333 uint32_t bd_CHS2sect (bloc_device_t
*bd
,
334 int cyl
, int head
, int sect
)
336 return (((cyl
* bd
->heads
) + head
) * bd
->sects
) + sect
- 1;
340 #define FDC_OUT_BASE (0x03F0)
341 #define FDC_DOR_PORT (FDC_OUT_BASE + 0x0002)
342 #define FDC_TAPE_PORT (FDC_OUT_BASE + 0x0003)
343 #define FDC_MAIN_STATUS (FDC_OUT_BASE + 0x0004)
344 #define FDC_WRITE_PORT (FDC_OUT_BASE + 0x0005)
345 #define FDC_READ_PORT (FDC_OUT_BASE + 0x0005)
347 static int fdc_read_data (uint8_t *addr
, int len
)
352 for (i
= 0; i
< len
; i
++) {
353 status
= inb(FDC_MAIN_STATUS
);
354 if ((status
& 0xD0) != 0xD0) {
356 ERROR("fdc_read_data: read data status != READ_DATA: %0x\n",
361 addr
[i
] = inb(FDC_READ_PORT
);
367 static inline int fdc_write_cmd (uint8_t cmd
)
371 status
= inb(FDC_MAIN_STATUS
);
372 if ((status
& 0xC0) != 0x80) {
374 ERROR("fdc_write_cmd: read data status != WRITE_CMD: %0x\n",
379 outb(FDC_WRITE_PORT
, cmd
);
384 static int fdc_reset (void)
388 dor
= inb(FDC_DOR_PORT
);
389 /* Stop motors & enter reset */
391 outb(FDC_DOR_PORT
, dor
);
393 /* leave reset state */
395 outb(FDC_DOR_PORT
, dor
);
401 static int fdc_recalibrate (int drv
)
409 if (fdc_write_cmd(0x07) < 0) {
410 ERROR("fdc_recalibrate != WRITE_CMD\n");
413 if (fdc_write_cmd(data
[0]) < 0) {
414 ERROR("fdc_recalibrate data\n");
417 /* Wait for drive to go out of busy state */
418 while ((inb(FDC_MAIN_STATUS
) & 0x0F) != 0x00)
420 /* Check command status */
421 if (fdc_write_cmd(0x08) < 0) {
422 ERROR("fdc_recalibrate != SENSE_INTERRUPT_STATUS\n");
425 data
[0] = inb(FDC_READ_PORT
);
426 data
[1] = inb(FDC_READ_PORT
);
427 if (data
[0] & 0xD0) {
428 /* recalibrate / seek failed */
431 /* Status should be WRITE_CMD right now */
432 if ((inb(FDC_MAIN_STATUS
) & 0xD0) != 0x80) {
433 ERROR("fdc_recalibrate status\n");
440 static int fdc_start_read (int drv
, uint8_t hd
, uint8_t trk
, uint8_t sect
,
443 uint8_t fdc_cmd
[9], status
;
461 for (i
= 0; i
< (int)sizeof(fdc_cmd
); i
++) {
462 status
= inb(FDC_MAIN_STATUS
);
463 if ((status
& 0xC0) != 0x80) {
464 ERROR("fdc_start_read: write command status != WRITE_CMD: %0x\n",
468 outb(FDC_WRITE_PORT
, fdc_cmd
[i
]);
470 status
= inb(FDC_MAIN_STATUS
);
471 if ((status
& 0xD0) != 0xD0) {
472 ERROR("fdc_read_sector: status != READ_DATA: %0x\n", status
);
479 /* FDC driver entry points */
480 static int fdc_initialize (bloc_device_t
*bd
, int device
)
490 DPRINTF("Init FDC drive %d\n", device
);
491 /* Manage 1.44 MB disks only, for now */
500 if (fdc_write_cmd(0x0E) < 0) {
502 ERROR("fdc_reset: DUMP_REGISTER != WRITE_CMD\n");
506 if (fdc_read_data(fifo
, 10) < 0) {
507 ERROR("fdc_reset: DUMP_REGISTER data\n");
510 /* SPECIFY: be sure we're not in DMA mode */
511 if (fdc_write_cmd(0x03) < 0) {
512 ERROR("fdc_reset: SPECIFY != WRITE_CMD\n");
515 if (fdc_write_cmd(fifo
[4]) < 0 || fdc_write_cmd(fifo
[5] | 0x01)) {
516 ERROR("fdc_reset: SPECIFY data\n");
519 /* Status should be WRITE_CMD right now */
520 status
= inb(FDC_MAIN_STATUS
);
521 if ((status
& 0xD0) != 0x80) {
522 ERROR("fdc_initialise: read data status != WRITE_CMD: %0x\n",
527 if (fdc_recalibrate(device
) < 0) {
528 printf("fd%c: no floppy inserted\n", 'a' + device
);
531 printf("fd%c initialized\n", 'a' + device
);
536 static int fdc_read_sector (bloc_device_t
*bd
, void *buffer
, int secnum
)
542 printf("Read fdc sector: %d at: %0x\n", secnum
, (uint32_t)buffer
);
543 bd_sect2CHS(bd
, secnum
, &cyl
, &head
, §
);
544 printf("cur: %d hd: %d trk: %d sect: %d\n", bd
->bloc
, head
, cyl
, sect
);
546 if (secnum
!= bd
->tmp
) {
547 if (fdc_reset() < 0 || fdc_recalibrate(bd
->drv
) < 0)
553 bd_sect2CHS(bd
, secnum
, &cyl
, &head
, §
);
554 if (need_restart
== 1 || (head
== 0 && sect
== 1)) {
555 if (need_restart
== 0) {
556 /* Read the status */
559 while (fdc_read_data(tmp
, 1) == 0)
562 #if !defined (DEBUG_BIOS)
565 if (fdc_start_read(bd
->drv
, head
, cyl
, sect
, 1) < 0)
570 if (fdc_read_data(buffer
, bd
->seclen
) < 0)
578 /* SPC: primary commands, common to all devices */
579 static int spc_inquiry_req (void *buffer
, int maxlen
)
595 static int spc_inquiry_treat (void *buffer
, int len
)
602 if ((p
[0] >> 5) != 0) {
603 ERROR("Logical unit not ready\n");
610 static int spc_test_unit_ready_req (void *buffer
)
625 /* MMC: multimedia commands */
626 static int mmc_read_capacity_req (void *buffer
)
645 static int mmc_read_capacity_treat (uint32_t *size
, uint32_t *ssize
,
646 const void *buffer
, int len
)
653 /* Only handle CDROM address mode for now */
654 *size
= ((p
[0] << 24) | (p
[1] << 16) | (p
[2] << 8) | p
[3]) + 1;
655 *ssize
= ((p
[4] << 24) | (p
[5] << 16) | (p
[6] << 8) | p
[7]);
660 static int mmc_read12_req (void *buffer
, uint32_t LBA
, uint32_t size
)
681 /* IDE disk driver */
682 static uint32_t ide_base
[2] = { 0x1F0, 0x170, };
683 static uint32_t ide_base2
[2] = { 0x3F6, 0x376, };
685 typedef struct ide_ops_t
{
686 uint8_t (*port_read
)(bloc_device_t
*bd
, int port
);
687 void (*port_write
)(bloc_device_t
*bd
, int port
, uint8_t value
);
688 uint32_t (*data_readl
)(bloc_device_t
*bd
);
689 void (*data_writel
)(bloc_device_t
*bd
, uint32_t val
);
690 void (*control_write
)(bloc_device_t
*bd
, uint32_t val
);
692 #ifdef USE_OPENFIRMWARE
698 static uint8_t ide_isa_port_read (bloc_device_t
*bd
, int port
)
700 return inb(bd
->io_base
+ port
);
703 static void ide_isa_port_write (bloc_device_t
*bd
, int port
, uint8_t value
)
705 outb(bd
->io_base
+ port
, value
);
708 static uint32_t ide_isa_data_readl (bloc_device_t
*bd
)
710 return inl(bd
->io_base
);
713 static void ide_isa_data_writel (bloc_device_t
*bd
, uint32_t val
)
715 return outl(bd
->io_base
, val
);
718 static void ide_isa_control_write (bloc_device_t
*bd
, uint32_t val
)
723 static ide_ops_t ide_isa_ops
= {
727 &ide_isa_data_writel
,
728 &ide_isa_control_write
,
730 #ifdef USE_OPENFIRMWARE
735 static ide_ops_t
*ide_pci_ops
;
737 /* IDE PCI access for pc */
738 static uint8_t ide_pci_port_read (bloc_device_t
*bd
, int port
)
741 value
= inb(bd
->io_base
+ port
);
745 static void ide_pci_port_write (bloc_device_t
*bd
, int port
, uint8_t value
)
747 outb(bd
->io_base
+ port
, value
);
750 static uint32_t ide_pci_data_readl (bloc_device_t
*bd
)
752 return inl(bd
->io_base
);
755 static void ide_pci_data_writel (bloc_device_t
*bd
, uint32_t val
)
757 outl(bd
->io_base
, val
);
760 static void ide_pci_control_write (bloc_device_t
*bd
, uint32_t val
)
762 outb(bd
->tmp
+ 2, val
);
765 static ide_ops_t ide_pci_pc_ops
= {
769 &ide_pci_data_writel
,
770 &ide_pci_control_write
,
772 #ifdef USE_OPENFIRMWARE
777 void ide_pci_pc_register (uint32_t io_base0
, uint32_t io_base1
,
778 uint32_t io_base2
, uint32_t io_base3
,
779 void *OF_private0
, void *OF_private1
)
781 if (ide_pci_ops
== NULL
) {
782 ide_pci_ops
= malloc(sizeof(ide_ops_t
));
783 if (ide_pci_ops
== NULL
)
785 memcpy(ide_pci_ops
, &ide_pci_pc_ops
, sizeof(ide_ops_t
));
787 if ((io_base0
!= 0 || io_base1
!= 0) &&
788 ide_pci_ops
->base
[0] == 0 && ide_pci_ops
->base
[2] == 0) {
789 ide_pci_ops
->base
[0] = io_base0
;
790 ide_pci_ops
->base
[2] = io_base1
;
791 #ifdef USE_OPENFIRMWARE
792 ide_pci_ops
->OF_private
[0] = OF_private0
;
795 if ((io_base2
!= 0 || io_base3
!= 0) &&
796 ide_pci_ops
->base
[1] == 0 && ide_pci_ops
->base
[3] == 0) {
797 ide_pci_ops
->base
[1] = io_base2
;
798 ide_pci_ops
->base
[3] = io_base3
;
799 #ifdef USE_OPENFIRMWARE
800 ide_pci_ops
->OF_private
[1] = OF_private1
;
805 /* IDE PCI access for pmac */
806 static uint8_t ide_pmac_port_read (bloc_device_t
*bd
, int port
)
811 addr
= bd
->io_base
+ (port
<< 4);
813 addr
= bd
->io_base
+ 0x160;
816 return *((uint8_t *)addr
);
819 static void ide_pmac_port_write (bloc_device_t
*bd
, int port
, uint8_t value
)
824 addr
= bd
->io_base
+ (port
<< 4);
826 addr
= bd
->io_base
+ 0x160;
827 *((uint8_t *)addr
) = value
;
831 static uint32_t ide_pmac_data_readl (bloc_device_t
*bd
)
834 return ldswap32((uint32_t *)bd
->io_base
);
835 // return *((uint32_t *)bd->io_base);
838 static void ide_pmac_data_writel (bloc_device_t
*bd
, uint32_t val
)
840 // *((uint32_t *)bd->io_base) = val;
841 stswap32((uint32_t *)bd
->io_base
, val
);
845 static void ide_pmac_control_write (bloc_device_t
*bd
, uint32_t val
)
847 ide_pmac_port_write(bd
, 8, val
);
850 static ide_ops_t ide_pmac_ops
= {
852 &ide_pmac_port_write
,
853 &ide_pmac_data_readl
,
854 &ide_pmac_data_writel
,
855 &ide_pmac_control_write
,
857 #ifdef USE_OPENFIRMWARE
862 void ide_pci_pmac_register (uint32_t io_base0
, uint32_t io_base1
,
863 unused
void *OF_private
)
865 if (ide_pci_ops
== NULL
) {
866 ide_pci_ops
= malloc(sizeof(ide_ops_t
));
867 if (ide_pci_ops
== NULL
)
869 memcpy(ide_pci_ops
, &ide_pmac_ops
, sizeof(ide_ops_t
));
871 if (io_base0
!= 0 && ide_pci_ops
->base
[0] == 0) {
872 ide_pci_ops
->base
[0] = io_base0
;
873 #ifdef USE_OPENFIRMWARE
874 ide_pci_ops
->OF_private
[0] = OF_private
;
877 if (io_base1
!= 0 && ide_pci_ops
->base
[1] == 0) {
878 ide_pci_ops
->base
[1] = io_base1
;
879 #ifdef USE_OPENFIRMWARE
880 ide_pci_ops
->OF_private
[1] = OF_private
;
885 static inline uint8_t ide_port_read (bloc_device_t
*bd
, int port
)
887 ide_ops_t
*ops
= bd
->private;
889 return ops
->port_read(bd
, port
);
892 static inline void ide_port_write (bloc_device_t
*bd
, int port
, uint8_t value
)
894 ide_ops_t
*ops
= bd
->private;
896 ops
->port_write(bd
, port
, value
);
899 static inline uint32_t ide_data_readl (bloc_device_t
*bd
)
901 ide_ops_t
*ops
= bd
->private;
903 return ops
->data_readl(bd
);
906 static inline void ide_data_writel (bloc_device_t
*bd
, uint32_t val
)
908 ide_ops_t
*ops
= bd
->private;
910 return ops
->data_writel(bd
, val
);
913 static inline void ide_control_write (bloc_device_t
*bd
, uint32_t val
)
915 ide_ops_t
*ops
= bd
->private;
917 return ops
->control_write(bd
, val
);
920 static int ide_reset (bloc_device_t
*bd
)
922 int status
, is_cdrom
, lcyl
;
924 ide_control_write(bd
, 0x04);
925 status
= ide_port_read(bd
, 0x07);
926 if (status
!= 0x90) {
929 ide_control_write(bd
, 0x00);
931 ide_port_write(bd
, 0x06, 0xa0);
933 ide_port_write(bd
, 0x06, 0xb0);
935 lcyl
= ide_port_read(bd
, 0x04);
952 static void atapi_pad_req (void *buffer
, int len
);
953 static void atapi_make_req (bloc_device_t
*bd
, uint32_t *buffer
,
955 static int atapi_read_sector (bloc_device_t
*bd
, void *buffer
, int secnum
);
957 static int ide_initialize (bloc_device_t
*bd
, int device
)
959 #ifdef USE_OPENFIRMWARE
962 const unsigned char *devname
, *devtype
, *alias
;
963 uint32_t atapi_buffer
[9];
965 int status
, base
, is_cdrom
, len
, i
;
971 if (ide_pci_ops
!= NULL
) {
972 bd
->private = ide_pci_ops
;
973 bd
->io_base
= ide_pci_ops
->base
[base
];
974 bd
->tmp
= ide_pci_ops
->base
[2 + base
];
975 if (bd
->io_base
== 0x00000000 || bd
->io_base
== 0xFFFFFFFF) {
976 ERROR("No IDE drive %c\n", device
);
980 bd
->private = &ide_isa_ops
;
981 bd
->io_base
= ide_base
[base
];
982 bd
->tmp
= ide_base2
[base
];
984 bd
->drv
= device
& 1;
985 DPRINTF("Init IDE drive %d-%d (%d)\n", base
, bd
->drv
, device
);
986 is_cdrom
= ide_reset(bd
);
987 printf("ide%d: drive %d: ",
988 (device
>> 1), bd
->drv
);
991 printf("Hard Disk\n");
1011 #ifdef USE_OPENFIRMWARE
1012 /* Register disk into OF tree */
1013 OF_parent
= ide_pci_ops
->OF_private
[base
];
1014 if (OF_parent
!= NULL
) {
1015 bd
->OF_private
= OF_blockdev_register(OF_parent
, bd
, devtype
,
1016 devname
, bd
->drv
, alias
);
1021 ide_port_write(bd
, 0x06, 0x40);
1023 ide_port_write(bd
, 0x06, 0x50);
1024 /* WIN_DEVICE_RESET */
1025 ide_port_write(bd
, 0x07, 0x08);
1026 status
= ide_port_read(bd
, 0x07);
1028 if (status
!= 0x00) {
1029 ERROR("WIN_DEVICE_RESET : status %0x != 0x00 (is_cdrom: %d)\n",
1033 /* TEST_UNIT_READY */
1034 DPRINTF("TEST_UNIT_READY\n");
1035 len
= spc_test_unit_ready_req(&atapi_buffer
);
1036 atapi_pad_req(&atapi_buffer
, len
);
1037 ide_port_write(bd
, 0x07, 0xA0);
1038 status
= ide_port_read(bd
, 0x07);
1039 if (status
!= 0x08) {
1040 ERROR("ATAPI TEST_UNIT_READY : status %0x != 0x08\n", status
);
1041 /*return -1;*/ /* fails to boot from cdrom? */
1043 for (i
= 0; i
< 3; i
++) {
1044 ide_data_writel(bd
, ldswap32(&atapi_buffer
[i
]));
1046 status
= ide_port_read(bd
, 0x07);
1047 if (status
!= 0x40) {
1048 ERROR("ATAPI TEST_UNIT_READY : status %0x != 0x40\n", status
);
1052 DPRINTF("INQUIRY\n");
1053 len
= spc_inquiry_req(&atapi_buffer
, 36);
1054 atapi_pad_req(&atapi_buffer
, len
);
1055 atapi_make_req(bd
, atapi_buffer
, 36);
1056 status
= ide_port_read(bd
, 0x07);
1057 if (status
!= 0x48) {
1058 ERROR("ATAPI INQUIRY : status %0x != 0x48\n", status
);
1061 for (i
= 0; i
< 9; i
++)
1062 stswap32(&atapi_buffer
[i
], ide_data_readl(bd
));
1063 if (spc_inquiry_treat(&atapi_buffer
, 36) != 0x05) {
1064 ERROR("Only ATAPI CDROMs are handled for now\n");
1068 DPRINTF("READ_CAPACITY\n");
1069 len
= mmc_read_capacity_req(&atapi_buffer
);
1070 atapi_pad_req(&atapi_buffer
, len
);
1071 atapi_make_req(bd
, atapi_buffer
, 8);
1072 status
= ide_port_read(bd
, 0x07);
1073 if (status
!= 0x48) {
1074 ERROR("ATAPI READ_CAPACITY : status %0x != 0x48\n", status
);
1077 for (i
= 0; i
< 2; i
++)
1078 stswap32(&atapi_buffer
[i
], ide_data_readl(bd
));
1079 if (mmc_read_capacity_treat(&size
, &bd
->seclen
,
1080 &atapi_buffer
, 8) != 0) {
1081 ERROR("Error retrieving ATAPI CDROM capacity\n");
1084 bd
->read_sector
= &atapi_read_sector
;
1085 DPRINTF("ATAPI: size=%d ssize=%d\n", size
, bd
->seclen
);
1087 if (status
!= 0x41) {
1088 ERROR("WIN_DEVICE_RESET : status %0x != 0x41 (is_cdrom: %d)\n",
1092 /* WIN_READ_NATIVE_MAX */
1093 ide_port_write(bd
, 0x07, 0xF8);
1094 status
= ide_port_read(bd
, 0x07);
1095 if (status
!= 0x40) {
1096 ERROR("WIN_READ_NATIVE_MAX : status %0x != 0x40\n", status
);
1099 /* Retrieve parameters */
1100 size
= (ide_port_read(bd
, 0x06) & ~0xF0) << 24;
1101 size
|= ide_port_read(bd
, 0x05) << 16;
1102 size
|= ide_port_read(bd
, 0x04) << 8;
1103 size
|= ide_port_read(bd
, 0x03);
1108 bd
->trks
= (size
+ (16 * 64 - 1)) >> 10;
1113 static void atapi_pad_req (void *buffer
, int len
)
1118 memset(p
+ len
, 0, 12 - len
);
1121 static void atapi_make_req (bloc_device_t
*bd
, uint32_t *buffer
,
1127 ide_port_write(bd
, 0x06, 0x40);
1129 ide_port_write(bd
, 0x06, 0x50);
1130 ide_port_write(bd
, 0x04, maxlen
& 0xff);
1131 ide_port_write(bd
, 0x05, (maxlen
>> 8) & 0xff);
1132 ide_port_write(bd
, 0x07, 0xA0);
1133 for (i
= 0; i
< 3; i
++)
1134 ide_data_writel(bd
, ldswap32(&buffer
[i
]));
1137 static int atapi_read_sector (bloc_device_t
*bd
, void *buffer
, int secnum
)
1139 uint32_t atapi_buffer
[4];
1141 uint32_t status
, value
;
1144 len
= mmc_read12_req(atapi_buffer
, secnum
, 1);
1145 atapi_pad_req(&atapi_buffer
, len
);
1146 atapi_make_req(bd
, atapi_buffer
, bd
->seclen
);
1147 status
= ide_port_read(bd
, 0x07);
1148 if (status
!= 0x48) {
1149 ERROR("ATAPI READ12 : status %0x != 0x48\n", status
);
1153 for (i
= 0; i
< bd
->seclen
; i
+= 4) {
1154 value
= ide_data_readl(bd
);
1160 status
= ide_port_read(bd
, 0x07);
1161 if (status
!= 0x40) {
1162 ERROR("ATAPI READ12 done : status %0x != 0x48\n", status
);
1169 static int ide_read_sector (bloc_device_t
*bd
, void *buffer
, int secnum
)
1177 // printf("ide_read_sector: drv %d secnum %d buf %p\n", bd->drv, secnum, buffer);
1178 /* select drive & set highest bytes */
1180 ide_port_write(bd
, 0x06, 0x40 | (secnum
>> 24));
1182 ide_port_write(bd
, 0x06, 0x50 | (secnum
>> 24));
1184 ide_port_write(bd
, 0x05, secnum
>> 16);
1186 ide_port_write(bd
, 0x04, secnum
>> 8);
1188 ide_port_write(bd
, 0x03, secnum
);
1190 ide_port_write(bd
, 0x02, 1);
1192 ide_port_write(bd
, 0x07, 0x20);
1193 status
= ide_port_read(bd
, 0x07);
1194 // DPRINTF("ide_read_sector: try %d\n", secnum);
1195 if (status
!= 0x58) {
1196 ERROR("ide_read_sector: %d status %0x != 0x58\n", secnum
, status
);
1201 for (i
= 0; i
< bd
->seclen
; i
+= 4) {
1202 value
= ide_data_readl(bd
);
1208 status
= ide_port_read(bd
, 0x07);
1209 if (status
!= 0x50) {
1210 ERROR("ide_read_sector 6: status %0x != 0x50\n", status
);
1217 /* Memory image access driver */
1218 static int mem_initialize (bloc_device_t
*bd
, int device
)
1226 return device
== 'm';
1229 static int mem_read_sector (bloc_device_t
*bd
, void *buffer
, int secnum
)
1231 if (buffer
!= (char *)bd
->private + (bd
->seclen
* secnum
)) {
1233 (char *)bd
->private + (bd
->seclen
* secnum
), bd
->seclen
);
1239 static int mem_ioctl (bloc_device_t
*bd
, int func
, void *args
)
1251 bd
->trks
= (*u32
+ bd
->seclen
- 1) / bd
->seclen
+ 1;