diff options
Diffstat (limited to 'utils/rk27utils/rk27load')
23 files changed, 1046 insertions, 0 deletions
diff --git a/utils/rk27utils/rk27load/Makefile b/utils/rk27utils/rk27load/Makefile new file mode 100644 index 0000000000..f777e76c36 --- /dev/null +++ b/utils/rk27utils/rk27load/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | all: rk27load | ||
2 | |||
3 | rk27load: main.c scramble.c checksum.c common.c stage1_upload.c stage2_upload.c stage3_upload.c | ||
4 | gcc -g -std=c99 -o $@ -W -Wall -lusb-1.0 -I/usr/include/libusb-1.0/ $^ | ||
5 | |||
6 | clean: | ||
7 | rm -fr *.o rk27load | ||
diff --git a/utils/rk27utils/rk27load/checksum.c b/utils/rk27utils/rk27load/checksum.c new file mode 100644 index 0000000000..f0fe59350e --- /dev/null +++ b/utils/rk27utils/rk27load/checksum.c | |||
@@ -0,0 +1,35 @@ | |||
1 | #include <stdint.h> | ||
2 | #include "checksum.h" | ||
3 | |||
4 | uint16_t checksum(void *buff, uint32_t size) | ||
5 | { | ||
6 | uint32_t r2 = 0xffff; | ||
7 | uint32_t r3 = 0; | ||
8 | uint32_t i, j; | ||
9 | |||
10 | for (i=0; i<size; i++) { | ||
11 | r3 = 0x80; | ||
12 | for (j=0; j<8; j++) { | ||
13 | if ((r2 & 0x8000) != 0) { | ||
14 | r2 <<= 17; | ||
15 | r2 >>= 16; | ||
16 | r2 ^= 0x1000; | ||
17 | r2 ^= 0x21; | ||
18 | } | ||
19 | else { | ||
20 | r2 <<= 17; | ||
21 | r2 >>= 16; | ||
22 | } | ||
23 | |||
24 | if ((((uint8_t *)buff)[i] & r3) != 0) { | ||
25 | r2 ^= 0x1000; | ||
26 | r2 ^= 0x21; | ||
27 | } | ||
28 | |||
29 | r3 >>= 1; | ||
30 | } | ||
31 | } | ||
32 | |||
33 | return r2 & 0xffff; | ||
34 | } | ||
35 | |||
diff --git a/utils/rk27utils/rk27load/checksum.h b/utils/rk27utils/rk27load/checksum.h new file mode 100644 index 0000000000..468ca6643e --- /dev/null +++ b/utils/rk27utils/rk27load/checksum.h | |||
@@ -0,0 +1 @@ | |||
uint16_t checksum(void *buff, uint32_t size); | |||
diff --git a/utils/rk27utils/rk27load/common.c b/utils/rk27utils/rk27load/common.c new file mode 100644 index 0000000000..b97cfbcd79 --- /dev/null +++ b/utils/rk27utils/rk27load/common.c | |||
@@ -0,0 +1,16 @@ | |||
1 | #include <stdint.h> | ||
2 | #include <stdio.h> | ||
3 | |||
4 | #include "common.h" | ||
5 | |||
6 | uint32_t filesize(FILE * f) | ||
7 | { | ||
8 | uint32_t filesize; | ||
9 | |||
10 | fseek(f, 0, SEEK_END); | ||
11 | filesize = ftell(f); | ||
12 | fseek(f, 0, SEEK_SET); | ||
13 | |||
14 | return filesize; | ||
15 | } | ||
16 | |||
diff --git a/utils/rk27utils/rk27load/common.h b/utils/rk27utils/rk27load/common.h new file mode 100644 index 0000000000..f22ec7de40 --- /dev/null +++ b/utils/rk27utils/rk27load/common.h | |||
@@ -0,0 +1 @@ | |||
uint32_t filesize(FILE * f); | |||
diff --git a/utils/rk27utils/rk27load/main.c b/utils/rk27utils/rk27load/main.c new file mode 100644 index 0000000000..d183ae2df1 --- /dev/null +++ b/utils/rk27utils/rk27load/main.c | |||
@@ -0,0 +1,165 @@ | |||
1 | #include <stdlib.h> | ||
2 | #include <stdio.h> | ||
3 | #include <string.h> | ||
4 | #include <stdint.h> | ||
5 | #include <stdbool.h> | ||
6 | |||
7 | #include <libusb.h> | ||
8 | |||
9 | #include "rk27load.h" | ||
10 | #include "common.h" | ||
11 | #include "stage1_upload.h" | ||
12 | #include "stage2_upload.h" | ||
13 | #include "stage3_upload.h" | ||
14 | |||
15 | #define VERSION "v0.2" | ||
16 | |||
17 | enum { | ||
18 | NONE = 0, | ||
19 | ENCODE_S1 = 1, | ||
20 | ENCODE_S2 = 2 | ||
21 | }; | ||
22 | |||
23 | static void usage(char *name) | ||
24 | { | ||
25 | printf("usage: (sudo) %s [-e1 -e2] -s1 stage1.bin -s2 stage2.bin -s3 usercode.bin\n", name); | ||
26 | printf("stage1.bin - binary of the stage1 (sdram init)\n"); | ||
27 | printf("stage2.bin - binary of the stage2 bootloader\n"); | ||
28 | printf("usercode.bin - binary of the custom usercode\n"); | ||
29 | printf("\n"); | ||
30 | printf("options:\n"); | ||
31 | printf("-e1 - encode stage1 bootloader\n"); | ||
32 | printf("-e2 - encode stage2 bootloader\n"); | ||
33 | } | ||
34 | |||
35 | int main(int argc, char **argv) | ||
36 | { | ||
37 | libusb_device_handle *hdev; | ||
38 | char *filenames[3]; | ||
39 | int i=1, action=0, ret=0; | ||
40 | |||
41 | while (i < argc) | ||
42 | { | ||
43 | if (strcmp(argv[i],"-e1") == 0) | ||
44 | { | ||
45 | action |= ENCODE_S1; | ||
46 | i++; | ||
47 | } | ||
48 | else if (strcmp(argv[i],"-e2") == 0) | ||
49 | { | ||
50 | action |= ENCODE_S2; | ||
51 | i++; | ||
52 | } | ||
53 | else if (strcmp(argv[i],"-s1") == 0) | ||
54 | { | ||
55 | i++; | ||
56 | if (i == argc) | ||
57 | { | ||
58 | usage(argv[0]); | ||
59 | return -1; | ||
60 | } | ||
61 | filenames[0] = argv[i]; | ||
62 | printf("%s", argv[i]); | ||
63 | i++; | ||
64 | } | ||
65 | else if (strcmp(argv[i],"-s2") == 0) | ||
66 | { | ||
67 | i++; | ||
68 | if (i == argc) | ||
69 | { | ||
70 | usage(argv[0]); | ||
71 | return -2; | ||
72 | } | ||
73 | filenames[1] = argv[i]; | ||
74 | i++; | ||
75 | } | ||
76 | else if (strcmp(argv[i],"-s3") == 0) | ||
77 | { | ||
78 | i++; | ||
79 | if (i == argc) | ||
80 | { | ||
81 | usage(argv[0]); | ||
82 | return -3; | ||
83 | } | ||
84 | filenames[2] = argv[i]; | ||
85 | i++; | ||
86 | } | ||
87 | else | ||
88 | { | ||
89 | usage(argv[0]); | ||
90 | return -4; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | |||
95 | fprintf(stderr,"rk27load " VERSION "\n"); | ||
96 | fprintf(stderr,"(C) Marcin Bukat 2011\n"); | ||
97 | fprintf(stderr,"Based on rk27load ver. 0.1 written by AleMaxx (alemaxx at hotmail.de)\n\n"); | ||
98 | fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n"); | ||
99 | fprintf(stderr,"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); | ||
100 | |||
101 | /* initialize libusb */ | ||
102 | libusb_init(NULL); | ||
103 | |||
104 | /* configure device */ | ||
105 | fprintf(stderr, "[info]: Initializing device... "); | ||
106 | hdev = libusb_open_device_with_vid_pid(NULL, VENDORID, PRODUCTID); | ||
107 | |||
108 | if (hdev == NULL) | ||
109 | { | ||
110 | fprintf(stderr, "\n[error]: Could not find rockchip device\n"); | ||
111 | ret = -2; | ||
112 | goto finish; | ||
113 | } | ||
114 | |||
115 | ret = libusb_set_configuration(hdev, 1); | ||
116 | if (ret < 0) | ||
117 | { | ||
118 | fprintf(stderr, "\n[error]: Could not select configuration (1)\n"); | ||
119 | ret = -3; | ||
120 | goto finish; | ||
121 | } | ||
122 | |||
123 | ret = libusb_claim_interface(hdev, 0); | ||
124 | if (ret < 0) | ||
125 | { | ||
126 | fprintf(stderr, "\n[error]: Could not claim interface #0\n"); | ||
127 | ret = -4; | ||
128 | goto finish; | ||
129 | } | ||
130 | |||
131 | ret = libusb_set_interface_alt_setting(hdev, 0, 0); | ||
132 | if (ret < 0) | ||
133 | { | ||
134 | fprintf(stderr, "\n[error]: Could not set alternate interface #0\n"); | ||
135 | ret = -5; | ||
136 | goto finish; | ||
137 | } | ||
138 | |||
139 | fprintf(stderr, "done\n"); | ||
140 | |||
141 | |||
142 | ret = upload_stage1_code(hdev, filenames[0], (action & ENCODE_S1)); | ||
143 | if (ret < 0) | ||
144 | goto finish; | ||
145 | |||
146 | ret = upload_stage2_code(hdev, filenames[1], (action & ENCODE_S2)); | ||
147 | if (ret < 0) | ||
148 | goto finish; | ||
149 | |||
150 | ret = upload_stage3_code(hdev, filenames[2]); | ||
151 | if (ret < 0) | ||
152 | goto finish; | ||
153 | |||
154 | /* done */ | ||
155 | ret = 0; | ||
156 | |||
157 | finish: | ||
158 | if (hdev != NULL) | ||
159 | libusb_close(hdev); | ||
160 | |||
161 | if (ret < 0) | ||
162 | fprintf(stderr, "[error]: Error %d\n", ret); | ||
163 | |||
164 | return ret; | ||
165 | } | ||
diff --git a/utils/rk27utils/rk27load/rk27load.h b/utils/rk27utils/rk27load/rk27load.h new file mode 100644 index 0000000000..8239176a0d --- /dev/null +++ b/utils/rk27utils/rk27load/rk27load.h | |||
@@ -0,0 +1,11 @@ | |||
1 | #define USB_TIMEOUT 512 | ||
2 | |||
3 | #define VENDORID 0x71b | ||
4 | #define PRODUCTID 0x3201 | ||
5 | |||
6 | #define USB_EP0 0x41 | ||
7 | |||
8 | #define VCMD_UPLOAD 0x0c | ||
9 | #define VCMD_INDEX_STAGE1 0x471 | ||
10 | #define VCMD_INDEX_STAGE2 0x472 | ||
11 | |||
diff --git a/utils/rk27utils/rk27load/scramble.c b/utils/rk27utils/rk27load/scramble.c new file mode 100644 index 0000000000..7e5b1518d7 --- /dev/null +++ b/utils/rk27utils/rk27load/scramble.c | |||
@@ -0,0 +1,46 @@ | |||
1 | #include <stdint.h> | ||
2 | #include "scramble.h" | ||
3 | |||
4 | void scramble(uint8_t *in, uint8_t *out, const int size) | ||
5 | { | ||
6 | /* table extracted from bootrom */ | ||
7 | static const uint8_t key[] = { | ||
8 | 0x7C, 0x4E, 0x03, 0x04, | ||
9 | 0x55, 0x05, 0x09, 0x07, | ||
10 | 0x2D, 0x2C, 0x7B, 0x38, | ||
11 | 0x17, 0x0D, 0x17, 0x11 | ||
12 | }; | ||
13 | |||
14 | int i, i3, x, val, idx; | ||
15 | |||
16 | uint8_t key1[0x100]; | ||
17 | uint8_t key2[0x100]; | ||
18 | |||
19 | for (i=0; i<0x100; i++) { | ||
20 | key1[i] = i; | ||
21 | key2[i] = key[i&0xf]; | ||
22 | } | ||
23 | |||
24 | i3 = 0; | ||
25 | for (i=0; i<0x100; i++) { | ||
26 | x = key1[i]; | ||
27 | i3 = key1[i] + i3; | ||
28 | i3 += key2[i]; | ||
29 | i3 &= 0xff; | ||
30 | key1[i] = key1[i3]; | ||
31 | key1[i3] = x; | ||
32 | } | ||
33 | |||
34 | idx = 0; | ||
35 | for (i=0; i<size; i++) { | ||
36 | x = key1[(i+1) & 0xff]; | ||
37 | val = x; | ||
38 | idx = (x + idx) & 0xff; | ||
39 | key1[(i+1) & 0xff] = key1[idx]; | ||
40 | key1[idx] = (x & 0xff); | ||
41 | val = (key1[(i+1)&0xff] + x) & 0xff; | ||
42 | val = key1[val]; | ||
43 | out[i] = val ^ in[i]; | ||
44 | } | ||
45 | } | ||
46 | |||
diff --git a/utils/rk27utils/rk27load/scramble.h b/utils/rk27utils/rk27load/scramble.h new file mode 100644 index 0000000000..ed4b291316 --- /dev/null +++ b/utils/rk27utils/rk27load/scramble.h | |||
@@ -0,0 +1 @@ | |||
void scramble(uint8_t *in, uint8_t *out, const int size); | |||
diff --git a/utils/rk27utils/rk27load/stage1/Makefile b/utils/rk27utils/rk27load/stage1/Makefile new file mode 100644 index 0000000000..5291685032 --- /dev/null +++ b/utils/rk27utils/rk27load/stage1/Makefile | |||
@@ -0,0 +1,48 @@ | |||
1 | |||
2 | TARGET = stage1 | ||
3 | |||
4 | TOOLCHAIN = arm-elf-eabi- | ||
5 | |||
6 | CC = $(TOOLCHAIN)gcc | ||
7 | CPP = $(TOOLCHAIN)cpp | ||
8 | LD = $(TOOLCHAIN)gcc | ||
9 | AS = $(TOOLCHAIN)as | ||
10 | OBJCOPY = $(TOOLCHAIN)objcopy | ||
11 | OBJDUMP = $(TOOLCHAIN)objdump | ||
12 | |||
13 | CFLAGS = -Wundef -marm -march=armv5te -nostdlib -mfpu=fpa -O0 -c | ||
14 | #ASFLAGS = -mcpu=arm926ej-s | ||
15 | |||
16 | OBJS = main.o | ||
17 | LDSCRIPT= stage1.lds | ||
18 | |||
19 | #LIBDIRS = -L../arm/lib/gcc/arm-elf/4.1.0/ -L../lib | ||
20 | #LIBS = -lgcc | ||
21 | LIBS = | ||
22 | LDFLAGS = -Wundef -marm -march=armv5te -T$(LDSCRIPT) -nostartfiles \ | ||
23 | -mfpu=fpa -nostdlib -Xlinker -Map=$(TARGET).map | ||
24 | |||
25 | all : $(TARGET).bin | ||
26 | ls -ls $(TARGET).bin | ||
27 | |||
28 | %.o : %.c | ||
29 | $(CC) $(CPPFLAGS) $(CFLAGS) $(INCDIRS) $< -o $@ | ||
30 | |||
31 | %.o : %.S | ||
32 | $(CC) $(CFLAGS) -c $< -o $@ | ||
33 | |||
34 | $(TARGET).elf : $(OBJS) | ||
35 | $(LD) $(LDFLAGS) $(OBJS) $(LIBDIRS) $(LIBS) -o $(TARGET).elf | ||
36 | |||
37 | $(TARGET).bin : $(TARGET).elf | ||
38 | $(OBJCOPY) -O binary $(TARGET).elf $(TARGET).bin | ||
39 | |||
40 | dasm : $(TARGET).bin | ||
41 | $(OBJDUMP) -m arm -D $(TARGET).elf | cat > $(TARGET).asm | ||
42 | |||
43 | clean : | ||
44 | rm -f $(OBJS) | ||
45 | rm -f $(TARGET).elf | ||
46 | rm -f $(TARGET).bin | ||
47 | rm -f $(TARGET).asm | ||
48 | rm -f $(TARGET).map | ||
diff --git a/utils/rk27utils/rk27load/stage1/main.S b/utils/rk27utils/rk27load/stage1/main.S new file mode 100644 index 0000000000..44e7e2f914 --- /dev/null +++ b/utils/rk27utils/rk27load/stage1/main.S | |||
@@ -0,0 +1,42 @@ | |||
1 | .section .text,"ax",%progbits | ||
2 | .global start | ||
3 | |||
4 | start: | ||
5 | msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ | ||
6 | |||
7 | pll_setup: | ||
8 | mov r0, #0x18000000 | ||
9 | add r0, r0, #0x1c000 | ||
10 | |||
11 | /* setup ARM core freq = 200MHz */ | ||
12 | /* AHB bus freq (HCLK) = 100MHz */ | ||
13 | /* APB bus freq (PCLK) = 50MHz */ | ||
14 | ldr r1, [r0,#0x14] /* SCU_DIVCON1 */ | ||
15 | orr r1, #9 /* ARM slow mode, HCLK:PCLK = 2:1 */ | ||
16 | str r1, [r0,#0x14] | ||
17 | |||
18 | ldr r1,=0x01970c70 /* (1<<24) | (1<<23) | (23<<16) | (199<<4) */ | ||
19 | str r1, [r0,#0x08] | ||
20 | |||
21 | ldr r2,=0x40000 | ||
22 | 1: | ||
23 | ldr r1, [r0,#0x2c] /* SCU_STATUS */ | ||
24 | tst r1, #1 /* ARM pll lock */ | ||
25 | bne 1f | ||
26 | subs r2, #1 | ||
27 | bne 1b | ||
28 | 1: | ||
29 | ldr r1, [r0,#0x14] /* SCU_DIVCON1 */ | ||
30 | bic r1, #5 /* leave ARM slow mode, ARMclk:HCLK = 2:1 */ | ||
31 | str r1, [r0,#0x14] | ||
32 | |||
33 | sdram_config: | ||
34 | add r0, r0, #0x94000 /* SDRAM base */ | ||
35 | |||
36 | mov r1, #1 | ||
37 | str r1, [r0,#0x10c] /* MCSDR_BASIC Round-robin, SDRAM width 16bits */ | ||
38 | |||
39 | add r1, #0x10 | ||
40 | str r1, [r0,#0x108] /* MCSDR_ADDCFG 12 bits row/9 bits col addr */ | ||
41 | |||
42 | mov pc, lr /* we are done, return to bootrom code */ | ||
diff --git a/utils/rk27utils/rk27load/stage1/stage1.lds b/utils/rk27utils/rk27load/stage1/stage1.lds new file mode 100644 index 0000000000..4af8b93c55 --- /dev/null +++ b/utils/rk27utils/rk27load/stage1/stage1.lds | |||
@@ -0,0 +1,23 @@ | |||
1 | ENTRY(start) | ||
2 | OUTPUT_FORMAT(elf32-littlearm) | ||
3 | OUTPUT_ARCH(arm) | ||
4 | /* STARTUP(crt0.o) */ | ||
5 | |||
6 | /* this is where bootrom loads sdram init code */ | ||
7 | MEMORY | ||
8 | { | ||
9 | IRAM : ORIGIN = 0x18200E00, LENGTH = 0x00000200 | ||
10 | } | ||
11 | |||
12 | SECTIONS | ||
13 | { | ||
14 | .text : { | ||
15 | *(.text*) | ||
16 | *(.glue_7*) | ||
17 | } > IRAM | ||
18 | |||
19 | .data : { | ||
20 | *(.rodata*) | ||
21 | *(.data*) | ||
22 | } > IRAM | ||
23 | } | ||
diff --git a/utils/rk27utils/rk27load/stage1_upload.c b/utils/rk27utils/rk27load/stage1_upload.c new file mode 100644 index 0000000000..8eb4ae9e37 --- /dev/null +++ b/utils/rk27utils/rk27load/stage1_upload.c | |||
@@ -0,0 +1,113 @@ | |||
1 | #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 ### */ | ||
16 | int 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 | |||
diff --git a/utils/rk27utils/rk27load/stage1_upload.h b/utils/rk27utils/rk27load/stage1_upload.h new file mode 100644 index 0000000000..efb1c3407e --- /dev/null +++ b/utils/rk27utils/rk27load/stage1_upload.h | |||
@@ -0,0 +1,3 @@ | |||
1 | int upload_stage1_code(libusb_device_handle * hdev, char *fn_stage1, | ||
2 | bool do_scramble); | ||
3 | |||
diff --git a/utils/rk27utils/rk27load/stage2/Makefile b/utils/rk27utils/rk27load/stage2/Makefile new file mode 100644 index 0000000000..4b216db2f3 --- /dev/null +++ b/utils/rk27utils/rk27load/stage2/Makefile | |||
@@ -0,0 +1,48 @@ | |||
1 | |||
2 | TARGET = stage2 | ||
3 | |||
4 | TOOLCHAIN = arm-elf-eabi- | ||
5 | |||
6 | CC = $(TOOLCHAIN)gcc | ||
7 | CPP = $(TOOLCHAIN)cpp | ||
8 | LD = $(TOOLCHAIN)gcc | ||
9 | AS = $(TOOLCHAIN)as | ||
10 | OBJCOPY = $(TOOLCHAIN)objcopy | ||
11 | OBJDUMP = $(TOOLCHAIN)objdump | ||
12 | |||
13 | CFLAGS = -Wundef -marm -march=armv5te -nostdlib -mfpu=fpa -O0 -c | ||
14 | #ASFLAGS = -mcpu=arm926ej-s | ||
15 | |||
16 | OBJS = crt0.o main.o irq.o | ||
17 | LDSCRIPT= stage2.lds | ||
18 | |||
19 | #LIBDIRS = -L../arm/lib/gcc/arm-elf/4.1.0/ -L../lib | ||
20 | #LIBS = -lgcc | ||
21 | LIBS = | ||
22 | LDFLAGS = -Wundef -marm -march=armv5te -T$(LDSCRIPT) -nostartfiles \ | ||
23 | -mfpu=fpa -nostdlib -Xlinker -Map=$(TARGET).map | ||
24 | |||
25 | all : $(TARGET).bin | ||
26 | ls -ls $(TARGET).bin | ||
27 | |||
28 | %.o : %.c | ||
29 | $(CC) $(CPPFLAGS) $(CFLAGS) $(INCDIRS) $< -o $@ | ||
30 | |||
31 | %.o : %.S | ||
32 | $(CC) $(CFLAGS) -c $< -o $@ | ||
33 | |||
34 | $(TARGET).elf : $(OBJS) | ||
35 | $(LD) $(LDFLAGS) $(OBJS) $(LIBDIRS) $(LIBS) -o $(TARGET).elf | ||
36 | |||
37 | $(TARGET).bin : $(TARGET).elf | ||
38 | $(OBJCOPY) -O binary $(TARGET).elf $(TARGET).bin | ||
39 | |||
40 | dasm : $(TARGET).bin | ||
41 | $(OBJDUMP) -m arm -D $(TARGET).elf | cat > $(TARGET).asm | ||
42 | |||
43 | clean : | ||
44 | rm -f $(OBJS) | ||
45 | rm -f $(TARGET).elf | ||
46 | rm -f $(TARGET).bin | ||
47 | rm -f $(TARGET).asm | ||
48 | rm -f $(TARGET).map | ||
diff --git a/utils/rk27utils/rk27load/stage2/crt0.S b/utils/rk27utils/rk27load/stage2/crt0.S new file mode 100644 index 0000000000..c85477546d --- /dev/null +++ b/utils/rk27utils/rk27load/stage2/crt0.S | |||
@@ -0,0 +1,55 @@ | |||
1 | // | ||
2 | // startup code | ||
3 | // | ||
4 | // | ||
5 | |||
6 | #define PSR_MODE 0x0000001f | ||
7 | #define PSR_USR_MODE 0x00000010 | ||
8 | #define PSR_IRQ_MODE 0x00000012 | ||
9 | #define PSR_SVC_MODE 0x00000013 | ||
10 | |||
11 | #define PSR_INT_MASK 0x000000c0 | ||
12 | #define PSR_FIQ_DIS 0x00000040 | ||
13 | #define PSR_IRQ_DIS 0x00000080 | ||
14 | |||
15 | .section .init.text,"ax",%progbits | ||
16 | .global start | ||
17 | .extern _interrupt_disable | ||
18 | |||
19 | // ----------------------------------------------------- | ||
20 | // startup code (setup stacks, branch to main) | ||
21 | // ----------------------------------------------------- | ||
22 | start: | ||
23 | // setup IRQ stack | ||
24 | mov r0, #(PSR_IRQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) | ||
25 | msr cpsr, r0 | ||
26 | ldr sp,=irqstackend | ||
27 | |||
28 | // setup SVC stack | ||
29 | mov r0, #(PSR_SVC_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) | ||
30 | msr cpsr, r0 | ||
31 | ldr sp,=stackend | ||
32 | |||
33 | // disbale interrupts | ||
34 | mrs r0, cpsr | ||
35 | orr r0, r0, #0xc0 | ||
36 | msr cpsr_c, r0 | ||
37 | |||
38 | // remap | ||
39 | mov r0, #0x18000000 | ||
40 | add r0, r0, #0x1C000 | ||
41 | ldr r1,=0xdeadbeef | ||
42 | str r1, [r0, #4] | ||
43 | |||
44 | // relocate itself | ||
45 | ldr r0,=_relocstart | ||
46 | ldr r1,=_relocend | ||
47 | ldr r2,=0x0 | ||
48 | 1: | ||
49 | cmp r1,r0 | ||
50 | ldrhi r3,[r0],#4 | ||
51 | strhi r3,[r2],#4 | ||
52 | bhi 1b | ||
53 | |||
54 | // continue running in SVC (supervisor mode) | ||
55 | ldr pc,=0x0 | ||
diff --git a/utils/rk27utils/rk27load/stage2/irq.S b/utils/rk27utils/rk27load/stage2/irq.S new file mode 100644 index 0000000000..043bf185a5 --- /dev/null +++ b/utils/rk27utils/rk27load/stage2/irq.S | |||
@@ -0,0 +1,103 @@ | |||
1 | .section .text | ||
2 | .align 4 | ||
3 | |||
4 | .global irq_handler | ||
5 | #define BUFF_ADDR 0x60800000 | ||
6 | |||
7 | irq_handler: | ||
8 | stmfd sp!, {r0-r7, ip, lr} | ||
9 | |||
10 | // get interrupt number | ||
11 | mov r4, #0x18000000 | ||
12 | add r4, r4, #0x80000 | ||
13 | ldr r5, [r4, #0x104] | ||
14 | and r5, r5, #0x1f | ||
15 | cmp r5, #0x10 // UDC interrupt | ||
16 | |||
17 | bleq udc_irq | ||
18 | |||
19 | // clear pending interrupt | ||
20 | mov r3, #1 | ||
21 | mov r2, r3, LSL r5 | ||
22 | str r2, [r4, #0x118] | ||
23 | |||
24 | ldmfd sp!, {r0-r7, ip, lr} | ||
25 | subs pc, lr, #4 | ||
26 | |||
27 | udc_irq: | ||
28 | stmfd sp!, {r4-r8, lr} | ||
29 | |||
30 | // handle usb interrupt | ||
31 | ldr r4,=0x180A0000 | ||
32 | ldr r5, [r4, #0x18] // UDC_INTFLAG | ||
33 | |||
34 | // ep0 in intr | ||
35 | tst r5, #0x04 | ||
36 | beq bulk_recv_intr | ||
37 | |||
38 | // write_reg32(UDC_TX0STAT, read_reg32(UDC_TX0STAT) & ~0x7FF); | ||
39 | ldr r5, [r4, #0x40] | ||
40 | mov r5, r5, lsr #10 | ||
41 | mov r5, r5, lsl #10 // clear clower 10 bits | ||
42 | str r5, [r4, #0x40] | ||
43 | |||
44 | // write_reg32(UDC_DMA0LM_OADDR, (uint32_t)(state.ctrlep_data)); | ||
45 | mov r5, #0x60000000 | ||
46 | str r5, [r4, #0x3c] | ||
47 | |||
48 | // write_reg32(UDC_DMA0CTLO, read_reg32(UDC_DMA0CTLO) | ENP_DMA_START); | ||
49 | mov r5, #1 | ||
50 | str r5, [r4, #0x38] | ||
51 | |||
52 | ldmfd sp!, {r4-r8, pc} | ||
53 | |||
54 | // bulk out interrupt | ||
55 | bulk_recv_intr: | ||
56 | tst r5, #0x100 | ||
57 | ldmeqfd sp!, {r4-r8, pc} | ||
58 | |||
59 | // read UDC_RX1STAT | ||
60 | ldr r5, [r4, #0x54] | ||
61 | mov r5, r5, lsl #21 | ||
62 | mov r5, r5, lsr #21 // r5 = length | ||
63 | |||
64 | ldr r6,=usb_sz | ||
65 | ldr r6, [r6] | ||
66 | ldr r7, [r6] // r7 = total_code_length expected | ||
67 | |||
68 | subs r7, r7, r5 | ||
69 | bne usb_bulk_out1_recv | ||
70 | |||
71 | // copy from buff to the begining of the ram | ||
72 | ldr r0,=BUFF_ADDR | ||
73 | ldr r1,[r0,#-4] // size | ||
74 | |||
75 | ldr r1,=0x800000 // buffer size | ||
76 | |||
77 | add r1,r1,r0 // end address | ||
78 | ldr r2,=0x60000000 // destination | ||
79 | 1: | ||
80 | cmp r1,r0 | ||
81 | ldrhi r3,[r0],#4 | ||
82 | strhi r3,[r2],#4 | ||
83 | bhi 1b | ||
84 | |||
85 | // execute user code | ||
86 | ldr r0,=0x60000000 | ||
87 | bx r0 // jump to 0x60000000 | ||
88 | |||
89 | usb_bulk_out1_recv: | ||
90 | str r7, [r6] // size = size - received | ||
91 | |||
92 | ldr r6,=usb_write_addr | ||
93 | ldr r7, [r6] | ||
94 | |||
95 | add r7, r7, r5 | ||
96 | str r7, [r6] // usb_write_addr += length | ||
97 | |||
98 | str r7, [r4, #0x60] // DMA1LM_OADDR = usb_write_addr | ||
99 | |||
100 | mov r5, #1 | ||
101 | str r5, [r4, #0x5c] // DMA1_CTL0 = ENP_DMA_START | ||
102 | |||
103 | ldmfd sp!, {r4-r8, pc} | ||
diff --git a/utils/rk27utils/rk27load/stage2/main.S b/utils/rk27utils/rk27load/stage2/main.S new file mode 100644 index 0000000000..c8474b0579 --- /dev/null +++ b/utils/rk27utils/rk27load/stage2/main.S | |||
@@ -0,0 +1,89 @@ | |||
1 | |||
2 | .section .text | ||
3 | .align 4 | ||
4 | |||
5 | .arm | ||
6 | |||
7 | .global main | ||
8 | .global _interrupt_disable | ||
9 | .global _interrupt_enable | ||
10 | |||
11 | .global usb_write_addr | ||
12 | .global usb_sz | ||
13 | |||
14 | #define BUFF_ADDR 0x60800000 | ||
15 | |||
16 | // ----------------------------------------------------- | ||
17 | // vector table | ||
18 | // ----------------------------------------------------- | ||
19 | ldr pc, =main | ||
20 | ldr pc, =main | ||
21 | ldr pc, =main | ||
22 | ldr pc, =main | ||
23 | ldr pc, =main | ||
24 | ldr pc, =main | ||
25 | ldr pc, =irq_handler | ||
26 | ldr pc, =main | ||
27 | |||
28 | // ----------------------------------------------------- | ||
29 | // main | ||
30 | // ----------------------------------------------------- | ||
31 | main: | ||
32 | // turn on usb interrupts | ||
33 | mov r0, #0x18000000 | ||
34 | add r0, r0, #0x80000 | ||
35 | ldr r1, [r0, #0x10c] | ||
36 | orr r1, r1, #0x10000 | ||
37 | str r1, [r0, #0x10c] | ||
38 | |||
39 | // enable usb-bulk | ||
40 | add r0, r0, #0x20000 // R0 = 0x180A0000 (UDC_BASE) | ||
41 | |||
42 | // enable EP1, write_reg32(UDC_RX1CON, (0x1 << 8) | RxACKINTEN | RxEPEN); | ||
43 | mov r1, #0x190 // bits 8,7,4 -> 0x190 | ||
44 | str r1, [r0, #0x58] | ||
45 | |||
46 | // setup receive buffer (must be aligned on dword boundary) | ||
47 | ldr r1,=usb_write_addr // write_reg32(UDC_DMA1LM_OADDR, (uint32_t)rx_buff); | ||
48 | ldr r1, [r1] | ||
49 | str r1, [r0, #0x60] // UDC_DMA1LM_OADDR = usb_write_addr | ||
50 | |||
51 | // write_reg32(UDC_DMA1CTRLO, read_reg32(UDC_DMA1CTRLO) | ENP_DMA_START); | ||
52 | ldr r1, [r0, #0x5c] | ||
53 | orr r1, r1, #2 | ||
54 | str r1, [r0, #0x5c] | ||
55 | |||
56 | // enable bulk_out1 interrupt | ||
57 | ldr r1, [r0, #0x14] // UDC_ENINT | ||
58 | orr r1, r1, #0x100 // EN_BOUT1_INTR | ||
59 | str r1, [r0, #0x14] | ||
60 | |||
61 | bl _interrupt_enable | ||
62 | idle: | ||
63 | b idle | ||
64 | |||
65 | // ----------------------------------------------------- | ||
66 | // _interrupt_enable - enables interrupts | ||
67 | // ----------------------------------------------------- | ||
68 | _interrupt_enable: | ||
69 | mrs r0, cpsr | ||
70 | bic r0, r0, #0x80 | ||
71 | msr cpsr_c, r0 | ||
72 | mov pc, lr | ||
73 | |||
74 | // ----------------------------------------------------- | ||
75 | // _interrupt_disable - disables interrupts | ||
76 | // ----------------------------------------------------- | ||
77 | _interrupt_disable: | ||
78 | mrs r0, cpsr | ||
79 | orr r0, r0, #0xc0 | ||
80 | msr cpsr_c, r0 | ||
81 | mov pc, lr | ||
82 | |||
83 | |||
84 | .section .data | ||
85 | usb_write_addr: | ||
86 | .word (BUFF_ADDR-4) | ||
87 | |||
88 | usb_sz: | ||
89 | .word (BUFF_ADDR-4) | ||
diff --git a/utils/rk27utils/rk27load/stage2/stage2.lds b/utils/rk27utils/rk27load/stage2/stage2.lds new file mode 100644 index 0000000000..2c07b201f7 --- /dev/null +++ b/utils/rk27utils/rk27load/stage2/stage2.lds | |||
@@ -0,0 +1,40 @@ | |||
1 | ENTRY(start) | ||
2 | OUTPUT_FORMAT(elf32-littlearm) | ||
3 | OUTPUT_ARCH(arm) | ||
4 | /* STARTUP(crt0.o) */ | ||
5 | |||
6 | MEMORY | ||
7 | { | ||
8 | DRAM : ORIGIN = 0x60000000, LENGTH = 0x01000000 | ||
9 | IRAM : ORIGIN = 0x00000000, LENGTH = 0x00002000 | ||
10 | } | ||
11 | |||
12 | SECTIONS | ||
13 | { | ||
14 | .init.text : { | ||
15 | *(.init.text) | ||
16 | } > DRAM | ||
17 | |||
18 | .text : { | ||
19 | *(.text*) | ||
20 | *(.glue_7*) | ||
21 | } > IRAM AT > DRAM | ||
22 | |||
23 | .data : { | ||
24 | *(.data*) | ||
25 | } > IRAM AT > DRAM | ||
26 | |||
27 | _relocstart = LOADADDR(.text); | ||
28 | _relocend = LOADADDR(.data) + SIZEOF(.data); | ||
29 | |||
30 | .stack (NOLOAD) : { | ||
31 | . = ALIGN(0x100); | ||
32 | *(.stack) | ||
33 | stackbegin = .; | ||
34 | . += 0x200; | ||
35 | stackend = .; | ||
36 | irqstackbegin = .; | ||
37 | . += 0x200; | ||
38 | irqstackend = .; | ||
39 | } > IRAM | ||
40 | } | ||
diff --git a/utils/rk27utils/rk27load/stage2_upload.c b/utils/rk27utils/rk27load/stage2_upload.c new file mode 100644 index 0000000000..820ad4463c --- /dev/null +++ b/utils/rk27utils/rk27load/stage2_upload.c | |||
@@ -0,0 +1,102 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdint.h> | ||
3 | #include <stdbool.h> | ||
4 | #include <stdlib.h> | ||
5 | #include <string.h> | ||
6 | #include <libusb.h> | ||
7 | |||
8 | #include "rk27load.h" | ||
9 | #include "common.h" | ||
10 | #include "scramble.h" | ||
11 | #include "checksum.h" | ||
12 | #include "stage2_upload.h" | ||
13 | |||
14 | int upload_stage2_code(libusb_device_handle *hdev, char *fn_stage2, | ||
15 | bool do_scramble) | ||
16 | { | ||
17 | FILE *f; | ||
18 | uint32_t codesize; | ||
19 | uint8_t *code; | ||
20 | uint16_t cks; | ||
21 | int ret; | ||
22 | |||
23 | if ((f = fopen(fn_stage2, "rb")) == NULL) | ||
24 | { | ||
25 | fprintf(stderr, "[error]: Could not open file \"%s\"\n", fn_stage2); | ||
26 | return -21; | ||
27 | } | ||
28 | |||
29 | codesize = filesize(f); | ||
30 | |||
31 | fprintf(stderr, "[stage1]: Loading %d bytes (%s) of code... ", codesize, fn_stage2); | ||
32 | |||
33 | code = (uint8_t *) malloc(codesize + 0x400); | ||
34 | if (code == NULL) | ||
35 | { | ||
36 | fprintf(stderr, "\n[error]: Out of memory\n"); | ||
37 | fclose(f); | ||
38 | return -22; | ||
39 | |||
40 | } | ||
41 | |||
42 | memset(code, 0, codesize + 0x400); | ||
43 | |||
44 | if (fread(code, 1, codesize, f) != codesize) | ||
45 | { | ||
46 | fprintf(stderr, "\n[error]: I/O error\n"); | ||
47 | fclose(f); | ||
48 | free(code); | ||
49 | return -23; | ||
50 | } | ||
51 | fprintf(stderr, "done\n"); | ||
52 | fclose(f); | ||
53 | |||
54 | codesize = ((codesize + 0x201) & 0xfffffe00) - 2; | ||
55 | |||
56 | if (do_scramble) | ||
57 | { | ||
58 | /* encode data if its user code */ | ||
59 | fprintf(stderr, "[stage2]: Encoding %d bytes data... ", codesize); | ||
60 | scramble(code, code, codesize); | ||
61 | fprintf(stderr, "done\n"); | ||
62 | } | ||
63 | |||
64 | fprintf(stderr, "[stage2]: Calculating checksum... "); | ||
65 | cks = checksum(code, codesize); | ||
66 | code[codesize + 0] = (cks >> 8) & 0xff; | ||
67 | code[codesize + 1] = cks & 0xff; | ||
68 | codesize += 2; | ||
69 | fprintf(stderr, "0x%04x\n", cks); | ||
70 | |||
71 | fprintf(stderr, "[stage2]: Uploading code (%d bytes)... ", codesize); | ||
72 | |||
73 | ret = libusb_control_transfer(hdev, /* device handle */ | ||
74 | USB_EP0, /* bmRequestType */ | ||
75 | VCMD_UPLOAD, /* bRequest */ | ||
76 | 0, /* wValue */ | ||
77 | VCMD_INDEX_STAGE2, /* wIndex */ | ||
78 | code, /* data */ | ||
79 | codesize, /* wLength */ | ||
80 | USB_TIMEOUT /* timeout */ | ||
81 | ); | ||
82 | |||
83 | if (ret < 0) | ||
84 | { | ||
85 | fprintf(stderr, "\n[error]: Code upload request failed (ret=%d)\n", ret); | ||
86 | free(code); | ||
87 | return -24; | ||
88 | } | ||
89 | |||
90 | if (ret != (int)codesize) | ||
91 | { | ||
92 | fprintf(stderr, "[error]: Sent %d of %d total\n", ret, codesize); | ||
93 | free(code); | ||
94 | return -25; | ||
95 | } | ||
96 | |||
97 | fprintf(stderr, "done\n"); | ||
98 | |||
99 | free(code); | ||
100 | return 0; | ||
101 | } | ||
102 | |||
diff --git a/utils/rk27utils/rk27load/stage2_upload.h b/utils/rk27utils/rk27load/stage2_upload.h new file mode 100644 index 0000000000..852d17adb2 --- /dev/null +++ b/utils/rk27utils/rk27load/stage2_upload.h | |||
@@ -0,0 +1,3 @@ | |||
1 | int upload_stage2_code(libusb_device_handle * hdev, char *fn_stage2, | ||
2 | bool do_scramble); | ||
3 | |||
diff --git a/utils/rk27utils/rk27load/stage3_upload.c b/utils/rk27utils/rk27load/stage3_upload.c new file mode 100644 index 0000000000..6f10a7c995 --- /dev/null +++ b/utils/rk27utils/rk27load/stage3_upload.c | |||
@@ -0,0 +1,93 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdint.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <string.h> | ||
5 | #include <libusb.h> | ||
6 | |||
7 | #include "rk27load.h" | ||
8 | #include "common.h" | ||
9 | #include "scramble.h" | ||
10 | #include "checksum.h" | ||
11 | #include "stage3_upload.h" | ||
12 | |||
13 | int upload_stage3_code(libusb_device_handle *hdev, char *fn_stage3) | ||
14 | { | ||
15 | FILE *f; | ||
16 | uint32_t codesize; | ||
17 | uint32_t remain; | ||
18 | uint8_t *code; | ||
19 | uint16_t send_size = 0x200; | ||
20 | uint32_t i = 0; | ||
21 | int ret, transfered; | ||
22 | |||
23 | if ((f = fopen(fn_stage3, "rb")) == NULL) | ||
24 | { | ||
25 | fprintf(stderr, "[error]: Could not open file \"%s\"\n", fn_stage3); | ||
26 | return -31; | ||
27 | } | ||
28 | |||
29 | codesize = filesize(f); | ||
30 | |||
31 | fprintf(stderr, "[stage3]: Loading user code (%d bytes)... ", codesize); | ||
32 | |||
33 | /* allocate buffer */ | ||
34 | code = (uint8_t *) malloc(codesize + 0x204); | ||
35 | if (code == NULL) | ||
36 | { | ||
37 | fprintf(stderr, "\n[error]: Out of memory\n"); | ||
38 | fclose(f); | ||
39 | return -32; | ||
40 | } | ||
41 | |||
42 | memset(code, 0, codesize + 0x204); | ||
43 | /* read usercode into buffer */ | ||
44 | if (fread(&code[4], 1, codesize, f) != codesize) | ||
45 | { | ||
46 | fprintf(stderr, "\n[error]: I/O error\n"); | ||
47 | fclose(f); | ||
48 | free(f); | ||
49 | return -33; | ||
50 | } | ||
51 | fprintf(stderr, "done\n"); | ||
52 | |||
53 | fclose(f); | ||
54 | |||
55 | /* put code size at the first 4 bytes */ | ||
56 | codesize += 4; | ||
57 | code[0] = codesize & 0xff; | ||
58 | code[1] = (codesize >> 8) & 0xff; | ||
59 | code[2] = (codesize >> 16) & 0xff; | ||
60 | code[3] = (codesize >> 24) & 0xff; | ||
61 | |||
62 | fprintf(stderr, "[stage3]: Uploading user code (%d bytes)... ", codesize); | ||
63 | |||
64 | remain = codesize; | ||
65 | |||
66 | while (remain > 0) | ||
67 | { | ||
68 | if (remain < 0x200) | ||
69 | send_size = remain; | ||
70 | |||
71 | ret = libusb_bulk_transfer(hdev, /* handle */ | ||
72 | 1, /* EP */ | ||
73 | &code[i * 0x200], /* data */ | ||
74 | send_size, /* length */ | ||
75 | &transfered, /* xfered */ | ||
76 | USB_TIMEOUT /* timeout */ | ||
77 | ); | ||
78 | |||
79 | if (ret != LIBUSB_SUCCESS) | ||
80 | { | ||
81 | fprintf(stderr, "\n[error]: Bulk transfer error (%d, %d)\n", ret, i); | ||
82 | free(code); | ||
83 | return -34; | ||
84 | } | ||
85 | |||
86 | remain -= send_size; | ||
87 | i++; | ||
88 | } | ||
89 | |||
90 | fprintf(stderr,"done (sent %d blocks)\n", i); | ||
91 | return 0; | ||
92 | } | ||
93 | |||
diff --git a/utils/rk27utils/rk27load/stage3_upload.h b/utils/rk27utils/rk27load/stage3_upload.h new file mode 100644 index 0000000000..03f9f0e46a --- /dev/null +++ b/utils/rk27utils/rk27load/stage3_upload.h | |||
@@ -0,0 +1 @@ | |||
int upload_stage3_code(libusb_device_handle *hdev, char *fn_stage3); | |||