mntl.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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 <platform/boot_mode.h>
  32. #include <platform/mntl.h>
  33. #include <platform/mntl_types.h>
  34. #include <platform/mntl_gpt.h>
  35. #include <stdlib.h>
  36. #include <debug.h>
  37. #include "sparse_format.h"
  38. extern struct mntl_handler *mntl;
  39. int mntl_erase(const char *arg, void *data, unsigned sz)
  40. {
  41. uint64_t StartLBA = 0, EndLBA = 0;
  42. mntl_read_gpt(arg, &StartLBA, &EndLBA);
  43. mntl_discard(mntl, StartLBA, EndLBA - StartLBA + 1);
  44. dprintf(CRITICAL, "%s: mntl partition %s, sz %u\n",
  45. __FUNCTION__, arg, sz);
  46. return 0;
  47. }
  48. BOOL mntl_flash_img(const char *arg, void *data, unsigned sz)
  49. {
  50. unsigned int chunk;
  51. unsigned int crc_value;
  52. uint32_t *fill_buf = NULL;
  53. uint32_t fill_val;
  54. unsigned long long chunk_data_sz;
  55. uint64_t chunk_sector_sz;
  56. sparse_header_t *sparse_header;
  57. chunk_header_t *chunk_header;
  58. uint32_t total_blocks = 0;
  59. uint64_t StartLBA = 0, EndLBA = 0;
  60. struct mntl_scatter_list list[2];
  61. int ret;
  62. int i;
  63. mntl_read_gpt(arg, &StartLBA, &EndLBA);
  64. /* Read and skip over sparse image header */
  65. sparse_header = (sparse_header_t *) data;
  66. dprintf (ALWAYS, "=== Sparse Image Header ===\n");
  67. dprintf (ALWAYS, "magic: 0x%x\n", sparse_header->magic);
  68. dprintf (ALWAYS, "major_version: 0x%x\n", sparse_header->major_version);
  69. dprintf (ALWAYS, "minor_version: 0x%x\n", sparse_header->minor_version);
  70. dprintf (ALWAYS, "file_hdr_sz: %d\n", sparse_header->file_hdr_sz);
  71. dprintf (ALWAYS, "chunk_hdr_sz: %d\n", sparse_header->chunk_hdr_sz);
  72. dprintf (ALWAYS, "blk_sz: %d\n", sparse_header->blk_sz);
  73. dprintf (ALWAYS, "total_blks: %d\n", sparse_header->total_blks);
  74. dprintf (ALWAYS, "total_chunks: %d\n", sparse_header->total_chunks);
  75. dprintf(ALWAYS, "Image size span 0x%llx, partition size 0x%llx\n", (unsigned long long)sparse_header->total_blks*sparse_header->blk_sz, (EndLBA - StartLBA + 1) * 4096);
  76. if ((unsigned long long)sparse_header->total_blks*sparse_header->blk_sz > (EndLBA - StartLBA + 1) * 4096) {
  77. dprintf(CRITICAL, "sparse image size span overflow.");
  78. return FALSE;
  79. }
  80. data += sparse_header->file_hdr_sz;
  81. if (sparse_header->file_hdr_sz > sizeof(sparse_header_t)) {
  82. /* Skip the remaining bytes in a header that is longer than
  83. * we expected.
  84. */
  85. data += (sparse_header->file_hdr_sz - sizeof(sparse_header_t));
  86. }
  87. dprintf(CRITICAL, "\nWriting Flash ... ");
  88. /* Start processing chunks */
  89. for (chunk=0; chunk<sparse_header->total_chunks; chunk++) {
  90. /* Read and skip over chunk header */
  91. chunk_header = (chunk_header_t *) data;
  92. data += sizeof(chunk_header_t);
  93. /*
  94. dprintf (ALWAYS, "=== Chunk Header ===\n");
  95. dprintf (ALWAYS, "chunk_type: 0x%x\n", chunk_header->chunk_type);
  96. dprintf (ALWAYS, "chunk_data_sz: 0x%x\n", chunk_header->chunk_sz);
  97. dprintf (ALWAYS, "total_size: 0x%x\n", chunk_header->total_sz);
  98. */
  99. if (sparse_header->chunk_hdr_sz > sizeof(chunk_header_t)) {
  100. /* Skip the remaining bytes in a header that is longer than
  101. * we expected.
  102. */
  103. data += (sparse_header->chunk_hdr_sz - sizeof(chunk_header_t));
  104. }
  105. chunk_data_sz = (unsigned long long)(sparse_header->blk_sz&0xFFFFFFFF);
  106. chunk_data_sz = chunk_data_sz * chunk_header->chunk_sz;
  107. chunk_sector_sz = chunk_data_sz / 4096;
  108. switch (chunk_header->chunk_type) {
  109. case CHUNK_TYPE_RAW:
  110. if (chunk_header->total_sz != (sparse_header->chunk_hdr_sz +
  111. chunk_data_sz)) {
  112. dprintf(CRITICAL, "size mismatch, chunk_header->total_sz %llu total size %llu", chunk_header->total_sz,
  113. (sparse_header->chunk_hdr_sz + chunk_data_sz));
  114. return FALSE;
  115. }
  116. list[0].address = data;
  117. list[0].size = chunk_data_sz;
  118. list[1].size = 0;
  119. ret = mntl_write(mntl, StartLBA, &list);
  120. if (ret < 0) {
  121. dprintf(CRITICAL, "flash write failure");
  122. return FALSE;
  123. }
  124. data += chunk_data_sz;
  125. StartLBA += chunk_sector_sz;
  126. break;
  127. case CHUNK_TYPE_DONT_CARE:
  128. StartLBA += chunk_sector_sz;
  129. break;
  130. case CHUNK_TYPE_CRC:
  131. crc_value = *(unsigned int*)data;
  132. data += 4;
  133. break;
  134. case CHUNK_TYPE_FILL:
  135. dprintf (ALWAYS, "%s %d: CHUNK_TYPE_FILL=0x%x size=%d chunk_data_sz=%d\n", __FUNCTION__, __LINE__, *(uint32_t *)data, ROUNDUP(sparse_header->blk_sz, CACHE_LINE), chunk_data_sz);
  136. if (chunk_header->total_sz != (sparse_header->chunk_hdr_sz + sizeof(uint32_t))) {
  137. dprintf(CRITICAL, "Bogus chunk size for chunk type FILL");
  138. return FALSE;
  139. }
  140. fill_buf = (uint32_t *)memalign(CACHE_LINE, ROUNDUP(sparse_header->blk_sz, CACHE_LINE));
  141. if (!fill_buf) {
  142. dprintf(CRITICAL, "Malloc failed for: CHUNK_TYPE_FILL");
  143. return FALSE;
  144. }
  145. fill_val = *(uint32_t *)data;
  146. for (i = 0; i < (sparse_header->blk_sz / sizeof(fill_val)); i++) {
  147. fill_buf[i] = fill_val;
  148. }
  149. for (i = 0; i < chunk_header->chunk_sz; i++) {
  150. list[0].address = fill_buf;
  151. list[0].size = sparse_header->blk_sz;
  152. list[1].size = 0;
  153. ret = mntl_write(mntl, StartLBA, &list);
  154. if (ret < 0) {
  155. dprintf(CRITICAL, "CHUNK_TYPE_FILL flash write failure");
  156. free(fill_buf);
  157. return FALSE;
  158. }
  159. StartLBA += sparse_header->blk_sz / 4096;
  160. }
  161. free(fill_buf);
  162. data += 4; //data length is 4.
  163. break;
  164. default:
  165. dprintf(CRITICAL, "Unknown chunk type");
  166. return FALSE;
  167. }
  168. dprintf(CRITICAL, "\rWrite Data", total_blocks*sparse_header->blk_sz, sparse_header->total_blks*sparse_header->blk_sz);
  169. }
  170. mntl_commit(mntl);
  171. dprintf(CRITICAL, "%s: mntl partition %s, sz %u, StartLBA %llu\n",
  172. __FUNCTION__, arg, sz, StartLBA);
  173. return TRUE;
  174. }
  175. int mntl_partition_erase(char *part_name)
  176. {
  177. uint64_t StartLBA = 0, EndLBA = 0;
  178. mntl_read_gpt(part_name, &StartLBA, &EndLBA);
  179. mntl_discard(mntl, StartLBA, EndLBA - StartLBA + 1);
  180. dprintf(CRITICAL, "%s: mntl partition %s\n",
  181. __FUNCTION__, part_name);
  182. return 0;
  183. }