fwupdate.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * (C) Copyright 2007 Schindler Lift Inc.
  3. * (C) Copyright 2007 DENX Software Engineering
  4. *
  5. * Author: Michel Marti <mma@objectxp.com>
  6. * Adapted for U-Boot 1.2 by Piotr Kruszynski <ppk@semihalf.com>:
  7. * - code clean-up
  8. * - bugfix for overwriting bootargs by user
  9. *
  10. * SPDX-License-Identifier: GPL-2.0+
  11. */
  12. #include <common.h>
  13. #include <command.h>
  14. #include <fat.h>
  15. #include <malloc.h>
  16. #include <image.h>
  17. #include <usb.h>
  18. #include <fat.h>
  19. #include "fwupdate.h"
  20. static int load_rescue_image(ulong);
  21. void cm5200_fwupdate(void)
  22. {
  23. cmd_tbl_t *bcmd;
  24. char *rsargs;
  25. char *tmp = NULL;
  26. char ka[16];
  27. char * const argv[3] = { "bootm", ka, NULL };
  28. /* Check if rescue system is disabled... */
  29. if (getenv("norescue")) {
  30. printf(LOG_PREFIX "Rescue System disabled.\n");
  31. return;
  32. }
  33. /* Check if we have a USB storage device and load image */
  34. if (load_rescue_image(LOAD_ADDR))
  35. return;
  36. bcmd = find_cmd("bootm");
  37. if (!bcmd)
  38. return;
  39. sprintf(ka, "%lx", (ulong)LOAD_ADDR);
  40. /* prepare our bootargs */
  41. rsargs = getenv("rs-args");
  42. if (!rsargs)
  43. rsargs = RS_BOOTARGS;
  44. else {
  45. tmp = malloc(strlen(rsargs+1));
  46. if (!tmp) {
  47. printf(LOG_PREFIX "Memory allocation failed\n");
  48. return;
  49. }
  50. strcpy(tmp, rsargs);
  51. rsargs = tmp;
  52. }
  53. setenv("bootargs", rsargs);
  54. if (rsargs == tmp)
  55. free(rsargs);
  56. printf(LOG_PREFIX "Starting update system (bootargs=%s)...\n", rsargs);
  57. do_bootm(bcmd, 0, 2, argv);
  58. }
  59. static int load_rescue_image(ulong addr)
  60. {
  61. disk_partition_t info;
  62. int devno;
  63. int partno;
  64. int i;
  65. char fwdir[64];
  66. char nxri[128];
  67. char *tmp;
  68. char dev[7];
  69. char addr_str[16];
  70. char * const argv[6] = { "fatload", "usb", dev, addr_str, nxri, NULL };
  71. struct blk_desc *stor_dev = NULL;
  72. cmd_tbl_t *bcmd;
  73. /* Get name of firmware directory */
  74. tmp = getenv("fw-dir");
  75. /* Copy it into fwdir */
  76. strncpy(fwdir, tmp ? tmp : FW_DIR, sizeof(fwdir));
  77. fwdir[sizeof(fwdir) - 1] = 0; /* Terminate string */
  78. printf(LOG_PREFIX "Checking for firmware image directory '%s' on USB"
  79. " storage...\n", fwdir);
  80. usb_stop();
  81. if (usb_init() != 0)
  82. return 1;
  83. /* Check for storage device */
  84. if (usb_stor_scan(1) != 0) {
  85. usb_stop();
  86. return 1;
  87. }
  88. /* Detect storage device */
  89. for (devno = 0; devno < USB_MAX_STOR_DEV; devno++) {
  90. stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, devno);
  91. if (stor_dev->type != DEV_TYPE_UNKNOWN)
  92. break;
  93. }
  94. if (!stor_dev || stor_dev->type == DEV_TYPE_UNKNOWN) {
  95. printf(LOG_PREFIX "No valid storage device found...\n");
  96. usb_stop();
  97. return 1;
  98. }
  99. /* Detect partition */
  100. for (partno = -1, i = 0; i < 6; i++) {
  101. if (part_get_info(stor_dev, i, &info) == 0) {
  102. if (fat_register_device(stor_dev, i) == 0) {
  103. /* Check if rescue image is present */
  104. FW_DEBUG("Looking for firmware directory '%s'"
  105. " on partition %d\n", fwdir, i);
  106. if (!fat_exists(fwdir)) {
  107. FW_DEBUG("No NX rescue image on "
  108. "partition %d.\n", i);
  109. partno = -2;
  110. } else {
  111. partno = i;
  112. FW_DEBUG("Partition %d contains "
  113. "firmware directory\n", partno);
  114. break;
  115. }
  116. }
  117. }
  118. }
  119. if (partno < 0) {
  120. switch (partno) {
  121. case -1:
  122. printf(LOG_PREFIX "Error: No valid (FAT) partition "
  123. "detected\n");
  124. break;
  125. case -2:
  126. printf(LOG_PREFIX "Error: No NX rescue image on FAT "
  127. "partition\n");
  128. break;
  129. default:
  130. printf(LOG_PREFIX "Error: Failed with code %d\n",
  131. partno);
  132. }
  133. usb_stop();
  134. return 1;
  135. }
  136. /* Load the rescue image */
  137. bcmd = find_cmd("fatload");
  138. if (!bcmd) {
  139. printf(LOG_PREFIX "Error - 'fatload' command not present.\n");
  140. usb_stop();
  141. return 1;
  142. }
  143. tmp = getenv("nx-rescue-image");
  144. sprintf(nxri, "%s/%s", fwdir, tmp ? tmp : RESCUE_IMAGE);
  145. sprintf(dev, "%d:%d", devno, partno);
  146. sprintf(addr_str, "%lx", addr);
  147. FW_DEBUG("fat_fsload device='%s', addr='%s', file: %s\n",
  148. dev, addr_str, nxri);
  149. if (do_fat_fsload(bcmd, 0, 5, argv) != 0) {
  150. usb_stop();
  151. return 1;
  152. }
  153. /* Stop USB */
  154. usb_stop();
  155. return 0;
  156. }