• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "los_vm_phys.h"
33 #include "los_vm_boot.h"
34 #include "los_vm_common.h"
35 #include "los_vm_map.h"
36 #include "los_vm_dump.h"
37 #include "los_process_pri.h"
38 
39 
40 #ifdef LOSCFG_KERNEL_VM
41 
42 #define ONE_PAGE    1
43 
44 /* Physical memory area array */
45 STATIC struct VmPhysArea g_physArea[] = {
46     {
47         .start = SYS_MEM_BASE,
48         .size = SYS_MEM_SIZE_DEFAULT,
49     },
50 };
51 
52 struct VmPhysSeg g_vmPhysSeg[VM_PHYS_SEG_MAX];
53 INT32 g_vmPhysSegNum = 0;
54 
OsGVmPhysSegGet()55 LosVmPhysSeg *OsGVmPhysSegGet()
56 {
57     return g_vmPhysSeg;
58 }
59 
OsVmPhysLruInit(struct VmPhysSeg * seg)60 STATIC VOID OsVmPhysLruInit(struct VmPhysSeg *seg)
61 {
62     INT32 i;
63     UINT32 intSave;
64     LOS_SpinInit(&seg->lruLock);
65 
66     LOS_SpinLockSave(&seg->lruLock, &intSave);
67     for (i = 0; i < VM_NR_LRU_LISTS; i++) {
68         seg->lruSize[i] = 0;
69         LOS_ListInit(&seg->lruList[i]);
70     }
71     LOS_SpinUnlockRestore(&seg->lruLock, intSave);
72 }
73 
OsVmPhysSegCreate(paddr_t start,size_t size)74 STATIC INT32 OsVmPhysSegCreate(paddr_t start, size_t size)
75 {
76     struct VmPhysSeg *seg = NULL;
77 
78     if (g_vmPhysSegNum >= VM_PHYS_SEG_MAX) {
79         return -1;
80     }
81 
82     seg = &g_vmPhysSeg[g_vmPhysSegNum++];
83     for (; (seg > g_vmPhysSeg) && ((seg - 1)->start > (start + size)); seg--) {
84         *seg = *(seg - 1);
85     }
86     seg->start = start;
87     seg->size = size;
88 
89     return 0;
90 }
91 
OsVmPhysSegAdd(VOID)92 VOID OsVmPhysSegAdd(VOID)
93 {
94     INT32 i, ret;
95 
96     LOS_ASSERT(g_vmPhysSegNum < VM_PHYS_SEG_MAX);
97 
98     for (i = 0; i < (sizeof(g_physArea) / sizeof(g_physArea[0])); i++) {
99         ret = OsVmPhysSegCreate(g_physArea[i].start, g_physArea[i].size);
100         if (ret != 0) {
101             VM_ERR("create phys seg failed");
102         }
103     }
104 }
105 
OsVmPhysAreaSizeAdjust(size_t size)106 VOID OsVmPhysAreaSizeAdjust(size_t size)
107 {
108     /*
109      * The first physics memory segment is used for kernel image and kernel heap,
110      * so just need to adjust the first one here.
111      */
112     g_physArea[0].start += size;
113     g_physArea[0].size -= size;
114 }
115 
OsVmPhysPageNumGet(VOID)116 UINT32 OsVmPhysPageNumGet(VOID)
117 {
118     UINT32 nPages = 0;
119     INT32 i;
120 
121     for (i = 0; i < (sizeof(g_physArea) / sizeof(g_physArea[0])); i++) {
122         nPages += g_physArea[i].size >> PAGE_SHIFT;
123     }
124 
125     return nPages;
126 }
127 
OsVmPhysFreeListInit(struct VmPhysSeg * seg)128 STATIC INLINE VOID OsVmPhysFreeListInit(struct VmPhysSeg *seg)
129 {
130     int i;
131     UINT32 intSave;
132     struct VmFreeList *list = NULL;
133 
134     LOS_SpinInit(&seg->freeListLock);
135 
136     LOS_SpinLockSave(&seg->freeListLock, &intSave);
137     for (i = 0; i < VM_LIST_ORDER_MAX; i++) {
138         list = &seg->freeList[i];
139         LOS_ListInit(&list->node);
140         list->listCnt = 0;
141     }
142     LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
143 }
144 
OsVmPhysInit(VOID)145 VOID OsVmPhysInit(VOID)
146 {
147     struct VmPhysSeg *seg = NULL;
148     UINT32 nPages = 0;
149     int i;
150 
151     for (i = 0; i < g_vmPhysSegNum; i++) {
152         seg = &g_vmPhysSeg[i];
153         seg->pageBase = &g_vmPageArray[nPages];
154         nPages += seg->size >> PAGE_SHIFT;
155         OsVmPhysFreeListInit(seg);
156         OsVmPhysLruInit(seg);
157     }
158 }
159 
OsVmPhysFreeListAddUnsafe(LosVmPage * page,UINT8 order)160 STATIC VOID OsVmPhysFreeListAddUnsafe(LosVmPage *page, UINT8 order)
161 {
162     struct VmPhysSeg *seg = NULL;
163     struct VmFreeList *list = NULL;
164 
165     if (page->segID >= VM_PHYS_SEG_MAX) {
166         LOS_Panic("The page segment id(%d) is invalid\n", page->segID);
167     }
168 
169     page->order = order;
170     seg = &g_vmPhysSeg[page->segID];
171 
172     list = &seg->freeList[order];
173     LOS_ListTailInsert(&list->node, &page->node);
174     list->listCnt++;
175 }
176 
OsVmPhysFreeListDelUnsafe(LosVmPage * page)177 STATIC VOID OsVmPhysFreeListDelUnsafe(LosVmPage *page)
178 {
179     struct VmPhysSeg *seg = NULL;
180     struct VmFreeList *list = NULL;
181 
182     if ((page->segID >= VM_PHYS_SEG_MAX) || (page->order >= VM_LIST_ORDER_MAX)) {
183         LOS_Panic("The page segment id(%u) or order(%u) is invalid\n", page->segID, page->order);
184     }
185 
186     seg = &g_vmPhysSeg[page->segID];
187     list = &seg->freeList[page->order];
188     list->listCnt--;
189     LOS_ListDelete(&page->node);
190     page->order = VM_LIST_ORDER_MAX;
191 }
192 
OsVmPhysPagesSpiltUnsafe(LosVmPage * page,UINT8 oldOrder,UINT8 newOrder)193 STATIC VOID OsVmPhysPagesSpiltUnsafe(LosVmPage *page, UINT8 oldOrder, UINT8 newOrder)
194 {
195     UINT32 order;
196     LosVmPage *buddyPage = NULL;
197 
198     for (order = newOrder; order > oldOrder;) {
199         order--;
200         buddyPage = &page[VM_ORDER_TO_PAGES(order)];
201         LOS_ASSERT(buddyPage->order == VM_LIST_ORDER_MAX);
202         OsVmPhysFreeListAddUnsafe(buddyPage, order);
203     }
204 }
205 
OsVmPhysToPage(paddr_t pa,UINT8 segID)206 LosVmPage *OsVmPhysToPage(paddr_t pa, UINT8 segID)
207 {
208     struct VmPhysSeg *seg = NULL;
209     paddr_t offset;
210 
211     if (segID >= VM_PHYS_SEG_MAX) {
212         LOS_Panic("The page segment id(%d) is invalid\n", segID);
213     }
214     seg = &g_vmPhysSeg[segID];
215     if ((pa < seg->start) || (pa >= (seg->start + seg->size))) {
216         return NULL;
217     }
218 
219     offset = pa - seg->start;
220     return (seg->pageBase + (offset >> PAGE_SHIFT));
221 }
222 
OsVmPaddrToPage(paddr_t paddr)223 LosVmPage *OsVmPaddrToPage(paddr_t paddr)
224 {
225     INT32 segID;
226     LosVmPage *vmPage = NULL;
227 
228     for (segID = 0; segID < g_vmPhysSegNum; segID++) {
229         vmPage = OsVmPhysToPage(paddr, segID);
230         if (vmPage != NULL) {
231             return vmPage;
232         }
233     }
234     return NULL;
235 }
236 
OsVmPageToVaddr(LosVmPage * page)237 VOID *OsVmPageToVaddr(LosVmPage *page)
238 {
239     VADDR_T vaddr;
240     vaddr = KERNEL_ASPACE_BASE + page->physAddr - SYS_MEM_BASE;
241 
242     return (VOID *)(UINTPTR)vaddr;
243 }
244 
OsVmVaddrToPage(VOID * ptr)245 LosVmPage *OsVmVaddrToPage(VOID *ptr)
246 {
247     struct VmPhysSeg *seg = NULL;
248     PADDR_T pa = LOS_PaddrQuery(ptr);
249     UINT32 segID;
250 
251     for (segID = 0; segID < g_vmPhysSegNum; segID++) {
252         seg = &g_vmPhysSeg[segID];
253         if ((pa >= seg->start) && (pa < (seg->start + seg->size))) {
254             return seg->pageBase + ((pa - seg->start) >> PAGE_SHIFT);
255         }
256     }
257 
258     return NULL;
259 }
260 
OsVmRecycleExtraPages(LosVmPage * page,size_t startPage,size_t endPage)261 STATIC INLINE VOID OsVmRecycleExtraPages(LosVmPage *page, size_t startPage, size_t endPage)
262 {
263     if (startPage >= endPage) {
264         return;
265     }
266 
267     OsVmPhysPagesFreeContiguous(page, endPage - startPage);
268 }
269 
OsVmPhysLargeAlloc(struct VmPhysSeg * seg,size_t nPages)270 STATIC LosVmPage *OsVmPhysLargeAlloc(struct VmPhysSeg *seg, size_t nPages)
271 {
272     struct VmFreeList *list = NULL;
273     LosVmPage *page = NULL;
274     LosVmPage *tmp = NULL;
275     PADDR_T paStart;
276     PADDR_T paEnd;
277     size_t size = nPages << PAGE_SHIFT;
278 
279     list = &seg->freeList[VM_LIST_ORDER_MAX - 1];
280     LOS_DL_LIST_FOR_EACH_ENTRY(page, &list->node, LosVmPage, node) {
281         paStart = page->physAddr;
282         paEnd = paStart + size;
283         if (paEnd > (seg->start + seg->size)) {
284             continue;
285         }
286 
287         for (;;) {
288             paStart += PAGE_SIZE << (VM_LIST_ORDER_MAX - 1);
289             if ((paStart >= paEnd) || (paStart < seg->start) ||
290                 (paStart >= (seg->start + seg->size))) {
291                 break;
292             }
293             tmp = &seg->pageBase[(paStart - seg->start) >> PAGE_SHIFT];
294             if (tmp->order != (VM_LIST_ORDER_MAX - 1)) {
295                 break;
296             }
297         }
298         if (paStart >= paEnd) {
299             return page;
300         }
301     }
302 
303     return NULL;
304 }
305 
OsVmPhysPagesAlloc(struct VmPhysSeg * seg,size_t nPages)306 STATIC LosVmPage *OsVmPhysPagesAlloc(struct VmPhysSeg *seg, size_t nPages)
307 {
308     struct VmFreeList *list = NULL;
309     LosVmPage *page = NULL;
310     LosVmPage *tmp = NULL;
311     UINT32 order;
312     UINT32 newOrder;
313 
314     order = OsVmPagesToOrder(nPages);
315     if (order < VM_LIST_ORDER_MAX) {
316         for (newOrder = order; newOrder < VM_LIST_ORDER_MAX; newOrder++) {
317             list = &seg->freeList[newOrder];
318             if (LOS_ListEmpty(&list->node)) {
319                 continue;
320             }
321             page = LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(&list->node), LosVmPage, node);
322             goto DONE;
323         }
324     } else {
325         newOrder = VM_LIST_ORDER_MAX - 1;
326         page = OsVmPhysLargeAlloc(seg, nPages);
327         if (page != NULL) {
328             goto DONE;
329         }
330     }
331     return NULL;
332 DONE:
333 
334     for (tmp = page; tmp < &page[nPages]; tmp = &tmp[1 << newOrder]) {
335         OsVmPhysFreeListDelUnsafe(tmp);
336     }
337     OsVmPhysPagesSpiltUnsafe(page, order, newOrder);
338     OsVmRecycleExtraPages(&page[nPages], nPages, ROUNDUP(nPages, (1 << min(order, newOrder))));
339 
340     return page;
341 }
342 
OsVmPhysPagesFree(LosVmPage * page,UINT8 order)343 VOID OsVmPhysPagesFree(LosVmPage *page, UINT8 order)
344 {
345     paddr_t pa;
346     LosVmPage *buddyPage = NULL;
347 
348     if ((page == NULL) || (order >= VM_LIST_ORDER_MAX)) {
349         return;
350     }
351 
352     if (order < VM_LIST_ORDER_MAX - 1) {
353         pa = VM_PAGE_TO_PHYS(page);
354         do {
355             pa ^= VM_ORDER_TO_PHYS(order);
356             buddyPage = OsVmPhysToPage(pa, page->segID);
357             if ((buddyPage == NULL) || (buddyPage->order != order)) {
358                 break;
359             }
360             OsVmPhysFreeListDelUnsafe(buddyPage);
361             order++;
362             pa &= ~(VM_ORDER_TO_PHYS(order) - 1);
363             page = OsVmPhysToPage(pa, page->segID);
364         } while (order < VM_LIST_ORDER_MAX - 1);
365     }
366 
367     OsVmPhysFreeListAddUnsafe(page, order);
368 }
369 
OsVmPhysPagesFreeContiguous(LosVmPage * page,size_t nPages)370 VOID OsVmPhysPagesFreeContiguous(LosVmPage *page, size_t nPages)
371 {
372     paddr_t pa;
373     UINT32 order;
374     size_t n;
375 
376     while (TRUE) {
377         pa = VM_PAGE_TO_PHYS(page);
378         order = VM_PHYS_TO_ORDER(pa);
379         n = VM_ORDER_TO_PAGES(order);
380         if (n > nPages) {
381             break;
382         }
383         OsVmPhysPagesFree(page, order);
384         nPages -= n;
385         page += n;
386     }
387 
388     while (nPages > 0) {
389         order = LOS_HighBitGet(nPages);
390         n = VM_ORDER_TO_PAGES(order);
391         OsVmPhysPagesFree(page, order);
392         nPages -= n;
393         page += n;
394     }
395 }
396 
OsVmPhysPagesGet(size_t nPages)397 STATIC LosVmPage *OsVmPhysPagesGet(size_t nPages)
398 {
399     UINT32 intSave;
400     struct VmPhysSeg *seg = NULL;
401     LosVmPage *page = NULL;
402     UINT32 segID;
403 
404     for (segID = 0; segID < g_vmPhysSegNum; segID++) {
405         seg = &g_vmPhysSeg[segID];
406         LOS_SpinLockSave(&seg->freeListLock, &intSave);
407         page = OsVmPhysPagesAlloc(seg, nPages);
408         if (page != NULL) {
409             /* the first page of continuous physical addresses holds refCounts */
410             LOS_AtomicSet(&page->refCounts, 0);
411             page->nPages = nPages;
412             LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
413             return page;
414         }
415         LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
416     }
417     return NULL;
418 }
419 
LOS_PhysPagesAllocContiguous(size_t nPages)420 VOID *LOS_PhysPagesAllocContiguous(size_t nPages)
421 {
422     LosVmPage *page = NULL;
423 
424     if (nPages == 0) {
425         return NULL;
426     }
427 
428     page = OsVmPhysPagesGet(nPages);
429     if (page == NULL) {
430         return NULL;
431     }
432 
433     return OsVmPageToVaddr(page);
434 }
435 
LOS_PhysPagesFreeContiguous(VOID * ptr,size_t nPages)436 VOID LOS_PhysPagesFreeContiguous(VOID *ptr, size_t nPages)
437 {
438     UINT32 intSave;
439     struct VmPhysSeg *seg = NULL;
440     LosVmPage *page = NULL;
441 
442     if (ptr == NULL) {
443         return;
444     }
445 
446     page = OsVmVaddrToPage(ptr);
447     if (page == NULL) {
448         VM_ERR("vm page of ptr(%#x) is null", ptr);
449         return;
450     }
451     page->nPages = 0;
452 
453     seg = &g_vmPhysSeg[page->segID];
454     LOS_SpinLockSave(&seg->freeListLock, &intSave);
455 
456     OsVmPhysPagesFreeContiguous(page, nPages);
457 
458     LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
459 }
460 
OsKVaddrToPaddr(VADDR_T kvaddr)461 PADDR_T OsKVaddrToPaddr(VADDR_T kvaddr)
462 {
463     if (kvaddr == 0) {
464         return 0;
465     }
466     return (kvaddr - KERNEL_ASPACE_BASE + SYS_MEM_BASE);
467 }
468 
LOS_PaddrToKVaddr(PADDR_T paddr)469 VADDR_T *LOS_PaddrToKVaddr(PADDR_T paddr)
470 {
471     struct VmPhysSeg *seg = NULL;
472     UINT32 segID;
473 
474     if (paddr == 0) {
475         return NULL;
476     }
477 
478     for (segID = 0; segID < g_vmPhysSegNum; segID++) {
479         seg = &g_vmPhysSeg[segID];
480         if ((paddr >= seg->start) && (paddr < (seg->start + seg->size))) {
481             return (VADDR_T *)(UINTPTR)(paddr - SYS_MEM_BASE + KERNEL_ASPACE_BASE);
482         }
483     }
484 
485     return (VADDR_T *)(UINTPTR)(paddr - SYS_MEM_BASE + KERNEL_ASPACE_BASE);
486 }
487 
LOS_PhysPageFree(LosVmPage * page)488 VOID LOS_PhysPageFree(LosVmPage *page)
489 {
490     UINT32 intSave;
491     struct VmPhysSeg *seg = NULL;
492 
493     if (page == NULL) {
494         return;
495     }
496 
497     if (LOS_AtomicDecRet(&page->refCounts) <= 0) {
498         seg = &g_vmPhysSeg[page->segID];
499         LOS_SpinLockSave(&seg->freeListLock, &intSave);
500 
501         OsVmPhysPagesFreeContiguous(page, ONE_PAGE);
502         LOS_AtomicSet(&page->refCounts, 0);
503 
504         LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
505     }
506 }
507 
LOS_PhysPageAlloc(VOID)508 LosVmPage *LOS_PhysPageAlloc(VOID)
509 {
510     return OsVmPhysPagesGet(ONE_PAGE);
511 }
512 
LOS_PhysPagesAlloc(size_t nPages,LOS_DL_LIST * list)513 size_t LOS_PhysPagesAlloc(size_t nPages, LOS_DL_LIST *list)
514 {
515     LosVmPage *page = NULL;
516     size_t count = 0;
517 
518     if ((list == NULL) || (nPages == 0)) {
519         return 0;
520     }
521 
522     while (nPages--) {
523         page = OsVmPhysPagesGet(ONE_PAGE);
524         if (page == NULL) {
525             break;
526         }
527         LOS_ListTailInsert(list, &page->node);
528         count++;
529     }
530 
531     return count;
532 }
533 
OsPhysSharePageCopy(PADDR_T oldPaddr,PADDR_T * newPaddr,LosVmPage * newPage)534 VOID OsPhysSharePageCopy(PADDR_T oldPaddr, PADDR_T *newPaddr, LosVmPage *newPage)
535 {
536     UINT32 intSave;
537     LosVmPage *oldPage = NULL;
538     VOID *newMem = NULL;
539     VOID *oldMem = NULL;
540     LosVmPhysSeg *seg = NULL;
541 
542     if ((newPage == NULL) || (newPaddr == NULL)) {
543         VM_ERR("new Page invalid");
544         return;
545     }
546 
547     oldPage = LOS_VmPageGet(oldPaddr);
548     if (oldPage == NULL) {
549         VM_ERR("invalid oldPaddr %p", oldPaddr);
550         return;
551     }
552 
553     seg = &g_vmPhysSeg[oldPage->segID];
554     LOS_SpinLockSave(&seg->freeListLock, &intSave);
555     if (LOS_AtomicRead(&oldPage->refCounts) == 1) {
556         *newPaddr = oldPaddr;
557     } else {
558         newMem = LOS_PaddrToKVaddr(*newPaddr);
559         oldMem = LOS_PaddrToKVaddr(oldPaddr);
560         if ((newMem == NULL) || (oldMem == NULL)) {
561             LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
562             return;
563         }
564         if (memcpy_s(newMem, PAGE_SIZE, oldMem, PAGE_SIZE) != EOK) {
565             VM_ERR("memcpy_s failed");
566         }
567 
568         LOS_AtomicInc(&newPage->refCounts);
569         LOS_AtomicDec(&oldPage->refCounts);
570     }
571     LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
572     return;
573 }
574 
OsVmPhysSegGet(LosVmPage * page)575 struct VmPhysSeg *OsVmPhysSegGet(LosVmPage *page)
576 {
577     if ((page == NULL) || (page->segID >= VM_PHYS_SEG_MAX)) {
578         return NULL;
579     }
580 
581     return (OsGVmPhysSegGet() + page->segID);
582 }
583 
OsVmPagesToOrder(size_t nPages)584 UINT32 OsVmPagesToOrder(size_t nPages)
585 {
586     UINT32 order;
587 
588     for (order = 0; VM_ORDER_TO_PAGES(order) < nPages; order++);
589 
590     return order;
591 }
592 
LOS_PhysPagesFree(LOS_DL_LIST * list)593 size_t LOS_PhysPagesFree(LOS_DL_LIST *list)
594 {
595     UINT32 intSave;
596     LosVmPage *page = NULL;
597     LosVmPage *nPage = NULL;
598     LosVmPhysSeg *seg = NULL;
599     size_t count = 0;
600 
601     if (list == NULL) {
602         return 0;
603     }
604 
605     LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(page, nPage, list, LosVmPage, node) {
606         LOS_ListDelete(&page->node);
607         if (LOS_AtomicDecRet(&page->refCounts) <= 0) {
608             seg = &g_vmPhysSeg[page->segID];
609             LOS_SpinLockSave(&seg->freeListLock, &intSave);
610             OsVmPhysPagesFreeContiguous(page, ONE_PAGE);
611             LOS_AtomicSet(&page->refCounts, 0);
612             LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
613         }
614         count++;
615     }
616 
617     return count;
618 }
619 #else
LOS_PaddrToKVaddr(PADDR_T paddr)620 VADDR_T *LOS_PaddrToKVaddr(PADDR_T paddr)
621 {
622     if ((paddr < DDR_MEM_ADDR) || (paddr >= ((PADDR_T)DDR_MEM_ADDR + DDR_MEM_SIZE))) {
623         return NULL;
624     }
625 
626     return (VADDR_T *)DMA_TO_VMM_ADDR(paddr);
627 }
628 #endif
629 
630