@@ -109,11 +109,13 @@ VP_IDX3(vaddr_t va)
109109}
110110
111111
112- #if VP_IDX2_SIZE != VP_IDX3_SIZE
113- #error pmap allocation code expects IDX2 and IDX3 size to be same
114- #endif
115- struct pmapvp {
116- void * vp [VP_IDX1_SIZE ];
112+ struct pmapvp2 {
113+ vaddr_t l2 [VP_IDX2_CNT ];
114+ void * vp [VP_IDX2_CNT ];
115+ };
116+
117+ struct pmapvp3 {
118+ void * vp [VP_IDX3_CNT ];
117119};
118120
119121/*
@@ -126,21 +128,21 @@ struct pmapvp {
126128struct pte_desc *
127129pmap_vp_lookup (pmap_t pm , vaddr_t va )
128130{
129- struct pmapvp * vp1 ;
130- struct pmapvp * vp2 ;
131+ struct pmapvp2 * vp2 ;
132+ struct pmapvp3 * vp3 ;
131133 struct pte_desc * pted ;
132134
133- vp1 = pm -> pm_vp [VP_IDX1 (va )];
134- if (vp1 == NULL ) {
135+ vp2 = pm -> pm_vp [VP_IDX1 (va )];
136+ if (vp2 == NULL ) {
135137 return NULL ;
136138 }
137139
138- vp2 = vp1 -> vp [VP_IDX2 (va )];
139- if (vp2 == NULL ) {
140+ vp3 = vp2 -> vp [VP_IDX2 (va )];
141+ if (vp3 == NULL ) {
140142 return NULL ;
141143 }
142144
143- pted = vp2 -> vp [VP_IDX3 (va )];
145+ pted = vp3 -> vp [VP_IDX3 (va )];
144146
145147 return pted ;
146148}
@@ -151,22 +153,22 @@ pmap_vp_lookup(pmap_t pm, vaddr_t va)
151153struct pte_desc *
152154pmap_vp_remove (pmap_t pm , vaddr_t va )
153155{
154- struct pmapvp * vp1 ;
155- struct pmapvp * vp2 ;
156+ struct pmapvp2 * vp2 ;
157+ struct pmapvp3 * vp3 ;
156158 struct pte_desc * pted ;
157159
158- vp1 = pm -> pm_vp [VP_IDX1 (va )];
159- if (vp1 == NULL ) {
160+ vp2 = pm -> pm_vp [VP_IDX1 (va )];
161+ if (vp2 == NULL ) {
160162 return NULL ;
161163 }
162164
163- vp2 = vp1 -> vp [VP_IDX2 (va )];
164- if (vp2 == NULL ) {
165+ vp3 = vp2 -> vp [VP_IDX2 (va )];
166+ if (vp3 == NULL ) {
165167 return NULL ;
166168 }
167169
168- pted = vp2 -> vp [VP_IDX3 (va )];
169- vp2 -> vp [VP_IDX3 (va )] = NULL ;
170+ pted = vp3 -> vp [VP_IDX3 (va )];
171+ vp3 -> vp [VP_IDX3 (va )] = NULL ;
170172
171173 return pted ;
172174}
@@ -180,27 +182,27 @@ pmap_vp_remove(pmap_t pm, vaddr_t va)
180182void
181183pmap_vp_enter (pmap_t pm , vaddr_t va , struct pte_desc * pted )
182184{
183- struct pmapvp * vp1 ;
184- struct pmapvp * vp2 ;
185+ struct pmapvp2 * vp2 ;
186+ struct pmapvp3 * vp3 ;
185187 int s ;
186188
187- vp1 = pm -> pm_vp [VP_IDX1 (va )];
188- if (vp1 == NULL ) {
189+ vp2 = pm -> pm_vp [VP_IDX1 (va )];
190+ if (vp2 == NULL ) {
189191 s = splvm ();
190- vp1 = pool_get (& pmap_vp_pool , PR_NOWAIT | PR_ZERO );
192+ vp2 = pool_get (& pmap_vp_pool , PR_NOWAIT | PR_ZERO );
191193 splx (s );
192- pm -> pm_vp [VP_IDX1 (va )] = vp1 ;
194+ pm -> pm_vp [VP_IDX1 (va )] = vp2 ;
193195 }
194196
195- vp2 = vp1 -> vp [VP_IDX2 (va )];
196- if (vp2 == NULL ) {
197+ vp3 = vp2 -> vp [VP_IDX2 (va )];
198+ if (vp3 == NULL ) {
197199 s = splvm ();
198- vp2 = pool_get (& pmap_vp_pool , PR_NOWAIT | PR_ZERO );
200+ vp3 = pool_get (& pmap_vp_pool , PR_NOWAIT | PR_ZERO );
199201 splx (s );
200- vp1 -> vp [VP_IDX2 (va )] = vp2 ;
202+ vp2 -> vp [VP_IDX2 (va )] = vp3 ;
201203 }
202204
203- vp2 -> vp [VP_IDX3 (va )] = pted ;
205+ vp3 -> vp [VP_IDX3 (va )] = pted ;
204206}
205207
206208
@@ -355,8 +357,8 @@ pmap_remove(pmap_t pm, vaddr_t va, vaddr_t endva)
355357 int i_vp1 , s_vp1 , e_vp1 ;
356358 int i_vp2 , s_vp2 , e_vp2 ;
357359 int i_vp3 , s_vp3 , e_vp3 ;
358- struct pmapvp * vp2 ;
359- struct pmapvp * vp3 ;
360+ struct pmapvp2 * vp2 ;
361+ struct pmapvp3 * vp3 ;
360362
361363 /* I suspect that if this loop were unrolled better
362364 * it would have better performance, testing i_vp1 and i_vp2
@@ -378,7 +380,7 @@ pmap_remove(pmap_t pm, vaddr_t va, vaddr_t endva)
378380 if (i_vp1 == e_vp1 )
379381 e_vp2 = VP_IDX2 (endva );
380382 else
381- e_vp2 = VP_IDX2_SIZE - 1 ;
383+ e_vp2 = VP_IDX2_CNT - 1 ;
382384
383385 for (i_vp2 = s_vp2 ; i_vp2 <= e_vp2 ; i_vp2 ++ ) {
384386 vp3 = vp2 -> vp [i_vp2 ];
@@ -393,7 +395,7 @@ pmap_remove(pmap_t pm, vaddr_t va, vaddr_t endva)
393395 if ((i_vp1 == e_vp1 ) && (i_vp2 == e_vp2 ))
394396 e_vp3 = VP_IDX3 (endva );
395397 else
396- e_vp3 = VP_IDX3_SIZE ;
398+ e_vp3 = VP_IDX3_CNT ;
397399
398400 for (i_vp3 = s_vp3 ; i_vp3 < e_vp3 ; i_vp3 ++ ) {
399401 if (vp3 -> vp [i_vp3 ] != NULL ) {
@@ -733,26 +735,26 @@ pmap_vp_destroy(pmap_t pm)
733735{
734736 int i , j ;
735737 int s ;
736- struct pmapvp * vp1 ;
737- struct pmapvp * vp2 ;
738+ struct pmapvp2 * vp2 ;
739+ struct pmapvp3 * vp3 ;
738740
739- for (i = 0 ; i < VP_IDX1_SIZE ; i ++ ) {
740- vp1 = pm -> pm_vp [i ];
741- if (vp1 == NULL )
741+ for (i = 0 ; i < VP_IDX1_CNT ; i ++ ) {
742+ vp2 = pm -> pm_vp [i ];
743+ if (vp2 == NULL )
742744 continue ;
743745
744- for (j = 0 ; j < VP_IDX2_SIZE ; j ++ ) {
745- vp2 = vp1 -> vp [j ];
746- if (vp2 == NULL )
746+ for (j = 0 ; j < VP_IDX2_CNT ; j ++ ) {
747+ vp3 = vp2 -> vp [j ];
748+ if (vp3 == NULL )
747749 continue ;
748750
749751 s = splvm ();
750- pool_put (& pmap_vp_pool , vp2 );
752+ pool_put (& pmap_vp_pool , vp3 );
751753 splx (s );
752754 }
753755 pm -> pm_vp [i ] = NULL ;
754756 s = splvm ();
755- pool_put (& pmap_vp_pool , vp1 );
757+ pool_put (& pmap_vp_pool , vp2 );
756758 splx (s );
757759 }
758760}
@@ -835,13 +837,29 @@ pmap_bootstrap(u_int kernelstart, u_int kernelend, uint32_t ram_start,
835837 uint32_t ram_end )
836838{
837839 vaddr_t kvo ;
840+ struct pmapvp2 * vp2 ;
841+ int i ;
838842
839843 kvo = KERNEL_BASE_VIRT - KERNEL_BASE_PHYS ;
840844
841845 pmap_setup_avail (ram_start , ram_end );
842846 pmap_remove_avail (kernelstart - kvo , kernelend - kvo );
843847
844848
849+ /* allocate kernel l1 page table */
850+ pmap_kernel ()-> l1_va = pmap_steal_avail (L1_TABLE_SIZE , L1_TABLE_SIZE );
851+
852+ /* allocate v->p mappings for pmap_kernel() */
853+ for (i = 0 ; i < VP_IDX1_CNT ; i ++ ) {
854+ pmap_kernel ()-> pm_vp [i ] = NULL ;
855+ }
856+
857+ vp2 = pmap_steal_avail (sizeof (struct pmapvp2 ), 4 );
858+ bzero (vp2 , sizeof (struct pmapvp2 ));
859+ //pmap_premap(kernelstart, kernelend, kvo);
860+ pmap_kernel ()-> pm_vp [VP_IDX1 (KERNEL_BASE_VIRT )] = vp2 ;
861+
862+
845863 /* XXX */
846864
847865 zero_page = VM_MIN_KERNEL_ADDRESS + arm_kvm_stolen ;
@@ -1013,7 +1031,7 @@ pmap_init()
10131031{
10141032 pool_init (& pmap_pmap_pool , sizeof (struct pmap ), 0 , 0 , 0 , "pmap" , NULL );
10151033 pool_setlowat (& pmap_pmap_pool , 2 );
1016- pool_init (& pmap_vp_pool , sizeof (struct pmapvp ), 0 , 0 , 0 , "vp" , NULL );
1034+ pool_init (& pmap_vp_pool , sizeof (struct pmapvp2 ), 0 , 0 , 0 , "vp" , NULL );
10171035 pool_setlowat (& pmap_vp_pool , 10 );
10181036 pool_init (& pmap_pted_pool , sizeof (struct pte_desc ), 0 , 0 , 0 , "pted" ,
10191037 NULL );
@@ -1325,3 +1343,42 @@ pmap_steal_avail(size_t size, int align)
13251343 panic ("unable to allocate region with size %x align %x" ,
13261344 size , align );
13271345}
1346+
1347+ #if 0
1348+ /*
1349+ * Create a V -> P mapping for the given pmap and virtual address
1350+ * with reference to the pte descriptor that is used to map the page.
1351+ * This code should track allocations of vp table allocations
1352+ * so they can be freed efficiently.
1353+ */
1354+ void
1355+ pmap_premap (vaddr_t startaddr , struct pte_desc * pted )
1356+ pmap_premap (vaddr_t va , struct pte_desc * pted )
1357+ {
1358+ struct pmapvp2 * vp2 ;
1359+ struct pmapvp3 * vp3 ;
1360+ int s ;
1361+
1362+ vp2 = pm -> pm_vp [VP_IDX1 (va )];
1363+ if (vp2 == NULL ) {
1364+ s = splvm ();
1365+ vp2 = pmap_steal_avail (sizeof (struct pmapvp2 ), 4 )
1366+ vp2 -> l1_va = pmap_steal_avail (L2_
1367+ bzero (vp2 ,
1368+ vp2 ->
1369+ pmap_set_l1 (pm , va , vp2 -> l1_va )
1370+ splx (s );
1371+ pm -> pm_vp [VP_IDX1 (va )] = vp2 ;
1372+ }
1373+
1374+ vp3 = vp2 -> vp [VP_IDX2 (va )];
1375+ if (vp3 == NULL ) {
1376+ s = splvm ();
1377+ vp3 = pool_get (& pmap_vp_pool , PR_NOWAIT | PR_ZERO );
1378+ splx (s );
1379+ vp2 -> vp [VP_IDX2 (va )] = vp3 ;
1380+ }
1381+
1382+ vp3 -> vp [VP_IDX3 (va )] = pted ;
1383+ }
1384+ #endif
0 commit comments