1 #include <common.h>
2 #include <command.h>
3 #include <ext2fs.h>
4 #include "hvideo.h"
5 #include "sys_dep.h"
6 #include "sam_ide.h"
7
8 #include "malloc.h"
9
10 extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
11
12 #ifdef CONFIG_CMD_SCSI
13 extern block_dev_desc_t * scsi_get_dev(int);
14 #else
scsi_get_dev(int a)15 block_dev_desc_t * scsi_get_dev(int a)
16 {
17 return (block_dev_desc_t *)0;
18 }
19 #endif
20
21 #include <usb.h> // I need usb_stor_get_dev()
22 #define MAX_USB_UNITNUM USB_MAX_STOR_DEV
23
24 //System-dependent support for the A1 first and second level bootloaders.
25
26 #define MAX_IDE_UNITNUM CFG_IDE_MAXDEVICE
27 //#define MAX_SCSI_UNITNUM CFG_SCSI_MAX_DEVICE
28
29 #include <fdc.h>
30
31 static struct MinList dev_list; //Made out of uboot_scan_handles
32 static struct MinList old_dev_list; //Made out of old_uboot_scan_handles
33 static SCAN_HANDLE curr_disk;
34
find_dae(const char * s)35 struct dev_access_entry * find_dae(const char * s)
36 {
37 static struct dev_access_entry devices_access_table[]={
38 {NULL, NULL, DEV_TYPE_NETBOOT, 1, BUSTYPE_NET},
39 {NULL, NULL, DEV_TYPE_CDROM, MAX_USB_UNITNUM, BUSTYPE_USB},
40 {NULL, NULL, DEV_TYPE_HARDDISK, MAX_USB_UNITNUM, BUSTYPE_USB},
41 {NULL, NULL, DEV_TYPE_HARDDISK, MAX_S_SII_UNITS, BUSTYPE_SIL_SERIAL},
42 {NULL, NULL, DEV_TYPE_CDROM, MAX_S_SII_UNITS, BUSTYPE_SIL_SERIAL},
43 {NULL, NULL, DEV_TYPE_HARDDISK, MAX_S_4_SII_UNITS, BUSTYPE_SIL_4_SERIAL},
44 {NULL, NULL, DEV_TYPE_CDROM, MAX_S_4_SII_UNITS, BUSTYPE_SIL_4_SERIAL},
45 {NULL, NULL, DEV_TYPE_HARDDISK, MAX_P_SII_UNITS, BUSTYPE_SIL_PARALLEL},
46 {NULL, NULL, DEV_TYPE_CDROM, MAX_P_SII_UNITS, BUSTYPE_SIL_PARALLEL},
47 #ifdef CONFIG_SAM460EX
48 {NULL, NULL, DEV_TYPE_HARDDISK, MAX_SATA2_460_UNITS,BUSTYPE_SATA2_460},
49 #endif
50 {NULL, NULL, DEV_TYPE_DUMMY_END, 0, 0}
51 //{NULL, NULL, DEV_TYPE_CDROM, MAX_SCSI_UNITNUM, BUSTYPE_SCSI},
52 //{NULL, NULL, DEV_TYPE_HARDDISK, MAX_SCSI_UNITNUM, BUSTYPE_SCSI},
53 };
54
55 devices_access_table[0].dae_identifier = "net";
56 devices_access_table[1].dae_identifier = "ucdrom";
57 devices_access_table[2].dae_identifier = "usb";
58 devices_access_table[3].dae_identifier = "ssii";
59 devices_access_table[4].dae_identifier = "ssiicdrom";
60 devices_access_table[5].dae_identifier = "s4sii";
61 devices_access_table[6].dae_identifier = "s4siicdrom";
62 devices_access_table[7].dae_identifier = "psii";
63 devices_access_table[8].dae_identifier = "psiicdrom";
64 #ifdef CONFIG_SAM460EX
65 devices_access_table[9].dae_identifier = "sata2-460";
66 devices_access_table[10].dae_identifier = NULL;
67 #else
68 devices_access_table[9].dae_identifier = NULL;
69 #endif
70 //devices_access_table[1].dae_identifier = "scdrom";
71 //devices_access_table[2].dae_identifier = "scsi";
72
73 struct dev_access_entry * current;
74
75 for(current = devices_access_table;
76 current->dae_request_type != DEV_TYPE_DUMMY_END;
77 current++)
78 {
79 if(!strcmp(s, current->dae_identifier))
80 {
81 /* The get_dev() hooks MUST be assigned at runtime, since uboot is relocated! */
82 switch(current->dae_bustype)
83 {
84 //case BUSTYPE_SCSI:
85 // current->dae_get_dev = scsi_get_dev;
86 // break;
87
88 case BUSTYPE_USB:
89 current->dae_get_dev = usb_stor_get_dev;
90 break;
91
92 case BUSTYPE_SIL_SERIAL:
93 current->dae_get_dev = s_sii_get_dev;
94 break;
95
96 case BUSTYPE_SIL_4_SERIAL:
97 current->dae_get_dev = s_4_sii_get_dev;
98 break;
99
100 case BUSTYPE_SIL_PARALLEL:
101 current->dae_get_dev = p_sii_get_dev;
102 break;
103
104 #ifdef CONFIG_SAM460EX
105 case BUSTYPE_SATA2_460:
106 current->dae_get_dev = sata2_460_get_dev;
107 break;
108 #endif
109
110 default:
111 break;
112 }
113
114 //printf("found hook is %08lx\n", current->dae_get_dev);
115 return current;
116 }
117 }
118
119 return NULL;
120 }
121
next_unit_scan(SCAN_HANDLE h,ULONG * const blocksize)122 SCAN_HANDLE next_unit_scan(SCAN_HANDLE h, ULONG * const blocksize)
123 {
124 SCAN_HANDLE next = (SCAN_HANDLE)h->ush_link.mln_Succ;
125
126 h->ush_already_scanned = TRUE; //Mark the past handle as already scanned.
127
128 //printf("Entered next_unit_scan\n");
129 if(next->ush_link.mln_Succ) //more to go ?
130 {
131 *blocksize = next->ush_device.blksz;
132
133 /*
134 printf("NUS: returning device with data: interface type %d, devnumber %d, type %u\n",
135 curr_disk->ush_device.if_type, curr_disk->ush_device.dev, curr_disk->ush_device.type);
136 */
137
138 return (curr_disk = next);
139 }
140 else
141 {
142 //printf("NUS: no more units in list\n");
143 return NULL;
144 }
145 }
146
start_unit_scan(const void * scan_list,ULONG * const blocksize)147 SCAN_HANDLE start_unit_scan(const void * scan_list, ULONG * const blocksize)
148 {
149 const char ** opt_list;
150 struct dev_access_entry * dae_found;
151 //printf("entered start_unit_scan\n");
152 if (!scan_list || !blocksize) return NULL;
153 //floppy_like_an_hd.block_read = internal_floppy_block_read;
154
155 /* This routine builds a list of scan handles from the env-vars passed in scan_list. */
156
157 NewList(&dev_list);
158
159 for(opt_list = scan_list;*opt_list;opt_list++) //Iterates till empty string.
160 {
161 //printf("Now examining boot source '%s'\n", *opt_list);
162
163 dae_found = find_dae(*opt_list);
164
165 //printf("Done find_dae\n");
166 if(dae_found)
167 {
168 SCAN_HANDLE s_h;
169 block_dev_desc_t * newdev;
170 UBYTE curr_unit;
171
172 //printf("Found dae matching identifier %s, looping\n", dae_found->dae_identifier);
173 for(curr_unit = 0; curr_unit < dae_found->dae_max_unitnum; curr_unit++)
174 {
175 if(dae_found->dae_bustype == BUSTYPE_NET) //Special case!!
176 {
177 //printf("Found special boot type network.\n");
178 s_h = alloc_mem_for_anythingelse(sizeof (struct uboot_scan_handle));
179
180 memset(s_h, 0, sizeof(struct uboot_scan_handle));
181
182 s_h->ush_bustype = dae_found->dae_bustype;
183 s_h->ush_device.blksz = 1500; //Fake value.
184 s_h->ush_device.type = DEV_TYPE_NETBOOT;
185 AddTail(&dev_list, &s_h->ush_link);
186 continue;
187 }
188
189 if((newdev = dae_found->dae_get_dev(curr_unit)))
190 if((newdev->blksz) && (newdev->type == dae_found->dae_request_type))
191 //uboot sei sempre una merda.
192 {
193 s_h = alloc_mem_for_anythingelse(sizeof (struct uboot_scan_handle));
194 memset(s_h, 0, sizeof(struct uboot_scan_handle));
195 s_h->ush_device = *newdev; //Full structure copy.
196 s_h->ush_bustype = dae_found->dae_bustype;
197
198 /*
199 printf("SUN: found unit; data as follows: interface type %d, devnumber %d, type %u, device points to %08lx\n",
200 s_h->ush_device.if_type, s_h->ush_device.dev, s_h->ush_device.type, &s_h->ush_device);
201 */
202
203 AddTail(&dev_list, &s_h->ush_link);
204 }
205 }
206 }
207 }
208
209 curr_disk = (SCAN_HANDLE)dev_list.mlh_Head;
210
211 if(curr_disk->ush_device.blksz)
212 {
213 *blocksize = curr_disk->ush_device.blksz;
214 //printf("Blocksize for first device is %lu, type %u\n", *blocksize, curr_disk->ush_bustype);
215 }
216 //printf("Exiting start_unit_scan\n");
217 return curr_disk;
218 }
219
220
open_specific_unit(const SCAN_HANDLE h)221 BOOL open_specific_unit(const SCAN_HANDLE h)
222 {
223 curr_disk = h; //We simply set the current disk to be the one given in.
224 /*
225 printf("Opening specific unit; data as follows: interface type %d, devnumber %d, type %u\n",
226 curr_disk->ush_device.if_type, curr_disk->ush_device.dev, curr_disk->ush_device.type);
227 */
228 return TRUE;
229 }
230
old_open_specific_unit(const OLD_SCAN_HANDLE h)231 BOOL old_open_specific_unit(const OLD_SCAN_HANDLE h)
232 {
233 //printf("Old_open_specific unit; real handle to %08lx\n", h->ush_new_reference);
234
235 curr_disk = h->ush_device.backpointer; //We simply set the current disk to be the one given in.
236 /*
237 printf("Opening specific unit; data as follows: interface type %d, devnumber %d, type %u\n",
238 curr_disk->ush_device.if_type, curr_disk->ush_device.dev, curr_disk->ush_device.type);
239 */
240 return TRUE;
241 }
242
end_unit_scan(SCAN_HANDLE h)243 void end_unit_scan(SCAN_HANDLE h)
244 {
245 //Nothing: no special resources are opened while scanning
246 }
247
end_global_scan(void)248 void end_global_scan(void)
249 {
250 // Just like a1_end_unit_scan()
251 }
252
loadsector(const ULONG sectn,const ULONG sect_size,const ULONG numb_sects,void * const dest_buf)253 BOOL loadsector(const ULONG sectn, const ULONG sect_size, const ULONG numb_sects, void * const dest_buf)
254 {
255 block_dev_desc_t * dev = &curr_disk->ush_device;
256
257 //printf("Loadsector: sectornum. %lu, current device %08lx\n", sectn, dev);
258
259 if(sect_size) //Sector size check is only performed when passing a non-zero value
260 {
261 if(dev->blksz != sect_size)
262 {
263 //printf("Loadsector: Bad blocksize: current is %lu, supplied is %lu (base structure at %p)\n", dev->blksz, sect_size, &curr_disk);
264 return FALSE;
265 }
266 }
267
268 if(dev->block_read(dev->dev, sectn, numb_sects, dest_buf) != numb_sects)
269 {
270 printf("Loadsector: error when reading from block %lu\n", sectn);
271 return FALSE;
272 }
273 else return TRUE;
274 }
275
uboot_4aligned_malloc(const size_t size)276 void * uboot_4aligned_malloc(const size_t size)
277 {
278 unsigned long temp;
279
280 //printf("Allocating %d bytes, jumping to %08lx\n", size, malloc);
281 temp = (unsigned long)malloc(size + 4);
282 temp = (temp + 3) & ~3;
283
284 // printf("uboot_4aligned_malloc : asked for memsize %d, returned pointer at %08lx\n", size, (ULONG)temp);
285 return (void *)temp;
286 }
287
alloc_mem_for_iobuffers(const unsigned long size)288 void * alloc_mem_for_iobuffers(const unsigned long size)
289 {
290 return uboot_4aligned_malloc((const size_t)size);
291 }
292
alloc_mem_for_kickmodule(const unsigned long size)293 void * alloc_mem_for_kickmodule(const unsigned long size)
294 {
295 return uboot_4aligned_malloc((const size_t) size);
296 }
297
alloc_mem_for_execNG(const unsigned long size)298 void * alloc_mem_for_execNG(const unsigned long size)
299 {
300 return uboot_4aligned_malloc((const size_t) size);
301 }
302
alloc_mem_for_anythingelse(const unsigned long size)303 void * alloc_mem_for_anythingelse(const unsigned long size)
304 {
305 return uboot_4aligned_malloc((const size_t) size);
306 }
307
alloc_mem_for_bootloader(const unsigned long size)308 void * alloc_mem_for_bootloader(const unsigned long size)
309 {
310 return uboot_4aligned_malloc((const size_t) size);
311 }
312
313 /*
314 void * alloc_mem_for_bootloader_ABS(const unsigned long size, void * addr)
315 {
316 return addr; //Yeah, bulldozing anything that comes in the way!
317 }
318
319 //No longer used, since the absolute bulldozing will be done by the ELF loader & relocator.
320 */
321
322 /*
323 static int local_get_part_info(int part, disk_partition_t *info)
324 //This function will use the file-global curr_disk to get the partition info from uboot
325 {
326 return get_partition_info(curr_disk, part, info);
327 }
328 */
329
get_board_info(void)330 void * get_board_info(void)
331 {
332 DECLARE_GLOBAL_DATA_PTR;
333 return (void *)gd->bd;
334 }
335
my_NetLoop(char * fn,void * buff)336 int my_NetLoop(char * fn, void * buff)
337 {
338 //printf("Entering %s\n", __PRETTY_FUNCTION__);
339 copy_filename(BootFile, fn, sizeof(BootFile));
340 load_addr = (ulong) buff;
341 //The cast is necessary because someone was so smart to declare an address
342 //as something else than a pointer.
343
344 return NetLoop(TFTP);
345 }
346
set_load_addr(void * const new_load_addr)347 static void set_load_addr(void * const new_load_addr)
348 {
349 load_addr = (ulong)new_load_addr;
350 }
351
build_callback_context(void * scanopts)352 struct sbl_callback_context * build_callback_context(void * scanopts)
353 {
354 static struct sbl_callback_context context;
355
356 context.ssc_version = CALLBACK_VERSION;
357 context.ssc_printf_like = printf;
358 context.ssc_getc_like = getc;
359
360 context.ssc_scan_list = scanopts;
361 context.ssc_devices_list = &dev_list;
362 context.ssc_curr_device = curr_disk;
363
364 context.ssc_start_unit_scan = start_unit_scan;
365 context.ssc_next_unit_scan = next_unit_scan;
366 context.ssc_open_specific_unit = open_specific_unit;
367 context.ssc_end_unit_scan = end_unit_scan;
368 context.ssc_end_global_scan = end_global_scan;
369 context.ssc_loadsector = loadsector;
370
371 context.ssc_my_netloop = my_NetLoop;
372
373 context.ssc_getenv = getenv;
374 context.ssc_setenv = setenv;
375
376 context.ssc_alloc_mem_for_iobuffers = uboot_4aligned_malloc;
377 context.ssc_alloc_mem_for_kickmodule =uboot_4aligned_malloc;
378 context.ssc_alloc_mem_for_execNG = uboot_4aligned_malloc;
379 context.ssc_alloc_mem_for_anythingelse=uboot_4aligned_malloc;
380 context.ssc_alloc_mem_for_bootloader =uboot_4aligned_malloc;
381 context.ssc_free_mem = free;
382
383 context.ssc_get_board_info = get_board_info;
384
385 #ifdef CONFIG_BZIP2
386 context.ssc_BZ2_bzBuffToBuffDecompress = BZ2_bzBuffToBuffDecompress;
387 #endif
388
389 context.ssc_video_clear = video_clear;
390 context.ssc_video_draw_box = video_draw_box;
391 context.ssc_video_draw_text = video_draw_text;
392 context.ssc_video_repeat_char = video_repeat_char;
393
394 context.ssc_set_partial_scroll_limits = set_partial_scroll_limits;
395 context.ssc_get_partial_scroll_limits = get_partial_scroll_limits;
396 context.ssc_video_get_key = video_get_key;
397
398 //printf("Allocation functions pointing at %08lx\n", uboot_4aligned_malloc);
399
400 context.ssc_do_bootm = do_bootm;
401 context.ssc_memmove = memmove;
402
403 context.ssc_set_load_addr = set_load_addr;
404
405 context.ssc_tstc = tstc;
406 context.ssc_udelay = udelay;
407 context.ssc_sprintf = sprintf;
408
409 context.ssc_ext2fs_set_blk_dev_full=ext2fs_set_blk_dev_full;
410 context.ssc_ext2fs_open=ext2fs_open;
411 context.ssc_ext2fs_read=ext2fs_read;
412 context.ssc_ext2fs_mount=ext2fs_mount;
413 context.ssc_ext2fs_close=ext2fs_close;
414
415 return &context;
416 }
417 /*
418 void degrade_to_old_frigging_interface(struct sbl_callback_context * c)
419 {
420 SCAN_HANDLE actual;
421 NewList(&old_dev_list);
422 c->ssc_version = 3;
423
424 for(actual = (SCAN_HANDLE)c->ssc_devices_list->mlh_Head; actual->ush_link.mln_Succ; actual = (SCAN_HANDLE)actual->ush_link.mln_Succ)
425 {
426 OLD_SCAN_HANDLE old_h = alloc_mem_for_anythingelse(sizeof(struct uboot_old_scan_handle));
427
428 old_h->ush_bustype = actual->ush_bustype;
429 old_h->ush_already_scanned = actual->ush_already_scanned;
430
431 old_h->ush_device.if_type = actual->ush_device.if_type ;
432 old_h->ush_device.dev = actual->ush_device.dev;
433 old_h->ush_device.part_type = actual->ush_device.part_type;
434 old_h->ush_device.target = actual->ush_device.target;
435 old_h->ush_device.lun = actual->ush_device.lun;
436 old_h->ush_device.type = actual->ush_device.type;
437 old_h->ush_device.lba = (unsigned long)actual->ush_device.lba;
438 old_h->ush_device.blksz = actual->ush_device.blksz;
439 memcpy(&old_h->ush_device.vendor, &actual->ush_device,40);
440 memcpy(&old_h->ush_device.product, &actual->ush_device,20);
441 memcpy(&old_h->ush_device.revision, &actual->ush_device,4);
442 old_h->ush_device.removable = actual->ush_device.removable;
443 old_h->ush_device.block_read = actual->ush_device.block_read;
444
445 old_h->ush_device.backpointer = actual; //Backpointer used by old_open_specific_unit()
446
447 AddTail(&old_dev_list, &old_h->ush_link);
448 if(c->ssc_curr_device == actual)
449 c->ssc_curr_device = (SCAN_HANDLE)old_h;
450 }
451
452 c->ssc_devices_list = &old_dev_list;
453 c->ssc_open_specific_unit = old_open_specific_unit;
454 }
455 */
456