From d48d0fb1bb53262bf44a03dbe8388529f1566a1c Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 19 May 2006 15:06:51 +0000 Subject: Add the concept of a "user pointer" (similar to the void __user * in the kernel), which encapsulates the information needed to refer to an external buffer. Under normal operation, this can just be a void * equivalent, but under -DKEEP_IT_REAL it would be a segoff_t equivalent. Use this concept to avoid the need for bounce buffers in int13.c, which reduces memory usage and opens up the possibility of using multi-sector reads. Extend the block-device API and the SCSI block device implementation to support multi-sector reads. Update iscsi.c to use user buffers. Move the obsolete portions of realmode.h to old_realmode.h. MS-DOS now boots an order of magnitude faster over iSCSI (~10 seconds from power-up to C:> prompt in bochs). --- src/include/gpxe/blockdev.h | 8 ++++++-- src/include/gpxe/scsi.h | 5 +++-- src/include/gpxe/uaccess.h | 24 ++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 src/include/gpxe/uaccess.h (limited to 'src/include') diff --git a/src/include/gpxe/blockdev.h b/src/include/gpxe/blockdev.h index 59f5bf746..467ed1d9d 100644 --- a/src/include/gpxe/blockdev.h +++ b/src/include/gpxe/blockdev.h @@ -8,6 +8,8 @@ * */ +#include + /** A block device */ struct block_device { /** Block size */ @@ -19,21 +21,23 @@ struct block_device { * * @v blockdev Block device * @v block Block number + * @v count Block count * @v buffer Data buffer * @ret rc Return status code */ int ( * read ) ( struct block_device *blockdev, uint64_t block, - void *buffer ); + unsigned long count, userptr_t buffer ); /** * Write block * * @v blockdev Block device * @v block Block number + * @v count Block count * @v buffer Data buffer * @ret rc Return status code */ int ( * write ) ( struct block_device *blockdev, uint64_t block, - const void *buffer ); + unsigned long count, userptr_t buffer ); }; #endif /* _GPXE_BLOCKDEV_H */ diff --git a/src/include/gpxe/scsi.h b/src/include/gpxe/scsi.h index dea39e162..d7da1255e 100644 --- a/src/include/gpxe/scsi.h +++ b/src/include/gpxe/scsi.h @@ -3,6 +3,7 @@ #include #include +#include /** * @defgroup scsiops SCSI operation codes @@ -123,14 +124,14 @@ struct scsi_command { /** CDB for this command */ union scsi_cdb cdb; /** Data-out buffer (may be NULL) */ - const void *data_out; + userptr_t data_out; /** Data-out buffer length * * Must be zero if @c data_out is NULL */ size_t data_out_len; /** Data-in buffer (may be NULL) */ - void *data_in; + userptr_t data_in; /** Data-in buffer length * * Must be zero if @c data_in is NULL diff --git a/src/include/gpxe/uaccess.h b/src/include/gpxe/uaccess.h new file mode 100644 index 000000000..38853bfbc --- /dev/null +++ b/src/include/gpxe/uaccess.h @@ -0,0 +1,24 @@ +#ifndef _GPXE_UACCESS_H +#define _GPXE_UACCESS_H + +/** + * @file + * + * Access to external ("user") memory + * + * gPXE often needs to transfer data between internal and external + * buffers. On i386, the external buffers may require access via a + * different segment, and the buffer address cannot be encoded into a + * simple void * pointer. The @c userptr_t type encapsulates the + * information needed to identify an external buffer, and the + * copy_to_user() and copy_from_user() functions provide methods for + * transferring data between internal and external buffers. + * + * Note that userptr_t is an opaque type; in particular, performing + * arithmetic upon a userptr_t is not allowed. + * + */ + +#include + +#endif /* _GPXE_UACCESS_H */ -- cgit v1.2.3-55-g7522