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