FreeCalypso > hg > freecalypso-tools
comparison target-utils/loadagent/intelflash.c @ 658:0da2cf5a999c
target-utils: libload eliminated
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 03 Mar 2020 06:06:17 +0000 |
parents | target-utils/libload/intelflash.c@e7502631a0f9 |
children | 761e8b0c65b0 |
comparison
equal
deleted
inserted
replaced
657:742c99c1ff52 | 658:0da2cf5a999c |
---|---|
1 /* | |
2 * This module implements the INFB and INFW commands for programming | |
3 * Intel-style flash memories. The syntax and operation are exactly | |
4 * the same as the AMD flash counterparts AMFB and AMFW. | |
5 * | |
6 * The intel-rewrite-sector command (erase+program with a minimum of | |
7 * vulnerability for brickable-boot Compal phones) is implemented | |
8 * here as well. | |
9 */ | |
10 | |
11 #include <sys/types.h> | |
12 #include "types.h" | |
13 | |
14 static u32 base_addr; | |
15 | |
16 void | |
17 cmd_INFB(argbulk) | |
18 char *argbulk; | |
19 { | |
20 char *argv[2]; | |
21 u_long addr; | |
22 | |
23 if (parse_args(argbulk, 1, 1, argv, 0) < 0) | |
24 return; | |
25 if (parse_hexarg(argv[0], 8, &addr) < 0) { | |
26 printf("ERROR: argument must be a valid 32-bit hex address\n"); | |
27 return; | |
28 } | |
29 if (addr & 1) { | |
30 printf("ERROR: odd address\n"); | |
31 return; | |
32 } | |
33 base_addr = addr; | |
34 } | |
35 | |
36 void | |
37 cmd_INFW(argbulk) | |
38 char *argbulk; | |
39 { | |
40 char *argv[3], *s; | |
41 u_long offset; | |
42 volatile u16 *flashptr; | |
43 u32 datum; /* needs to be u32 for decode_hex_digits() */ | |
44 u16 stat; | |
45 int i; | |
46 | |
47 if (parse_args(argbulk, 2, 2, argv, 0) < 0) | |
48 return; | |
49 if (parse_hexarg(argv[0], 8, &offset) < 0) { | |
50 printf("ERROR: offset argument must a valid 32-bit hex value\n"); | |
51 return; | |
52 } | |
53 if (offset & 1) { | |
54 printf("ERROR: odd offset argument\n"); | |
55 return; | |
56 } | |
57 flashptr = (volatile u16 *)(base_addr + offset); | |
58 for (s = argv[1]; *s; flashptr++, s += 4) { | |
59 if (decode_hex_digits(s, 4, &datum) < 0) { | |
60 printf("ERROR: bad INFW hex string argument\n"); | |
61 return; | |
62 } | |
63 *flashptr = 0x40; | |
64 *flashptr = datum; | |
65 for (i = 10000; i; i--) { | |
66 stat = *flashptr; | |
67 if (stat & 0x80) | |
68 break; | |
69 } | |
70 if (!i) { | |
71 printf("ERROR: flash write timeout at %08X\n", | |
72 (u_long) flashptr); | |
73 return; | |
74 } | |
75 if (stat & 0x10) { | |
76 printf("ERROR: program operation failed at %08X\n", | |
77 (u_long) flashptr); | |
78 return; | |
79 } | |
80 } | |
81 } | |
82 | |
83 void | |
84 cmd_intel_rewrite_sector(argbulk) | |
85 char *argbulk; | |
86 { | |
87 char *argv[4]; | |
88 u_long srcaddr, dstaddr, len; | |
89 const u16 *srcptr; | |
90 volatile u16 *flashptr; | |
91 u16 stat; | |
92 | |
93 if (parse_args(argbulk, 3, 3, argv, 0) < 0) | |
94 return; | |
95 if (parse_hexarg(argv[0], 8, &srcaddr) < 0) { | |
96 invarg: printf("ERROR: invalid argument(s)\n"); | |
97 return; | |
98 } | |
99 if (parse_hexarg(argv[1], 8, &dstaddr) < 0) | |
100 goto invarg; | |
101 if (parse_hexarg(argv[2], 8, &len) < 0) | |
102 goto invarg; | |
103 if (srcaddr & 1 || dstaddr & 1 || len & 1) { | |
104 printf("ERROR: all 3 arguments must be even\n"); | |
105 return; | |
106 } | |
107 srcptr = (const u16 *) srcaddr; | |
108 flashptr = (volatile u16 *) dstaddr; | |
109 /* unlock the flash sector first */ | |
110 *flashptr = 0x60; | |
111 *flashptr = 0xD0; | |
112 /* clear SR */ | |
113 *flashptr = 0x50; | |
114 /* erase */ | |
115 *flashptr = 0x20; | |
116 *flashptr = 0xD0; | |
117 /* wait for erase completion */ | |
118 for (;;) { | |
119 stat = *flashptr; | |
120 if (stat & 0x80) | |
121 break; | |
122 } | |
123 if (stat & 0x30) { | |
124 printf("ERROR: erase operation failed!\n"); | |
125 return; | |
126 } | |
127 /* now program the new content */ | |
128 for (; len; len -= 2) { | |
129 *flashptr = 0x40; | |
130 *flashptr = *srcptr++; | |
131 for (;;) { | |
132 stat = *flashptr; | |
133 if (stat & 0x80) | |
134 break; | |
135 } | |
136 flashptr++; | |
137 } | |
138 printf("Operation complete, final SR: %02X\n", stat & 0xFF); | |
139 } |