fwupdate.c 4.0 KB

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