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