[FREELDR/AMD64]
[reactos.git] / reactos / boot / freeldr / freeldr / arch / powerpc / prep_ide.c
1 #include "freeldr.h"
2 #include "machine.h"
3 #include "ppcmmu/mmu.h"
4 #include "prep.h"
5
6 #define SWAP_W(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))
7
8 typedef struct _idectl_desc {
9 int port;
10 long long seekto;
11 int seek_cylinder, seek_head, seek_sector;
12 int cylinders, heads, sectors, bytespersec;
13 } idectl_desc;
14
15 idectl_desc ide1_desc = { 0x800001f0 };
16
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;
27 }
28
29 /* Thanks chuck moore. This is based on the color forth ide code */
30 /* Wait for ready */
31 void ide_rdy( void *extension ) {
32 idectl_desc *desc = (idectl_desc *)extension;
33 while( !(GetPhysByte(desc->port+7) & 0x40) ) sync();
34 }
35
36 void ide_drq( void *extension ) {
37 idectl_desc *desc = (idectl_desc *)extension;
38 while( !(GetPhysByte(desc->port+7) & 0x08) ) sync();
39 }
40
41 void ide_bsy( void *extension ) {
42 idectl_desc *desc = (idectl_desc *)extension;
43 while( GetPhysByte(desc->port+7) & 0x80 )
44 {
45 printf("Waiting for not busy\n");
46 sync();
47 }
48 }
49
50 int ide_read( void *extension, char *buffer, int bytes ) {
51 idectl_desc *desc = (idectl_desc *)extension;
52 short *databuf = (short *)buffer;
53 int inwords;
54
55 ide_bsy( extension );
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);
62
63 for( inwords = 0; inwords < desc->bytespersec / sizeof(short); inwords++ ) {
64 databuf[inwords] = GetPhysHalf(desc->port);
65 }
66
67 desc->seekto += desc->bytespersec;
68 ide_seek( extension, desc->seekto, desc->seekto >> 32 );
69
70 return bytes - (bytes % desc->bytespersec);
71 }
72
73 void ide_setup( void *extension ) {
74 idectl_desc *desc = (idectl_desc *)extension;
75 short identbuffer[256];
76 char namebuf[41];
77 short *databuf = (short *)identbuffer, in;
78 int inwords;
79
80 ide_rdy( extension );
81 ide_bsy( extension );
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);
89 ide_drq( extension );
90
91 for( inwords = 0; inwords < desc->bytespersec / sizeof(short); inwords++ ) {
92 in = GetPhysHalf(desc->port);
93 databuf[inwords] = SWAP_W(in);
94 sync();
95 }
96
97 desc->cylinders = identbuffer[1];
98 desc->heads = identbuffer[3];
99 desc->sectors = identbuffer[6];
100
101 /* Debug: Write out hard disc model */
102
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);
106 }