• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020, 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 "linux/kernel.h"
33 #include "linux/module.h"
34 #include "math.h"
35 #include "limits.h"
36 #include "sys/statfs.h"
37 #include "los_sys_pri.h"
38 #include "los_swtmr.h"
39 #ifdef LOSCFG_KERNEL_DYNLOAD
40 #include "los_ld_elflib.h"
41 #endif
42 #ifdef LOSCFG_NET_LWIP_SACK
43 #include "lwip/sockets.h"
44 #include "lwip/api.h"
45 #include "lwip/netdb.h"
46 #endif
47 #include "linux/rbtree.h"
48 #include "los_vm_common.h"
49 #include "los_vm_zone.h"
50 #include "los_vm_lock.h"
51 
52 
53 #ifdef __LP64__
dl_iterate_phdr(int (* callback)(void * info,size_t size,void * data),void * data)54 int dl_iterate_phdr(int (*callback)(void *info, size_t size, void *data), void *data)
55 {
56     PRINT_ERR("%s NOT SUPPORT\n", __FUNCTION__);
57     errno = ENOSYS;
58     return -1;
59 }
60 #endif
61 
fs_show(const char * path)62 void fs_show(const char *path)
63 {
64     INT32 ret;
65     struct statfs fss;
66     if (path == NULL) {
67         PRINTK("path is NULL\n");
68         return;
69     }
70     ret = statfs(path, &fss);
71     PRINTK("Filesystem %s info: \n", path);
72     PRINTK("----------------------------------------\n");
73     if (ret == ENOERR) {
74         PRINTK("  Total clusters: %u \n", fss.f_blocks);
75         PRINTK("  Cluster size: %u \n", fss.f_bsize);
76         PRINTK("  Free clusters: %u \n", fss.f_bfree);
77     } else {
78         ret = get_errno();
79         PRINT_ERR("Get fsinfo failed: %d \n", ret);
80     }
81 }
82 
83 #define MAX_JIFFY_OFFSET ((LONG_MAX >> 1) - 1)
84 
msecs_to_jiffies(const unsigned int m)85 unsigned long msecs_to_jiffies(const unsigned int m)
86 {
87     /* Negative value, means infinite timeout: */
88     if ((INT32)m < 0) {
89         return (unsigned long)MAX_JIFFY_OFFSET;
90     }
91 
92 #if (HZ <= OS_SYS_MS_PER_SECOND) && !(OS_SYS_MS_PER_SECOND % HZ)
93     /*
94      * HZ is equal to or smaller than 1000, and 1000 is a nice
95      * round multiple of HZ, divide with the factor between them,
96      * but round upwards:
97      */
98     return ((m + (OS_SYS_MS_PER_SECOND / HZ)) - 1) / (OS_SYS_MS_PER_SECOND / HZ);
99 #else
100     PRINT_ERR("HZ: %d is not supported in %s\n", HZ, __FUNCTION__);
101     return ENOSUPP;
102 #endif
103 }
104 
jiffies_to_tick(unsigned long j)105 UINT64 jiffies_to_tick(unsigned long j)
106 {
107     return j;
108 }
109 
110 #define MAX_SCHEDULE_TIMEOUT UINT_MAX
schedule_timeout(signed long timeout)111 signed long schedule_timeout(signed long timeout)
112 {
113     UINT32 ret;
114 
115     if (OS_INT_ACTIVE) {
116         PRINT_ERR("ERROR: OS_ERRNO_SWTMR_HWI_ACTIVE\n");
117         return LOS_ERRNO_SWTMR_HWI_ACTIVE;
118     }
119     if (timeout < 0) {
120         PRINT_ERR("schedule_timeout: wrong timeout\n");
121         return 0;
122     }
123 #ifdef __LP64__
124     if (timeout > MAX_SCHEDULE_TIMEOUT) {
125         timeout = LOS_WAIT_FOREVER;
126     }
127 #endif
128     ret = LOS_TaskDelay(timeout);
129     if (ret == LOS_OK) {
130         return ret;
131     } else {
132         PRINT_ERR("ERROR: OS_ERRNO_SWTMR_NOT_STARTED\n");
133         return LOS_ERRNO_SWTMR_NOT_STARTED;
134     }
135 }
136 
do_div_imp(UINT64 * n,UINT32 base)137 UINT32 do_div_imp(UINT64 *n, UINT32 base)
138 {
139     UINT32 r;
140 
141     if ((n == NULL) || (base == 0)) {
142         PRINT_ERR("%s invalid input param, n:%p, base %u\n", __FUNCTION__, n, base);
143         return 0;
144     }
145 
146     r = *n % base;
147     *n = *n / base;
148     return r;
149 }
150 
do_div_s64_imp(INT64 * n,INT32 base)151 INT32 do_div_s64_imp(INT64 *n, INT32 base)
152 {
153     INT32 r;
154 
155     if ((n == NULL) || (base == 0)) {
156         PRINT_ERR("%s invalid input param, n:%p, base:%u\n", __FUNCTION__, n, base);
157         return 0;
158     }
159 
160     r = *n % base;
161     *n = *n / base;
162     return r;
163 }
164 
basename(const char * path)165 char *basename(const char *path)
166 {
167     STATIC const CHAR empty[] = ".";
168     CHAR *first = (CHAR *)empty;
169     register CHAR *last = NULL;
170 
171     if ((path != NULL) && *path) {
172         first = (CHAR *)path;
173         last = (CHAR *)path - 1;
174 
175         do {
176             if ((*path != '/') && (path > ++last)) {
177                 last = first = (CHAR *)path;
178             }
179         } while (*++path);
180 
181         if (*first == '/') {
182             last = first;
183         }
184         last[1] = 0;
185     }
186 
187     return first;
188 }
189 
190 void *__dso_handle = NULL;
191 
192 /* Undo Linux compat changes. */
193 #undef RB_ROOT
194 #define RB_ROOT(head)   (head)->rbh_root
195 
panic_cmp(struct rb_node * one,struct rb_node * two)196 int panic_cmp(struct rb_node *one, struct rb_node *two)
197 {
198     LOS_Panic("no cmp");
199     return 0;
200 }
201 
202 RB_GENERATE(linux_root, rb_node, __entry, panic_cmp);
203 
204 #define IS_PERIPH_ADDR(addr) \
205     (((addr) >= U32_C(PERIPH_PMM_BASE)) && ((addr) <= U32_C(PERIPH_PMM_BASE) + U32_C(PERIPH_PMM_SIZE)))
206 #define IS_MEMORY_ADDR(addr) \
207     (((addr) >= U32_C(DDR_MEM_ADDR)) && ((addr) <= U32_C(DDR_MEM_ADDR) + U32_C(DDR_MEM_SIZE)))
208 
ioremap(PADDR_T paddr,unsigned long size)209 VOID *ioremap(PADDR_T paddr, unsigned long size)
210 {
211     if (IS_PERIPH_ADDR(paddr) && IS_PERIPH_ADDR(paddr + size)) {
212         return (VOID *)(UINTPTR)IO_DEVICE_ADDR(paddr);
213     }
214 
215     VM_ERR("ioremap failed invalid addr or size %p %d", paddr, size);
216     return (VOID *)(UINTPTR)paddr;
217 }
218 
iounmap(VOID * vaddr)219 VOID iounmap(VOID *vaddr) {}
220 
ioremap_nocache(PADDR_T paddr,unsigned long size)221 VOID *ioremap_nocache(PADDR_T paddr, unsigned long size)
222 {
223     if (IS_PERIPH_ADDR(paddr) && IS_PERIPH_ADDR(paddr + size)) {
224         return (VOID *)(UINTPTR)IO_UNCACHED_ADDR(paddr);
225     }
226 
227     if (IS_MEMORY_ADDR(paddr) && IS_MEMORY_ADDR(paddr + size)) {
228         return (VOID *)(UINTPTR)MEM_UNCACHED_ADDR(paddr);
229     }
230 
231     VM_ERR("ioremap_nocache failed invalid addr or size %p %d", paddr, size);
232     return (VOID *)(UINTPTR)paddr;
233 }
234 
ioremap_cached(PADDR_T paddr,unsigned long size)235 VOID *ioremap_cached(PADDR_T paddr, unsigned long size)
236 {
237     if (IS_PERIPH_ADDR(paddr) && IS_PERIPH_ADDR(paddr + size)) {
238         return (VOID *)(UINTPTR)IO_CACHED_ADDR(paddr);
239     }
240 
241     if (IS_MEMORY_ADDR(paddr) && IS_MEMORY_ADDR(paddr + size)) {
242         return (VOID *)(UINTPTR)MEM_CACHED_ADDR(paddr);
243     }
244 
245     VM_ERR("ioremap_cached failed invalid addr or size %p %d", paddr, size);
246     return (VOID *)(UINTPTR)paddr;
247 }
248 
249 #ifdef LOSCFG_KERNEL_VM
remap_pfn_range(VADDR_T vaddr,unsigned long pfn,unsigned long size,unsigned long prot)250 int remap_pfn_range(VADDR_T vaddr, unsigned long pfn, unsigned long size, unsigned long prot)
251 {
252     STATUS_T status = LOS_OK;
253     int ret;
254     LosVmMapRegion *region = NULL;
255     unsigned long vpos;
256     unsigned long end;
257     unsigned long paddr = pfn << PAGE_SHIFT;
258     LosVmSpace *space = LOS_SpaceGet(vaddr);
259 
260     if (size == 0) {
261         VM_ERR("invalid map size %u", size);
262         return LOS_ERRNO_VM_INVALID_ARGS;
263     }
264     size = ROUNDUP(size, PAGE_SIZE);
265 
266     if (!IS_PAGE_ALIGNED(vaddr) || pfn == 0) {
267         VM_ERR("invalid map map vaddr %x or pfn %x", vaddr, pfn);
268         return LOS_ERRNO_VM_INVALID_ARGS;
269     }
270 
271     if (space == NULL) {
272         VM_ERR("aspace not exists");
273         return LOS_ERRNO_VM_NOT_FOUND;
274     }
275 
276     (VOID)LOS_MuxAcquire(&space->regionMux);
277 
278     region = LOS_RegionFind(space, vaddr);
279     if (region == NULL) {
280         VM_ERR("region not exists");
281         status = LOS_ERRNO_VM_NOT_FOUND;
282         goto OUT;
283     }
284     end = vaddr + size;
285     if (region->range.base + region->range.size < end) {
286         VM_ERR("out of range:base=%x size=%d vaddr=%x len=%u",
287                region->range.base, region->range.size, vaddr, size);
288         status = LOS_ERRNO_VM_INVALID_ARGS;
289         goto OUT;
290     }
291 
292     /* check */
293     for (vpos = vaddr; vpos < end; vpos += PAGE_SIZE) {
294         status = LOS_ArchMmuQuery(&space->archMmu, (VADDR_T)vpos, NULL, NULL);
295         if (status == LOS_OK) {
296             VM_ERR("remap_pfn_range, address mapping already exist");
297             status = LOS_ERRNO_VM_INVALID_ARGS;
298             goto OUT;
299         }
300     }
301 
302     /* map all */
303     ret = LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, size >> PAGE_SHIFT, prot);
304     if (ret <= 0) {
305         VM_ERR("ioremap LOS_ArchMmuMap failed err = %d", ret);
306         goto OUT;
307     }
308 
309     status = LOS_OK;
310 
311 OUT:
312     (VOID)LOS_MuxRelease(&space->regionMux);
313     return status;
314 }
315 #endif
316