/[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.10 by neal, Tue Mar 8 17:44:53 2005 UTC revision 1.11 by neal, Wed Apr 6 14:07:29 2005 UTC
# Line 1  Line 1 
1  /* physmem.c - Generic definitions.  /* physmem.h - Interfaces exported by physmem.
2     Copyright (C) 2003, 2005 Free Software Foundation, Inc.     Copyright (C) 2004, 2005 Free Software Foundation, Inc.
3     Written by Neal H. Walfield <neal@gnu.org>.     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.
# Line 19  Line 19 
19     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
20     USA.  */     USA.  */
21    
22  #include <errno.h>  #ifndef HURD_PHYSMEM_H
23  #include <l4.h>  #define HURD_PHYSMEM_H
 #include <hurd/btree.h>  
 #include <hurd/cap-server.h>  
24    
25  #include <compiler.h>  /* Execute permission.  */
26    #define HURD_PM_CONT_EXECUTE            (1 << 0)
27    /* Write permission.  */
28    #define HURD_PM_CONT_WRITE              (1 << 1)
29    /* Read permission.  */
30    #define HURD_PM_CONT_READ               (1 << 2)
31    /* Read and write permission.  */
32    #define HURD_PM_CONT_RW                 (HURD_PM_CONT_READ|HURD_PM_CONT_WRITE)
33    /* Read, write and execute.  */
34    #define HURD_PM_CONT_RWX                (HURD_PM_CONT_RW|HURD_PM_CONT_EXECUTE)
35    
36    /* Don't copy on write (COW), simply share (a la SYSV SHM).  */
37    #define HURD_PM_CONT_COPY_SHARED        (1 << 3)
38    /* Don't copy the region, move it.  */
39    #define HURD_PM_CONT_COPY_MOVE          (1 << 4)
40    
41    /* Either completely fail or completely succeed: don't partially
42       succeed.  */
43    #define HURD_PM_CONT_ALL_OR_NONE        (1 << 8)
44    
45    /* Do not fail if the specified identifier is already in use.
46       Instead, deallocate the current frame and allocate a new one in its
47       place.  This is useful only to shortcut explicit deallocation
48       requests; using it to avoid EEXIST error messages will lead to
49       problems as it suggests that the client is not keep track of
50       frames.  */
51    #define HURD_PM_CONT_ALLOC_SQUASH       (1 << 9)
52    /* Allocate extra frames if needed.  */
53    #define HURD_PM_CONT_ALLOC_EXTRA        (1 << 10)
54    /* Only allocate frames suitable for DMA.  */
55    #define HURD_PM_CONT_ALLOC_DMA          (1 << 11)
56    
57    /* RPC Identifiers.  */
58    enum
59      {
60        hurd_pm_container_create_id = 130,
61        hurd_pm_container_share_id,
62        hurd_pm_container_allocate_id,
63        hurd_pm_container_deallocate_id,
64        hurd_pm_container_map_id,
65        hurd_pm_container_copy_id
66      };
67    
68    #include <hurd/types.h>
69    
70  #include "output.h"  /* Memory control object.  */
71    typedef hurd_cap_handle_t hurd_pm_control_t;
72    
73    /* Container.  */
74  /* The program name.  */  typedef hurd_cap_handle_t hurd_pm_container_t;
 extern char program_name[];  
   
 #define BUG_ADDRESS     "<bug-hurd@gnu.org>"  
   
 int main (int argc, char *argv[]);  
   
   
 /* The following function must be defined by the architecture  
    dependent code.  */  
   
 /* Switch execution transparently to thread TO.  The thread FROM,  
    which must be the current thread, will be halted.  */  
 void switch_thread (l4_thread_id_t from, l4_thread_id_t to);  
   
   
 /* Return true if INDEX lies within (START, START+SIZE-1)  
    inclusive.  */  
 static bool  
 within (l4_word_t index, l4_word_t start, l4_word_t size)  
 {  
   return index >= start && index < start + size;  
 }  
   
 /* Return true if (INDEX1, INDEX1+SIZE1-1) inclusive overlaps with  
    (INDEX2, INDEX2+SIZE2-1) inclusive.  */  
 static bool  
 overlap (l4_word_t index1, l4_word_t size1, l4_word_t index2, l4_word_t size2)  
 {  
   return  
     /* Is the start of the first region within the second?  
           2  1  2  1  
        or 2  1  1  2  */  
     within (index1, index2, size2)  
     /* Is the end of the first region within the second?  
           1  2  1  2  
        or 2  1  1  2  */  
     || within (index1 + size1 - 1, index2, size2)  
     /* Is start of the second region within the first?  
           1  2  1  2  
        or 1  2  2  1 */  
     || within (index2, index1, size1);  
   
   /* We have implicitly checked if the end of the second region is  
      within the first (i.e. within (index2 + size2 - 1, index1, size1))  
           2  1  2  1  
        or 1  2  2  1  
      in check 1 and check 3.  */  
 }  
   
 /* A region of memory.  */  
 struct region  
 {  
   /* Start of the region.  */  
   uintptr_t start;  
   /* And its extent.  */  
   size_t size;  
 };  
   
 static inline int  
 region_compare (const struct region *a, const struct region *b)  
 {  
   if (overlap (a->start, a->size, b->start, b->size))  
     return 0;  
   else  
     return a->start - b->start;  
 }  
   
 /* Forward.  */  
 struct frame_entry;  
   
 /* A frame referrs directly to physical memory.  Exactly one frame  
    structure refers to each piece of allocated (to users, i.e. not  
    internal) physical memory.  */  
 struct frame  
 {  
   /* One reference per frame entry plus any active users.  */  
   int refs;  
   
   /* The physical memory allocated to this frame.  This is allocated  
      lazily.  If the address portion is 0, memory has not yet been  
      allocated.  */  
   l4_fpage_t memory;  
   
   /* If a mapping has been made since the last time this frame was  
      unmapped.  This does not mean that it actually is mapped as users  
      can unmap it themselves.  */  
   bool may_be_mapped;  
   
   /* Number of extant copy on writes.  */  
   int cow;  
   
   /* List of frame entries referring to this frame.  */  
   struct frame_entry *frame_entries;  
 };  
   
 /* Regions in containers refer to physical memory.  Multiple regions  
    may refer to the same phsyical memory (thereby allowing sharing and  
    COW).  Every region has its own frame entry which contains the  
    per-region state.  FRAME refers to the physical memory.  */  
 struct frame_entry  
 {  
   /* The name of this region within the containing container.  */  
   struct region region;  
   /* The physical memory backing this region.  */  
   struct frame *frame;  
   /* The frame entry may not reference all of the physical memory in  
      FRAME (due to partial sharing, etc).  This is the offset to the  
      start of the memory which this frame entry uses.  */  
   size_t frame_offset;  
   
   hurd_btree_node_t node;  
   
   /* The list entry for FRAME's list of frame entries referring to  
      itself.  */  
   struct frame_entry *next;  
   struct frame_entry **prevp;  
 };  
   
 BTREE_CLASS(frame_entry, struct frame_entry, struct region, region,  
             node, region_compare)  
   
 struct container  
 {  
   pthread_mutex_t lock;  
   /* List of allocate frames in this container.  */  
   hurd_btree_frame_entry_t frame_entries;  
 };  
   
 /* Allocate an uninitialized frame entry structure.  Return NULL if  
    there is insufficient memory.  */  
 extern struct frame_entry *frame_entry_alloc (void);  
   
 /* Deallocate frame entry FRAME_ENTRY.  NB: this function does not  
    deinitialize any resources FRAME_ENTRY may still reference.  It is  
    the dual of frame_entry_alloc.  */  
 extern void frame_entry_dealloc (struct frame_entry *frame_entry);  
   
 /* Initialize the previously uninitialized frame entry structure  
    FRAME_ENTRY to cover the region starting at byte START and  
    extending SIZE bytes on container CONT.  SIZE must be a power of 2.  
    CONT must be locked.  Physical memory is reserved, however, it is  
    not allocated until a frame is attached and that frame is bound  
    using frame_memory_bind.  
   
    If the specified region overlaps with any in the container, EEXIST  
    is returned.  */  
 extern error_t frame_entry_new (struct container *cont,  
                                 struct frame_entry *frame_entry,  
                                 uintptr_t start, size_t size);  
   
 /* Initialize the previously uninitialized frame entry structure  
    FRAME_ENTRY to cover the region starting at byte START and  
    extending SIZE bytes in container CONT.  FRAME_ENTRY refers to the  
    physical memory in FRAME starting at offset OFFSET (hence when  
    OFFSET is non-zero, FRAME_ENTRY only refers to a portion of FRAME).  
    SIZE must be a power of 2.  CONT must be locked.  A reference is  
    added to FRAME.  
   
    If the specified region overlaps with any in the container, EEXIST  
    is returned.  */  
 extern error_t frame_entry_use_frame (struct container *cont,  
                                       struct frame_entry *frame_entry,  
                                       uintptr_t start, size_t size,  
                                       struct frame *frame,  
                                       size_t offset);  
   
 /* Deinitialize frame entry FRAME_ENTRY which is in the locked  
    container CONT dereferencing any frame it may be using in the  
    process.  This does *not* deallocate the FRAME_ENTRY structure.  
    This must still be done using frame_entry_dealloc.  */  
 extern void frame_entry_drop (struct container *cont,  
                               struct frame_entry *frame_entry);  
   
 /* Find a frame entry which overlaps with the region START+SIZE and  
    return it.  Returns NULL if no frame entry in container overlaps  
    with the provided region.  CONT must be locked.  */  
 extern struct frame_entry *frame_entry_find (struct container *cont,  
                                              uintptr_t start,  
                                              size_t size);  
   
 /* Attach frame entry FRAME_ENTRY into container CONT.  FRAME_ENTRY  
    must not currently be part of any container.  Returns EEXIST if  
    FRAME_ENTRY overlaps with a frame entry in CONT.  */  
 extern error_t frame_entry_attach (struct container *cont,  
                                    struct frame_entry *frame_entry);  
   
 /* Detach frame entry FRAME_ENTRY from container CONT.  */  
 extern void frame_entry_detach (struct container *cont,  
                                 struct frame_entry *frame_entry);  
   
 /* Allocate a frame structure holding SIZE bytes.  Physical memory  
    must have already been reserved (by, e.g. a prior frame_entry_alloc  
    call).  Allocation of the physical memory is deferred until  
    frame_memory_alloc is called.  The returned frame has a single  
    reference and is locked.  */  
 extern struct frame *frame_alloc (size_t size);  
   
 /* Bind frame FRAME to physical memory if not already done.  */  
 static inline void  
 frame_memory_bind (struct frame *frame)  
 {  
   /* Actually allocates the physical memory.  */  
   extern void frame_memory_alloc (struct frame *frame);  
   
   if (! l4_address (frame->memory))  
     frame_memory_alloc (frame);  
 }  
   
 /* Add a reference to frame FRAME.  */  
 static inline void  
 frame_ref (struct frame *frame)  
 {  
   frame->refs ++;  
 }  
   
 /* Release a reference to frame FRAME.  FRAME must be locked.  When  
    the last reference is removed, any exant client mappings will be  
    unmapped, any physical memory will be deallocated and FRAME will be  
    freed.  */  
 extern void frame_deref (struct frame *frame);  
   
 /* Add FRAME_ENTRY as a user of FRAME.  A reference for FRAME_ENTRY  
    must already be held.  */  
 extern void frame_add_user (struct frame *frame,  
                             struct frame_entry *frame_entry);  
   
 /* Remove FRAME_ENTRY as a user of FRAME.  A reference to frame is  
    released in the process.  */  
 extern void frame_drop_user (struct frame *frame,  
                              struct frame_entry *frame_entry);  
   
 /* Allocate a new container object covering the NR_FPAGES fpages  
    listed in FPAGES.  The object returned is locked and has one  
    reference.  */  
 extern error_t container_alloc (l4_word_t nr_fpages, l4_word_t *fpages,  
                                 struct container **r_container);  
75    
76    #endif /* HURD_PHYSMEM_H */

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.11

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