Browse Source

Fix bug with >256 cylinders.

Allow our functions to return a non-zero, non-error status (since the
INT 13 Extensions Check has to return the API version in the register
that is otherwise always used for the error code).

Report a non-zero API version from the INT 13 Extensions Check; GRUB
now uses extended reads.
tags/v0.9.3
Michael Brown 18 years ago
parent
commit
17eea9f933
1 changed files with 18 additions and 15 deletions
  1. 18
    15
      src/arch/i386/interface/pcbios/int13.c

+ 18
- 15
src/arch/i386/interface/pcbios/int13.c View File

115
 	userptr_t buffer;
115
 	userptr_t buffer;
116
 
116
 
117
 	/* Calculate parameters */
117
 	/* Calculate parameters */
118
-	cylinder = ( ( ( ix86->regs.cl & 0xc0 ) << 8 ) | ix86->regs.ch );
118
+	cylinder = ( ( ( ix86->regs.cl & 0xc0 ) << 2 ) | ix86->regs.ch );
119
 	assert ( cylinder < drive->cylinders );
119
 	assert ( cylinder < drive->cylinders );
120
 	head = ix86->regs.dh;
120
 	head = ix86->regs.dh;
121
 	assert ( head < drive->heads );
121
 	assert ( head < drive->heads );
133
 	if ( blockdev->blksize != INT13_BLKSIZE ) {
133
 	if ( blockdev->blksize != INT13_BLKSIZE ) {
134
 		DBG ( "Invalid blocksize (%zd) for non-extended read/write\n",
134
 		DBG ( "Invalid blocksize (%zd) for non-extended read/write\n",
135
 		      blockdev->blksize );
135
 		      blockdev->blksize );
136
-		return INT13_STATUS_INVALID;
136
+		return -INT13_STATUS_INVALID;
137
 	}
137
 	}
138
 	
138
 	
139
 	/* Read from / write to block device */
139
 	/* Read from / write to block device */
140
 	if ( io ( blockdev, lba, count, buffer ) != 0 )
140
 	if ( io ( blockdev, lba, count, buffer ) != 0 )
141
-		return INT13_STATUS_READ_ERROR;
141
+		return -INT13_STATUS_READ_ERROR;
142
 
142
 
143
 	return 0;
143
 	return 0;
144
 }
144
 }
214
  * @v bx		0x55aa
214
  * @v bx		0x55aa
215
  * @ret bx		0xaa55
215
  * @ret bx		0xaa55
216
  * @ret cx		Extensions API support bitmap
216
  * @ret cx		Extensions API support bitmap
217
- * @ret status		Status code
217
+ * @ret status		Status code / API version
218
  */
218
  */
219
 static int int13_extension_check ( struct int13_drive *drive __unused,
219
 static int int13_extension_check ( struct int13_drive *drive __unused,
220
 				   struct i386_all_regs *ix86 ) {
220
 				   struct i386_all_regs *ix86 ) {
222
 		DBG ( "INT 13 extensions installation check\n" );
222
 		DBG ( "INT 13 extensions installation check\n" );
223
 		ix86->regs.bx = 0xaa55;
223
 		ix86->regs.bx = 0xaa55;
224
 		ix86->regs.cx = INT13_EXTENSION_LINEAR;
224
 		ix86->regs.cx = INT13_EXTENSION_LINEAR;
225
-		return 0;
225
+		return INT13_EXTENSION_VER_1_X;
226
 	} else {
226
 	} else {
227
-		return INT13_STATUS_INVALID;
227
+		return -INT13_STATUS_INVALID;
228
 	}
228
 	}
229
 }
229
 }
230
 
230
 
259
 	
259
 	
260
 	/* Read from / write to block device */
260
 	/* Read from / write to block device */
261
 	if ( io ( blockdev, lba, count, buffer ) != 0 )
261
 	if ( io ( blockdev, lba, count, buffer ) != 0 )
262
-		return INT13_STATUS_READ_ERROR;
262
+		return -INT13_STATUS_READ_ERROR;
263
 
263
 
264
 	return 0;
264
 	return 0;
265
 }
265
 }
322
  *
322
  *
323
  */
323
  */
324
 static void int13 ( struct i386_all_regs *ix86 ) {
324
 static void int13 ( struct i386_all_regs *ix86 ) {
325
+	int command = ix86->regs.ah;
325
 	struct int13_drive *drive;
326
 	struct int13_drive *drive;
326
 	int status;
327
 	int status;
327
 
328
 
329
 		if ( drive->drive != ix86->regs.dl )
330
 		if ( drive->drive != ix86->regs.dl )
330
 			continue;
331
 			continue;
331
 		
332
 		
332
-		DBG ( "INT 13,%02x (%02x): ", ix86->regs.ah,
333
-		      ix86->regs.dl );
334
-	
335
-		switch ( ix86->regs.ah ) {
333
+		DBG ( "INT 13,%02x (%02x): ", command, drive->drive );
334
+
335
+		switch ( command ) {
336
 		case INT13_RESET:
336
 		case INT13_RESET:
337
 			status = int13_reset ( drive, ix86 );
337
 			status = int13_reset ( drive, ix86 );
338
 			break;
338
 			break;
362
 			break;
362
 			break;
363
 		default:
363
 		default:
364
 			DBG ( "Unrecognised INT 13\n" );
364
 			DBG ( "Unrecognised INT 13\n" );
365
-			status = INT13_STATUS_INVALID;
365
+			status = -INT13_STATUS_INVALID;
366
 			break;
366
 			break;
367
 		}
367
 		}
368
 
368
 
369
 		/* Store status for INT 13,01 */
369
 		/* Store status for INT 13,01 */
370
 		drive->last_status = status;
370
 		drive->last_status = status;
371
-		/* All functions return status via %ah and CF */
372
-		ix86->regs.ah = status;
373
-		if ( status ) {
371
+
372
+		/* Negative status indicates an error */
373
+		if ( status < 0 ) {
374
 			ix86->flags |= CF;
374
 			ix86->flags |= CF;
375
+			status = -status;
375
 			DBG ( "INT13 failed with status %x\n", status );
376
 			DBG ( "INT13 failed with status %x\n", status );
376
 		}
377
 		}
378
+		ix86->regs.ah = status;
379
+
377
 		/* Set OF to indicate to wrapper not to chain this call */
380
 		/* Set OF to indicate to wrapper not to chain this call */
378
 		ix86->flags |= OF;
381
 		ix86->flags |= OF;
379
 	}
382
 	}

Loading…
Cancel
Save