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 }