Diff markup
001 001
002 002
003 003
004 004
005 005
006 006
007 007
008 008
009 009
010 010
011 011
012 012
013 013
014 014
015 015
016 016
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 031
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 040
041 041
042 static void resource_ref(struct sos_umem_vmm_v 042 static void resource_ref(struct sos_umem_vmm_vr * vr)
043 { 043 {
044 044
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 050
051 resource->ref_cnt ++; 051 resource->ref_cnt ++;
052 } 052 }
053 053
054 054
055 055
056 056
057 static void resource_unref(struct sos_umem_vmm 057 static void resource_unref(struct sos_umem_vmm_vr * vr)
058 { 058 {
059 059
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 065
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 069
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 075
076 076
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 085
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 089
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 093
094 ppage_paddr = sos_paging_get_paddr(SOS_PAGE_ 094 ppage_paddr = sos_paging_get_paddr(SOS_PAGE_ALIGN_INF(vaddr));
095 095
096 096
097 if (! ppage_paddr) 097 if (! ppage_paddr)
098 return -SOS_EFAULT; 098 return -SOS_EFAULT;
099 099
100 100
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 110
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 119
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 126
127 127
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 138
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 153
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 167
168 168
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 176
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 180
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 189
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 198
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 205
206 206
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 }