]> git.saurik.com Git - apple/boot.git/blame - i386/boot1u/disk.c
boot-122.tar.gz
[apple/boot.git] / i386 / boot1u / disk.c
CommitLineData
f083c6c3 1/*
57c72a9a 2 * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
f083c6c3
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
57c72a9a 6 * Portions Copyright (c) 2002-2003 Apple Computer, Inc. All Rights
4f6e3300
A
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
57c72a9a 9 * Source License Version 2.0 (the "License"). You may not use this file
4f6e3300
A
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
f083c6c3
A
13 *
14 * The Original Code and all software distributed under the License are
4f6e3300 15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
f083c6c3
A
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
4f6e3300
A
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
f083c6c3
A
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25#include <string.h>
26#include "boot1u.h"
27#include <memory.h>
28#include <saio_types.h>
29#include <saio_internal.h>
30#include <fdisk.h>
31
32#include "ufs.h"
33
34/*
35 * trackbuf points to the start of the track cache. Biosread()
36 * will store the sectors read from disk to this memory area.
37 *
38 * biosbuf points to a sector within the track cache, and is
39 * updated by Biosread().
40 */
41#if 0
42static const char * const trackbuf = (char *) ptov(BIOS_ADDR);
43#endif
44static const char * biosbuf = (char *) ptov(BIOS_ADDR);
45
46/*
47 * diskinfo unpacking.
48 */
49#define SPT(di) ((di) & 0xff)
50#define HEADS(di) ((((di)>>8) & 0xff) + 1)
51#define SPC(di) (SPT(di) * HEADS(di))
52
53#define BPS 512 /* sector size of the device */
54#define N_CACHE_SECS (BIOS_LEN / BPS)
55#define UFS_FRONT_PORCH 0
56
57#define ECC_CORRECTED_ERR 0x11
58
f083c6c3
A
59extern void bios(biosBuf_t *bb);
60
61static biosBuf_t bb;
57c72a9a 62
f083c6c3
A
63int ebiosread(int dev, long sec, int count)
64{
65 int i;
66 static struct {
67 unsigned char size;
68 unsigned char reserved;
69 unsigned char numblocks;
70 unsigned char reserved2;
71 unsigned short bufferOffset;
72 unsigned short bufferSegment;
73 unsigned long long startblock;
74 } addrpacket = {0};
75 addrpacket.size = sizeof(addrpacket);
76
77 for (i=0;;) {
78 bb.intno = 0x13;
79 bb.eax.r.h = 0x42;
80 bb.edx.r.l = dev;
81 bb.esi.rr = OFFSET((unsigned)&addrpacket);
82 bb.ds = SEGMENT((unsigned)&addrpacket);
83 addrpacket.reserved = addrpacket.reserved2 = 0;
84 addrpacket.numblocks = count;
85 addrpacket.bufferOffset = OFFSET(ptov(BIOS_ADDR));
86 addrpacket.bufferSegment = SEGMENT(ptov(BIOS_ADDR));
87 addrpacket.startblock = sec;
88 bios(&bb);
89 if ((bb.eax.r.h == 0x00) || (i++ >= 5))
90 break;
91
92 /* reset disk subsystem and try again */
93 bb.eax.r.h = 0x00;
94 bios(&bb);
95 }
96 return bb.eax.r.h;
97}
98
99//==========================================================================
100// Use BIOS INT13 calls to read the sector specified. This function will
101// also perform read-ahead to cache a few subsequent sector to the sector
102// cache.
103//
104// Return:
105// 0 on success, or an error code from INT13/F2 or INT13/F42 BIOS call.
106
107static int Biosread( int biosdev, unsigned int secno )
108{
109 int rc;
110
111 DEBUG_DISK(("Biosread dev %x sec %d \n", biosdev, secno));
112
113 rc = ebiosread(biosdev, secno, 1);
114 if (rc == ECC_CORRECTED_ERR) {
115 rc = 0;
116 }
117 return rc;
118}
119
120//==========================================================================
121
122static int readBytes( int biosdev, unsigned int blkno,
123 unsigned int byteCount, void * buffer )
124{
125
126 char * cbuf = (char *) buffer;
127 int error;
128 int copy_len;
129
130 DEBUG_DISK(("%s: dev %x block %x [%d] -> 0x%x...", __FUNCTION__,
131 biosdev, blkno, byteCount, (unsigned)cbuf));
132
133 for ( ; byteCount; cbuf += BPS, blkno++ )
134 {
135 error = Biosread( biosdev, blkno );
136 if ( error )
137 {
138 DEBUG_DISK(("error\n"));
139 return (-1);
140 }
141
142 copy_len = (byteCount > BPS) ? BPS : byteCount;
143 bcopy( biosbuf, cbuf, copy_len );
144 byteCount -= copy_len;
145 }
146
147 DEBUG_DISK(("done\n"));
148
149 return 0;
150}
151
152//==========================================================================
153
154//==========================================================================
155// Handle seek request from filesystem modules.
156
157void diskSeek( BVRef bvr, long long position )
158{
159 bvr->fs_boff = position / BPS;
160}
161
162//==========================================================================
163// Handle read request from filesystem modules.
164
165int diskRead( BVRef bvr, long addr, long length )
166{
167 return readBytes( bvr->biosdev,
168 bvr->fs_boff + bvr->part_boff,
169 length,
170 (void *) addr );
171}
172
57c72a9a 173
f083c6c3
A
174int
175findUFSPartition(int dev, struct fdisk_part *_fp)
176{
177 struct disk_blk0 *db;
178 struct fdisk_part *fp;
179 int i, cc;
180 unsigned long offset = 0;
57c72a9a
A
181 unsigned long firstoff = 0;
182 int ext_index = -1;
f083c6c3
A
183
184 db = (struct disk_blk0 *)biosbuf;
57c72a9a
A
185 do {
186 DEBUG_DISK(("reading at offset %d\n", offset));
f083c6c3
A
187 cc = Biosread(dev, offset);
188 if (cc < 0) {
57c72a9a 189 return cc;
f083c6c3 190 }
57c72a9a
A
191 for (i=0; i<FDISK_NPART; i++) {
192 DEBUG_DISK(("i=%d, offset %ld\n", i, offset));
193 fp = (struct fdisk_part *)&db->parts[i];
194 DEBUG_DISK(("systid %x\n", fp->systid));
195 if (fp->systid == FDISK_UFS) {
196 bcopy(fp, _fp, sizeof(struct fdisk_part));
197 _fp->relsect += offset;
198 DEBUG_DISK(("** found UFS at partition %d\n", i));
199 return 0;
200 } else if (fp->systid == FDISK_DOSEXT ||
201 fp->systid == 0x0F ||
202 fp->systid == 0x85) {
203 ext_index = i;
204 }
205 }
206 if (ext_index != -1) {
207 DEBUG_DISK(("Found ext part at %d\n", ext_index));
208 fp = (struct fdisk_part *)&db->parts[ext_index];
209 ext_index = -1;
210 offset = firstoff + fp->relsect;
211 if (firstoff == 0) {
212 firstoff = fp->relsect;
213 }
214 continue;
215 }
216 break;
217 } while (1);
f083c6c3
A
218 return -1;
219}
220
221
222void
223initUFSBVRef( BVRef bvr, int biosdev, const struct fdisk_part * part)
224{
57c72a9a
A
225 bvr->biosdev = biosdev;
226 bvr->part_no = 0;
227 bvr->part_boff = part->relsect + UFS_FRONT_PORCH/BPS,
f083c6c3 228 bvr->part_type = part->systid;
57c72a9a
A
229 bvr->fs_loadfile = UFSLoadFile;
230 //bvr->fs_getdirentry = UFSGetDirEntry;
231 bvr->description = 0;
f083c6c3
A
232}
233
234void putc(int ch)
235{
236 bb.intno = 0x10;
237 bb.ebx.r.h = 0x00; /* background black */
238 bb.ebx.r.l = 0x0F; /* foreground white */
239 bb.eax.r.h = 0x0e;
240 bb.eax.r.l = ch;
241 bios(&bb);
242}
243
244int bgetc(void)
245{
246 bb.intno = 0x16;
247 bb.eax.r.h = 0x00;
248 bios(&bb);
249 return bb.eax.rr;
250}
251
252void delay(int ms)
253{
254 bb.intno = 0x15;
255 bb.eax.r.h = 0x86;
256 bb.ecx.rr = ms >> 16;
257 bb.edx.rr = ms & 0xFFFF;
258 bios(&bb);
259}