Blame view

common/aboot.c 7.21 KB
b4e4bbe5a   Steve Rae   add code to handl...
1
2
3
4
5
  /*
   * Copyright (c) 2009, Google Inc.
   * All rights reserved.
   *
   * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
e6ca1ad60   Steve Rae   implement the And...
6
   * Portions Copyright 2014 Broadcom Corporation.
b4e4bbe5a   Steve Rae   add code to handl...
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are met:
   *     * Redistributions of source code must retain the above copyright
   *       notice, this list of conditions and the following disclaimer.
   *     * Redistributions in binary form must reproduce the above copyright
   *       notice, this list of conditions and the following disclaimer in the
   *       documentation and/or other materials provided with the distribution.
   *     * Neither the name of The Linux Foundation nor
   *       the names of its contributors may be used to endorse or promote
   *       products derived from this software without specific prior written
   *       permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
1c39d856d   Steve Rae   cleanup code whic...
32
33
34
   * NOTE:
   *   Although it is very similar, this license text is not identical
   *   to the "BSD-3-Clause", therefore, DO NOT MODIFY THIS LICENSE TEXT!
b4e4bbe5a   Steve Rae   add code to handl...
35
   */
e6ca1ad60   Steve Rae   implement the And...
36
37
38
39
40
41
42
43
44
45
  #include <config.h>
  #include <common.h>
  #include <aboot.h>
  #include <malloc.h>
  #include <part.h>
  #include <sparse_format.h>
  
  void write_sparse_image(block_dev_desc_t *dev_desc,
  		disk_partition_t *info, const char *part_name,
  		void *data, unsigned sz)
