Root/usbboot/src/cmd.c

1/*
2 * Copyright(C) 2009 Qi Hardware Inc.,
3 * Authors: Marek Lindner <lindner_marek@yahoo.de>
4 * Xiangfu Liu <xiangfu@qi-hardware.com>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <stdio.h>
21#include <string.h>
22#include <unistd.h>
23#include <stdlib.h>
24#include <errno.h>
25#include <fcntl.h>
26#include <sys/types.h>
27#include <sys/stat.h>
28#include <ctype.h>
29#include "cmd.h"
30#include "ingenic_cfg.h"
31#include "ingenic_usb.h"
32#include "usb_boot_defines.h"
33
34struct sdram_in sdram_in;
35
36unsigned int total_size;
37static char code_buf[4 * 512 * 1024];
38static char ret[8];
39
40static int load_file(struct ingenic_dev *dev, const char *file_path, char *buf)
41{
42    struct stat fstat;
43    int fd, status;
44
45    status = stat(file_path, &fstat);
46
47    if (status < 0) {
48        fprintf(stderr, "Error - can't get file size from '%s': %s\n",
49            file_path, strerror(errno));
50        return errno;
51    }
52
53    fd = open(file_path, O_RDONLY);
54
55    if (fd < 0) {
56        fprintf(stderr, "Error - can't open file '%s': %s\n",
57            file_path, strerror(errno));
58        return errno;
59    }
60
61    status = read(fd, buf, fstat.st_size);
62
63    if (status < (int)fstat.st_size) {
64        fprintf(stderr, "Error - can't read file '%s': %s\n",
65            file_path, strerror(errno));
66        goto close;
67    }
68
69    /* write args to code */
70    memcpy(buf + 8, &dev->config.fw_args, sizeof(struct fw_args));
71
72close:
73    close(fd);
74
75    return fstat.st_size;
76}
77
78/* after upload stage2. must init device */
79void init_cfg(struct ingenic_dev *dev)
80{
81    if (usb_get_ingenic_cpu(dev) < 3) {
82        printf("XBurst CPU not booted yet, boot it first!\n");
83        return;
84    }
85
86    if (usb_send_data_to_ingenic(dev, (char*)&dev->config, sizeof(dev->config))
87    < 0)
88        goto xout;
89
90    if (usb_ingenic_configration(dev, DS_hand) < 0)
91        goto xout;
92
93    if (usb_read_data_from_ingenic(dev, ret, 8) < 0)
94        goto xout;
95
96    printf("Configuring XBurst CPU succeeded.\n");
97    return;
98xout:
99    printf("Configuring XBurst CPU failed.\n");
100}
101
102int boot(struct ingenic_dev *dev, const char *stage1_path, const char *stage2_path)
103{
104    int status;
105    int size;
106
107    status = usb_get_ingenic_cpu(dev);
108    switch (status) {
109    case INGENIC_CPU_JZ4740V1:
110        status = 0;
111        dev->config.fw_args.cpu_id = 0x4740;
112        break;
113    case INGENIC_CPU_JZ4750V1:
114        status = 0;
115        dev->config.fw_args.cpu_id = 0x4750;
116        break;
117    case INGENIC_CPU_JZ4740:
118        status = 1;
119        dev->config.fw_args.cpu_id = 0x4740;
120        break;
121    case INGENIC_CPU_JZ4750:
122        status = 1;
123        dev->config.fw_args.cpu_id = 0x4750;
124        break;
125    default:
126        return (status < 0) ? status : -1;
127    }
128
129    if (status) {
130        printf("Already booted.\n");
131        return 0;
132    } else {
133        printf("CPU not yet booted, now booting...\n");
134
135        /* now we upload the boot stage1 */
136        printf("Loading stage1 from '%s'\n", stage1_path);
137        size = load_file(dev, stage1_path, code_buf);
138        if (size < 0)
139            return size;
140
141        if (usb_ingenic_upload(dev, 1, code_buf, size) < 0)
142            return -1;
143
144        /* now we upload the boot stage2 */
145        usleep(100);
146        printf("Loading stage2 from '%s'\n", stage2_path);
147        size = load_file(dev, stage2_path, code_buf);
148        if (size < 0) {
149            printf("FOOBAR");
150            return size;
151        }
152
153        if (usb_ingenic_upload(dev, 2, code_buf, size) < 0)
154            return -1;
155
156        printf("Booted successfully!\n");
157    }
158    usleep(100);
159    init_cfg(dev);
160    return 0;
161}
162
163
164int debug_memory(struct ingenic_dev *dev, int obj, unsigned int start, unsigned int size)
165{
166    char buffer[8], tmp;
167
168    (void)obj;
169
170    tmp = usb_get_ingenic_cpu(dev);
171    if (tmp > 2) {
172        printf("This command only run under UNBOOT state!\n");
173        return -1;
174    }
175
176    switch (tmp) {
177    case 1:
178        dev->config.fw_args.cpu_id = 0x4740;
179        break;
180    case 2:
181        dev->config.fw_args.cpu_id = 0x4750;
182        break;
183    }
184
185    dev->config.fw_args.debug_ops = 1;/* tell device it's memory debug */
186    dev->config.fw_args.start = start;
187
188    if (size == 0)
189        dev->config.fw_args.size = total_size;
190    else
191        dev->config.fw_args.size = size;
192
193    printf("Now test memory from 0x%x to 0x%x: \n",
194           start, start + dev->config.fw_args.size);
195
196    size = load_file(dev, STAGE1_FILE_PATH, code_buf);
197    if (size < 0)
198        return size;
199    if (usb_ingenic_upload(dev, 1, code_buf, size) < 1)
200        return -1;
201
202    usleep(100);
203    usb_read_data_from_ingenic(dev, buffer, 8);
204    if (buffer[0] != 0)
205        printf("Test memory fail! Last error address is 0x%x !\n",
206               buffer[0]);
207    else
208        printf("Test memory pass!\n");
209
210    return 1;
211}
212
213int debug_go(struct ingenic_dev *dev, size_t argc, char *argv[])
214{
215    unsigned int addr, obj;
216    if (argc < 3) {
217        printf(" Usage: go (1) (2) \n"
218               " 1:start SDRAM address\n"
219               " 2:device index number\n");
220        return 0;
221    }
222
223    addr = strtoul(argv[1], NULL, 0);
224    obj = atoi(argv[2]);
225
226    printf("Executing No.%d device at address 0x%x\n", obj, addr);
227
228    if (usb_ingenic_start(dev, VR_PROGRAM_START2, addr) < 1)
229        return -1;
230
231    return 1;
232}
233
234int sdram_load(struct ingenic_dev *dev, struct sdram_in *sdram_in)
235{
236    if (usb_get_ingenic_cpu(dev) < 3) {
237        printf("Device unboot! Boot it first!\n");
238        return -1;
239    }
240
241    if (sdram_in->length > (unsigned int) MAX_LOAD_SIZE) {
242        printf("Image length too long!\n");
243        return -1;
244    }
245
246    usb_send_data_to_ingenic(dev, sdram_in->buf, sdram_in->length);
247    usb_send_data_address_to_ingenic(dev, sdram_in->start);
248    usb_send_data_length_to_ingenic(dev, sdram_in->length);
249/* usb_ingenic_sdram_ops(dev, sdram_in);*/
250
251    usb_read_data_from_ingenic(dev, ret, 8);
252    printf("Load last address at 0x%x\n",
253           ((ret[3]<<24)|(ret[2]<<16)|(ret[1]<<8)|(ret[0]<<0)));
254
255    return 1;
256}
257
258int sdram_load_file(struct ingenic_dev *dev, struct sdram_in *sdram_in, char *file_path)
259{
260    struct stat fstat;
261    unsigned int flen,m,j,offset,k;
262    int fd, status, res = -1;
263
264    status = stat(file_path, &fstat);
265    if (status < 0) {
266        fprintf(stderr, "Error - can't get file size from '%s': %s\n",
267            file_path, strerror(errno));
268        goto out;
269    }
270    flen = fstat.st_size;
271
272    fd = open(file_path, O_RDONLY);
273    if (fd < 0) {
274        fprintf(stderr, "Error - can't open file '%s': %s\n",
275            file_path, strerror(errno));
276        goto out;
277    }
278
279    m = flen / MAX_LOAD_SIZE;
280    j = flen % MAX_LOAD_SIZE;
281    offset = 0;
282
283    printf("Total size to send in byte is :%d\n", flen);
284    printf("Loading data to SDRAM :\n");
285
286    for (k = 0; k < m; k++) {
287        status = read(fd, sdram_in->buf, MAX_LOAD_SIZE);
288        if (status < MAX_LOAD_SIZE) {
289            fprintf(stderr, "Error - can't read file '%s': %s\n",
290                file_path, strerror(errno));
291            goto close;
292        }
293
294        sdram_in->length = MAX_LOAD_SIZE;
295        if (sdram_load(dev, sdram_in) < 1)
296            goto close;
297
298        sdram_in->start += MAX_LOAD_SIZE;
299        if ( k % 60 == 0)
300            printf(" 0x%x \n", sdram_in->start);
301    }
302
303    if (j) {
304        if (j % 4 !=0)
305            j += 4 - (j % 4);
306        status = read(fd, sdram_in->buf, j);
307        if (status < (int)j) {
308            fprintf(stderr, "Error - can't read file '%s': %s\n",
309                file_path, strerror(errno));
310            goto close;
311        }
312
313        sdram_in->length = j;
314        if (sdram_load(dev, sdram_in) < 1)
315            goto close;
316    }
317
318    res = 1;
319
320close:
321    close(fd);
322out:
323    return res;
324}
325

Archive Download this file



interactive