OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* |
2 | * (C) Copyright 2013 |
||
3 | * |
||
4 | * Ma Haijun <mahaijuns@gmail.com> |
||
5 | * |
||
6 | * See file CREDITS for list of people who contributed to this |
||
7 | * project. |
||
8 | * |
||
9 | * This program is free software; you can redistribute it and/or |
||
10 | * modify it under the terms of the GNU General Public License as |
||
11 | * published by the Free Software Foundation; either version 2 of |
||
12 | * the License, or (at your option) any later version. |
||
13 | * |
||
14 | * This program is distributed in the hope that it will be useful, |
||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
17 | * GNU General Public License for more details. |
||
18 | * |
||
19 | * You should have received a copy of the GNU General Public License |
||
20 | * along with this program; if not, write to the Free Software |
||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||
22 | * MA 02111-1307 USA |
||
23 | */ |
||
24 | #include <common.h> |
||
25 | #include <spl.h> |
||
26 | #include <asm/u-boot.h> |
||
27 | #include <asm/utils.h> |
||
28 | #include <version.h> |
||
29 | #include <part.h> |
||
30 | #include <fat.h> |
||
31 | #include <ext4fs.h> |
||
32 | |||
33 | /* should be implemented by board */ |
||
34 | extern void spl_block_device_init(void); |
||
35 | |||
36 | block_dev_desc_t * spl_get_block_device(void) |
||
37 | { |
||
38 | block_dev_desc_t * device; |
||
39 | |||
40 | spl_block_device_init(); |
||
41 | |||
42 | device = get_dev(CONFIG_SPL_BLOCKDEV_INTERFACE, CONFIG_SPL_BLOCKDEV_ID); |
||
43 | if (!device) { |
||
44 | printf("blk device %s%d not exists\n", |
||
45 | CONFIG_SPL_BLOCKDEV_INTERFACE, |
||
46 | CONFIG_SPL_BLOCKDEV_ID); |
||
47 | hang(); |
||
48 | } |
||
49 | |||
50 | return device; |
||
51 | } |
||
52 | |||
53 | #ifdef CONFIG_SPL_FAT_SUPPORT |
||
54 | static int block_load_image_fat(const char *filename) |
||
55 | { |
||
56 | int err; |
||
57 | struct image_header *header; |
||
58 | |||
59 | header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - |
||
60 | sizeof(struct image_header)); |
||
61 | |||
62 | err = file_fat_read(filename, header, sizeof(struct image_header)); |
||
63 | if (err <= 0) |
||
64 | goto end; |
||
65 | |||
66 | spl_parse_image_header(header); |
||
67 | |||
68 | err = file_fat_read(filename, (u8 *)spl_image.load_addr, 0); |
||
69 | |||
70 | end: |
||
71 | if (err <= 0) |
||
72 | printf("spl: error reading image %s, err - %d\n", |
||
73 | filename, err); |
||
74 | |||
75 | return (err <= 0); |
||
76 | } |
||
77 | |||
78 | #ifdef CONFIG_SPL_OS_BOOT |
||
79 | static int block_load_image_fat_os(void) |
||
80 | { |
||
81 | int err; |
||
82 | |||
83 | err = file_fat_read(CONFIG_SPL_FAT_LOAD_ARGS_NAME, |
||
84 | (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0); |
||
85 | if (err <= 0) { |
||
86 | return -1; |
||
87 | } |
||
88 | |||
89 | return block_load_image_fat(CONFIG_SPL_FAT_LOAD_KERNEL_NAME); |
||
90 | } |
||
91 | #endif |
||
92 | |||
93 | void spl_block_load_image(void) |
||
94 | { |
||
95 | int err; |
||
96 | block_dev_desc_t * device; |
||
97 | |||
98 | device = spl_get_block_device(); |
||
99 | err = fat_register_device(device, CONFIG_BLOCKDEV_FAT_BOOT_PARTITION); |
||
100 | if (err) { |
||
101 | printf("spl: fat register err - %d\n", err); |
||
102 | hang(); |
||
103 | } |
||
104 | #ifdef CONFIG_SPL_OS_BOOT |
||
105 | if (spl_start_uboot() || block_load_image_fat_os()) |
||
106 | #endif |
||
107 | { |
||
108 | err = block_load_image_fat(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME); |
||
109 | if (err) |
||
110 | hang(); |
||
111 | } |
||
112 | } |
||
113 | #elif defined(CONFIG_SPL_EXT4_SUPPORT) /* end CONFIG_SPL_FAT_SUPPORT */ |
||
114 | static int block_load_image_ext4(const char *filename) |
||
115 | { |
||
116 | int err; |
||
117 | struct image_header *header; |
||
118 | |||
119 | header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - |
||
120 | sizeof(struct image_header)); |
||
121 | |||
122 | err = ext4_read_file(filename, header, 0, sizeof(struct image_header)); |
||
123 | if (err <= 0) |
||
124 | goto end; |
||
125 | |||
126 | spl_parse_image_header(header); |
||
127 | |||
128 | err = ext4_read_file(filename, (u8 *)spl_image.load_addr, 0, 0); |
||
129 | |||
130 | end: |
||
131 | return (err <= 0); |
||
132 | } |
||
133 | |||
134 | #ifdef CONFIG_SPL_OS_BOOT |
||
135 | static int block_load_image_ext4_os(void) |
||
136 | { |
||
137 | int err; |
||
138 | |||
139 | err = ext4_read_file(CONFIG_SPL_EXT4_LOAD_ARGS_NAME, |
||
140 | (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0, 0); |
||
141 | if (err <= 0) { |
||
142 | return -1; |
||
143 | } |
||
144 | |||
145 | return block_load_image_ext4(CONFIG_SPL_EXT4_LOAD_KERNEL_NAME); |
||
146 | } |
||
147 | #endif |
||
148 | |||
149 | void spl_block_load_image(void) |
||
150 | { |
||
151 | int err; |
||
152 | block_dev_desc_t * device; |
||
153 | |||
154 | device = spl_get_block_device(); |
||
155 | err = ext4_register_device(device, CONFIG_BLOCKDEV_EXT4_BOOT_PARTITION); |
||
156 | if (err) { |
||
157 | hang(); |
||
158 | } |
||
159 | #ifdef CONFIG_SPL_OS_BOOT |
||
160 | if (spl_start_uboot() || block_load_image_ext4_os()) |
||
161 | #endif |
||
162 | { |
||
163 | err = block_load_image_ext4(CONFIG_SPL_EXT4_LOAD_PAYLOAD_NAME); |
||
164 | if (err) |
||
165 | hang(); |
||
166 | } |
||
167 | } |
||
168 | #else /* end CONFIG_SPL_EXT4_SUPPORT */ |
||
169 | static int block_load_image_raw(block_dev_desc_t * device, lbaint_t sector) |
||
170 | { |
||
171 | int n; |
||
172 | u32 image_size_sectors; |
||
173 | struct image_header *header; |
||
174 | |||
175 | header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - |
||
176 | sizeof(struct image_header)); |
||
177 | |||
178 | /* read image header to find the image size & load address */ |
||
179 | n = device->block_read(device->dev, sector, 1, header); |
||
180 | |||
181 | if (n != 1) { |
||
182 | printf("spl: blk read err\n"); |
||
183 | return 1; |
||
184 | } |
||
185 | |||
186 | spl_parse_image_header(header); |
||
187 | |||
188 | /* convert size to sectors - round up */ |
||
189 | image_size_sectors = (spl_image.size + 512 - 1) / 512; |
||
190 | n = device->block_read(device->dev, sector, image_size_sectors, |
||
191 | (void *)spl_image.load_addr); |
||
192 | |||
193 | if (n != image_size_sectors) { |
||
194 | printf("spl: blk read err\n"); |
||
195 | return 1; |
||
196 | } |
||
197 | return 0; |
||
198 | } |
||
199 | |||
200 | #ifdef CONFIG_SPL_OS_BOOT |
||
201 | static int block_load_image_raw_os(block_dev_desc_t * device) |
||
202 | { |
||
203 | int n; |
||
204 | |||
205 | n = device->block_read(device->dev, CONFIG_SYS_BLOCK_RAW_MODE_ARGS_SECTOR, |
||
206 | CONFIG_SYS_BLOCK_RAW_MODE_ARGS_SECTORS, |
||
207 | (u32 *)CONFIG_SYS_SPL_ARGS_ADDR); |
||
208 | /* flush cache after read */ |
||
209 | flush_cache(addr, CONFIG_SYS_BLOCK_RAW_MODE_ARGS_SECTORS * 512); |
||
210 | |||
211 | if (n != CONFIG_SYS_BLOCK_RAW_MODE_ARGS_SECTORS) { |
||
212 | printf("args blk read error\n"); |
||
213 | return -1; |
||
214 | } |
||
215 | |||
216 | return block_load_image_raw(device, CONFIG_SYS_BLOCK_RAW_MODE_KERNEL_SECTOR); |
||
217 | } |
||
218 | #endif |
||
219 | |||
220 | void spl_block_load_image(void) |
||
221 | { |
||
222 | int err; |
||
223 | block_dev_desc_t * device; |
||
224 | |||
225 | device = spl_get_block_device(); |
||
226 | #ifdef CONFIG_SPL_OS_BOOT |
||
227 | if (spl_start_uboot() || block_load_image_raw_os(device)) |
||
228 | #endif |
||
229 | { |
||
230 | err = block_load_image_raw(device, |
||
231 | CONFIG_SYS_BLOCK_RAW_MODE_U_BOOT_SECTOR); |
||
232 | if (err) |
||
233 | hang(); |
||
234 | } |
||
235 | } |
||
236 | #endif /* CONFIG_SPL_FAT_SUPPORT */ |