]>
git.saurik.com Git - apple/boot.git/blob - i386/boot1u/disk.c
2 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
29 #include <saio_types.h>
30 #include <saio_internal.h>
36 * trackbuf points to the start of the track cache. Biosread()
37 * will store the sectors read from disk to this memory area.
39 * biosbuf points to a sector within the track cache, and is
40 * updated by Biosread().
43 static const char * const trackbuf
= (char *) ptov(BIOS_ADDR
);
45 static const char * biosbuf
= (char *) ptov(BIOS_ADDR
);
50 #define SPT(di) ((di) & 0xff)
51 #define HEADS(di) ((((di)>>8) & 0xff) + 1)
52 #define SPC(di) (SPT(di) * HEADS(di))
54 #define BPS 512 /* sector size of the device */
55 #define N_CACHE_SECS (BIOS_LEN / BPS)
56 #define UFS_FRONT_PORCH 0
58 #define ECC_CORRECTED_ERR 0x11
61 //#define DEBUG_DISK(x) printf x
63 extern void bios(biosBuf_t
*bb
);
66 int ebiosread(int dev
, long sec
, int count
)
71 unsigned char reserved
;
72 unsigned char numblocks
;
73 unsigned char reserved2
;
74 unsigned short bufferOffset
;
75 unsigned short bufferSegment
;
76 unsigned long long startblock
;
78 addrpacket
.size
= sizeof(addrpacket
);
84 bb
.esi
.rr
= OFFSET((unsigned)&addrpacket
);
85 bb
.ds
= SEGMENT((unsigned)&addrpacket
);
86 addrpacket
.reserved
= addrpacket
.reserved2
= 0;
87 addrpacket
.numblocks
= count
;
88 addrpacket
.bufferOffset
= OFFSET(ptov(BIOS_ADDR
));
89 addrpacket
.bufferSegment
= SEGMENT(ptov(BIOS_ADDR
));
90 addrpacket
.startblock
= sec
;
92 if ((bb
.eax
.r
.h
== 0x00) || (i
++ >= 5))
95 /* reset disk subsystem and try again */
102 //==========================================================================
103 // Use BIOS INT13 calls to read the sector specified. This function will
104 // also perform read-ahead to cache a few subsequent sector to the sector
108 // 0 on success, or an error code from INT13/F2 or INT13/F42 BIOS call.
110 static int Biosread( int biosdev
, unsigned int secno
)
114 DEBUG_DISK(("Biosread dev %x sec %d \n", biosdev
, secno
));
116 rc
= ebiosread(biosdev
, secno
, 1);
117 if (rc
== ECC_CORRECTED_ERR
) {
123 //==========================================================================
125 static int readBytes( int biosdev
, unsigned int blkno
,
126 unsigned int byteCount
, void * buffer
)
129 char * cbuf
= (char *) buffer
;
133 DEBUG_DISK(("%s: dev %x block %x [%d] -> 0x%x...", __FUNCTION__
,
134 biosdev
, blkno
, byteCount
, (unsigned)cbuf
));
136 for ( ; byteCount
; cbuf
+= BPS
, blkno
++ )
138 error
= Biosread( biosdev
, blkno
);
141 DEBUG_DISK(("error\n"));
145 copy_len
= (byteCount
> BPS
) ? BPS
: byteCount
;
146 bcopy( biosbuf
, cbuf
, copy_len
);
147 byteCount
-= copy_len
;
150 DEBUG_DISK(("done\n"));
155 //==========================================================================
157 //==========================================================================
158 // Handle seek request from filesystem modules.
160 void diskSeek( BVRef bvr
, long long position
)
162 bvr
->fs_boff
= position
/ BPS
;
165 //==========================================================================
166 // Handle read request from filesystem modules.
168 int diskRead( BVRef bvr
, long addr
, long length
)
170 return readBytes( bvr
->biosdev
,
171 bvr
->fs_boff
+ bvr
->part_boff
,
177 findUFSPartition(int dev
, struct fdisk_part
*_fp
)
179 struct disk_blk0
*db
;
180 struct fdisk_part
*fp
;
182 unsigned long offset
= 0;
184 db
= (struct disk_blk0
*)biosbuf
;
185 for (i
=0; i
<FDISK_NPART
; i
++) {
186 DEBUG_DISK(("i=%d, %ld\n", i
, offset
));
188 DEBUG_DISK(("reading\n"));
189 cc
= Biosread(dev
, offset
);
194 fp
= (struct fdisk_part
*)&db
->parts
[i
];
195 DEBUG_DISK(("systid %x\n", fp
->systid
));
196 if (fp
->systid
== 0xA8) {
197 bcopy(fp
, _fp
, sizeof(struct fdisk_part
));
198 _fp
->relsect
+= offset
;
199 DEBUG_DISK(("found %d\n", i
));
201 } else if (fp
->systid
== 0x05 ||
202 fp
->systid
== 0x0F ||
203 fp
->systid
== 0x85) {
204 offset
+= fp
->relsect
;
214 initUFSBVRef( BVRef bvr
, int biosdev
, const struct fdisk_part
* part
)
216 bvr
->biosdev
= biosdev
;
218 bvr
->part_boff
= part
->relsect
+ UFS_FRONT_PORCH
/BPS
,
219 bvr
->part_type
= part
->systid
;
220 bvr
->fs_loadfile
= UFSLoadFile
;
221 bvr
->fs_getdirentry
= UFSGetDirEntry
;
222 bvr
->description
= 0;
228 bb
.ebx
.r
.h
= 0x00; /* background black */
229 bb
.ebx
.r
.l
= 0x0F; /* foreground white */
247 bb
.ecx
.rr
= ms
>> 16;
248 bb
.edx
.rr
= ms
& 0xFFFF;