Don't include etherboot.h; we get a circular dependency
[people/xl0/gpxe.git] / src / include / buffer.h
1 #ifndef BUFFER_H
2 #define BUFFER_H
3
4 #include "compiler.h"
5 #include "stdint.h"
6
7 /** @file
8  *
9  * Buffers for loading files.
10  *
11  * This file provides routines for filling a buffer with data received
12  * piecemeal, where the size of the data is not necessarily known in
13  * advance.
14  *
15  * Some protocols do not provide a mechanism for us to know the size
16  * of the file before we happen to receive a particular block
17  * (e.g. the final block in an MTFTP transfer).  In addition, some
18  * protocols (all the multicast protocols plus any TCP-based protocol)
19  * can, in theory, provide the data in any order.
20  *
21  * Rather than requiring each protocol to implement its own equivalent
22  * of "dd" to arrange the data into well-sized pieces before handing
23  * off to the image loader, we provide these generic buffer functions
24  * which assemble a file into a single contiguous block.  The whole
25  * block is then passed to the image loader.
26  *
27  * Example usage:
28  *
29  * @code
30  *
31  *   struct buffer my_buffer;
32  *   void *data;
33  *   off_t offset;
34  *   size_t len;
35  *   
36  *   // We have an area of memory [buf_start,buf_end) into which we want
37  *   // to load a file, where buf_start and buf_end are physical addresses.
38  *   buffer->start = buf_start;
39  *   buffer->end = buf_end;
40  *   init_buffer ( &buffer );
41  *   ...
42  *   while ( get_file_block ( ... ) ) {
43  *     // Downloaded block is stored in [data,data+len), and represents 
44  *     // the portion of the file at offsets [offset,offset+len)
45  *     if ( ! fill_buffer ( &buffer, data, offset, len ) ) {
46  *       // An error occurred
47  *       return 0;
48  *     }
49  *     ...
50  *   }
51  *   ...
52  *   // The whole file is now present at [buf_start,buf_start+filesize),
53  *   // where buf_start is a physical address.  The struct buffer can simply
54  *   // be discarded; there is no done_buffer() call.
55  *
56  * @endcode
57  *
58  * For a description of the internal operation, see buffer.c.
59  *
60  */
61
62 /**
63  * A buffer
64  *
65  * @c start and @c end denote the real boundaries of the buffer, and
66  * are physical addresses.  @c fill denotes the offset to the first
67  * free block in the buffer.  (If the buffer is full, @c fill will
68  * equal @c end-start.)
69  *
70  */
71 struct buffer {
72         physaddr_t      start;          /**< Start of buffer in memory */
73         physaddr_t      end;            /**< End of buffer in memory */
74         off_t           fill;           /**< Offset to first gap in buffer */
75 };
76
77 /**
78  * A free block descriptor.
79  *
80  * See buffer.c for a full description of the fields.
81  *
82  */
83 struct buffer_free_block {
84         char            tail;           /**< Tail byte marker */
85         physaddr_t      next_free;      /**< Address of next free block */
86         physaddr_t      end;            /**< End of this block */
87 } __attribute__ (( packed ));
88
89 /* Functions in buffer.c */
90
91 extern void init_buffer ( struct buffer *buffer );
92 extern int fill_buffer ( struct buffer *buffer, const void *data,
93                          off_t offset, size_t len );
94
95 #endif /* BUFFER_H */