ccci_lk_load_img_plat_tmp.c 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #include <sys/types.h>
  32. #include <stdint.h>
  33. #include <platform/partition.h>
  34. #include <platform/mt_typedefs.h>
  35. #include <platform/boot_mode.h>
  36. #include <platform/mt_reg_base.h>
  37. #include <platform/errno.h>
  38. #include <printf.h>
  39. #include <string.h>
  40. #include <malloc.h>
  41. #include <libfdt.h>
  42. #include <assert.h>
  43. #include <platform/mt_gpt.h>
  44. #include <platform/mt_emi_mpu.h>
  45. #include <mtk_secure_api.h>
  46. #include <debug.h>
  47. #define MODULE_NAME "LK_LD_MD"
  48. #include "ccci_ld_md_core.h"
  49. #include "ccci_ld_md_errno.h"
  50. #ifdef MTK_DFD_ENABLE_CACHE_DUMP
  51. #define CCCI_SMEM_SIZE_DFD (8*1024*1024)
  52. #else
  53. #define CCCI_SMEM_SIZE_DFD (448*1024)
  54. #endif
  55. #define CCCI_SMEM_SIZE_UDC_NONCACHE ((14*1024+448)*1024)
  56. #define CCCI_SMEM_SIZE_UDC_CACHE (512*1024)
  57. #define CCCI_SMEM_WIFI_MD_PROXY (32*1024)
  58. #define CCCI_SMEM_SIZE_CCB_DHL (2*1024*1024)
  59. #define CCCI_SMEM_SIZE_RAW_DHL (62*1024*1024)
  60. #define CCCI_SMEM_SIZE_LWA (0) // (8*1024*1024)
  61. #define CCB_DATA_BUF_SIZE (CCCI_SMEM_SIZE_CCB_DHL + CCCI_SMEM_SIZE_RAW_DHL)
  62. #define CACHABLE_SMEM_MAX_SIZE (96*1024*1024)
  63. #define CCB_DATA_BUF_DEFAULT_GEAR 12 /* NOTE: This value may be different at different platform */
  64. /***************************************************************************************************
  65. ** Feature Option setting part
  66. ***************************************************************************************************/
  67. #define ENABLE_EMI_PROTECTION
  68. /*------------------------------------------------------------------------------------------------*/
  69. /* Suppor function for share memory calculate */
  70. /*------------------------------------------------------------------------------------------------*/
  71. /* copy from kernel */
  72. enum SMEM_USER_ID_K {
  73. /* this should remain to be 0 for backward compatibility */
  74. SMEM_USER_RAW_DBM = 0,
  75. /* sequence in CCB users matters, must align with ccb_configs[] */
  76. SMEM_USER_CCB_START,
  77. SMEM_USER_CCB_DHL = SMEM_USER_CCB_START,
  78. SMEM_USER_CCB_MD_MONITOR,
  79. SMEM_USER_CCB_META,
  80. SMEM_USER_CCB_END = SMEM_USER_CCB_META,
  81. /* squence of other users does not matter */
  82. SMEM_USER_RAW_CCB_CTRL,
  83. SMEM_USER_RAW_DHL,
  84. SMEM_USER_RAW_MDM,
  85. SMEM_USER_RAW_NETD,
  86. SMEM_USER_RAW_USB,
  87. SMEM_USER_RAW_AUDIO,
  88. SMEM_USER_RAW_DFD_K,
  89. SMEM_USER_RAW_LWA,
  90. SMEM_USER_RAW_MDCCCI_DBG,
  91. SMEM_USER_RAW_MDSS_DBG,
  92. SMEM_USER_RAW_RUNTIME_DATA,
  93. SMEM_USER_RAW_FORCE_ASSERT,
  94. SMEM_USER_CCISM_SCP,
  95. SMEM_USER_RAW_MD2MD,
  96. SMEM_USER_RAW_RESERVED,
  97. SMEM_USER_CCISM_MCU,
  98. SMEM_USER_CCISM_MCU_EXP,
  99. SMEM_USER_SMART_LOGGING,
  100. SMEM_USER_RAW_MD_CONSYS,//22
  101. SMEM_USER_RAW_PHY_CAP,
  102. SMEM_USER_RAW_USIP,
  103. SMEM_USER_RESV_0,// Sync to MT6779 SMEM_USER_MAX_K,
  104. SMEM_USER_ALIGN_PADDING, // Sync to MT6779 SMEM_USER_NON_PADDING
  105. SMEM_USER_RAW_UDC_DATA,
  106. SMEM_USER_RAW_UDC_DESCTAB,
  107. SMEM_USER_RAW_AMMS_POS,
  108. SMEM_USER_RAW_AMMS_ALIGN_PADDING,
  109. SMEM_USER_MD_WIFI_PROXY,
  110. SMEM_USER_MD_NVRAM_CACHE,
  111. SMEM_USER_LAST, /* Make sure USER ID sync with Kernel before SMEM_USER_LAST */
  112. /* Note, if you add more user, please update the followig table: smem_align_ref[] */
  113. };
  114. static const unsigned int smem_align_ref[SMEM_USER_LAST] = {
  115. 0, /* SMEM_USER_RAW_DBM */
  116. 1024*1024, /* SMEM_USER_CCB_DHL */
  117. 0, /* SMEM_USER_CCB_MD_MONITOR */
  118. 0, /* SMEM_USER_CCB_META */
  119. 0, /* SMEM_USER_RAW_CCB_CTRL */
  120. 0, /* SMEM_USER_RAW_DHL */
  121. 0, /* SMEM_USER_RAW_MDM */
  122. 0, /* SMEM_USER_RAW_NETD */
  123. 0, /* SMEM_USER_RAW_USB */
  124. 0, /* SMEM_USER_RAW_AUDIO */
  125. 16*1024*1024, /* SMEM_USER_RAW_DFD_K 97!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
  126. //1*1024*1024, /* SMEM_USER_RAW_DFD_K 95!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
  127. 0, /* SMEM_USER_RAW_LWA */
  128. 0, /* SMEM_USER_RAW_MDCCCI_DBG */
  129. 0, /* SMEM_USER_RAW_MDSS_DBG */
  130. 0, /* SMEM_USER_RAW_RUNTIME_DATA */
  131. 0, /* SMEM_USER_RAW_FORCE_ASSERT */
  132. 0, /* SMEM_USER_CCISM_SCP */
  133. 0, /* SMEM_USER_RAW_MD2MD */
  134. 0, /* SMEM_USER_RAW_RESERVED */
  135. 0, /* SMEM_USER_CCISM_MCU */
  136. 0, /* SMEM_USER_CCISM_MCU_EXP */
  137. 0, /* SMEM_USER_SMART_LOGGING */
  138. 64*1024, /* SMEM_USER_RAW_MD_CONSYS */
  139. 0, /* SMEM_USER_RAW_PHY_CAP */
  140. 128, /* SMEM_USER_RAW_USIP */
  141. 0, /* SMEM_USER_RESV_0 */
  142. 0, /* SMEM_USER_ALIGN_PADDING */
  143. 0, /* SMEM_USER_RAW_UDC_DATA */
  144. 0, /* SMEM_USER_RAW_UDC_DESCTAB */
  145. 64*1024, /* SMEM_USER_RAW_AMMS_POS */
  146. 0, /* SMEM_USER_RAW_AMMS_ALIGN_PADDING */
  147. 0, /* SMEM_USER_MD_WIFI_PROXY */
  148. 64, /* SMEM_USER_MD_NVRAM_CACHE */
  149. };
  150. static unsigned int get_align_ref(unsigned int id)
  151. {
  152. if (id >= SMEM_USER_LAST)
  153. return 0;
  154. return smem_align_ref[id];
  155. }
  156. static unsigned int get_align_sz(unsigned int val, unsigned int align)
  157. {
  158. unsigned int tmp;
  159. tmp = val;
  160. return ((val + align - 1) & (~(align - 1))) - tmp;
  161. }
  162. static unsigned int get_align_sz_by_user(unsigned int val, enum SMEM_USER_ID_K user)
  163. {
  164. unsigned int align;
  165. align = get_align_ref(user);
  166. if (!align)
  167. return 0;
  168. return get_align_sz(val, align);
  169. }
  170. /*---------------------------------------------------------------------------------------------------*/
  171. /* Global variable for share memory */
  172. /*---------------------------------------------------------------------------------------------------*/
  173. static unsigned int ap_md1_smem_size_at_img;
  174. static unsigned int amms_pos_size_at_img;
  175. static unsigned int consys_size_at_img;
  176. static unsigned int udc_support_at_img;
  177. static unsigned int amms_pos_offset;
  178. #define AP_MD1_SMEM_SIZE 0x100000
  179. #define MAX_SMEM_SIZE 0x10000000 //history: 6M-->256M-->64M-->256M
  180. typedef struct _smem_layout {
  181. unsigned long long base_addr;
  182. unsigned int ap_md1_smem_offset;
  183. /* ap_md1_smem_size: this is for MD MPU, not total ap_md1 share size. */
  184. unsigned int ap_md1_smem_size;
  185. unsigned int ap_md3_smem_offset;
  186. unsigned int ap_md3_smem_size;
  187. unsigned int md1_md3_smem_offset;
  188. unsigned int md1_md3_smem_size;
  189. unsigned int total_smem_size;
  190. } smem_layout_t;
  191. static smem_layout_t smem_info;
  192. typedef struct _ccb_layout {
  193. unsigned long long ccb_data_buffer_addr;
  194. unsigned int ccb_data_buffer_size;
  195. } ccb_layout_t;
  196. static ccb_layout_t ccb_info;
  197. typedef struct _nc_smem_node {
  198. unsigned int ap_offset;
  199. unsigned int md_offset;
  200. unsigned int size;
  201. unsigned int id;
  202. } nc_smem_node;
  203. static nc_smem_node nc_smem_info_ext[] = {
  204. {0, 0, 0, SMEM_USER_RAW_UDC_DATA},
  205. {0, 0, 0, SMEM_USER_MD_WIFI_PROXY},
  206. {0, 0, 0, SMEM_USER_RAW_DFD_K},
  207. };
  208. static void update_nc_smem_info(unsigned int id, unsigned int ap, unsigned int md, unsigned int size)
  209. {
  210. unsigned int i;
  211. for (i = 0; i < sizeof(nc_smem_info_ext)/sizeof(nc_smem_node); i++) {
  212. if (nc_smem_info_ext[i].id == id) {
  213. nc_smem_info_ext[i].ap_offset = ap;
  214. nc_smem_info_ext[i].md_offset = md;
  215. nc_smem_info_ext[i].size = size;
  216. return;
  217. }
  218. }
  219. ALWAYS_LOG("un-support NC smem user id:%d\n", id);
  220. assert(0);
  221. }
  222. static void add_nc_smem_to_tag_inf(void)
  223. {
  224. unsigned int num = sizeof(nc_smem_info_ext)/sizeof(nc_smem_node);
  225. if (insert_ccci_tag_inf("nc_smem_info_ext",
  226. (char*)nc_smem_info_ext, sizeof(nc_smem_info_ext)) < 0) {
  227. ALWAYS_LOG("insert nc_smem_info_ext fail\n");
  228. return;
  229. }
  230. if (insert_ccci_tag_inf("nc_smem_info_ext_num",
  231. (char*)&num, sizeof(int)) < 0)
  232. ALWAYS_LOG("insert nc_smem_info_ext_num fail\n");
  233. }
  234. typedef struct _csmem_item {
  235. unsigned long long csmem_buffer_addr;
  236. unsigned int md_offset;
  237. unsigned int csmem_buffer_size;
  238. unsigned int item_cnt;
  239. } csmem_item_t;
  240. static csmem_item_t csmem_info;
  241. #if WITH_GZ_MD_SHAREMEM
  242. extern BOOT_ARGUMENT *g_boot_arg;
  243. #endif
  244. static int cal_nc_share_mem_size(void)
  245. {
  246. unsigned int align_sz, nc_size, offset, size;
  247. /* MD Share memory layout */
  248. /* AP <--> MD1 */
  249. smem_info.ap_md1_smem_offset = 0;
  250. smem_info.md1_md3_smem_offset = 0;
  251. smem_info.ap_md3_smem_offset = 0;
  252. smem_info.md1_md3_smem_size = 0;
  253. smem_info.ap_md3_smem_size = 0;
  254. nc_size = 0;
  255. /* AP/MD CCCI */
  256. offset = 0;
  257. size = AP_MD1_SMEM_SIZE;
  258. nc_size += size;
  259. ALWAYS_LOG("[NC] block: AP/MD CCCI: 0x%x(0x%x)<0x%x>\n", offset, size, nc_size);
  260. /* UDC */
  261. if (udc_support_at_img) {
  262. size = CCCI_SMEM_SIZE_UDC_NONCACHE;
  263. align_sz = get_align_sz_by_user(nc_size, SMEM_USER_RAW_UDC_DATA);
  264. ALWAYS_LOG("[NC] align size for UDC: 0x%x\n", align_sz);
  265. nc_size += align_sz;
  266. offset = nc_size;
  267. nc_size += size;
  268. ALWAYS_LOG("[NC] block: UDC: 0x%x(0x%x)<0x%x>\n", offset, size, nc_size);
  269. update_nc_smem_info(SMEM_USER_RAW_UDC_DATA, offset, offset, size);
  270. }
  271. /* WIFI Proxy */
  272. size = CCCI_SMEM_WIFI_MD_PROXY;
  273. align_sz = get_align_sz_by_user(nc_size, SMEM_USER_MD_WIFI_PROXY);
  274. ALWAYS_LOG("[NC] align size for WIFI Proxy: 0x%x\n", align_sz);
  275. nc_size += align_sz;
  276. offset = nc_size;
  277. nc_size += size;
  278. ALWAYS_LOG("[NC] block: WIFI proxy: 0x%x(0x%x)<0x%x>\n", offset, size, nc_size);
  279. update_nc_smem_info(SMEM_USER_MD_WIFI_PROXY, offset, offset, size);
  280. /* DFD */
  281. size = CCCI_SMEM_SIZE_DFD;
  282. align_sz = get_align_sz_by_user(nc_size, SMEM_USER_RAW_DFD_K);
  283. ALWAYS_LOG("[NC] align size for DFD: 0x%x\n", align_sz);
  284. nc_size += align_sz;
  285. offset = nc_size;
  286. nc_size += size;
  287. ALWAYS_LOG("[NC] block: DFD: 0x%x(0x%x)<0x%x>\n", offset, size, nc_size);
  288. update_nc_smem_info(SMEM_USER_RAW_DFD_K, offset, offset, size);
  289. align_sz = get_align_sz(nc_size, 0x10000); /* 64K align */
  290. ALWAYS_LOG("[NC] align size for final: 0x%x\n", align_sz);
  291. nc_size += align_sz;
  292. smem_info.ap_md1_smem_size = nc_size;
  293. /* total_smem_size: in factly, this is for MD MPU, not ap-md share total size. */
  294. smem_info.total_smem_size = nc_size;
  295. ALWAYS_LOG("smem_info.ap_md1_smem_offset: %x\n", smem_info.ap_md1_smem_offset);
  296. ALWAYS_LOG("smem_info.ap_md1_smem_size: %x\n", smem_info.ap_md1_smem_size);
  297. ALWAYS_LOG("smem_info.ap_md3_smem_offset: %x\n", smem_info.ap_md3_smem_offset);
  298. ALWAYS_LOG("smem_info.ap_md3_smem_size: %x\n", smem_info.ap_md3_smem_size);
  299. ALWAYS_LOG("smem_info.md1_md3_smem_offset: %x\n", smem_info.md1_md3_smem_offset);
  300. ALWAYS_LOG("smem_info.md1_md3_smem_size: %x\n", smem_info.md1_md3_smem_size);
  301. ALWAYS_LOG("smem_info.total_smem_size: %x\n", smem_info.total_smem_size);
  302. ALWAYS_LOG("amms_pos_offset: %x\n", amms_pos_offset);
  303. add_nc_smem_to_tag_inf();
  304. return (int)smem_info.total_smem_size; /* non-cacheable */
  305. }
  306. #define SMEM_MD_CONSYS_SIZE (4*1024*1024) /* must be 4M or 0M */
  307. #define SMEM_MD_NVRAM_CACHE_SIZE (15*1024*1024) /* LID */
  308. #define SMEM_MD_USIP_SIZE (384*1024) /* Audio */
  309. static csmem_item_t csmem_layout[] = {
  310. {0, 0, SMEM_MD_CONSYS_SIZE, SMEM_USER_RAW_MD_CONSYS},
  311. {0, 0, SMEM_MD_NVRAM_CACHE_SIZE, SMEM_USER_MD_NVRAM_CACHE},
  312. {0, 0, (22*1024*1024), SMEM_USER_CCB_START},
  313. {0, 0, 0, SMEM_USER_RAW_UDC_DESCTAB},
  314. {0, 0, SMEM_MD_USIP_SIZE, SMEM_USER_RAW_USIP}, /* audio */
  315. };
  316. /* Dynamic CCB seciton */
  317. struct ccb_gear_id_mapping {
  318. unsigned int gear_id;
  319. unsigned int size;
  320. };
  321. const struct ccb_gear_id_mapping ccb_support_tbl[] = {
  322. {1, 22 * 1024 * 1024},
  323. {2, 12 * 1024 * 1024},
  324. {3, 0 * 1024 * 1024},
  325. {11, 4 * 1024 * 1024},
  326. {12, 64 * 1024 * 1024}
  327. };
  328. static unsigned int get_ccb_size_from_gear_id(unsigned int gear_id)
  329. {
  330. int i;
  331. for (i = 0; i < (int)(sizeof(ccb_support_tbl)/sizeof(struct ccb_gear_id_mapping)); i++) {
  332. if (gear_id == ccb_support_tbl[i].gear_id)
  333. return ccb_support_tbl[i].size;
  334. }
  335. return 0xFFFFFFFF;
  336. }
  337. static void set_ccb_gear_val(unsigned int gear_id)
  338. {
  339. int ret;
  340. char env_buf[12];
  341. memset(env_buf, 0, sizeof(env_buf));
  342. snprintf(env_buf, sizeof(env_buf), "%u", gear_id);
  343. ret = set_env("md1_ccb_cap_gear", env_buf);
  344. if (ret < 0) {
  345. ALWAYS_LOG("set env[md1_ccb_cap_gear]fail, ret=%d\n", ret);
  346. assert(0);
  347. } else
  348. ALWAYS_LOG("set env[md1_ccb_cap_gear]%d\n", gear_id);
  349. }
  350. static unsigned int get_ccb_gear_val(void)
  351. {
  352. unsigned int md1_ccb_cap_gear;
  353. unsigned int md1_ccb_size;
  354. if (g_boot_mode == META_BOOT || true == get_atm_enable_status()) {
  355. ALWAYS_LOG("meta mode[md1_ccb_cap_gear]%d\n", CCB_DATA_BUF_DEFAULT_GEAR);
  356. set_ccb_gear_val(CCB_DATA_BUF_DEFAULT_GEAR);
  357. return CCB_DATA_BUF_DEFAULT_GEAR;
  358. }
  359. md1_ccb_cap_gear = str2uint(get_env("md1_ccb_cap_gear"));
  360. if (md1_ccb_cap_gear != 0) {
  361. md1_ccb_size = get_ccb_size_from_gear_id(md1_ccb_cap_gear);
  362. if (md1_ccb_size == 0xFFFFFFFF) {
  363. ALWAYS_LOG("CCB cfg abnormal!!! un-support ccb gear id: %d\n", md1_ccb_cap_gear);
  364. assert(0);
  365. }
  366. ALWAYS_LOG("get env[md1_ccb_cap_gear]%d\n", md1_ccb_cap_gear);
  367. return md1_ccb_cap_gear;
  368. } else {
  369. #ifdef MTK_DYNAMIC_CCB_BUFFER_GEAR_ID
  370. md1_ccb_cap_gear = MTK_DYNAMIC_CCB_BUFFER_GEAR_ID;
  371. #else
  372. md1_ccb_cap_gear = CCB_DATA_BUF_DEFAULT_GEAR;
  373. #endif
  374. set_ccb_gear_val(md1_ccb_cap_gear);
  375. return md1_ccb_cap_gear;
  376. }
  377. }
  378. static void set_gear_id_list()
  379. {
  380. int ret;
  381. ret = set_env("md1_ccb_gear_list",
  382. "1(2,20);2(2,10);3(0,0);11(2,2);12(2,62)");
  383. if (ret) {
  384. ALWAYS_LOG("set_gear_id_list error: %x\n", ret);
  385. }
  386. }
  387. static int cal_c_smem_size_and_layout(int load_flag)
  388. {
  389. unsigned int md1_ccb_cap_gear;
  390. unsigned int md1_phy_cap_gear;
  391. unsigned int md1_bank4_cache_offset;
  392. unsigned int md1_ccb_size = CCB_DATA_BUF_SIZE;
  393. unsigned char * ccb_data_buf = NULL;
  394. unsigned char *cacheable_buf = NULL;
  395. unsigned int cacheable_buf_sz = 0;
  396. unsigned int i;
  397. unsigned int alignment;
  398. unsigned int offset;
  399. unsigned int region_size;
  400. unsigned int padding_size;
  401. #if WITH_GZ_MD_SHAREMEM
  402. unsigned int mtee_support = 1;
  403. #endif
  404. ALWAYS_LOG("smem_info.base_addr: %x\n", (unsigned int)smem_info.base_addr);
  405. md1_ccb_cap_gear = get_ccb_gear_val();
  406. md1_ccb_size = get_ccb_size_from_gear_id(md1_ccb_cap_gear);
  407. set_gear_id_list();
  408. ALWAYS_LOG("allocate ccb data buffer0x%x\n", md1_ccb_size);
  409. if (insert_ccci_tag_inf("ccb_gear_id", (char*)&md1_ccb_cap_gear, sizeof(unsigned int)) < 0)
  410. ALWAYS_LOG("insert ccb_gear_id fail\n");
  411. /* cacheable MD cacheable share memory layout */
  412. offset = 0;
  413. for (i = 0; i < sizeof(csmem_layout)/sizeof(csmem_item_t); i++) {
  414. /* Runtime update for special */
  415. switch (csmem_layout[i].item_cnt) {
  416. case SMEM_USER_RAW_MD_CONSYS:
  417. //csmem_layout[i].csmem_buffer_size = consys_size_at_img;
  418. csmem_layout[i].csmem_buffer_size = 4*1024*1024;
  419. break;
  420. case SMEM_USER_CCB_START:
  421. csmem_layout[i].csmem_buffer_size = md1_ccb_size;
  422. break;
  423. case SMEM_USER_RAW_UDC_DESCTAB:
  424. if (udc_support_at_img) {
  425. csmem_layout[i].csmem_buffer_size = CCCI_SMEM_SIZE_UDC_CACHE;
  426. ALWAYS_LOG("UDC cache size: 0x%x\n", CCCI_SMEM_SIZE_UDC_CACHE);
  427. }
  428. break;
  429. default:
  430. break;
  431. }
  432. region_size = csmem_layout[i].csmem_buffer_size;
  433. alignment = get_align_ref(csmem_layout[i].item_cnt);
  434. if (offset && alignment) {
  435. padding_size = get_align_sz(offset, alignment);
  436. if (padding_size) {
  437. offset += padding_size;
  438. cacheable_buf_sz += padding_size;
  439. }
  440. } else
  441. padding_size = 0;
  442. csmem_layout[i].md_offset = offset;
  443. cacheable_buf_sz += region_size;
  444. offset += region_size;
  445. }
  446. if (cacheable_buf_sz != 0) {
  447. ALWAYS_LOG("[C] before align: 0x%x\n", cacheable_buf_sz);
  448. cacheable_buf_sz += get_align_sz(cacheable_buf_sz, 0x10000);
  449. ALWAYS_LOG("[C] after align: 0x%x\n", cacheable_buf_sz);
  450. cacheable_buf = ccci_request_named_mem("ap_md_c_smem", cacheable_buf_sz);
  451. }
  452. if (cacheable_buf_sz == 0) {
  453. csmem_info.csmem_buffer_addr = 0;
  454. csmem_info.csmem_buffer_size = 0;
  455. csmem_info.item_cnt = 0;
  456. ccb_info.ccb_data_buffer_addr = 0;
  457. ccb_info.ccb_data_buffer_size = 0;
  458. ALWAYS_LOG("allocate ccb data buffer share memory fail\n");
  459. } else {
  460. csmem_info.csmem_buffer_addr = (unsigned long long)((unsigned long)cacheable_buf);
  461. csmem_info.md_offset = MAX_SMEM_SIZE - CACHABLE_SMEM_MAX_SIZE;
  462. csmem_info.csmem_buffer_size = cacheable_buf_sz;
  463. csmem_info.item_cnt = sizeof(csmem_layout)/sizeof(csmem_item_t);
  464. ALWAYS_LOG("cache_buffer_addr: %x\n", (unsigned int)csmem_info.csmem_buffer_addr);
  465. ALWAYS_LOG("cache_buffer_size: %x\n", csmem_info.csmem_buffer_size);
  466. ALWAYS_LOG("cache_buffer_itm_cnt: %x\n", (unsigned int)csmem_info.item_cnt);
  467. for (i = 0; i < sizeof(csmem_layout)/sizeof(csmem_item_t); i++) {
  468. csmem_layout[i].csmem_buffer_addr = (unsigned long long)csmem_layout[i].md_offset
  469. + csmem_info.csmem_buffer_addr;
  470. if (csmem_layout[i].item_cnt == SMEM_USER_CCB_START)
  471. ccb_data_buf = csmem_layout[i].csmem_buffer_addr;
  472. }
  473. if (insert_ccci_tag_inf("md1_bank4_cache_info", (char *)&csmem_info,
  474. sizeof(csmem_info)) < 0)
  475. ALWAYS_LOG("insert md1_smem_cahce_info fail\n");
  476. if (insert_ccci_tag_inf("md1_bank4_cache_layout", (char *)&csmem_layout,
  477. sizeof(csmem_layout)) < 0)
  478. ALWAYS_LOG("insert md1_smem_cahce_layout fail\n");
  479. for (i = 0; i < sizeof(csmem_layout)/sizeof(csmem_item_t); i++) {
  480. ALWAYS_LOG("cache[%d]_buffer_addr: %x\n", i,
  481. (unsigned int)csmem_layout[i].csmem_buffer_addr);
  482. ALWAYS_LOG("cache[%d]_buffer_offset: %x\n", i,
  483. (unsigned int)csmem_layout[i].md_offset);
  484. ALWAYS_LOG("cache[%d]_buffer_size: %x\n", i,
  485. csmem_layout[i].csmem_buffer_size);
  486. }
  487. //ccb_data_buf = cacheable_buf + SMEM_MD_CONSYS_SIZE;
  488. ccb_info.ccb_data_buffer_addr = (unsigned long long)((unsigned long)ccb_data_buf);
  489. ccb_info.ccb_data_buffer_size = md1_ccb_size;
  490. /* CCB must in last 2*32M */
  491. md1_bank4_cache_offset = MAX_SMEM_SIZE - CACHABLE_SMEM_MAX_SIZE;
  492. if (insert_ccci_tag_inf("md1_smem_cahce_offset", (char*)&md1_bank4_cache_offset,
  493. sizeof(md1_bank4_cache_offset)) < 0)
  494. ALWAYS_LOG("insert md1_smem_cahce_offset fail\n");
  495. if (insert_ccci_tag_inf("ccb_info", (char*)&ccb_info, sizeof(ccb_layout_t)) < 0)
  496. ALWAYS_LOG("insert ccb_info fail\n");
  497. ALWAYS_LOG("ccb_info.ccb_data_buffer_addr: %x\n", (unsigned int)ccb_info.ccb_data_buffer_addr);
  498. ALWAYS_LOG("ccb_info.ccb_data_buffer_size: %x\n", ccb_info.ccb_data_buffer_size);
  499. }
  500. /* cacheable memory End */
  501. ALWAYS_LOG("smem_info.total_smem_size: %x\n", smem_info.total_smem_size);
  502. /* insert share memory layout to lk info */
  503. if (insert_ccci_tag_inf("smem_layout", (char*)&smem_info, sizeof(smem_layout_t)) < 0)
  504. ALWAYS_LOG("insert smem_layout fail\n");
  505. /* slot 5 */
  506. #if WITH_GZ_MD_SHAREMEM
  507. if (g_boot_arg->gz_md_shm_pa && g_boot_arg->gz_md_shm_sz) {
  508. ALWAYS_LOG("mtee.base_addr: 0x%x, 0x%x\n",
  509. (unsigned int)g_boot_arg->gz_md_shm_pa, g_boot_arg->gz_md_shm_sz);
  510. if (insert_ccci_tag_inf("mtee_support", (char *)&mtee_support,
  511. sizeof(mtee_support)) < 0)
  512. ALWAYS_LOG("insert mtee_support fail\n");
  513. }
  514. #endif
  515. return (int)smem_info.total_smem_size;
  516. }
  517. /***************************************************************************************************
  518. ** HW remap section
  519. ***************************************************************************************************/
  520. extern unsigned int ddr_enable_4gb(void)__attribute__((weak));
  521. static int is_4gb_ddr_support_en(void)
  522. {
  523. int ret;
  524. if (ddr_enable_4gb) {
  525. ret = ddr_enable_4gb();
  526. ALWAYS_LOG("ddr_enable_4GB sta:%d\n", ret);
  527. return ret;
  528. } else {
  529. ALWAYS_LOG("ddr 4GB disable\n");
  530. return 0;
  531. }
  532. }
  533. int md_sib_rw_remapping(unsigned long long addr){}
  534. /*-------- Register base part -------------------------------*/
  535. /* HW remap for MD1 */
  536. #define INFRA_AO_BASE (0x10001000)
  537. /* -- MD1 Bank 0 */
  538. #define MD1_BANK0_MAP0 (INFRA_AO_BASE + 0x300)
  539. #define MD1_BANK0_MAP1 (INFRA_AO_BASE + 0x304)
  540. #define MD1_BANK0_MAP2 (INFRA_AO_BASE + 0x308)
  541. #define MD1_BANK0_MAP3 (INFRA_AO_BASE + 0x30C)
  542. /* -- MD1 Bank 1 */
  543. #define MD1_BANK1_MAP0 (INFRA_AO_BASE + 0x310)
  544. #define MD1_BANK1_MAP1 (INFRA_AO_BASE + 0x314)
  545. #define MD1_BANK1_MAP2 (INFRA_AO_BASE + 0x318)
  546. #define MD1_BANK1_MAP3 (INFRA_AO_BASE + 0x31C)
  547. /* -- MD1 Bank 4 */
  548. #define MD1_BANK4_MAP0 (INFRA_AO_BASE + 0x320)
  549. #define MD1_BANK4_MAP1 (INFRA_AO_BASE + 0x324)
  550. #define MD1_BANK4_MAP2 (INFRA_AO_BASE + 0x328)
  551. #define MD1_BANK4_MAP3 (INFRA_AO_BASE + 0x32C)
  552. /* HW remap lock register */
  553. #define MD_HW_REMAP_LOCK (INFRA_AO_BASE + 0xF80)
  554. #define MD1_LOCK (1<<16)
  555. static int md_mem_ro_rw_remapping(unsigned int md_id, unsigned long long addr)
  556. {
  557. unsigned long long md_img_start_addr;
  558. unsigned int hw_remapping_bank0_map0 = 0;
  559. unsigned int hw_remapping_bank0_map1 = 0;
  560. unsigned int hw_remapping_bank0_map2 = 0;
  561. unsigned int hw_remapping_bank0_map3 = 0;
  562. unsigned int write_val;
  563. switch (md_id) {
  564. case 0: // MD1
  565. hw_remapping_bank0_map0 = MD1_BANK0_MAP0;
  566. hw_remapping_bank0_map1 = MD1_BANK0_MAP1;
  567. hw_remapping_bank0_map2 = MD1_BANK0_MAP2;
  568. hw_remapping_bank0_map3 = MD1_BANK0_MAP3;
  569. break;
  570. default:
  571. ALWAYS_LOG("Invalid md id:%d\n", md_id);
  572. return -1;
  573. }
  574. md_img_start_addr = addr;
  575. ALWAYS_LOG("---> Map 0x00000000 to 0x%llx for MD%d\n", addr, md_id+1);
  576. /* For MDx_BANK0_MAP0 */
  577. write_val = (((md_img_start_addr >> 24) | 0x1) & 0x3FF)
  578. + ((((md_img_start_addr + 0x2000000*1) >> 8) | 1<<16) & 0x3FF0000);
  579. DRV_WriteReg32(hw_remapping_bank0_map0, write_val);
  580. ALWAYS_LOG("BANK0_MAP0 value:0x%X\n", DRV_Reg32(hw_remapping_bank0_map0));
  581. /* For MDx_BANK0_MAP1 */
  582. write_val = ((((md_img_start_addr + 0x2000000*2) >> 24) | 0x1) & 0x3FF)
  583. + ((((md_img_start_addr + 0x2000000*3) >> 8) | 1<<16) & 0x3FF0000);
  584. DRV_WriteReg32(hw_remapping_bank0_map1, write_val);
  585. ALWAYS_LOG("BANK0_MAP1 value:0x%X\n", DRV_Reg32(hw_remapping_bank0_map1));
  586. /* For MDx_BANK0_MAP2 */
  587. write_val = ((((md_img_start_addr + 0x2000000*4) >> 24) | 0x1) & 0x3FF)
  588. + ((((md_img_start_addr + 0x2000000*5) >> 8) | 1<<16) & 0x3FF0000);
  589. DRV_WriteReg32(hw_remapping_bank0_map2, write_val);
  590. ALWAYS_LOG("BANK0_MAP2 value:0x%X\n", DRV_Reg32(hw_remapping_bank0_map2));
  591. /* For MDx_BANK0_MAP3 */
  592. write_val = ((((md_img_start_addr + 0x2000000*6) >> 24) | 0x1) & 0x3FF)
  593. + ((((md_img_start_addr + 0x2000000*7) >> 8) | 1<<16) & 0x3FF0000);
  594. DRV_WriteReg32(hw_remapping_bank0_map3, write_val);
  595. ALWAYS_LOG("BANK0_MAP3 value:0x%X\n", DRV_Reg32(hw_remapping_bank0_map3));
  596. #ifdef DUMMY_AP_MODE
  597. /* For 256~512MB */
  598. if (md_id == MD_SYS1) {
  599. write_val = ((((md_img_start_addr + 0x2000000*8) >> 24) | 0x1) & 0x3FF)
  600. + ((((md_img_start_addr + 0x2000000*9) >> 8) | 1<<16) & 0x3FF0000);
  601. DRV_WriteReg32(MD1_BANK1_MAP0, write_val);
  602. ALWAYS_LOG("BANK1_MAP0 value:0x%X\n", DRV_Reg32(MD1_BANK1_MAP0));
  603. write_val = ((((md_img_start_addr + 0x2000000*10) >> 24) | 0x1) & 0x3FF)
  604. + ((((md_img_start_addr + 0x2000000*11) >> 8) | 1<<16) & 0x3FF0000);
  605. DRV_WriteReg32(MD1_BANK1_MAP1, write_val);
  606. ALWAYS_LOG("BANK1_MAP1 value:0x%X\n", DRV_Reg32(MD1_BANK1_MAP1));
  607. write_val = ((((md_img_start_addr + 0x2000000*12) >> 24) | 0x1) & 0x3FF)
  608. + ((((md_img_start_addr + 0x2000000*13) >> 8) | 1<<16) & 0x3FF0000);
  609. DRV_WriteReg32(MD1_BANK1_MAP2, write_val);
  610. ALWAYS_LOG("BANK1_MAP2 value:0x%X\n", DRV_Reg32(MD1_BANK1_MAP2));
  611. write_val = ((((md_img_start_addr + 0x2000000*14) >> 24) | 0x1) & 0x3FF)
  612. + ((((md_img_start_addr + 0x2000000*15) >> 8) | 1<<16) & 0x3FF0000);
  613. DRV_WriteReg32(MD1_BANK1_MAP3, write_val);
  614. ALWAYS_LOG("BANK1_MAP3 value:0x%X\n", DRV_Reg32(MD1_BANK1_MAP3));
  615. }
  616. #endif
  617. return 0;
  618. }
  619. static int md_bank4_remapping_by_slot(unsigned int md_id, unsigned long long addr, int slot)
  620. {
  621. unsigned int hw_remapping_bank4_map0 = 0;
  622. unsigned int hw_remapping_bank4_map1 = 0;
  623. unsigned int hw_remapping_bank4_map2 = 0;
  624. unsigned int hw_remapping_bank4_map3 = 0;
  625. unsigned int curr_val;
  626. switch (md_id) {
  627. case 0: // MD1
  628. hw_remapping_bank4_map0 = MD1_BANK4_MAP0;
  629. hw_remapping_bank4_map1 = MD1_BANK4_MAP1;
  630. hw_remapping_bank4_map2 = MD1_BANK4_MAP2;
  631. hw_remapping_bank4_map3 = MD1_BANK4_MAP3;
  632. break;
  633. default:
  634. ALWAYS_LOG("Invalid md id:%d\n", md_id);
  635. return -1;
  636. }
  637. switch(slot) {
  638. case 0:
  639. curr_val = DRV_Reg32(hw_remapping_bank4_map0);
  640. curr_val &= ~0x3FF;
  641. curr_val |= (((addr >> 24) | 0x1) & 0x3FF);
  642. DRV_WriteReg32(hw_remapping_bank4_map0, curr_val);
  643. ALWAYS_LOG("BANK4_MAP0 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map0));
  644. break;
  645. case 1:
  646. curr_val = DRV_Reg32(hw_remapping_bank4_map0);
  647. curr_val &= ~0x3FF0000;
  648. curr_val |= (((addr >> 8) | (1<<16)) & 0x3FF0000);
  649. DRV_WriteReg32(hw_remapping_bank4_map0, curr_val);
  650. ALWAYS_LOG("BANK4_MAP0 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map0));
  651. break;
  652. case 2:
  653. curr_val = DRV_Reg32(hw_remapping_bank4_map1);
  654. curr_val &= ~0x3FF;
  655. curr_val |= (((addr >> 24) | 0x1) & 0x3FF);
  656. DRV_WriteReg32(hw_remapping_bank4_map1, curr_val);
  657. ALWAYS_LOG("BANK4_MAP1 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map1));
  658. break;
  659. case 3:
  660. curr_val = DRV_Reg32(hw_remapping_bank4_map1);
  661. curr_val &= ~0x3FF0000;
  662. curr_val |= (((addr >> 8) | (1<<16)) & 0x3FF0000);
  663. DRV_WriteReg32(hw_remapping_bank4_map1, curr_val);
  664. ALWAYS_LOG("BANK4_MAP1 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map1));
  665. break;
  666. case 4:
  667. curr_val = DRV_Reg32(hw_remapping_bank4_map2);
  668. curr_val &= ~0x3FF;
  669. curr_val |= (((addr >> 24) | 0x1) & 0x3FF);
  670. DRV_WriteReg32(hw_remapping_bank4_map2, curr_val);
  671. ALWAYS_LOG("BANK4_MAP2 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map2));
  672. break;
  673. case 5:
  674. curr_val = DRV_Reg32(hw_remapping_bank4_map2);
  675. curr_val &= ~0x3FF0000;
  676. curr_val |= (((addr >> 8) | (1<<16)) & 0x3FF0000);
  677. DRV_WriteReg32(hw_remapping_bank4_map2, curr_val);
  678. ALWAYS_LOG("BANK4_MAP2 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map2));
  679. break;
  680. case 6:
  681. curr_val = DRV_Reg32(hw_remapping_bank4_map3);
  682. curr_val &= ~0x3FF;
  683. curr_val |= (((addr >> 24) | 0x1) & 0x3FF);
  684. DRV_WriteReg32(hw_remapping_bank4_map3, curr_val);
  685. ALWAYS_LOG("BANK4_MAP3 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map3));
  686. break;
  687. case 7:
  688. curr_val = DRV_Reg32(hw_remapping_bank4_map3);
  689. curr_val &= ~0x3FF0000;
  690. curr_val |= (((addr >> 8) | (1<<16)) & 0x3FF0000);
  691. DRV_WriteReg32(hw_remapping_bank4_map3, curr_val);
  692. ALWAYS_LOG("BANK4_MAP3 value:0x%X\n", DRV_Reg32(hw_remapping_bank4_map3));
  693. break;
  694. default:
  695. ALWAYS_LOG("Invalid slot id:%d\n", slot);
  696. return -1;
  697. }
  698. return 0;
  699. }
  700. static int md_smem_rw_remapping(unsigned int md_id, unsigned long long addr)
  701. {
  702. unsigned int i, csmem_32M_cnt;
  703. ALWAYS_LOG("---> Map 0x40000000 to 0x%llx for MD%d\n", addr, md_id+1);
  704. csmem_32M_cnt = 8 - CACHABLE_SMEM_MAX_SIZE/(32*1024*1024);
  705. for (i = 0; i < csmem_32M_cnt; i++)
  706. md_bank4_remapping_by_slot(md_id, addr + 0x2000000*i, i);
  707. #if WITH_GZ_MD_SHAREMEM
  708. if (g_boot_arg->gz_md_shm_pa && g_boot_arg->gz_md_shm_sz) {
  709. md_bank4_remapping_by_slot(MD_SYS1, g_boot_arg->gz_md_shm_pa, 5);
  710. }
  711. #endif
  712. /* remapping cacheable to last 2*32M in bank4 */
  713. ALWAYS_LOG("---> Map 0x40000000+0x%x to 0x%llx for MD%d\n", csmem_info.md_offset,
  714. csmem_info.csmem_buffer_addr, md_id+1);
  715. for (i = csmem_32M_cnt; i < 8; i++)
  716. md_bank4_remapping_by_slot(md_id, csmem_info.csmem_buffer_addr + 0x2000000*(i-csmem_32M_cnt), i);
  717. return 0;
  718. }
  719. static void md_emi_remapping_lock(unsigned int md_id)
  720. {
  721. unsigned int reg_val;
  722. unsigned int lock_bit;
  723. switch (md_id) {
  724. case 0: // MD1
  725. lock_bit = MD1_LOCK;
  726. break;
  727. default:
  728. ALWAYS_LOG("Invalid md id:%d for lock\n", md_id);
  729. return;
  730. }
  731. reg_val = DRV_Reg32(MD_HW_REMAP_LOCK);
  732. ALWAYS_LOG("before hw remap lock: MD1[%d]\n", !!(reg_val&MD1_LOCK));
  733. DRV_WriteReg32(MD_HW_REMAP_LOCK, (reg_val|lock_bit));
  734. reg_val = DRV_Reg32(MD_HW_REMAP_LOCK);
  735. ALWAYS_LOG("before hw remap lock: MD1[%d]\n", !!(reg_val&MD1_LOCK));
  736. }
  737. /* =================================================== */
  738. /* MPU Region defination */
  739. /* =================================================== */
  740. /* Note: This structure should sync with Kernel!!!! */
  741. typedef unsigned long long mpu_att_t;
  742. typedef struct _mpu_cfg {
  743. unsigned int start;
  744. unsigned int end;
  745. int region;
  746. unsigned int permission[EMI_MPU_DGROUP_NUM];
  747. int relate_region;
  748. } mpu_cfg_t;
  749. #define MPU_REGION_ID_MD1_ROM 11
  750. #define MPU_REGION_ID_MD_DSP1 12 /*DSP RO*/
  751. #define MPU_REGION_ID_MD_DSP2 13 /*DSP RW*/
  752. #define MPU_REGION_ID_MD_DRDI 14
  753. #define MPU_REGION_ID_MD1_MCURW_HWRW 15
  754. #define MPU_REGION_ID_MD1_MCURW_HWRO 16
  755. #define MPU_REGION_ID_MD1_MCURO_HWRW 17
  756. /*#define MPU_REGION_ID_PADDING1 17*/
  757. /*#define MPU_REGION_ID_PADDING2 18*/
  758. #define MPU_REGION_ID_PADDING3 19
  759. #define MPU_REGION_ID_PADDING4 20
  760. #define MPU_REGION_ID_PADDING5 21
  761. #define MPU_REGION_ID_MD_PROTECT 22
  762. #define MPU_REGION_ID_MD_CONSYS 23
  763. #define MPU_REGION_ID_MD1_CCB 24
  764. #define MPU_REGION_ID_MD1_SMEM 25
  765. #define MPU_REGION_ID_AP 31
  766. #define MPU_REGION_ID_TOTAL_NUM (MPU_REGION_ID_AP + 1)
  767. #define MPU_MDOMAIN_ID_AP 0
  768. #define MPU_MDOMAIN_ID_MD1 1
  769. #define MPU_MDOMAIN_ID_MDHW 7
  770. #define MPU_MDOMAIN_ID_TOTAL_NUM 16
  771. static const mpu_att_t mpu_att_default[MPU_REGION_ID_TOTAL_NUM][MPU_MDOMAIN_ID_TOTAL_NUM] = {
  772. /*===================================================================================================================*/
  773. /* No | | D0(AP) | D1(MD1) | D2(CONN) | D3(SCP) | D4(MM) | D5(Rsv ) | D6(MFG) | D7(MDHW)
  774. |D8(SSPM) |D9(SPM) |D10(ADSP) | D11-15(Rsv) */
  775. /*--------------+-----------------------------------------------------------------------------------------------------------------------*/
  776. /* 0*/{}, /*Secure OS*/
  777. /* 1*/{}, /*ATF*/
  778. /* 2*/{}, /*Secure Memory*/
  779. /* 3*/{}, /*Tinysys-SSPM ROM*/
  780. /* 4*/{}, /*Tinysys-SSPM share buffer*/
  781. /* 5*/{}, /*Tinysys-SCP ROM*/
  782. /* 6*/{}, /*Tinysys-SCP share buffer*/
  783. /* 7*/{}, /*Trusted UI*/
  784. /* 8*/{}, /*AMMS*/
  785. /* 9*/{}, /*AMMS*/
  786. /*10*/{}, /*Security CCCI share*/
  787. /*11*/{ SEC_R_NSEC_R, SEC_R_NSEC_R, [2 ... 6] = FORBIDDEN, SEC_R_NSEC_R, [8 ... 15] = FORBIDDEN},
  788. /*12*/{ SEC_R_NSEC_R, SEC_R_NSEC_R, [2 ... 6] = FORBIDDEN, SEC_R_NSEC_R, [8 ... 15] = FORBIDDEN},
  789. /*13*/{ SEC_R_NSEC_R, NO_PROTECTION, [2 ... 6] = FORBIDDEN, NO_PROTECTION, [8 ... 15] = FORBIDDEN},
  790. /*14*/{ SEC_R_NSEC_R, SEC_R_NSEC_R, [2 ... 6] = FORBIDDEN, SEC_R_NSEC_R, [8 ... 15] = FORBIDDEN}, /*DRDI*/
  791. /*15*/{ SEC_R_NSEC_R, NO_PROTECTION, [2 ... 6] = FORBIDDEN, NO_PROTECTION, [8 ... 15] = FORBIDDEN},
  792. /*16*/{ SEC_R_NSEC_R, NO_PROTECTION, [2 ... 6] = FORBIDDEN, SEC_R_NSEC_R, [8 ... 15] = FORBIDDEN},
  793. /*17*/{ SEC_R_NSEC_R, SEC_R_NSEC_R, [2 ... 6] = FORBIDDEN, NO_PROTECTION, [8 ... 15] = FORBIDDEN},
  794. // /*17*/{ SEC_R_NSEC_R, FORBIDDEN, [2 ... 6] = FORBIDDEN, FORBIDDEN, [8 ... 15] = FORBIDDEN},
  795. /*18*/{ SEC_R_NSEC_R, FORBIDDEN, [2 ... 6] = FORBIDDEN, FORBIDDEN, [8 ... 15] = FORBIDDEN},
  796. /*19*/{ SEC_R_NSEC_R, FORBIDDEN, [2 ... 6] = FORBIDDEN, FORBIDDEN, [8 ... 15] = FORBIDDEN},
  797. /*20*/{ SEC_R_NSEC_R, FORBIDDEN, [2 ... 6] = FORBIDDEN, FORBIDDEN, [8 ... 15] = FORBIDDEN},
  798. /*21*/{ SEC_R_NSEC_R, FORBIDDEN, [2 ... 6] = FORBIDDEN, FORBIDDEN, [8 ... 15] = FORBIDDEN},
  799. /*22*/{
  800. NO_PROTECTION, SEC_R_NSEC_R, [2 ... 3] = FORBIDDEN, NO_PROTECTION, FORBIDDEN, SEC_R_NSEC_RW,
  801. [7 ... 15] = FORBIDDEN
  802. },
  803. /*23*/{ FORBIDDEN, NO_PROTECTION, NO_PROTECTION, [3 ... 15] = FORBIDDEN},/*MD-Consys Direct Path*/
  804. /*24*/{ NO_PROTECTION, NO_PROTECTION, NO_PROTECTION, [3 ... 6] = FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN,
  805. NO_PROTECTION, [11 ... 15] = FORBIDDEN},
  806. /*25*/{ NO_PROTECTION, NO_PROTECTION, FORBIDDEN, NO_PROTECTION,[4 ... 6] = FORBIDDEN, NO_PROTECTION,
  807. [8 ... 15] = FORBIDDEN},
  808. /*26*/{}, /*WIFI EMI FW*/
  809. /*27*/{}, /*WMT*/
  810. /*28*/{}, /*ADSP*/
  811. /*29*/{}, /*GPS offload*/
  812. /*30*/{}, /*Set in LK MD dynamic*/
  813. /*31*/{
  814. NO_PROTECTION, FORBIDDEN, [2 ... 3] = FORBIDDEN, NO_PROTECTION, FORBIDDEN, SEC_R_NSEC_RW,
  815. FORBIDDEN, NO_PROTECTION, NO_PROTECTION, [10 ... 15] = FORBIDDEN
  816. },
  817. };
  818. #define MPU_STR_BUF_SIZE 64
  819. static void get_mpu_attr_str(int lock, unsigned int apc[EMI_MPU_DGROUP_NUM], char buf[], int size)
  820. {
  821. unsigned long long curr_attr;
  822. char ch = lock?'L':'U';
  823. if (EMI_MPU_DGROUP_NUM != 2) {
  824. ALWAYS_LOG("[error]abnormal mpu domain group number %d\n", EMI_MPU_DGROUP_NUM);
  825. return;
  826. }
  827. curr_attr = ((unsigned long long)apc[1] << 32) | apc[0];
  828. snprintf(buf, size, "%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld-%lld(%c)",
  829. curr_attr&7, (curr_attr>>3)&7, (curr_attr>>6)&7, (curr_attr>>9)&7,
  830. (curr_attr>>12)&7, (curr_attr>>15)&7, (curr_attr>>18)&7, (curr_attr>>21)&7,
  831. (curr_attr>>32)&7, (curr_attr>>35)&7, (curr_attr>>38)&7, (curr_attr>>41)&7,
  832. (curr_attr>>44)&7, (curr_attr>>47)&7, (curr_attr>>50)&7, (curr_attr>>53)&7, ch);
  833. }
  834. static const unsigned char region_mapping_at_hdr_md1[] = {
  835. MPU_REGION_ID_MD1_ROM, MPU_REGION_ID_MD1_MCURO_HWRW, MPU_REGION_ID_MD1_MCURW_HWRO,
  836. MPU_REGION_ID_MD1_MCURW_HWRW
  837. };
  838. static const int free_mpu_region[] = {
  839. MPU_REGION_ID_PADDING3, MPU_REGION_ID_PADDING4, MPU_REGION_ID_PADDING5, MPU_REGION_ID_MD_PROTECT, -1};
  840. static int curr_free_mpu_idx;
  841. static int get_free_mpu_region(void)
  842. {
  843. int ret;
  844. if (curr_free_mpu_idx < (int)(sizeof(free_mpu_region)/sizeof(int))) {
  845. ret = free_mpu_region[curr_free_mpu_idx];
  846. curr_free_mpu_idx++;
  847. } else
  848. ret = -LD_ERR_PLAT_MPU_REGION_EMPTY;
  849. return ret;
  850. }
  851. /*make sure protect region is the last valid region*/
  852. static int get_md_protect_mpu_region(void)
  853. {
  854. int last_index;
  855. last_index = (int)(sizeof(free_mpu_region)/sizeof(int)) -1;
  856. if (free_mpu_region[last_index] < 0) /*free region end by -1*/
  857. last_index--; /*make sure it is index of last valid region*/
  858. if (curr_free_mpu_idx > last_index)
  859. return -LD_ERR_PLAT_MPU_REGION_EMPTY;
  860. return free_mpu_region[last_index];
  861. }
  862. static void get_mpu_region_default_access_att(
  863. unsigned int apc[EMI_MPU_DGROUP_NUM], int region, int lock)
  864. {
  865. #ifdef ENABLE_EMI_PROTECTION
  866. SET_ACCESS_PERMISSION(apc, lock,
  867. mpu_att_default[region][15], mpu_att_default[region][14],
  868. mpu_att_default[region][13], mpu_att_default[region][12],
  869. mpu_att_default[region][11], mpu_att_default[region][10],
  870. mpu_att_default[region][9], mpu_att_default[region][8],
  871. mpu_att_default[region][7], mpu_att_default[region][6],
  872. mpu_att_default[region][5], mpu_att_default[region][4],
  873. mpu_att_default[region][3], mpu_att_default[region][2],
  874. mpu_att_default[region][1], mpu_att_default[region][0]);
  875. #endif
  876. }
  877. static void mpu_attr_calculate(
  878. unsigned int apc[EMI_MPU_DGROUP_NUM], int region_id, unsigned int request_attr)
  879. {
  880. mpu_att_t tmp_mpu_att[MPU_MDOMAIN_ID_TOTAL_NUM], i;
  881. for (i = 0; i < MPU_MDOMAIN_ID_TOTAL_NUM; i++)
  882. tmp_mpu_att[i] = mpu_att_default[region_id][i];
  883. /* AP MD1 MDHW: AP */
  884. if ((request_attr & 0xF) <= FORBIDDEN)
  885. tmp_mpu_att[MPU_MDOMAIN_ID_AP] = (request_attr & 0xF);
  886. /* AP MD1 MDHW: MD1 */
  887. request_attr = (request_attr >> 4);
  888. if ((request_attr & 0xF) <= FORBIDDEN)
  889. tmp_mpu_att[MPU_MDOMAIN_ID_MD1] = (request_attr & 0xF);
  890. /* AP MD1 MDHW: MDHW */
  891. request_attr = (request_attr >> 4);
  892. if ((request_attr & 0xF) <= FORBIDDEN)
  893. tmp_mpu_att[MPU_MDOMAIN_ID_MDHW] = (request_attr & 0xF);
  894. #ifdef ENABLE_EMI_PROTECTION
  895. /* MPU region lock */
  896. SET_ACCESS_PERMISSION(apc, 1,
  897. tmp_mpu_att[15], tmp_mpu_att[14],
  898. tmp_mpu_att[13], tmp_mpu_att[12],
  899. tmp_mpu_att[11], tmp_mpu_att[10],
  900. tmp_mpu_att[9], tmp_mpu_att[8],
  901. tmp_mpu_att[7], tmp_mpu_att[6],
  902. tmp_mpu_att[5], tmp_mpu_att[4],
  903. tmp_mpu_att[3], tmp_mpu_att[2],
  904. tmp_mpu_att[1], tmp_mpu_att[0]);
  905. #endif
  906. }
  907. static void ccci_mem_access_cfg(mpu_cfg_t *mpu_cfg_list, int clear)
  908. {
  909. #ifdef ENABLE_EMI_PROTECTION
  910. mpu_cfg_t *curr;
  911. struct emi_region_info_t region_info;
  912. unsigned int curr_attr[EMI_MPU_DGROUP_NUM];
  913. char buf[MPU_STR_BUF_SIZE];
  914. int i;
  915. if (NULL == mpu_cfg_list)
  916. return;
  917. SET_ACCESS_PERMISSION(curr_attr, 0,
  918. NO_PROTECTION, NO_PROTECTION, NO_PROTECTION, NO_PROTECTION,
  919. NO_PROTECTION, NO_PROTECTION, NO_PROTECTION, NO_PROTECTION,
  920. NO_PROTECTION, NO_PROTECTION, NO_PROTECTION, NO_PROTECTION,
  921. NO_PROTECTION, NO_PROTECTION, NO_PROTECTION, NO_PROTECTION);
  922. for (curr = mpu_cfg_list; curr->region != -1; curr++) {
  923. if (clear) {
  924. region_info.region = (unsigned int)curr->region;
  925. emi_mpu_clear_protection(&region_info);
  926. get_mpu_attr_str(0, curr_attr, buf, MPU_STR_BUF_SIZE);
  927. ALWAYS_LOG("Clr MPU:S:0x%x E:0x%x A:<%d>[0~15]%s\n",
  928. 0, 0, curr->region, buf);
  929. } else {
  930. region_info.start = curr->start;
  931. region_info.end = curr->end;
  932. region_info.region = (unsigned int)curr->region;
  933. for (i = 0; i < EMI_MPU_DGROUP_NUM; i++)
  934. region_info.apc[i] = curr->permission[i];
  935. emi_mpu_set_protection(&region_info);
  936. get_mpu_attr_str(0, curr->permission, buf, MPU_STR_BUF_SIZE);
  937. ALWAYS_LOG("Set MPU:S:0x%x E:0x%x A:<%d>[0~15]%s\n",
  938. curr->start, curr->end, curr->region, buf);
  939. }
  940. }
  941. #endif
  942. }
  943. /*--------- Implement one by one -------------------------------------------------------------------------------*/
  944. int plat_get_padding_mpu_num(void)
  945. {
  946. return (int)(sizeof(free_mpu_region)/sizeof(unsigned int)) - 1;
  947. }
  948. void plat_notify_secure(unsigned long base_addr)
  949. {
  950. unsigned long addr_get;
  951. mt_secure_call(MTK_SIP_LK_AMMS_MD_BASE_ADDR_AARCH32, base_addr, 0, 0, 0);
  952. addr_get = mt_secure_call(MTK_SIP_LK_AMMS_GET_MD_BASE_ADDR_AARCH32, 0, 0, 0, 0);
  953. ALWAYS_LOG("mt_secure_call: set_addr = 0x%lx, get_addr = 0x%lx\n", base_addr, addr_get);
  954. }
  955. /*---------------------------------------------------------------------------------------------------*/
  956. /* HW remap function implement */
  957. /*---------------------------------------------------------------------------------------------------*/
  958. int plat_apply_hw_remap_for_md_ro_rw(void* info)
  959. {
  960. modem_info_t *md_ld_info = (modem_info_t *)info;
  961. plat_notify_secure(md_ld_info->base_addr);
  962. return md_mem_ro_rw_remapping((unsigned int)md_ld_info->md_id, md_ld_info->base_addr);
  963. }
  964. int plat_apply_hw_remap_for_md_smem(void *addr, int size)
  965. {
  966. /* For share memory final size depends on MD number, just store start address and size
  967. ** actual setting will do later
  968. */
  969. smem_info.base_addr = (unsigned long long)((unsigned long)addr);
  970. return 0;
  971. }
  972. enum SMEM_USER_ID {
  973. SMEM_USER_RAW_DFD = 0,
  974. SMEM_USER_MAX,
  975. };
  976. int get_ccci_md_view_smem_addr_size(unsigned int user_id,
  977. unsigned long long *ap_addr, unsigned int *md_addr, unsigned int *size)
  978. {
  979. int ret = 0;
  980. switch(user_id){
  981. case SMEM_USER_RAW_DFD:
  982. *size = CCCI_SMEM_SIZE_DFD;
  983. if (ap_addr)
  984. *ap_addr = smem_info.base_addr + smem_info.ap_md1_smem_offset + 0x100000;
  985. else
  986. ret = -2;
  987. if (md_addr)
  988. *md_addr = 0x40000000 + smem_info.ap_md1_smem_offset + 0x100000;
  989. else
  990. ret = -3;
  991. break;
  992. default:
  993. ret = -1;
  994. }
  995. if (ret >= 0)
  996. ALWAYS_LOG("[ccci]get_md_view_smem: user_id = 0x%x, ap_addr = 0x%llx, md_addr = 0x%x, size = 0x%x\n",
  997. user_id, *ap_addr, *md_addr, *size);
  998. else
  999. ALWAYS_LOG("[ccci]get_md_view_smem: param error, ret = %d\n", ret);
  1000. return ret;
  1001. }
  1002. /*---------------------------------------------------------------------------------------------------*/
  1003. /* check header info collection by plat_post_hdr_info */
  1004. /*---------------------------------------------------------------------------------------------------*/
  1005. void plat_post_hdr_info(void* hdr, int ver, int id)
  1006. {
  1007. if (id == MD_SYS1) {
  1008. ap_md1_smem_size_at_img =
  1009. ((struct md_check_header_v6*)hdr)->ap_md_smem_size;
  1010. //parsing check-header: AMMS POS, CONSYS
  1011. amms_pos_size_at_img =
  1012. ((struct md_check_header_v6*)hdr)->amms_pos_size;
  1013. consys_size_at_img =
  1014. ((struct md_check_header_v6*)hdr)->consys_size;
  1015. udc_support_at_img =
  1016. ((struct md_check_header_v6*)hdr)->udc_support;
  1017. ALWAYS_LOG("[ccci]parse check-header: amms_pos_size = 0x%x,\
  1018. consys_size = 0x%x, udc_support = %d\n", amms_pos_size_at_img,
  1019. consys_size_at_img, udc_support_at_img);
  1020. }
  1021. }
  1022. /*---------------------------------------------------------------------------------------------------*/
  1023. /* MPU static global variable and mpu relate function implement */
  1024. /*---------------------------------------------------------------------------------------------------*/
  1025. #define MPU_REGION_TOTAL_NUM (16) /* = MD1+MD3 */
  1026. static mpu_cfg_t mpu_tbl[MPU_REGION_TOTAL_NUM];
  1027. static int s_g_curr_mpu_num;
  1028. /*
  1029. ** if set start=0x0, end=0x10000, the actural protected area will be 0x0-0x1FFFF,
  1030. ** here we use 64KB align, MPU actually request 32KB align since MT6582, but this works...
  1031. ** we assume emi_mpu_set_region_protection will round end address down to 64KB align.
  1032. */
  1033. static void dump_received_pure_mpu_setting(struct image_section_desc *mem_info, int item_num)
  1034. {
  1035. int i;
  1036. for (i =0; i < item_num; i++)
  1037. MPU_DBG_LOG("mpu sec dec %d: offset:%x, size:%x, mpu_attr:%x, ext_flag:%x, relate_idx:%x\n", i,
  1038. mem_info[i].offset, mem_info[i].size, mem_info[i].mpu_attr,
  1039. mem_info[i].ext_flag, mem_info[i].relate_idx);
  1040. }
  1041. static int find_bind_mpu_region(mpu_cfg_t *mpu_tbl_hdr, int item_num, unsigned int bind_key)
  1042. {
  1043. int i;
  1044. for (i = 0; i < item_num; i++) {
  1045. if (mpu_tbl_hdr[i].relate_region == (int)bind_key)
  1046. return i;
  1047. }
  1048. return -1;
  1049. }
  1050. static int md1_mpu_setting_process(void *p_md_ld_info, void *p_mem_info, mpu_cfg_t *mpu_tbl_hdr)
  1051. {
  1052. modem_info_t *md_ld_info = (modem_info_t *)p_md_ld_info;
  1053. struct image_section_desc *mem_info = (struct image_section_desc *)p_mem_info;
  1054. int normal_region_num = 0;
  1055. int total_region_num = 0;
  1056. int curr_idx = 0;
  1057. int i, j;
  1058. int all_range_region_idx = -1;
  1059. int bind_idx;
  1060. int free_region_id;
  1061. int didi_region_idx = -1;
  1062. /* Calculate mpu num and padding num */
  1063. for (i = 0; i < MPU_REGION_TOTAL_NUM; i++) {
  1064. if ((mem_info[i].offset == 0) && (mem_info[i].size == 0))
  1065. break;
  1066. if (mem_info[i].ext_flag & MD_ALL_RANGE)
  1067. all_range_region_idx = i;
  1068. if (mem_info[i].ext_flag & MD_DRDI_REGION)
  1069. didi_region_idx = i;
  1070. }
  1071. total_region_num = i;
  1072. dump_received_pure_mpu_setting(mem_info, total_region_num);
  1073. for (i = 0; i < total_region_num; i++) {
  1074. if (mem_info[i].ext_flag & (MD_DRDI_REGION|MD_ALL_RANGE|NEED_REMOVE|NEED_MPU_MORE))
  1075. continue;
  1076. /* Process normal case first */
  1077. if (curr_idx >= (int)(sizeof(region_mapping_at_hdr_md1)/sizeof(unsigned char))) {
  1078. ALWAYS_LOG("[error]md%d: mpu region too more %d\n", md_ld_info->md_id+1,
  1079. (int)(sizeof(region_mapping_at_hdr_md1)/sizeof(unsigned char)));
  1080. return -LD_ERR_PLAT_MPU_REGION_TOO_MORE;
  1081. }
  1082. mpu_tbl_hdr[curr_idx].start = (unsigned int)md_ld_info->base_addr + mem_info[i].offset;
  1083. mpu_tbl_hdr[curr_idx].end = mpu_tbl_hdr[curr_idx].start + mem_info[i].size;
  1084. mpu_tbl_hdr[curr_idx].end = ((mpu_tbl_hdr[curr_idx].end + 0xFFFF)&(~0xFFFF)) - 1;/* 64K align */
  1085. mpu_attr_calculate(
  1086. mpu_tbl_hdr[curr_idx].permission, region_mapping_at_hdr_md1[curr_idx], mem_info[i].mpu_attr);
  1087. mpu_tbl_hdr[curr_idx].region = (int)region_mapping_at_hdr_md1[curr_idx];
  1088. mpu_tbl_hdr[curr_idx].relate_region = mem_info[i].relate_idx;
  1089. curr_idx++;
  1090. normal_region_num++;
  1091. }
  1092. if (normal_region_num != (int)(sizeof(region_mapping_at_hdr_md1)/sizeof(unsigned char))) {
  1093. ALWAYS_LOG("[error]md%d: mpu region not sync %d:%d\n", md_ld_info->md_id+1, normal_region_num,
  1094. (int)(sizeof(region_mapping_at_hdr_md1)/sizeof(unsigned char)));
  1095. return -LD_ERR_PLAT_MPU_REGION_NUM_NOT_SYNC;
  1096. }
  1097. for (i = 0; i < total_region_num; i++) {
  1098. if (mem_info[i].ext_flag & NEED_MPU_MORE) {
  1099. bind_idx = find_bind_mpu_region(mpu_tbl_hdr, curr_idx, mem_info[i].relate_idx);
  1100. if (bind_idx >= 0) {
  1101. mpu_tbl_hdr[curr_idx].start = (unsigned int)md_ld_info->base_addr + mem_info[i].offset;
  1102. mpu_tbl_hdr[curr_idx].end = mpu_tbl_hdr[curr_idx].start + mem_info[i].size;
  1103. /* 64K align */
  1104. mpu_tbl_hdr[curr_idx].end = ((mpu_tbl_hdr[curr_idx].end + 0xFFFF)&(~0xFFFF)) - 1;
  1105. for (j = 0; j < EMI_MPU_DGROUP_NUM; j++)
  1106. mpu_tbl_hdr[curr_idx].permission[j] = mpu_tbl_hdr[bind_idx].permission[j];
  1107. /* setting relate region */
  1108. free_region_id = get_free_mpu_region();
  1109. if (free_region_id < 0) {
  1110. ALWAYS_LOG("[error]abnormal free region id %d +\n", free_region_id);
  1111. return -LD_ERR_PLAT_ABNORMAL_FREE_REGION;
  1112. }
  1113. mpu_tbl_hdr[curr_idx].region = free_region_id;
  1114. mpu_tbl_hdr[curr_idx].relate_region = mem_info[i].relate_idx;
  1115. mpu_tbl_hdr[bind_idx].relate_region = free_region_id;
  1116. curr_idx++;
  1117. } else {
  1118. ALWAYS_LOG("md%d: padding array abnormal\n", md_ld_info->md_id+1);
  1119. return -LD_ERR_PLAT_ABNORMAL_PAD_ARRAY;
  1120. }
  1121. }
  1122. }
  1123. /* Apply DRDI if needed */
  1124. if (didi_region_idx >= 0) {
  1125. get_mpu_region_default_access_att(mpu_tbl_hdr[curr_idx].permission, MPU_REGION_ID_MD_DRDI, 1);
  1126. mpu_tbl_hdr[curr_idx].start = (unsigned int)md_ld_info->base_addr + mem_info[didi_region_idx].offset;
  1127. mpu_tbl_hdr[curr_idx].end = mpu_tbl_hdr[curr_idx].start + mem_info[didi_region_idx].size;
  1128. /* 64K align */
  1129. mpu_tbl_hdr[curr_idx].end = ((mpu_tbl_hdr[curr_idx].end + 0xFFFF)&(~0xFFFF)) - 1;
  1130. mpu_tbl_hdr[curr_idx].region = MPU_REGION_ID_MD_DRDI;
  1131. mpu_tbl_hdr[curr_idx].relate_region = 0;
  1132. curr_idx++;
  1133. }
  1134. /* Apply MD all range mpu protect setting */
  1135. free_region_id = get_md_protect_mpu_region(); //get_free_mpu_region();
  1136. if (free_region_id < 0) {
  1137. ALWAYS_LOG("[error]no more free region\n");
  1138. return -LD_ERR_PLAT_NO_MORE_FREE_REGION;
  1139. }
  1140. get_mpu_region_default_access_att(mpu_tbl_hdr[curr_idx].permission, free_region_id, 1);
  1141. mpu_tbl_hdr[curr_idx].start = (unsigned int)md_ld_info->base_addr + mem_info[all_range_region_idx].offset;
  1142. /*mpu_tbl_hdr[curr_idx].end = mpu_tbl_hdr[curr_idx].start + mem_info[all_range_region_idx].size;*/
  1143. mpu_tbl_hdr[curr_idx].end = mpu_tbl_hdr[curr_idx].start + 256 * 1024 * 1024;
  1144. /* 64K align */
  1145. mpu_tbl_hdr[curr_idx].end = ((mpu_tbl_hdr[curr_idx].end + 0xFFFF)&(~0xFFFF)) - 1;
  1146. mpu_tbl_hdr[curr_idx].region = free_region_id;
  1147. mpu_tbl_hdr[curr_idx].relate_region = 0;
  1148. curr_idx++;
  1149. /* Clear logic relate index to 0 to mark as end */
  1150. for (i = 0; i < curr_idx; i++) {
  1151. if (mpu_tbl_hdr[i].relate_region >= LOGIC_BINDING_IDX_START)
  1152. mpu_tbl_hdr[i].relate_region = 0;
  1153. }
  1154. return curr_idx;
  1155. }
  1156. int plat_send_mpu_info_to_platorm(void *p_md_ld_info, void *p_mem_info)
  1157. {
  1158. modem_info_t *md_ld_info = (modem_info_t *)p_md_ld_info;
  1159. struct image_section_desc *mem_info = (struct image_section_desc *)p_mem_info;
  1160. int md_id = md_ld_info->md_id;
  1161. int ret;
  1162. int i;
  1163. char buf[MPU_STR_BUF_SIZE];
  1164. if (md_id == MD_SYS1) {
  1165. ret = md1_mpu_setting_process(p_md_ld_info, p_mem_info, &mpu_tbl[s_g_curr_mpu_num]);
  1166. if (ret > 0)
  1167. s_g_curr_mpu_num += ret;
  1168. } else if (md_id == MD1_DSP) {
  1169. /* RO part */
  1170. get_mpu_region_default_access_att(mpu_tbl[s_g_curr_mpu_num].permission, MPU_REGION_ID_MD_DSP1, 1);
  1171. mpu_tbl[s_g_curr_mpu_num].start = (unsigned int)md_ld_info->base_addr + mem_info[0].offset;
  1172. mpu_tbl[s_g_curr_mpu_num].end = mpu_tbl[s_g_curr_mpu_num].start + mem_info[0].size;
  1173. mpu_tbl[s_g_curr_mpu_num].region = MPU_REGION_ID_MD_DSP1;
  1174. /* 64K align */
  1175. mpu_tbl[s_g_curr_mpu_num].end = ((mpu_tbl[s_g_curr_mpu_num].end + 0xFFFF)&(~0xFFFF)) - 1;
  1176. s_g_curr_mpu_num++;
  1177. /* RW part */
  1178. get_mpu_region_default_access_att(mpu_tbl[s_g_curr_mpu_num].permission, MPU_REGION_ID_MD_DSP2, 1);
  1179. mpu_tbl[s_g_curr_mpu_num].start = (unsigned int)md_ld_info->base_addr + mem_info[1].offset;
  1180. mpu_tbl[s_g_curr_mpu_num].end = mpu_tbl[s_g_curr_mpu_num].start + mem_info[1].size;
  1181. mpu_tbl[s_g_curr_mpu_num].region = MPU_REGION_ID_MD_DSP2;
  1182. /* 64K align */
  1183. mpu_tbl[s_g_curr_mpu_num].end = ((mpu_tbl[s_g_curr_mpu_num].end + 0xFFFF)&(~0xFFFF)) - 1;
  1184. s_g_curr_mpu_num++;
  1185. }
  1186. for (i =0; i < s_g_curr_mpu_num; i++) {
  1187. get_mpu_attr_str(0, mpu_tbl[i].permission, buf, MPU_STR_BUF_SIZE);
  1188. MPU_DBG_LOG("plat mpu dec %d: region:%d[%d], start:0x%x, end:0x%x, attr:%s\n", i,
  1189. mpu_tbl[i].region, mpu_tbl[i].relate_region, mpu_tbl[i].start, mpu_tbl[i].end, buf);
  1190. }
  1191. return 0;
  1192. }
  1193. #ifdef MPU_REGION_ID_MD_CONSYS
  1194. static void emi_mpu_region_setting(unsigned int region, unsigned long long start, unsigned long long end)
  1195. {
  1196. #ifdef ENABLE_EMI_PROTECTION
  1197. struct emi_region_info_t region_info;
  1198. char buf[MPU_STR_BUF_SIZE];
  1199. SET_ACCESS_PERMISSION(region_info.apc, 0,
  1200. mpu_att_default[region][15], mpu_att_default[region][14],
  1201. mpu_att_default[region][13], mpu_att_default[region][12],
  1202. mpu_att_default[region][11], mpu_att_default[region][10],
  1203. mpu_att_default[region][9], mpu_att_default[region][8],
  1204. mpu_att_default[region][7], mpu_att_default[region][6],
  1205. mpu_att_default[region][5], mpu_att_default[region][4],
  1206. mpu_att_default[region][3], mpu_att_default[region][2],
  1207. mpu_att_default[region][1], mpu_att_default[region][0]);
  1208. region_info.start = start;
  1209. region_info.end = end;
  1210. region_info.region = region;
  1211. emi_mpu_set_protection(&region_info);
  1212. get_mpu_attr_str(0, region_info.apc, buf, MPU_STR_BUF_SIZE);
  1213. ALWAYS_LOG("Set MPU:S:0x%llx E:0x%llx A:<%d>[0~15]%s\n",
  1214. start, end, region, buf);
  1215. #endif
  1216. }
  1217. static void md_special_mpu_set()
  1218. {
  1219. unsigned int i;
  1220. for (i = 0; i < sizeof(csmem_layout)/sizeof(csmem_item_t); i++) {
  1221. if (csmem_layout[i].item_cnt == SMEM_USER_RAW_MD_CONSYS) {
  1222. emi_mpu_region_setting(MPU_REGION_ID_MD_CONSYS,
  1223. (csmem_layout[i].md_offset + csmem_info.csmem_buffer_addr),
  1224. (csmem_layout[i].md_offset +csmem_layout[i].csmem_buffer_size + csmem_info.csmem_buffer_addr - 1));
  1225. break;
  1226. }
  1227. }
  1228. }
  1229. #endif
  1230. static void boot_to_dummy_ap_mode(int load_md_flag);
  1231. /*------------------------------------------------------------------------------------------------*/
  1232. /* Note: This function using global variable
  1233. ** if set start=0x0, end=0x10000, the actural protected area will be 0x0-0x1FFFF,
  1234. ** here we use 64KB align, MPU actually request 32KB align since MT6582, but this works...
  1235. ** we assume emi_mpu_set_region_protection will round end address down to 64KB align.
  1236. */
  1237. int plat_apply_platform_setting(int load_md_flag)
  1238. {
  1239. int smem_final_size;
  1240. #ifdef DUMMY_AP_MODE
  1241. /* This function will never return */
  1242. ALWAYS_LOG("boot to dummy ap mode!!!\n");
  1243. boot_to_dummy_ap_mode(load_md_flag);
  1244. return 0;
  1245. #endif
  1246. /* Check loading validation */
  1247. if (((load_md_flag & (1<<MD_SYS1)) == 0) && (load_md_flag & (1<<MD_SYS3))) {
  1248. ALWAYS_LOG("md3 depends on md1,but md1 not loaded\n");
  1249. return -LD_ERR_PLAT_MD1_NOT_RDY;
  1250. }
  1251. if ((load_md_flag & ((1<<MD_SYS1)|(1<<MD_SYS3))) == 0) {
  1252. ALWAYS_LOG("both md1 and md3 not enable\n");
  1253. return 0;
  1254. }
  1255. smem_final_size = cal_c_smem_size_and_layout(load_md_flag);
  1256. ALWAYS_LOG("ap md1 share mem MPU need configure\n");
  1257. mpu_tbl[s_g_curr_mpu_num].region = MPU_REGION_ID_MD1_SMEM;
  1258. get_mpu_region_default_access_att(mpu_tbl[s_g_curr_mpu_num].permission, MPU_REGION_ID_MD1_SMEM, 0);
  1259. mpu_tbl[s_g_curr_mpu_num].start = (unsigned int)smem_info.base_addr + smem_info.ap_md1_smem_offset;
  1260. mpu_tbl[s_g_curr_mpu_num].end = (unsigned int)smem_info.base_addr + smem_info.ap_md1_smem_offset
  1261. + smem_final_size; /* ap_md1 share && phy_cap had 2M overlap */
  1262. mpu_tbl[s_g_curr_mpu_num].end = ((mpu_tbl[s_g_curr_mpu_num].end + 0xFFFF)&(~0xFFFF)) - 1;
  1263. s_g_curr_mpu_num++;
  1264. /* add for ccb data buffer mpu */
  1265. mpu_tbl[s_g_curr_mpu_num].region = MPU_REGION_ID_MD1_CCB;
  1266. get_mpu_region_default_access_att(mpu_tbl[s_g_curr_mpu_num].permission, MPU_REGION_ID_MD1_CCB, 0);
  1267. mpu_tbl[s_g_curr_mpu_num].start = (unsigned int)csmem_info.csmem_buffer_addr;//ccb_info.ccb_data_buffer_addr;
  1268. mpu_tbl[s_g_curr_mpu_num].end = (unsigned int)csmem_info.csmem_buffer_addr + csmem_info.csmem_buffer_size;//ccb_info.ccb_data_buffer_addr + ccb_info.ccb_data_buffer_size;
  1269. mpu_tbl[s_g_curr_mpu_num].end = ((mpu_tbl[s_g_curr_mpu_num].end + 0xFFFF)&(~0xFFFF)) - 1;
  1270. s_g_curr_mpu_num++;
  1271. mpu_tbl[s_g_curr_mpu_num].region = -1; /* mark for end */
  1272. /* Insert mpu tag info */
  1273. if (insert_ccci_tag_inf("md_mpu_inf", (char*)mpu_tbl, sizeof(mpu_cfg_t)*s_g_curr_mpu_num) < 0)
  1274. ALWAYS_LOG("insert md_mpu_inf fail\n");
  1275. if (insert_ccci_tag_inf("md_mpu_num", (char*)&s_g_curr_mpu_num, sizeof(int)) < 0)
  1276. ALWAYS_LOG("insert md_mpu_num fail\n");
  1277. /* Apply all MPU setting */
  1278. ccci_mem_access_cfg(mpu_tbl, 0);
  1279. #ifdef MPU_REGION_ID_MD_CONSYS
  1280. md_special_mpu_set();
  1281. #endif
  1282. /* Apply share memory HW remap setting and lock it */
  1283. if (load_md_flag & (1<<MD_SYS1)) {
  1284. md_smem_rw_remapping(MD_SYS1, (unsigned int)(smem_info.base_addr + smem_info.ap_md1_smem_offset));
  1285. md_emi_remapping_lock(MD_SYS1);
  1286. }
  1287. return smem_final_size;
  1288. }
  1289. /*****************************************************************************/
  1290. /* Memory --- limit and align settings */
  1291. /*****************************************************************************/
  1292. /* Share memory cacheable for MD */
  1293. #define SMEM_CACHE_ALIGNMENT 0x2000000L
  1294. #define SMEM_CACHE_LIMIT 0x90000000LL
  1295. /* Share memory non-cacheable for MD */
  1296. #define SMEM_NONCACHE_ALIGNMENT 0x2000000L
  1297. #define SMEM_NONCACHE_LIMIT 0x90000000LL
  1298. /* RO + RW memory non-cacheable for MD */
  1299. #define RO_RW_MEM_ALIGNMENT 0x2000000L
  1300. #ifdef DUMMY_AP_MODE
  1301. #define RO_RW_MEM_LIMIT 0xA0000000LL
  1302. #else
  1303. #define RO_RW_MEM_LIMIT 0xC0000000LL
  1304. #endif
  1305. /* SIB memory */
  1306. #define SIB_SMEM_ALIGNMENT 0x4000000L
  1307. #define SIB_SMEM_LIMIT 0x200000000LL
  1308. /*------------------------------------------------------------------------------------------------*/
  1309. /* platform configure setting info. */
  1310. /*------------------------------------------------------------------------------------------------*/
  1311. long long plat_ccci_get_ld_md_plat_setting(char cfg_name[])
  1312. {
  1313. if (strcmp(cfg_name, "share_memory_size") == 0) {
  1314. #ifdef DUMMY_AP_MODE
  1315. return 0x200000;
  1316. #endif
  1317. /* only for non-cacheable part. */
  1318. return (long long)cal_nc_share_mem_size();
  1319. }
  1320. if (strcmp(cfg_name, "share_mem_limit") == 0)
  1321. return 0x90000000LL;
  1322. if (strcmp(cfg_name, "ro_rw_mem_limit") == 0) {
  1323. #ifdef DUMMY_AP_MODE
  1324. return 0x100000000LL;
  1325. #endif
  1326. return 0xC0000000LL;
  1327. }
  1328. if (strcmp(cfg_name, "ro_rw_mem_align") == 0)
  1329. return 0x2000000LL;
  1330. if (strcmp(cfg_name, "share_mem_align") == 0)
  1331. return 0x2000000LL;
  1332. if (strcmp(cfg_name, "ld_version") == 0) {
  1333. #ifdef DUMMY_AP_MODE
  1334. return 0x20001;
  1335. #endif
  1336. return 0x20000;/* xxxx_yyyy, xxxx: main id, yyyy sub id */
  1337. }
  1338. if (strcmp(cfg_name, "rat_plat_ver") == 0)
  1339. return RAT_VER_93;
  1340. return -1LL;
  1341. }
  1342. /* CCCI tag info memory */
  1343. #define TAG_MEM_ALIGNMENT 0x1000L
  1344. #define TAG_MEM_LIMIT 0xC0000000LL
  1345. #define PLAT_DEFAULT_CCB_GEAR 1
  1346. struct mem_attr_setting {
  1347. char *name;
  1348. unsigned long long limit;
  1349. unsigned long align;
  1350. };
  1351. const struct mem_attr_setting c_md_mem_attr_cfg[] = {
  1352. {"ap_md_c_smem", SMEM_CACHE_LIMIT, SMEM_CACHE_ALIGNMENT},
  1353. {"ap_md_nc_smem", SMEM_NONCACHE_LIMIT, SMEM_NONCACHE_ALIGNMENT},
  1354. {"md_mem_usage", RO_RW_MEM_LIMIT, RO_RW_MEM_ALIGNMENT},
  1355. {"ccci_tag_mem", TAG_MEM_LIMIT, TAG_MEM_ALIGNMENT},
  1356. {"md3rom", RO_RW_MEM_LIMIT, RO_RW_MEM_ALIGNMENT},
  1357. {"md1_sib_mem", SIB_SMEM_LIMIT, SIB_SMEM_ALIGNMENT},
  1358. {NULL, 0LL, 0L},
  1359. };
  1360. int get_mem_limit_and_align(char key[], unsigned long long *limit, unsigned long *align)
  1361. {
  1362. int i = 0;
  1363. while(1) {
  1364. if (!c_md_mem_attr_cfg[i].name)
  1365. break;
  1366. if (strcmp(key, c_md_mem_attr_cfg[i].name) == 0) {
  1367. if (limit)
  1368. *limit = c_md_mem_attr_cfg[i].limit;
  1369. if (align)
  1370. *align = c_md_mem_attr_cfg[i].align;
  1371. return 0;
  1372. }
  1373. i++;
  1374. }
  1375. return -1;
  1376. }
  1377. #ifdef DUMMY_AP_MODE
  1378. #include <platform/mt_irq.h>
  1379. extern void dummy_ap_boot_up_md(int md_en_flag);
  1380. extern void load_modem_image(void);
  1381. extern int dummy_ap_irq_helper(unsigned int);
  1382. /* Remember add this function to file platform.c(platform code) */
  1383. void dummy_ap_entry(void)
  1384. {
  1385. load_modem_image();
  1386. }
  1387. /* Remember add this function to file interrupts.c(platform code) */
  1388. void dummy_ap_irq_handler(unsigned int irq)
  1389. {
  1390. if (dummy_ap_irq_helper(irq)) {
  1391. mt_irq_ack(irq);
  1392. mt_irq_unmask(irq);
  1393. }
  1394. }
  1395. void boot_to_dummy_ap_mode(int load_md_flag)
  1396. {
  1397. md_smem_rw_remapping(MD_SYS1, smem_info.base_addr);
  1398. /* Before boot dummy AP, clear share memory */
  1399. memset((void*)((unsigned long)smem_info.base_addr), 0, 0x200000);
  1400. dummy_ap_boot_up_md(load_md_flag);
  1401. }
  1402. #endif