3 #include "ppcmmu/mmu.h"
6 #define SWAP_W(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))
8 typedef struct _idectl_desc
{
11 int seek_cylinder
, seek_head
, seek_sector
;
12 int cylinders
, heads
, sectors
, bytespersec
;
15 idectl_desc ide1_desc
= { 0x800001f0 };
17 void ide_seek( void *extension
, int low
, int high
) {
18 idectl_desc
*desc
= (idectl_desc
*)extension
;
19 long long seekto
= ((((long long)high
) << 32) | (low
& 0xffffffff));
20 /* order = sector, head, cylinder */
21 desc
->seek_sector
= seekto
% desc
->sectors
;
22 seekto
/= desc
->sectors
;
23 desc
->seek_head
= seekto
% desc
->heads
;
24 seekto
/= desc
->heads
;
25 desc
->seek_cylinder
= seekto
;
26 desc
->seekto
= seekto
;
29 /* Thanks chuck moore. This is based on the color forth ide code */
31 void ide_rdy( void *extension
) {
32 idectl_desc
*desc
= (idectl_desc
*)extension
;
33 while( !(GetPhysByte(desc
->port
+7) & 0x40) ) sync();
36 void ide_drq( void *extension
) {
37 idectl_desc
*desc
= (idectl_desc
*)extension
;
38 while( !(GetPhysByte(desc
->port
+7) & 0x08) ) sync();
41 void ide_bsy( void *extension
) {
42 idectl_desc
*desc
= (idectl_desc
*)extension
;
43 while( GetPhysByte(desc
->port
+7) & 0x80 )
45 printf("Waiting for not busy\n");
50 int ide_read( void *extension
, char *buffer
, int bytes
) {
51 idectl_desc
*desc
= (idectl_desc
*)extension
;
52 short *databuf
= (short *)buffer
;
56 SetPhysByte(desc
->port
+2, bytes
/ desc
->bytespersec
);
57 SetPhysByte(desc
->port
+3, desc
->seek_sector
+ 1);
58 SetPhysByte(desc
->port
+4, desc
->seek_cylinder
);
59 SetPhysByte(desc
->port
+5, desc
->seek_cylinder
>> 8);
60 SetPhysByte(desc
->port
+6, desc
->seek_head
| 0xa0);
61 SetPhysByte(desc
->port
+7, 0x20);
63 for( inwords
= 0; inwords
< desc
->bytespersec
/ sizeof(short); inwords
++ ) {
64 databuf
[inwords
] = GetPhysHalf(desc
->port
);
67 desc
->seekto
+= desc
->bytespersec
;
68 ide_seek( extension
, desc
->seekto
, desc
->seekto
>> 32 );
70 return bytes
- (bytes
% desc
->bytespersec
);
73 void ide_setup( void *extension
) {
74 idectl_desc
*desc
= (idectl_desc
*)extension
;
75 short identbuffer
[256];
77 short *databuf
= (short *)identbuffer
, in
;
82 desc
->bytespersec
= 512;
83 SetPhysByte(desc
->port
+2, 1);
84 SetPhysByte(desc
->port
+3, 0);
85 SetPhysByte(desc
->port
+4, 0);
86 SetPhysByte(desc
->port
+5, 0);
87 SetPhysByte(desc
->port
+6, 0);
88 SetPhysByte(desc
->port
+7, 0xec);
91 for( inwords
= 0; inwords
< desc
->bytespersec
/ sizeof(short); inwords
++ ) {
92 in
= GetPhysHalf(desc
->port
);
93 databuf
[inwords
] = SWAP_W(in
);
97 desc
->cylinders
= identbuffer
[1];
98 desc
->heads
= identbuffer
[3];
99 desc
->sectors
= identbuffer
[6];
101 /* Debug: Write out hard disc model */
103 strncpy(namebuf
, (char *)(identbuffer
+0x1b), 41);
104 printf("HARD DISC MODEL: %s c,h,s %d,%d,%d\n",
105 namebuf
, desc
->cylinders
, desc
->heads
, desc
->sectors
);