scripts: support Sercomm load tags
[oweals/openwrt.git] / scripts / cfe-wfi-tag.py
1 #!/usr/bin/env python3
2
3 """
4 Whole Flash Image Tag
5
6 {
7         u32 crc32;
8         u32 version;
9         u32 chipID;
10         u32 flashType;
11         u32 flags;
12 }
13
14 CRC32: Ethernet (Poly 0x04C11DB7)
15
16 Version:
17         0x00005700: Any version
18         0x00005731: NAND 1MB data partition
19         0x00005732: Normal version
20
21 Chip ID:
22         Broadcom Chip ID
23         0x00006328: BCM6328
24         0x00006362: BCM6362
25         0x00006368: BCM6368
26         0x00063268: BCM63268
27
28 Flash Type:
29         1: NOR
30         2: NAND 16k blocks
31         3: NAND 128k blocks
32         4: NAND 256k blocks
33         5: NAND 512k blocks
34         6: NAND 1MB blocks
35         7: NAND 2MB blocks
36
37 Flags:
38         0x00000001: PMC
39         0x00000002: Secure BootROM
40
41 """
42
43 import argparse
44 import os
45 import struct
46
47 CRC32_INIT = 0xFFFFFFFF
48 CRC32_TABLE = [
49         0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
50         0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
51         0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
52         0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
53         0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
54         0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
55         0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
56         0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
57         0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
58         0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
59         0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
60         0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
61         0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
62         0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
63         0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
64         0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
65         0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
66         0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
67         0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
68         0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
69         0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
70         0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
71         0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
72         0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
73         0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
74         0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
75         0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
76         0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
77         0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
78         0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
79         0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
80         0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
81         0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
82         0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
83         0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
84         0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
85         0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
86         0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
87         0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
88         0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
89         0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
90         0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
91         0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
92         0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
93         0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
94         0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
95         0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
96         0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
97         0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
98         0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
99         0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
100         0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
101         0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
102         0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
103         0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
104         0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
105         0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
106         0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
107         0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
108         0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
109         0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
110         0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
111         0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
112         0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
113 ]
114
115 def auto_int(x):
116         return int(x, 0)
117
118 def crc32(bytes, size, crc):
119         i = 0
120         while (i < size):
121                 crc = (crc >> 8) ^ CRC32_TABLE[(crc ^ bytes[i]) & 0xff]
122                 i += 1
123         return crc
124
125 def create_tag(args, in_bytes, size):
126         crc = crc32(in_bytes, size, CRC32_INIT)
127         tag = struct.pack('>IIIII', crc, args.tag_version, args.chip_id, args.flash_type, args.flags)
128         return tag
129
130 def create_output(args):
131         in_st = os.stat(args.input_file)
132         in_size = in_st.st_size
133
134         in_f = open(args.input_file, 'r+b')
135         in_bytes = in_f.read(in_size)
136         in_f.close()
137
138         tag = create_tag(args, in_bytes, in_size)
139
140         out_f = open(args.output_file, 'w+b')
141         out_f.write(in_bytes)
142         out_f.write(tag)
143         out_f.close()
144
145 def main():
146         global args
147
148         parser = argparse.ArgumentParser(description='')
149
150         parser.add_argument('--input-file',
151                 dest='input_file',
152                 action='store',
153                 type=str,
154                 help='Input file')
155
156         parser.add_argument('--output-file',
157                 dest='output_file',
158                 action='store',
159                 type=str,
160                 help='Output file')
161
162         parser.add_argument('--version',
163                 dest='tag_version',
164                 action='store',
165                 type=auto_int,
166                 help='WFI Tag Version')
167
168         parser.add_argument('--chip-id',
169                 dest='chip_id',
170                 action='store',
171                 type=auto_int,
172                 help='WFI Chip ID')
173
174         parser.add_argument('--flash-type',
175                 dest='flash_type',
176                 action='store',
177                 type=auto_int,
178                 help='WFI Flash Type')
179
180         parser.add_argument('--flags',
181                 dest='flags',
182                 action='store',
183                 type=auto_int,
184                 help='WFI Flags')
185
186         args = parser.parse_args()
187
188         if not args.flags:
189                 args.flags = 0
190
191         if ((not args.input_file) or
192             (not args.output_file) or
193             (not args.tag_version) or
194             (not args.chip_id) or
195             (not args.flash_type)):
196                 parser.print_help()
197         else:
198                 create_output(args)
199
200 main()