b4e4bbe5a   Steve Rae   add code to handl...
46
  {
e6ca1ad60   Steve Rae   implement the And...
47
48
49
50
  	lbaint_t blk;
  	lbaint_t blkcnt;
  	lbaint_t blks;
  	uint32_t bytes_written = 0;
b4e4bbe5a   Steve Rae   add code to handl...
51
52
53
54
  	unsigned int chunk;
  	unsigned int chunk_data_sz;
  	uint32_t *fill_buf = NULL;
  	uint32_t fill_val;
b4e4bbe5a   Steve Rae   add code to handl...
55
56
57
  	sparse_header_t *sparse_header;
  	chunk_header_t *chunk_header;
  	uint32_t total_blocks = 0;
b4e4bbe5a   Steve Rae   add code to handl...
58
  	int i;
b4e4bbe5a   Steve Rae   add code to handl...
59
60
61
  
  	/* Read and skip over sparse image header */
  	sparse_header = (sparse_header_t *) data;
b4e4bbe5a   Steve Rae   add code to handl...
62
63
  
  	data += sparse_header->file_hdr_sz;
1c39d856d   Steve Rae   cleanup code whic...
64
  	if (sparse_header->file_hdr_sz > sizeof(sparse_header_t))
b4e4bbe5a   Steve Rae   add code to handl...
65
  	{
1c39d856d   Steve Rae   cleanup code whic...
66
67
  		/*
  		 * Skip the remaining bytes in a header that is longer than
b4e4bbe5a   Steve Rae   add code to handl...
68
69
70
71
  		 * we expected.
  		 */
  		data += (sparse_header->file_hdr_sz - sizeof(sparse_header_t));
  	}
1c39d856d   Steve Rae   cleanup code whic...
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
  	debug("=== Sparse Image Header ===
  ");
  	debug("magic: 0x%x
  ", sparse_header->magic);
  	debug("major_version: 0x%x
  ", sparse_header->major_version);
  	debug("minor_version: 0x%x
  ", sparse_header->minor_version);
  	debug("file_hdr_sz: %d
  ", sparse_header->file_hdr_sz);
  	debug("chunk_hdr_sz: %d
  ", sparse_header->chunk_hdr_sz);
  	debug("blk_sz: %d
  ", sparse_header->blk_sz);
  	debug("total_blks: %d
  ", sparse_header->total_blks);
  	debug("total_chunks: %d
  ", sparse_header->total_chunks);
b4e4bbe5a   Steve Rae   add code to handl...
90

e6ca1ad60   Steve Rae   implement the And...
91
92
93
94
95
96
97
98
99
100
101
102
  	/* verify sparse_header->blk_sz is an exact multiple of info->blksz */
  	if (sparse_header->blk_sz !=
  	    (sparse_header->blk_sz & ~(info->blksz - 1))) {
  		printf("%s: Sparse image block size issue [%u]
  ",
  		       __func__, sparse_header->blk_sz);
  		fastboot_fail("sparse image block size issue");
  		return;
  	}
  
  	puts("Flashing Sparse Image
  ");
b4e4bbe5a   Steve Rae   add code to handl...
103
  	/* Start processing chunks */
e6ca1ad60   Steve Rae   implement the And...
104
  	blk = info->start;
b4e4bbe5a   Steve Rae   add code to handl...
105
106
107
108
109
  	for (chunk=0; chunk<sparse_header->total_chunks; chunk++)
  	{
  		/* Read and skip over chunk header */
  		chunk_header = (chunk_header_t *) data;
  		data += sizeof(chunk_header_t);
e6ca1ad60   Steve Rae   implement the And...
110
111
112
113
114
115
116
117
118
119
  		if (chunk_header->chunk_type != CHUNK_TYPE_RAW) {
  			debug("=== Chunk Header ===
  ");
  			debug("chunk_type: 0x%x
  ", chunk_header->chunk_type);
  			debug("chunk_data_sz: 0x%x
  ", chunk_header->chunk_sz);
  			debug("total_size: 0x%x
  ", chunk_header->total_sz);
  		}
b4e4bbe5a   Steve Rae   add code to handl...
120

1c39d856d   Steve Rae   cleanup code whic...
121
  		if (sparse_header->chunk_hdr_sz > sizeof(chunk_header_t))
b4e4bbe5a   Steve Rae   add code to handl...
122
  		{
1c39d856d   Steve Rae   cleanup code whic...
123
124
125
  			/*
  			 * Skip the remaining bytes in a header that is longer
  			 * than we expected.
b4e4bbe5a   Steve Rae   add code to handl...
126
  			 */
1c39d856d   Steve Rae   cleanup code whic...
127
128
  			data += (sparse_header->chunk_hdr_sz -
  				 sizeof(chunk_header_t));
b4e4bbe5a   Steve Rae   add code to handl...
129
130
131
  		}
  
  		chunk_data_sz = sparse_header->blk_sz * chunk_header->chunk_sz;
e6ca1ad60   Steve Rae   implement the And...
132
  		blkcnt = chunk_data_sz / info->blksz;
b4e4bbe5a   Steve Rae   add code to handl...
133
134
135
  		switch (chunk_header->chunk_type)
  		{
  			case CHUNK_TYPE_RAW:
1c39d856d   Steve Rae   cleanup code whic...
136
137
  			if (chunk_header->total_sz !=
  			    (sparse_header->chunk_hdr_sz + chunk_data_sz))
b4e4bbe5a   Steve Rae   add code to handl...
138
  			{
1c39d856d   Steve Rae   cleanup code whic...
139
140
  				fastboot_fail(
  					"Bogus chunk size for chunk type Raw");
b4e4bbe5a   Steve Rae   add code to handl...
141
142
  				return;
  			}
e6ca1ad60   Steve Rae   implement the And...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  			if (blk + blkcnt > info->start + info->size) {
  				printf(
  				    "%s: Request would exceed partition size!
  ",
  				    __func__);
  				fastboot_fail(
  				    "Request would exceed partition size!");
  				return;
  			}
  
  			blks = dev_desc->block_write(dev_desc->dev, blk, blkcnt,
  						     data);
  			if (blks != blkcnt) {
  				printf("%s: Write failed " LBAFU "
  ",
  				       __func__, blks);
b4e4bbe5a   Steve Rae   add code to handl...
159
160
161
  				fastboot_fail("flash write failure");
  				return;
  			}
e6ca1ad60   Steve Rae   implement the And...
162
163
  			blk += blkcnt;
  			bytes_written += blkcnt * info->blksz;
b4e4bbe5a   Steve Rae   add code to handl...
164
165
166
167
168
  			total_blocks += chunk_header->chunk_sz;
  			data += chunk_data_sz;
  			break;
  
  			case CHUNK_TYPE_FILL:
1c39d856d   Steve Rae   cleanup code whic...
169
170
  			if (chunk_header->total_sz !=
  			    (sparse_header->chunk_hdr_sz + sizeof(uint32_t)))
b4e4bbe5a   Steve Rae   add code to handl...
171
  			{
1c39d856d   Steve Rae   cleanup code whic...
172
173
  				fastboot_fail(
  					"Bogus chunk size for chunk type FILL");
b4e4bbe5a   Steve Rae   add code to handl...
174
175
  				return;
  			}
1c39d856d   Steve Rae   cleanup code whic...
176
  			fill_buf = (uint32_t *)
e6ca1ad60   Steve Rae   implement the And...
177
178
179
  				   memalign(ARCH_DMA_MINALIGN,
  					    ROUNDUP(info->blksz,
  						    ARCH_DMA_MINALIGN));
b4e4bbe5a   Steve Rae   add code to handl...
180
181
  			if (!fill_buf)
  			{
1c39d856d   Steve Rae   cleanup code whic...
182
183
  				fastboot_fail(
  					"Malloc failed for: CHUNK_TYPE_FILL");
b4e4bbe5a   Steve Rae   add code to handl...
184
185
186
187
188
  				return;
  			}
  
  			fill_val = *(uint32_t *)data;
  			data = (char *) data + sizeof(uint32_t);
b4e4bbe5a   Steve Rae   add code to handl...
189

e6ca1ad60   Steve Rae   implement the And...
190
  			for (i = 0; i < (info->blksz / sizeof(fill_val)); i++)
b4e4bbe5a   Steve Rae   add code to handl...
191
  				fill_buf[i] = fill_val;
e6ca1ad60   Steve Rae   implement the And...
192
193
194
195
196
197
198
199
200
  
  			if (blk + blkcnt > info->start + info->size) {
  				printf(
  				    "%s: Request would exceed partition size!
  ",
  				    __func__);
  				fastboot_fail(
  				    "Request would exceed partition size!");
  				return;
b4e4bbe5a   Steve Rae   add code to handl...
201
  			}
e6ca1ad60   Steve Rae   implement the And...
202
203
204
205
206
207
208
209
  			for (i = 0; i < blkcnt; i++) {
  				blks = dev_desc->block_write(dev_desc->dev,
  							     blk, 1, fill_buf);
  				if (blks != 1) {
  					printf(
  					    "%s: Write failed, block # " LBAFU "
  ",
  					    __func__, blkcnt);
b4e4bbe5a   Steve Rae   add code to handl...
210
211
212
213
  					fastboot_fail("flash write failure");
  					free(fill_buf);
  					return;
  				}
e6ca1ad60   Steve Rae   implement the And...
214
  				blk++;
b4e4bbe5a   Steve Rae   add code to handl...
215
  			}
e6ca1ad60   Steve Rae   implement the And...
216
217
  			bytes_written += blkcnt * info->blksz;
  			total_blocks += chunk_data_sz / sparse_header->blk_sz;
b4e4bbe5a   Steve Rae   add code to handl...
218
219
220
221
222
223
224
  
  			free(fill_buf);
  			break;
  
  			case CHUNK_TYPE_DONT_CARE:
  			total_blocks += chunk_header->chunk_sz;
  			break;
e6ca1ad60   Steve Rae   implement the And...
225
  			case CHUNK_TYPE_CRC32:
1c39d856d   Steve Rae   cleanup code whic...
226
227
  			if (chunk_header->total_sz !=
  			    sparse_header->chunk_hdr_sz)
b4e4bbe5a   Steve Rae   add code to handl...
228
  			{
1c39d856d   Steve Rae   cleanup code whic...
229
230
  				fastboot_fail(
  					"Bogus chunk size for chunk type Dont Care");
b4e4bbe5a   Steve Rae   add code to handl...
231
232
233
234
235
236
237
  				return;
  			}
  			total_blocks += chunk_header->chunk_sz;
  			data += chunk_data_sz;
  			break;
  
  			default:
e6ca1ad60   Steve Rae   implement the And...
238
239
240
  			printf("%s: Unknown chunk type: %x
  ", __func__,
  			       chunk_header->chunk_type);
b4e4bbe5a   Steve Rae   add code to handl...
241
242
243
244
  			fastboot_fail("Unknown chunk type");
  			return;
  		}
  	}
1c39d856d   Steve Rae   cleanup code whic...
245
246
247
  	debug("Wrote %d blocks, expected to write %d blocks
  ",
  	      total_blocks, sparse_header->total_blks);
e6ca1ad60   Steve Rae   implement the And...
248
249
  	printf("........ wrote %u bytes to '%s'
  ", bytes_written, part_name);
b4e4bbe5a   Steve Rae   add code to handl...
250

1c39d856d   Steve Rae   cleanup code whic...
251
  	if (total_blocks != sparse_header->total_blks)
b4e4bbe5a   Steve Rae   add code to handl...
252
  		fastboot_fail("sparse image write failure");
b4e4bbe5a   Steve Rae   add code to handl...
253
254
255
256
  
  	fastboot_okay("");
  	return;
  }