blob: 8eb4ae9e37c65f9df76941e4dae14342121ab8a6 [file] [log] [blame]
Marcin Bukat8f4202d2011-05-30 21:10:43 +00001#include <unistd.h>
2#include <stdio.h>
3#include <stdint.h>
4#include <stdbool.h>
5#include <stdlib.h>
6#include <string.h>
7#include <libusb.h>
8
9#include "rk27load.h"
10#include "common.h"
11#include "scramble.h"
12#include "checksum.h"
13#include "stage1_upload.h"
14
15/* ### upload sdram init code ### */
16int upload_stage1_code(libusb_device_handle *hdev, char *fn_stage1,
17 bool do_scramble)
18{
19 FILE *f;
20 int ret;
21 uint8_t *code;
22 uint32_t codesize;
23 uint16_t cks;
24
25 if ((f = fopen(fn_stage1, "rb")) == NULL)
26 {
27 fprintf(stderr, "[error]: Could not open file \"%s\"\n", fn_stage1);
28 return -10;
29 }
30
31 codesize = filesize(f);
32
33 if (codesize > 0x1fe)
34 {
35 fprintf(stderr, "[error]: Code too big for stage1\n");
36 return -11;
37 }
38
39 fprintf(stderr, "[stage1]: Loading %d bytes (%s) of code... ", codesize, fn_stage1);
40
41 code = (uint8_t *)malloc(0x200);
42 if (code == NULL)
43 {
44 fprintf(stderr, "\n[error]: Out of memory\n");
45 fclose(f);
46 return -12;
47 }
48
49 memset(code, 0, 0x200);
50 if (fread(code, 1, codesize, f) != codesize)
51 {
52 fprintf(stderr, "\n[error]: I/O error\n");
53 fclose(f);
54 free(code);
55 return -13;
56 }
57
58 fprintf(stderr, "done\n");
59 fclose(f);
60
61 /* encode data if requested */
62 if (do_scramble)
63 {
64
65 fprintf(stderr, "[stage1]: Encoding %d bytes of data ... ", codesize);
66 scramble(code, code, codesize);
67 fprintf(stderr, "done\n");
68 }
69
70
71 fprintf(stderr, "[stage1]: codesize = %d (0x%x)\n", codesize, codesize);
72
73 fprintf(stderr, "[stage1]: Calculating checksum... ");
74 cks = checksum((void *)code, codesize);
75 fprintf(stderr, "0x%04x\n", cks);
76 code[0x1fe] = (cks >> 8) & 0xff;
77 code[0x1ff] = cks & 0xff;
78 codesize += 2;
79
80 fprintf(stderr, "[stage1]: Uploading code (%d bytes)... ", codesize);
81
82 ret = libusb_control_transfer(hdev, /* device handle */
83 USB_EP0, /* bmRequestType */
84 VCMD_UPLOAD, /* bRequest */
85 0, /* wValue */
86 VCMD_INDEX_STAGE1, /* wIndex */
87 code, /* data */
88 codesize, /* wLength */
89 USB_TIMEOUT /* timeout */
90 );
91 if (ret < 0)
92 {
93 fprintf(stderr, "\n[error]: Code upload request failed (ret=%d)\n", ret);
94 free(code);
95 return -14;
96 }
97
98 if (ret != (int)codesize)
99 {
100 fprintf(stderr, "\n[error]: Sent %d of %d total\n", ret, codesize);
101 free(code);
102 return -15;
103 }
104
105 sleep(1); /* wait for code to finish */
106 fprintf(stderr, "done\n");
107
108 /* free code */
109 free(code);
110
111 return 0;
112}
113