SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

Diff markup

Differences between /drivers/mem.c (Article 7.5) and /drivers/mem.c (Article 8)


001 /* Copyright (C) 2005 David Decotigny             001 /* Copyright (C) 2005 David Decotigny
002                                                   002 
003    This program is free software; you can redi    003    This program is free software; you can redistribute it and/or
004    modify it under the terms of the GNU Genera    004    modify it under the terms of the GNU General Public License
005    as published by the Free Software Foundatio    005    as published by the Free Software Foundation; either version 2
006    of the License, or (at your option) any lat    006    of the License, or (at your option) any later version.
007                                                   007    
008    This program is distributed in the hope tha    008    This program is distributed in the hope that it will be useful,
009    but WITHOUT ANY WARRANTY; without even the     009    but WITHOUT ANY WARRANTY; without even the implied warranty of
010    MERCHANTABILITY or FITNESS FOR A PARTICULAR    010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
011    GNU General Public License for more details    011    GNU General Public License for more details.
012                                                   012    
013    You should have received a copy of the GNU     013    You should have received a copy of the GNU General Public License
014    along with this program; if not, write to t    014    along with this program; if not, write to the Free Software
015    Foundation, Inc., 59 Temple Place - Suite 3    015    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
016    USA.                                           016    USA. 
017 */                                                017 */
018                                                   018 
019 #include <sos/assert.h>                           019 #include <sos/assert.h>
020 #include <sos/kmalloc.h>                          020 #include <sos/kmalloc.h>
021 #include <sos/physmem.h>                          021 #include <sos/physmem.h>
022 #include <hwcore/paging.h>                        022 #include <hwcore/paging.h>
023 #include <sos/kmem_slab.h>                        023 #include <sos/kmem_slab.h>
024 #include <sos/list.h>                             024 #include <sos/list.h>
025 #include <hwcore/paging.h>                        025 #include <hwcore/paging.h>
026                                                   026 
027 #include "mem.h"                                  027 #include "mem.h"
028                                                   028 
029                                                   029 
030 /**                                               030 /**
031  * A mapped mem/kmem resource                     031  * A mapped mem/kmem resource
032  */                                               032  */
033 struct kernel_remapped_resource                   033 struct kernel_remapped_resource
034 {                                                 034 {
035   int ref_cnt;                                    035   int ref_cnt;
036   struct sos_umem_vmm_mapped_resource mr;         036   struct sos_umem_vmm_mapped_resource mr;
037 };                                                037 };
038                                                   038 
039                                                   039 
040 /** Called after the virtual region has been i    040 /** Called after the virtual region has been inserted inside its
041     address space */                              041     address space */
042 static void resource_ref(struct sos_umem_vmm_v    042 static void resource_ref(struct sos_umem_vmm_vr * vr)
043 {                                                 043 {
044   /* Retrieve the mem/kmem structure associate    044   /* Retrieve the mem/kmem structure associated with the mapped resource */
045   struct kernel_remapped_resource * resource;     045   struct kernel_remapped_resource * resource;
046   resource                                        046   resource
047     = (struct kernel_remapped_resource*)          047     = (struct kernel_remapped_resource*)
048     sos_umem_vmm_get_mapped_resource_of_vr(vr)    048     sos_umem_vmm_get_mapped_resource_of_vr(vr)->custom_data;
049                                                   049 
050   /* Increment ref counter */                     050   /* Increment ref counter */
051   resource->ref_cnt ++;                           051   resource->ref_cnt ++;
052 }                                                 052 }
053                                                   053 
054                                                   054 
055 /** Called when the virtual region is removed     055 /** Called when the virtual region is removed from its address
056     space */                                      056     space */
057 static void resource_unref(struct sos_umem_vmm    057 static void resource_unref(struct sos_umem_vmm_vr * vr)
058 {                                                 058 {
059   /* Retrieve the mem/kmem structure associate    059   /* Retrieve the mem/kmem structure associated with the mapped resource */
060   struct kernel_remapped_resource * resource;     060   struct kernel_remapped_resource * resource;
061   resource                                        061   resource
062     = (struct kernel_remapped_resource*)          062     = (struct kernel_remapped_resource*)
063     sos_umem_vmm_get_mapped_resource_of_vr(vr)    063     sos_umem_vmm_get_mapped_resource_of_vr(vr)->custom_data;
064                                                   064   
065   /* Decrement ref coutner */                     065   /* Decrement ref coutner */
066   SOS_ASSERT_FATAL(resource->ref_cnt > 0);        066   SOS_ASSERT_FATAL(resource->ref_cnt > 0);
067   resource->ref_cnt --;                           067   resource->ref_cnt --;
068                                                   068 
069   /* Free the resource if it becomes unused */    069   /* Free the resource if it becomes unused */
070   if (resource->ref_cnt == 0)                     070   if (resource->ref_cnt == 0)
071     sos_kfree((sos_vaddr_t)resource);             071     sos_kfree((sos_vaddr_t)resource);
072 }                                                 072 }
073                                                   073 
074                                                   074 
075 /** MOST IMPORTANT callback ! Called when a th    075 /** MOST IMPORTANT callback ! Called when a thread page faults on the
076     resource's mapping */                         076     resource's mapping */
077 static sos_ret_t kmem_page_in(struct sos_umem_    077 static sos_ret_t kmem_page_in(struct sos_umem_vmm_vr * vr,
078                               sos_uaddr_t uadd    078                               sos_uaddr_t uaddr,
079                               sos_bool_t write    079                               sos_bool_t write_access)
080 {                                                 080 {
081   sos_vaddr_t vaddr;                              081   sos_vaddr_t vaddr;
082   sos_ret_t retval = SOS_OK;                      082   sos_ret_t retval = SOS_OK;
083   sos_paddr_t ppage_paddr;                        083   sos_paddr_t ppage_paddr;
084                                                   084 
085   /* Compute address of kernel page */            085   /* Compute address of kernel page */
086   vaddr = uaddr - sos_umem_vmm_get_start_of_vr    086   vaddr = uaddr - sos_umem_vmm_get_start_of_vr(vr)
087     + sos_umem_vmm_get_offset_in_resource(vr);    087     + sos_umem_vmm_get_offset_in_resource(vr);
088                                                   088 
089   /* Don't allow demand paging of non kernel p    089   /* Don't allow demand paging of non kernel pages */
090   if (vaddr >= SOS_PAGING_BASE_USER_ADDRESS)      090   if (vaddr >= SOS_PAGING_BASE_USER_ADDRESS)
091     return -SOS_EFAULT;                           091     return -SOS_EFAULT;
092                                                   092 
093   /* Lookup physical kernel page */               093   /* Lookup physical kernel page */
094   ppage_paddr = sos_paging_get_paddr(SOS_PAGE_    094   ppage_paddr = sos_paging_get_paddr(SOS_PAGE_ALIGN_INF(vaddr));
095                                                   095 
096   /* Cannot access unmapped kernel pages */       096   /* Cannot access unmapped kernel pages */
097   if (! ppage_paddr)                              097   if (! ppage_paddr)
098     return -SOS_EFAULT;                           098     return -SOS_EFAULT;
099                                                   099   
100   /* Remap it in user space */                    100   /* Remap it in user space */
101   retval = sos_paging_map(ppage_paddr,            101   retval = sos_paging_map(ppage_paddr,
102                           SOS_PAGE_ALIGN_INF(u    102                           SOS_PAGE_ALIGN_INF(uaddr),
103                           TRUE,                   103                           TRUE,
104                           sos_umem_vmm_get_pro    104                           sos_umem_vmm_get_prot_of_vr(vr));
105                                                   105 
106   return retval;                                  106   return retval;
107 }                                                 107 }
108                                                   108 
109                                                   109 
110 /** The callbacks for a mapped kmem resource *    110 /** The callbacks for a mapped kmem resource */
111 static struct sos_umem_vmm_vr_ops kmem_ops = (    111 static struct sos_umem_vmm_vr_ops kmem_ops = (struct sos_umem_vmm_vr_ops)
112 {                                                 112 {
113   .ref     = resource_ref,                        113   .ref     = resource_ref,
114   .unref   = resource_unref,                      114   .unref   = resource_unref,
115   .page_in = kmem_page_in,                        115   .page_in = kmem_page_in,
116 };                                                116 };
117                                                   117 
118                                                   118 
119 /** The callback that gets called when the res    119 /** The callback that gets called when the resource gets mapped */
120 static sos_ret_t kmem_mmap(struct sos_umem_vmm    120 static sos_ret_t kmem_mmap(struct sos_umem_vmm_vr *vr)
121 {                                                 121 {
122   return sos_umem_vmm_set_ops_of_vr(vr, &kmem_    122   return sos_umem_vmm_set_ops_of_vr(vr, &kmem_ops);
123 }                                                 123 }
124                                                   124 
125                                                   125 
126 /** The function responsible for mapping the /    126 /** The function responsible for mapping the /dev/kmem resource in
127     user space */                                 127     user space */
128 sos_ret_t sos_dev_kmem_map(struct sos_umem_vmm    128 sos_ret_t sos_dev_kmem_map(struct sos_umem_vmm_as * dest_as,
129                            sos_uaddr_t *uaddr,    129                            sos_uaddr_t *uaddr,
130                            sos_size_t size,       130                            sos_size_t size,
131                            sos_vaddr_t offset,    131                            sos_vaddr_t offset,
132                            sos_ui32_t access_r    132                            sos_ui32_t access_rights,
133                            sos_ui32_t flags)      133                            sos_ui32_t flags)
134 {                                                 134 {
135   sos_ret_t retval;                               135   sos_ret_t retval;
136   struct kernel_remapped_resource * kmem_resou    136   struct kernel_remapped_resource * kmem_resource;
137                                                   137 
138   /* Allocate a new "descriptor" for the resou    138   /* Allocate a new "descriptor" for the resource */
139   kmem_resource                                   139   kmem_resource
140     = (struct kernel_remapped_resource*) sos_k    140     = (struct kernel_remapped_resource*) sos_kmalloc(sizeof(*kmem_resource),
141                                                   141                                                      0);
142   if (! kmem_resource)                            142   if (! kmem_resource)
143     return -SOS_ENOMEM;                           143     return -SOS_ENOMEM;
144                                                   144 
145   memset(kmem_resource, 0x0, sizeof(*kmem_reso    145   memset(kmem_resource, 0x0, sizeof(*kmem_resource));
146   kmem_resource->mr.allowed_access_rights         146   kmem_resource->mr.allowed_access_rights 
147     = SOS_VM_MAP_PROT_READ                        147     = SOS_VM_MAP_PROT_READ
148     | SOS_VM_MAP_PROT_WRITE                       148     | SOS_VM_MAP_PROT_WRITE
149     | SOS_VM_MAP_PROT_EXEC;                       149     | SOS_VM_MAP_PROT_EXEC;
150   kmem_resource->mr.custom_data    = kmem_reso    150   kmem_resource->mr.custom_data    = kmem_resource;
151   kmem_resource->mr.mmap           = kmem_mmap    151   kmem_resource->mr.mmap           = kmem_mmap;
152                                                   152 
153   /* Map it in user space */                      153   /* Map it in user space */
154   retval = sos_umem_vmm_map(dest_as, uaddr, si    154   retval = sos_umem_vmm_map(dest_as, uaddr, size,
155                             access_rights, fla    155                             access_rights, flags,
156                             & kmem_resource->m    156                             & kmem_resource->mr, offset);
157   if (SOS_OK != retval)                           157   if (SOS_OK != retval)
158     {                                             158     {
159       sos_kfree((sos_vaddr_t)kmem_resource);      159       sos_kfree((sos_vaddr_t)kmem_resource);
160       return retval;                              160       return retval;
161     }                                             161     }
162                                                   162 
163   return SOS_OK;                                  163   return SOS_OK;
164 }                                                 164 }
165                                                   165 
166                                                   166 
167 /** MOST IMPORTANT callback ! Called when a th    167 /** MOST IMPORTANT callback ! Called when a thread page faults on the
168     resource's mapping */                         168     resource's mapping */
169 static sos_ret_t physmem_page_in(struct sos_um    169 static sos_ret_t physmem_page_in(struct sos_umem_vmm_vr * vr,
170                                  sos_uaddr_t u    170                                  sos_uaddr_t uaddr,
171                                  sos_bool_t wr    171                                  sos_bool_t write_access)
172 {                                                 172 {
173   sos_ret_t retval = SOS_OK;                      173   sos_ret_t retval = SOS_OK;
174   sos_paddr_t ppage_paddr;                        174   sos_paddr_t ppage_paddr;
175                                                   175 
176   /* Compute address of kernel page */            176   /* Compute address of kernel page */
177   ppage_paddr = uaddr - sos_umem_vmm_get_start    177   ppage_paddr = uaddr - sos_umem_vmm_get_start_of_vr(vr)
178     + sos_umem_vmm_get_offset_in_resource(vr);    178     + sos_umem_vmm_get_offset_in_resource(vr);
179                                                   179 
180   /* Remap page in user space */                  180   /* Remap page in user space */
181   retval = sos_paging_map(SOS_PAGE_ALIGN_INF(p    181   retval = sos_paging_map(SOS_PAGE_ALIGN_INF(ppage_paddr),
182                           SOS_PAGE_ALIGN_INF(u    182                           SOS_PAGE_ALIGN_INF(uaddr),
183                           TRUE,                   183                           TRUE,
184                           sos_umem_vmm_get_pro    184                           sos_umem_vmm_get_prot_of_vr(vr));
185   return retval;                                  185   return retval;
186 }                                                 186 }
187                                                   187 
188                                                   188 
189 /** The callbacks for a mapped physmem resourc    189 /** The callbacks for a mapped physmem resource */
190 static struct sos_umem_vmm_vr_ops physmem_ops     190 static struct sos_umem_vmm_vr_ops physmem_ops = (struct sos_umem_vmm_vr_ops)
191 {                                                 191 {
192   .ref     = resource_ref,                        192   .ref     = resource_ref,
193   .unref   = resource_unref,                      193   .unref   = resource_unref,
194   .page_in = physmem_page_in,                     194   .page_in = physmem_page_in,
195 };                                                195 };
196                                                   196 
197                                                   197 
198 /** The callback that gets called when the res    198 /** The callback that gets called when the resource gets mapped */
199 static sos_ret_t physmem_mmap(struct sos_umem_    199 static sos_ret_t physmem_mmap(struct sos_umem_vmm_vr *vr)
200 {                                                 200 {
201   return sos_umem_vmm_set_ops_of_vr(vr, &physm    201   return sos_umem_vmm_set_ops_of_vr(vr, &physmem_ops);
202 }                                                 202 }
203                                                   203 
204                                                   204 
205 /** The function responsible for mapping the /    205 /** The function responsible for mapping the /dev/mem resource in
206     user space */                                 206     user space */
207 sos_ret_t sos_dev_physmem_map(struct sos_umem_    207 sos_ret_t sos_dev_physmem_map(struct sos_umem_vmm_as * dest_as,
208                               sos_uaddr_t *uad    208                               sos_uaddr_t *uaddr,
209                               sos_size_t size,    209                               sos_size_t size,
210                               sos_paddr_t offs    210                               sos_paddr_t offset,
211                               sos_ui32_t acces    211                               sos_ui32_t access_rights,
212                               sos_ui32_t flags    212                               sos_ui32_t flags)
213 {                                                 213 {
214   sos_ret_t retval;                               214   sos_ret_t retval;
215   struct kernel_remapped_resource * physmem_re    215   struct kernel_remapped_resource * physmem_resource;
216                                                   216 
217   physmem_resource                                217   physmem_resource
218     = (struct kernel_remapped_resource*) sos_k    218     = (struct kernel_remapped_resource*) sos_kmalloc(sizeof(*physmem_resource),
219                                                   219                                                      0);
220   if (! physmem_resource)                         220   if (! physmem_resource)
221     return -SOS_ENOMEM;                           221     return -SOS_ENOMEM;
222                                                   222 
223   memset(physmem_resource, 0x0, sizeof(*physme    223   memset(physmem_resource, 0x0, sizeof(*physmem_resource));
224   physmem_resource->mr.allowed_access_rights      224   physmem_resource->mr.allowed_access_rights 
225     = SOS_VM_MAP_PROT_READ                        225     = SOS_VM_MAP_PROT_READ
226     | SOS_VM_MAP_PROT_WRITE                       226     | SOS_VM_MAP_PROT_WRITE
227     | SOS_VM_MAP_PROT_EXEC;                       227     | SOS_VM_MAP_PROT_EXEC;
228   physmem_resource->mr.custom_data    = physme    228   physmem_resource->mr.custom_data    = physmem_resource;
229   physmem_resource->mr.mmap           = physme    229   physmem_resource->mr.mmap           = physmem_mmap;
230                                                   230 
231   retval = sos_umem_vmm_map(dest_as, uaddr, si    231   retval = sos_umem_vmm_map(dest_as, uaddr, size,
232                             access_rights, fla    232                             access_rights, flags,
233                             & physmem_resource    233                             & physmem_resource->mr, offset);
234   if (SOS_OK != retval)                           234   if (SOS_OK != retval)
235     {                                             235     {
236       sos_kfree((sos_vaddr_t)physmem_resource)    236       sos_kfree((sos_vaddr_t)physmem_resource);
237       return retval;                              237       return retval;
238     }                                             238     }
239                                                   239 
240   return SOS_OK;                                  240   return SOS_OK;
241 }                                                 241 }
                                                      

source navigation ] diff markup ] identifier search ] general search ]