• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 #include <linux/module.h>
19 
20 #include "hi_osal.h"
21 #include "osal_mmz.h"
22 
23 #include "hi_debug.h"
24 #include "hi_common.h"
25 
26 #ifdef __cplusplus
27 #if __cplusplus
28 extern "C" {
29 #endif
30 #endif /* __cplusplus */
31 
cmpi_mmz_malloc(const hi_char * mmz_name,const hi_char * buf_name,hi_ulong size)32 hi_u64 cmpi_mmz_malloc(const hi_char *mmz_name, const hi_char *buf_name, hi_ulong size)
33 {
34     hil_mmb_t *pmmb = NULL;
35 
36     pmmb = hil_mmb_alloc(buf_name, size, 0, 0, mmz_name);
37     if (pmmb == NULL) {
38         osal_printk("mmz malloc failed!\n");
39         return HI_NULL;
40     }
41 
42     return hil_mmb_phys(pmmb);
43 }
44 EXPORT_SYMBOL(cmpi_mmz_malloc);
45 
cmpi_mmz_free(hi_u64 phy_addr,hi_void * vir_addr)46 hi_void cmpi_mmz_free(hi_u64 phy_addr, hi_void *vir_addr)
47 {
48     if (vir_addr != NULL) {
49         hil_mmb_t *pmmb = hil_mmb_getby_kvirt(vir_addr);
50 
51         if (pmmb != NULL) {
52             hil_mmb_unmap(pmmb);
53         }
54     }
55 
56     if (phy_addr != 0) {
57         hil_mmb_freeby_phys(phy_addr);
58     }
59 }
60 EXPORT_SYMBOL(cmpi_mmz_free);
61 
cmpi_remap_cached(hi_u64 phy_addr,hi_ulong size)62 hi_void *cmpi_remap_cached(hi_u64 phy_addr, hi_ulong size)
63 {
64     hi_u32 diff;
65     hi_u64 page_phy;
66     hi_u8 *page_addr;
67     hi_ulong page_size;
68 
69     /* the mmap address should align with page */
70     page_phy = phy_addr & 0xfffffffffffff000ULL;
71     diff = phy_addr - page_phy;
72 
73     /* the mmap size should be multiples of 1024 */
74     page_size = ((size + diff - 1) & 0xfffff000UL) + 0x1000;
75 
76     page_addr = hil_mmf_map2kern_cache(page_phy, page_size);
77     if (page_addr == NULL) {
78         osal_printk("phy(0x%llx) size(0x%lx) map cache err!\n", page_phy, page_size);
79         return NULL;
80     }
81 
82     return (page_addr + diff);
83 }
84 EXPORT_SYMBOL(cmpi_remap_cached);
85 
cmpi_remap_nocache(hi_u64 phy_addr,hi_ulong size)86 hi_void *cmpi_remap_nocache(hi_u64 phy_addr, hi_ulong size)
87 {
88     hi_u32 diff;
89     hi_u64 page_phy;
90     hi_u8 *page_addr;
91     hi_ulong page_size;
92 
93     /* the mmap address should align with page */
94     page_phy = phy_addr & 0xfffffffffffff000ULL;
95     diff = phy_addr - page_phy;
96 
97     /* the mmap size should be multiples of 1024 */
98     page_size = ((size + diff - 1) & 0xfffff000UL) + 0x1000;
99 
100     page_addr = hil_mmf_map2kern_nocache(page_phy, page_size);
101     if (page_addr == NULL) {
102         osal_printk("phy(0x%llx) size(0x%lx) map nocache err!\n", page_phy, page_size);
103         return NULL;
104     }
105 
106     return (page_addr + diff);
107 }
108 EXPORT_SYMBOL(cmpi_remap_nocache);
109 
cmpi_unmap(hi_void * virt_addr)110 hi_void cmpi_unmap(hi_void *virt_addr)
111 {
112     hil_mmf_unmap(virt_addr);
113 }
114 EXPORT_SYMBOL(cmpi_unmap);
115 
cmpi_mmz_malloc_nocache(const hi_char * cp_mmz_name,const hi_char * buf_name,hi_u64 * phy_addr,hi_void ** pp_vir_addr,hi_ulong len)116 hi_s32 cmpi_mmz_malloc_nocache(const hi_char *cp_mmz_name, const hi_char *buf_name,
117                                hi_u64 *phy_addr, hi_void **pp_vir_addr, hi_ulong len)
118 {
119     hil_mmb_t *pmmb = NULL;
120 
121     pmmb = hil_mmb_alloc(buf_name, len, 0, 0, cp_mmz_name);
122     if (pmmb == NULL) {
123         osal_printk("mmz malloc failed!\n");
124         return HI_FAILURE;
125     }
126 
127     // the buffer allocated by mmz is 4k align
128     *pp_vir_addr = hil_mmb_map2kern(pmmb);
129     if (*pp_vir_addr == NULL) {
130         hil_mmb_free(pmmb);
131         osal_printk("mmz remap no cache failed!\n");
132         return HI_FAILURE;
133     }
134     *phy_addr = hil_mmb_phys(pmmb);
135 
136     return HI_SUCCESS;
137 }
138 EXPORT_SYMBOL(cmpi_mmz_malloc_nocache);
139 
140 
cmpi_mmz_malloc_cached(const hi_char * cp_mmz_name,const hi_char * buf_name,hi_u64 * phy_addr,hi_void ** pp_vir_addr,hi_ulong len)141 hi_s32 cmpi_mmz_malloc_cached(const hi_char *cp_mmz_name, const hi_char *buf_name,
142                               hi_u64 *phy_addr, hi_void **pp_vir_addr, hi_ulong len)
143 {
144     hil_mmb_t *pmmb = NULL;
145 
146     pmmb = hil_mmb_alloc(buf_name, len, 0, 0, cp_mmz_name);
147     if (pmmb == NULL) {
148         osal_printk("mmz malloc failed!\n");
149         return HI_FAILURE;
150     }
151 
152     // the buffer allocated by mmz is 4k align
153     *pp_vir_addr = hil_mmb_map2kern_cached(pmmb);
154     if (*pp_vir_addr == NULL) {
155         hil_mmb_free(pmmb);
156         osal_printk("mmz remap cache failed!\n");
157         return HI_FAILURE;
158     }
159     *phy_addr = hil_mmb_phys(pmmb);
160 
161     return HI_SUCCESS;
162 }
163 EXPORT_SYMBOL(cmpi_mmz_malloc_cached);
164 
cmpi_check_mmz_phy_addr(unsigned long long phy_addr,unsigned int len)165 int cmpi_check_mmz_phy_addr(unsigned long long phy_addr, unsigned int len)
166 {
167     /* if address in mmz of current system */
168     if (hil_is_phys_in_mmz(phy_addr, len)) {
169         /* if in other system */
170         if (hil_map_mmz_check_phys(phy_addr, len)) {
171             return -1;
172         }
173     }
174 
175     return 0;
176 }
177 EXPORT_SYMBOL(cmpi_check_mmz_phy_addr);
178 
179 #ifdef __cplusplus
180 #if __cplusplus
181 }
182 #endif
183 #endif /* __cplusplus */
184 
185