/[hurd]/hurd-l4/physmem/physmem.h
ViewVC logotype

Diff of /hurd-l4/physmem/physmem.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.8 by marcus, Mon Nov 1 20:54:00 2004 UTC revision 1.9 by neal, Tue Jan 11 18:15:26 2005 UTC
# Line 1  Line 1 
1  /* physmem.h - Generic definitions.  /* physmem.c - Generic definitions.
2     Copyright (C) 2003 Free Software Foundation, Inc.     Copyright (C) 2003, 2005 Free Software Foundation, Inc.
3     Written by Marcus Brinkmann.     Written by Neal H. Walfield <neal@gnu.org>.
4    
5     This file is part of the GNU Hurd.     This file is part of the GNU Hurd.
6    
# Line 8  Line 8 
8     modify it under the terms of the GNU General Public License as     modify it under the terms of the GNU General Public License as
9     published by the Free Software Foundation; either version 2, or (at     published by the Free Software Foundation; either version 2, or (at
10     your option) any later version.     your option) any later version.
11      
12     The GNU Hurd is distributed in the hope that it will be useful, but     The GNU Hurd is distributed in the hope that it will be useful, but
13     WITHOUT ANY WARRANTY; without even the implied warranty of     WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15     General Public License for more details.     General Public License for more details.
16      
17     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software     along with the GNU Hurd; see the file COPYING.  If not, write to
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
20       USA.  */
21    
22  #include <errno.h>  #include <errno.h>
   
23  #include <l4.h>  #include <l4.h>
24    #include <hurd/btree.h>
25  #include <hurd/cap-server.h>  #include <hurd/cap-server.h>
26    
27  #include "string.h"  #include <compiler.h>
28    
29  #include "output.h"  #include "output.h"
30    
31    
# Line 43  int main (int argc, char *argv[]); Line 45  int main (int argc, char *argv[]);
45  void switch_thread (l4_thread_id_t from, l4_thread_id_t to);  void switch_thread (l4_thread_id_t from, l4_thread_id_t to);
46    
47    
48  /* Container objects.  */  /* Return true if INDEX lies within (START, START+SIZE-1)
49       inclusive.  */
50    static bool
51    within (l4_word_t index, l4_word_t start, l4_word_t size)
52    {
53      return index >= start && index < start + size;
54    }
55    
56  struct container  /* Return true if (INDEX1, INDEX1+SIZE1-1) inclusive overlaps with
57       (INDEX2, INDEX2+SIZE2-1) inclusive.  */
58    static bool
59    overlap (l4_word_t index1, l4_word_t size1, l4_word_t index2, l4_word_t size2)
60    {
61      return
62        /* Is the start of the first region within the second?
63              2  1  2  1
64           or 2  1  1  2  */
65        within (index1, index2, size2)
66        /* Is the end of the first region within the second?
67              1  2  1  2
68           or 2  1  1  2  */
69        || within (index1 + size1 - 1, index2, size2)
70        /* Is start of the second region within the first?
71              1  2  1  2
72           or 1  2  2  1 */
73        || within (index2, index1, size1);
74    
75      /* We have implicitly checked if the end of the second region is
76         within the first (i.e. within (index2 + size2 - 1, index1, size1))
77              2  1  2  1
78           or 1  2  2  1
79         in check 1 and check 3.  */
80    }
81    
82    /* A region of memory.  */
83    struct region
84    {
85      /* Start of the region.  */
86      uintptr_t start;
87      /* And its extent.  */
88      size_t size;
89    };
90    
91    static inline int
92    region_compare (const struct region *a, const struct region *b)
93    {
94      if (overlap (a->start, a->size, b->start, b->size))
95        return 0;
96      else
97        return a->start - b->start;
98    }
99    
100    /* Forward.  */
101    struct frame_entry;
102    
103    /* A frame referrs directly to physical memory.  Any allocated memory
104       (for users) will have exactly one frame structure referring to
105       it.  */
106    struct frame
107  {  {
108    /* For now, a container is nothing more than a contiguous,    /* One reference per frame entry plus any active users.  */
109       page-aligned range of memory.  This is the reason why    int refs;
      L4_FPAGE_SPAN_MAX fpages are sufficient.  */  
   l4_fpage_t fpages[L4_FPAGE_SPAN_MAX];  
110    
111    /* The number of entries in FPAGES.  */    /* The physical memory allocated to this frame.  This is allocated
112    l4_word_t nr_fpages;       lazily.  If this address portion is NULL, no memory has yet been
113         allocated.  */
114      l4_fpage_t memory;
115    
116      /* If a mapping has been made since the last time this frame was
117         unmapped.  This does not mean that it actually is mapped as any
118         users could have unmapped it themselves.  */
119      bool may_be_mapped;
120    
121      /* List of frame entries referring to this frame.  */
122      struct frame_entry *frame_entries;
123  };  };
 typedef struct container *container_t;  
