ccci_lk_load_img_plat.c 58 KB

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