summaryrefslogtreecommitdiffstats
path: root/src/arch/i386/include
diff options
context:
space:
mode:
authorMichael Brown2006-05-19 17:06:51 +0200
committerMichael Brown2006-05-19 17:06:51 +0200
commitd48d0fb1bb53262bf44a03dbe8388529f1566a1c (patch)
tree31081f33dbeb48c42d2e4cf806570853162781d9 /src/arch/i386/include
parentUse typeof(sizeof(...)) to define a size_t. This stops gcc complaining (diff)
downloadipxe-d48d0fb1bb53262bf44a03dbe8388529f1566a1c.tar.gz
ipxe-d48d0fb1bb53262bf44a03dbe8388529f1566a1c.tar.xz
ipxe-d48d0fb1bb53262bf44a03dbe8388529f1566a1c.zip
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).
Diffstat (limited to 'src/arch/i386/include')
-rw-r--r--src/arch/i386/include/bits/uaccess.h6
-rw-r--r--src/arch/i386/include/librm.h63
-rw-r--r--src/arch/i386/include/old_realmode.h22
-rw-r--r--src/arch/i386/include/realmode.h19
4 files changed, 91 insertions, 19 deletions
diff --git a/src/arch/i386/include/bits/uaccess.h b/src/arch/i386/include/bits/uaccess.h
new file mode 100644
index 000000000..9c6d0c214
--- /dev/null
+++ b/src/arch/i386/include/bits/uaccess.h
@@ -0,0 +1,6 @@
+#ifndef _BITS_UACCESS_H
+#define _BITS_UACCESS_H
+
+#include <realmode.h>
+
+#endif /* _BITS_UACCESS_H */
diff --git a/src/arch/i386/include/librm.h b/src/arch/i386/include/librm.h
index af1470b91..17fcc78ba 100644
--- a/src/arch/i386/include/librm.h
+++ b/src/arch/i386/include/librm.h
@@ -92,6 +92,69 @@ copy_from_real_librm ( void *dest, unsigned int src_seg,
#define put_real put_real_librm
#define get_real get_real_librm
+/**
+ * A pointer to a user buffer
+ *
+ * Even though we could just use a void *, we use an intptr_t so that
+ * attempts to use normal pointers show up as compiler warnings. Such
+ * code is actually valid for librm, but not for libkir (i.e. under
+ * KEEP_IT_REAL), so it's good to have the warnings even under librm.
+ */
+typedef intptr_t userptr_t;
+
+/**
+ * Copy data to user buffer
+ *
+ * @v buffer User buffer
+ * @v offset Offset within user buffer
+ * @v src Source
+ * @v len Length
+ */
+static inline __attribute__ (( always_inline )) void
+copy_to_user ( userptr_t buffer, off_t offset, const void *src, size_t len ) {
+ memcpy ( ( void * ) buffer + offset, src, len );
+}
+
+/**
+ * Copy data from user buffer
+ *
+ * @v dest Destination
+ * @v buffer User buffer
+ * @v offset Offset within user buffer
+ * @v len Length
+ */
+static inline __attribute__ (( always_inline )) void
+copy_from_user ( void *dest, userptr_t buffer, off_t offset, size_t len ) {
+ memcpy ( dest, ( void * ) buffer + offset, len );
+}
+
+/**
+ * Convert virtual address to user buffer
+ *
+ * @v virtual Virtual address
+ * @ret buffer User buffer
+ *
+ * This constructs a user buffer from an ordinary pointer. Use it
+ * when you need to pass a pointer to an internal buffer to a function
+ * that expects a @c userptr_t.
+ */
+static inline __attribute__ (( always_inline )) userptr_t
+virt_to_user ( void * virtual ) {
+ return ( ( intptr_t ) virtual );
+}
+
+/**
+ * Convert segment:offset address to user buffer
+ *
+ * @v segment Real-mode segment
+ * @v offset Real-mode offset
+ * @ret buffer User buffer
+ */
+static inline __attribute__ (( always_inline )) userptr_t
+real_to_user ( unsigned int segment, unsigned int offset ) {
+ return virt_to_user ( VIRTUAL ( segment, offset ) );
+}
+
/* Copy to/from real-mode stack */
extern uint16_t copy_to_rm_stack ( void *data, size_t size );
extern void remove_from_rm_stack ( void *data, size_t size );
diff --git a/src/arch/i386/include/old_realmode.h b/src/arch/i386/include/old_realmode.h
new file mode 100644
index 000000000..3dde8c810
--- /dev/null
+++ b/src/arch/i386/include/old_realmode.h
@@ -0,0 +1,22 @@
+#ifndef _OLD_REALMODE_H
+#define _OLD_REALMODE_H
+
+#include <realmode.h>
+
+#warning "Anything including this header is obsolete and must be rewritten"
+
+/* Just for now */
+#define SEGMENT(x) ( virt_to_phys ( x ) >> 4 )
+#define OFFSET(x) ( virt_to_phys ( x ) & 0xf )
+#define SEGOFF(x) { OFFSET(x), SEGMENT(x) }
+
+/* To make basemem.c compile */
+extern int lock_real_mode_stack;
+extern char *real_mode_stack;
+extern char real_mode_stack_size[];
+
+#define RM_FRAGMENT(name,asm) \
+ void name ( void ) {} \
+ extern char name ## _size[];
+
+#endif /* _OLD_REALMODE_H */
diff --git a/src/arch/i386/include/realmode.h b/src/arch/i386/include/realmode.h
index 07d41e544..10a28b237 100644
--- a/src/arch/i386/include/realmode.h
+++ b/src/arch/i386/include/realmode.h
@@ -149,25 +149,6 @@ typedef struct segoff segoff_t;
* "(discard)" in the above code.
*/
-#warning "realmode.h contains placeholders for obsolete macros"
-
-
-/* Just for now */
-#define SEGMENT(x) ( virt_to_phys ( x ) >> 4 )
-#define OFFSET(x) ( virt_to_phys ( x ) & 0xf )
-#define SEGOFF(x) { OFFSET(x), SEGMENT(x) }
-
-/* To make basemem.c compile */
-extern int lock_real_mode_stack;
-extern char *real_mode_stack;
-extern char real_mode_stack_size[];
-
-#define RM_FRAGMENT(name,asm) \
- void name ( void ) {} \
- extern char name ## _size[];
-
-
-
#endif /* ASSEMBLY */
#endif /* REALMODE_H */