124    
125    /* Regions in containers refer to physical memory.  Multiple regions
126       may refer to the same phsyical memory (thereby allowing sharing and
127       COW).  Every region has its own frame entry which contains the
128       per-region state.  FRAME refers to the physical memory.  */
129    struct frame_entry
130    {
131      /* The name of this region within the containing container.  */
132      struct region region;
133      /* The physical memory backing the region.  */
134      struct frame *frame;
135      /* The frame entry may not reference all of the physical memory in
136         FRAME (due to partial sharing, etc).  This offset to the start of
137         the memory which this frame entry uses.  */
138      size_t frame_offset;
139    
140      hurd_btree_node_t node;
141    
142      /* The list entry for FRAME's list of frame entries referring to
143         itself.  */
144      struct frame_entry *next;
145      struct frame_entry **prevp;
146    };
147    
148  /* Initialize the container class subsystem.  */  BTREE_CLASS(frame_entry, struct frame_entry, struct region, region,
149  error_t container_class_init ();              node, region_compare)
150    
151    struct container
152    {
153      pthread_mutex_t lock;
154      /* List of allocate frames in this container.  */
155      hurd_btree_frame_entry_t frame_entries;
156    };
157    
158    /* Allocate an uninitialized frame entry structure.  Returns NULL if
159       there is insufficient memory.  */
160    extern struct frame_entry *frame_entry_alloc (void);
161    
162    /* Deallocate frame entry FRAME_ENTRY.  NB: this function does not
163       deinitialize any resources FRAME_ENTRY may still reference.  It is
164       the dual of frame_entry_alloc.  */
165    extern void frame_entry_dealloc (struct frame_entry *frame_entry);
166    
167    /* Initialize the previously unitialized frame entry structure,
168       FRAME_ENTRY to cover the region starting at byte START and
169       extending SIZE bytes on container CONT.  SIZE must be a power of 2.
170       CONT must be locked.  Physical memory is reserved, however, it is
171       not allocated until a frame is attached and that frame is bound
172       using frame_memory_bind.
173    
174       If the specified region overlaps with any in the container, EEXIST
175       is returned.  */
176    extern error_t frame_entry_new (struct container *cont,
177                                    struct frame_entry *frame_entry,
178                                    uintptr_t start, size_t size);
179    
180    /* Initialize the previously uninitialized frame entry structure
181       FRAME_ENTRY to cover the region starting at byte START and
182       extending SIZE bytes on container CONT.  If FRAME is non-NULL,
183       FRAME_ENTRY refers to the physical memory in FRAME starting at
184       offset OFFSET (hence when OFFSET is non-zero, FRAME_ENTRY only
185       refers to a portion of FRAME).  SIZE must be a power of 2.  CONT
186       must be locked.  A reference is added to FRAME.
187    
188       If the specified region overlaps with any in the container, EEXIST
189       is returned.  */
190    extern error_t frame_entry_use (struct container *cont,
191                                    struct frame_entry *frame_entry,
192                                    uintptr_t start, size_t size,
193                                    struct frame *frame,
194                                    size_t offset);
195    
196    /* Deinitialize frame entry FRAME_ENTRY which is in the locked
197       container CONT dereferencing any frame it may be using in the
198       process.  This does *not* deallocate the FRAME_ENTRY structure.
199       This must still be done using frame_entry_dealloc.  */
200    extern void frame_entry_drop (struct container *cont,
201                                  struct frame_entry *frame_entry);
202    
203    /* Find a frame entry which overlaps with the region START+SIZE and
204       return it.  Returns NULL if no frame entry in container overlaps
205       with the provided region.  CONT must be locked.  */
206    extern struct frame_entry *frame_entry_find (struct container *cont,
207                                                 uintptr_t start,
208                                                 size_t size);
209    
210    /* Attach frame entry FRAME_ENTRY into container CONT.  FRAME_ENTRY
211       must not currently be part of any container.  Returns EEXIST if
212       FRAME_ENTRY overlaps with a frame entry in CONT.  */
213    extern error_t frame_entry_attach (struct container *cont,
214                                       struct frame_entry *frame_entry);
215    
216    /* Detach frame entry FRAME_ENTRY from container CONT.  */
217    extern void frame_entry_detach (struct container *cont,
218                                    struct frame_entry *frame_entry);
219    
220    /* Allocate a frame structure holding SIZE bytes.  Physical memory
221       must have already been reserved (by, e.g. a prior frame_entry_alloc
222       call).  Allocation of the physical memory is deferred until
223       frame_memory_alloc is called.  The returned frame has a single
224       reference and is locked.  */
225    extern struct frame *frame_alloc (size_t size);
226    
227    /* Bind frame FRAME to physical memory if not already done.  */
228    static inline void
229    frame_memory_bind (struct frame *frame)
230    {
231      /* Actually allocates the physical memory.  */
232      extern void frame_memory_alloc (struct frame *frame);
233    
234      if (! l4_address (frame->memory))
235        frame_memory_alloc (frame);
236    }
237    
238    /* Add a reference to frame FRAME.  */
239    static inline void
240    frame_ref (struct frame *frame)
241    {
242      frame->refs ++;
243    }
244    
245    /* Release a reference to frame FRAME.  FRAME must be locked.  When
246       the last reference is removed, any exant client mappings will be
247       unmapped, any physical memory will be deallocated and FRAME will be
248       freed.  */
249    extern void frame_deref (struct frame *frame);
250    
251    /* Add FRAME_ENTRY as a user of FRAME.  A reference for FRAME_ENTRY
252       must already be held.  */
253    extern void frame_use (struct frame *frame,
254                           struct frame_entry *frame_entry);
255    
256    /* Remove FRAME_ENTRY as a user of FRAME.  A reference to frame is
257       released in the process.  */
258    extern void frame_drop (struct frame *frame,
259                            struct frame_entry *frame_entry);
260    
261  /* Allocate a new container object covering the NR_FPAGES fpages  /* Allocate a new container object covering the NR_FPAGES fpages
262     listed in FPAGES.  The object returned is locked and has one     listed in FPAGES.  The object returned is locked and has one
263     reference.  */     reference.  */
264  error_t container_alloc (l4_word_t nr_fpages, l4_word_t *fpages,  extern error_t container_alloc (l4_word_t nr_fpages, l4_word_t *fpages,
265                           container_t  *r_container);                                  struct container **r_container);
266    

Legend:
Removed from v.1.8  
changed lines
  Added in v.1.9

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26