1 #define _STDDEF_H
2 #include <common.h>
3 #include "glue.h"
4 #include "scitech/include/x86emu/x86emu.h"
5 #include "x86interface.h"
6 #include "../common/misc_utils.h"
7 
8 /*
9  * This isn't nice, but there are a lot of incompatibilities in the U-Boot and scitech include
10  * files that this is the only really workable solution.
11  * Might be cleaned out later.
12  */
13 
14 #undef DEBUG
15 #undef SINGLESTEP
16 #undef FORCE_SINGLESTEP
17 
18 #undef IO_LOGGING
19 #undef MEM_LOGGING
20 
21 #ifdef IO_LOGGING
22 #define LOGIO(port, format, args...) if (dolog(port)) printf(format , ## args)
23 #else
24 #define LOGIO(port, format, args...)
25 #endif
26 
27 #ifdef MEM_LOGGIN
28 #define LOGMEM(format, args...) printf(format , ## args)
29 #else
30 #define LOGMEM(format, args...)
31 #endif
32 
33 #define log_printf(format, args...)  if (getenv("x86_log")) printf(format, ## args);
34 
35 #ifdef DEBUG
36 #define PRINTF(format, args...) printf(format , ## args)
37 #else
38 #define PRINTF(format, argc...)
39 #endif
40 
41 typedef unsigned char UBYTE;
42 typedef unsigned short UWORD;
43 typedef unsigned long ULONG;
44 
45 typedef char BYTE;
46 typedef short WORT;
47 typedef long LONG;
48 
49 #define EMULATOR_MEM_SIZE       (1024*1024)
50 #define EMULATOR_BIOS_OFFSET    0xC0000
51 #define EMULATOR_STRAP_OFFSET   0x30000
52 #define EMULATOR_STACK_OFFSET   0x20000
53 #define EMULATOR_LOGO_OFFSET    0x40000 // If you change this, change the strap code, too
54 
55 extern int tstc(void);
56 extern int getc(void);
57 extern unsigned char video_get_attr(void);
58 extern void find_radeon_values(pci_dev_t dev, u8 * rom_addr);
59 extern void reloc_mode_table(void *reloc_addr);
60 
61 extern int onbus;
62 extern u32 mmio_base_phys;
63 extern u32 io_base_phys;
64 
65 #include "x86interface.h"
66 
67 extern void bios_set_mode(int mode);
68 
sam440_remove_init_data(void)69 void sam440_remove_init_data(void)
70 {
71 
72 }
73 
setup_tlb_for_cache(int enable)74 void setup_tlb_for_cache(int enable)
75 {
76 	// not used anymore
77 }
78 
79 //Forward declaration
80 void do_inout(void);
81 
abs(int x)82 int abs(int x)
83 {
84     if (x < 0)
85        return -x;
86 
87     return x;
88 }
89 
cons_gets(char * buffer)90 void cons_gets(char *buffer)
91 {
92     int i = 0;
93     char c = 0;
94 
95     buffer[0] = 0;
96     if (getenv("x86_runthru")) return; //FIXME:
97     while (c != 0x0D && c != 0x0A)
98     {
99     	while (!tstc());
100     	c = getc();
101     	if (c>=32 && c < 127)
102     	{
103     	    buffer[i] = c;
104     	    i++;
105     	    buffer[i] = 0;
106     	    putc(c);
107     	}
108     	else
109     	{
110     	    if (c == 0x08)
111     	    {
112         		if (i>0) i--;
113         		buffer[i] = 0;
114     	    }
115     	}
116     }
117     buffer[i] = '\n';
118     buffer[i+1] = 0;
119 }
120 
121 char *bios_date = "08/14/02";
122 UBYTE model = 0xFC;
123 UBYTE submodel = 0x00;
124 
125 static int log_init = 0;
126 static int log_do = 0;
127 static int log_low = 0;
128 
dolog(int port)129 int dolog(int port)
130 {
131     if (log_init && log_do)
132     {
133     	if (log_low && port > 0x400) return 0;
134     	return 1;
135     }
136 
137     if (!log_init)
138     {
139     	log_init = 1;
140     	log_do = (getenv("x86_logio") != (char *)0);
141     	log_low = (getenv("x86_loglow") != (char *)0);
142     	if (log_do)
143     	{
144     	    if (log_low && port > 0x400) return 0;
145     	    return 1;
146     	}
147     }
148     return 0;
149 }
150 
151 static u32 dummy;
152 
screen_addr(u32 addr)153 u32 screen_addr(u32 addr)
154 {
155 	return &dummy;
156 }
157 
158 // Converts an emulator address to a physical address.
159 // Handles all special cases (bios date, model etc), and might need work
memaddr(u32 addr)160 u32 memaddr(u32 addr)
161 {
162 //    if (addr >= 0xF0000 && addr < 0xFFFFF) printf("WARNING: Segment F access (0x%x)\n", addr);
163 //    printf("MemAddr=%p\n", addr);
164     if (addr >= 0xA0000 && addr < 0xC0000)
165     	return screen_addr(addr); //CFG_ISA_IO_BASE_ADDRESS + addr;
166     else if (addr >= 0xFFFF5 && addr < 0xFFFFE)
167     {
168        	return (u32)bios_date+addr-0xFFFF5;
169     }
170     else if (addr == 0xFFFFE)
171 	    return (u32)&model;
172     else if (addr == 0xFFFFF)
173 	    return (u32)&submodel;
174     else if (addr >= 0x80000000)
175     {
176     	//printf("Warning: High memory access at 0x%x\n", addr);
177 	    return addr;
178     }
179     else
180     	return (u32)M.mem_base+addr;
181 }
182 
A1_rdb(u32 addr)183 u8 A1_rdb(u32 addr)
184 {
185     u8 a = in8((UBYTE *)memaddr(addr));
186     LOGMEM("rdb: %x -> %x\n", addr, a);
187     return a;
188 }
189 
A1_rdw(u32 addr)190 u16 A1_rdw(u32 addr)
191 {
192     u16 a = in16r((UWORD *)memaddr(addr));
193     LOGMEM("rdw: %x -> %x\n", addr, a);
194     return a;
195 }
196 
A1_rdl(u32 addr)197 u32 A1_rdl(u32 addr)
198 {
199     u32 a = in32r((ULONG *)memaddr(addr));
200     LOGMEM("rdl: %x -> %x\n", addr, a);
201     return a;
202 }
203 
A1_wrb(u32 addr,u8 val)204 void A1_wrb(u32 addr, u8 val)
205 {
206     LOGMEM("wrb: %x <- %x\n", addr, val);
207     out8((UBYTE *)memaddr(addr), val);
208 }
209 
A1_wrw(u32 addr,u16 val)210 void A1_wrw(u32 addr, u16 val)
211 {
212     LOGMEM("wrw: %x <- %x\n", addr, val);
213     out16r((UWORD *)memaddr(addr), val);
214 }
215 
A1_wrl(u32 addr,u32 val)216 void A1_wrl(u32 addr, u32 val)
217 {
218     LOGMEM("wrl: %x <- %x\n", addr, val);
219     out32r((ULONG *)memaddr(addr), val);
220 }
221 
222 static X86EMU_memFuncs _A1_mem;
223 
224 #define in_byte(from) in8( (UBYTE *)port_to_mem(from))
225 #define in_word(from) in16r((UWORD *)port_to_mem(from))
226 #define in_long(from) in32r((ULONG *)port_to_mem(from))
227 #define out_byte(to, val) out8((UBYTE *)port_to_mem(to), val)
228 #define out_word(to, val) out16r((UWORD *)port_to_mem(to), val)
229 #define out_long(to, val) out32r((ULONG *)port_to_mem(to), val)
230 
port_to_mem(int port)231 u32 port_to_mem(int port)
232 {
233 #ifdef CONFIG_SAM460EX
234     /* here we assume that a Radeon is on bus 0 (PCI)         */
235     /* and a RadeonHD is on bus 1 or higher (PCI or PCI-E)    */
236 
237     if (onbus >= 1)
238     {
239         if (port >= io_base_phys) port -= io_base_phys;
240 
241         return mmio_base_phys + port;
242     }
243     else
244     {
245         if (port >= 0xcfc && port <= 0xcff)
246             return 0xDEC00004;
247         else if (port >= 0xcf8 && port <= 0xcfb)
248             return 0xDEC00000;
249 
250         return CFG_ISA_IO_BASE_ADDRESS + port;
251     }
252 #else
253     if (port >= 0xcfc && port <= 0xcff)
254 	    return 0xEEC00004;
255     else if (port >= 0xcf8 && port <= 0xcfb)
256 	    return 0xEEC00000;
257 
258 	return CFG_ISA_IO_BASE_ADDRESS + port;
259 #endif
260 }
261 
A1_inb(int port)262 u8 A1_inb(int port)
263 {
264     u8 a;
265     //if (port == 0x3BA) return 0;
266     a = in_byte(port);
267     LOGIO(port, "inb: %Xh -> %d (%Xh)\n", port, a, a);
268     return a;
269 }
270 
A1_inw(int port)271 u16 A1_inw(int port)
272 {
273     u16 a = in_word(port);
274     LOGIO(port, "inw: %Xh -> %d (%Xh)\n", port, a, a);
275     return a;
276 }
277 
A1_inl(int port)278 u32 A1_inl(int port)
279 {
280     u32 a = in_long(port);
281     LOGIO(port, "inl: %Xh -> %d (%Xh)\n", port, a, a);
282     return a;
283 }
284 
A1_outb(int port,u8 val)285 void A1_outb(int port, u8 val)
286 {
287     LOGIO(port, "outb: %Xh <- %d (%Xh)\n", port, val, val);
288 /*    if (port == 0xCF8) port = 0xCFB;
289     else if (port == 0xCF9) port = 0xCFA;
290     else if (port == 0xCFA) port = 0xCF9;
291     else if (port == 0xCFB) port = 0xCF8;*/
292 
293     out_byte(port, val);
294 }
295 
A1_outw(int port,u16 val)296 void A1_outw(int port, u16 val)
297 {
298     LOGIO(port, "outw: %Xh <- %d (%Xh)\n", port, val, val);
299     out_word(port, val);
300 }
301 
302 int blocked_port = 0;
303 
A1_outl(int port,u32 val)304 void A1_outl(int port, u32 val)
305 {
306     LOGIO(port, "outl: %Xh <- %d (%Xh)\n", port, val, val);
307 
308     // Workaround
309     if (port != blocked_port)
310     out_long(port, val);
311     else
312 	LOGIO(port, "blocked\n");
313 }
314 
315 static X86EMU_pioFuncs _A1_pio;
316 
317 static int reloced_ops = 0;
318 
reloc_ops(void * reloc_addr)319 void reloc_ops(void *reloc_addr)
320 {
321     extern void (*x86emu_optab[256])(u8);
322     extern void (*x86emu_optab2[256])(u8);
323     extern void tables_relocate(unsigned int offset);
324     int i;
325     unsigned long delta;
326     if (reloced_ops == 1) return;
327     reloced_ops = 1;
328 
329     PRINTF("reloc_addr = %p\n", reloc_addr);
330     delta = TEXT_BASE - (unsigned long)reloc_addr;
331     PRINTF("delta = %p\n", delta);
332     PRINTF("x86emu_optab %p\n",x86emu_optab);
333     PRINTF("x86emu_optab %p\n",x86emu_optab-delta);
334 
335     for (i=0; i<256; i++)
336     {
337     	x86emu_optab[i] -= delta;
338     	x86emu_optab2[i] -= delta;
339     }
340 
341     _A1_mem.rdb = A1_rdb;
342     _A1_mem.rdw = A1_rdw;
343     _A1_mem.rdl = A1_rdl;
344     _A1_mem.wrb = A1_wrb;
345     _A1_mem.wrw = A1_wrw;
346     _A1_mem.wrl = A1_wrl;
347 
348     _A1_pio.inb = (u8 (X86APIP)(X86EMU_pioAddr))A1_inb;
349     _A1_pio.inw = (u16 (X86APIP)(X86EMU_pioAddr))A1_inw;
350     _A1_pio.inl = (u32 (X86APIP)(X86EMU_pioAddr))A1_inl;
351     _A1_pio.outb = (void (X86APIP)(X86EMU_pioAddr, u8))A1_outb;
352     _A1_pio.outw = (void (X86APIP)(X86EMU_pioAddr, u16))A1_outw;
353     _A1_pio.outl = (void (X86APIP)(X86EMU_pioAddr, u32))A1_outl;
354 
355     tables_relocate(delta);
356 }
357 
358 
359 #define ANY_KEY(text)			\
360     printf(text);				\
361     while (!tstc());
362 
363 
364 unsigned char more_strap[] = {
365         0xb4, 0x0, 0xb0, 0x2, 0xcd, 0x10,
366 };
367 #define MORE_STRAP_BYTES 6 // Additional bytes of strap code
368 
369 
370 unsigned char *done_msg="VGA Initialized\0";
371 
execute_bios(pci_dev_t gr_dev,void * reloc_addr)372 int execute_bios(pci_dev_t gr_dev, void *reloc_addr)
373 {
374     extern void bios_init(void);
375     extern void remove_init_data(void);
376     extern int video_rows(void);
377     extern int video_cols(void);
378     extern int video_size(int, int);
379     u8 *strap;
380     //unsigned char *logo;
381     //u8 cfg;
382     int i;
383     //char c;
384     //char *s;
385 #ifdef EASTEREGG
386     int easteregg_active = 0;
387 #endif
388     char *pal_reset;
389     //u8 *fb;
390     //unsigned char *msg;
391     //unsigned char current_attr;
392 
393     PRINTF("Trying to remove init data\n");
394     sam440_remove_init_data();
395     PRINTF("Removed init data from cache, now in RAM\n");
396 
397     reloc_ops(reloc_addr);
398     reloc_mode_table(reloc_addr);
399 
400     PRINTF("Attempting to run emulator on %02x:%02x:%02x\n",
401 	   PCI_BUS(gr_dev), PCI_DEV(gr_dev), PCI_FUNC(gr_dev));
402 
403     // Enable compatibility hole for emulator access to frame buffer
404     //PRINTF("Enabling compatibility hole\n");
405     //enable_compatibility_hole();
406 
407 #ifdef DEBUG
408 /*
409     s = getenv("x86_ask_start");
410     if (s)
411     {
412 		printf("Press 'q' to skip initialization, 'd' for dry init\n'i' for i/o session");
413 		while (!tstc());
414 		c = getc();
415 		if (c == 'q') return 0;
416 		if (c == 'd')
417 		{
418 		    bios_set_mode(0x03);
419 		    return 0;
420 		}
421 		if (c == 'i') do_inout();
422     }
423 */
424 #endif
425 
426     // Allocate memory
427     // FIXME: We shouldn't use this much memory really.
428     memset(&M, 0, sizeof(X86EMU_sysEnv));
429     M.mem_base = (unsigned long)malloc(EMULATOR_MEM_SIZE);
430     M.mem_size = (unsigned long)EMULATOR_MEM_SIZE;
431 
432     if (!M.mem_base)
433     {
434 		PRINTF("Unable to allocate one megabyte for emulator\n");
435 		return 0;
436     }
437 
438     if (attempt_map_rom(gr_dev, (void *)(M.mem_base + EMULATOR_BIOS_OFFSET)) == 0)
439     {
440 		PRINTF("Error mapping rom. Emulation terminated\n");
441 		return 0;
442     }
443 
444 
445 #ifdef EASTEREGG
446 /*    if (tstc())
447     {
448 	if (getc() == 'c')
449 	{
450 	    easteregg_active = 1;
451 	}
452     }
453 */
454     if (getenv("easteregg"))
455     {
456 		easteregg_active = 1;
457     }
458 
459     if (easteregg_active)
460     {
461 		// Yay!
462 		setenv("x86_mode", "1");
463 		setenv("vga_fg_color", "11");
464 		setenv("vga_bg_color", "1");
465 		easteregg_active = 1;
466     }
467 #endif
468 
469     strap = (u8*)M.mem_base + EMULATOR_STRAP_OFFSET;
470 /*
471     {
472 		char *m = getenv("x86_mode");
473 		if (m)
474 		{
475 	    	more_strap[3] = atoi(m);
476 	    	if (more_strap[3] == 1) video_size(40, 25);
477 	    	else                    video_size(80, 25);
478 		}
479     }
480 */
481     /*
482      * Poke the strap routine. This might need a bit of extending
483      * if there is a mode switch involved, i.e. we want to int10
484      * afterwards to set a different graphics mode, or alternatively
485      * there might be a different start address requirement if the
486      * ROM doesn't have an x86 image in its first image.
487      */
488 
489     PRINTF("Poking strap...\n");
490 
491     // FAR CALL c000:0003
492     *strap++ = 0x9A; *strap++ = 0x03; *strap++ = 0x00;
493     *strap++ = 0x00; *strap++ = 0xC0;
494 
495 #if 1
496     // insert additional strap code
497     for (i=0; i < MORE_STRAP_BYTES; i++)
498     {
499     	*strap++ = more_strap[i];
500     }
501 #endif
502     // HALT
503     *strap++ = 0xF4;
504 
505     PRINTF("Done poking strap\n");
506 
507 #if 0
508     PRINTF("Setting up logo data\n");
509     logo = (unsigned char *)M.mem_base + EMULATOR_LOGO_OFFSET;
510     for (i=0; i<16; i++)
511     {
512 		*logo++ = 0xFF;
513     }
514 #endif
515     /*
516      * Setup the init parameters.
517      * Per PCI specs, AH must contain the bus and AL
518      * must contain the devfn, encoded as (dev<<3)|fn
519      */
520 
521     PRINTF("Settingup init parameters\n");
522     // Execution starts here
523     M.x86.R_CS = SEG(EMULATOR_STRAP_OFFSET);
524     M.x86.R_IP = OFF(EMULATOR_STRAP_OFFSET);
525 
526     // Stack at top of ram
527     M.x86.R_SS = SEG(EMULATOR_STACK_OFFSET);
528     M.x86.R_SP = OFF(EMULATOR_STACK_OFFSET);
529 
530     // Input parameters
531     M.x86.R_AH = PCI_BUS(gr_dev);
532     M.x86.R_AL = (PCI_DEV(gr_dev)<<3) | PCI_FUNC(gr_dev);
533 
534     PRINTF("Setting up I/O and memory access functions\n");
535     // Set the I/O and memory access functions
536     X86EMU_setupMemFuncs(&_A1_mem);
537     PRINTF("PIO\n");
538     X86EMU_setupPioFuncs(&_A1_pio);
539 
540 #if 0
541     // Enable timer 2
542     cfg = in_byte(0x61); // Get Misc control
543     cfg |= 0x01;         // Enable timer 2
544     out_byte(0x61, cfg); // output again
545 
546     // Set up the timers
547     out_byte(0x43, 0x54);
548     out_byte(0x41, 0x18);
549 
550     out_byte(0x43, 0x36);
551     out_byte(0x40, 0x00);
552     out_byte(0x40, 0x00);
553 
554     out_byte(0x43, 0xb6);
555     out_byte(0x42, 0x31);
556     out_byte(0x42, 0x13);
557 #endif
558 
559     // If the initializing card is an ATI card, block access to port 0x34
560     unsigned short vendor;
561     pci_read_config_word(gr_dev, PCI_VENDOR_ID, &vendor);
562     if (vendor == 0x1002)
563     {
564     	PRINTF("Initializing a Radeon, blocking port access\n");
565     	int bar;
566 
567     	for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar += 4)
568     	{
569     		unsigned int val;
570     		pci_read_config_dword(gr_dev, bar, &val);
571     		if (val & PCI_BASE_ADDRESS_SPACE_IO)
572     		{
573     			blocked_port = val & PCI_BASE_ADDRESS_IO_MASK;
574     			blocked_port += 0x34;
575     			break;
576     		}
577     	}
578     }
579     else
580     	blocked_port = 0;
581 	PRINTF("Blocked port %x\n",blocked_port);
582 
583     // Init the "BIOS".
584     PRINTF("BIOS init\n");
585     bios_init();
586     // Video Card Reset
587     PRINTF("Video card reset\n");
588     //    out_byte(0x3D8, 0);
589     //    out_byte(0x3B8, 1);
590     //    (void)in_byte(0x3BA);
591     //    (void)in_byte(0x3DA);
592     //    out_byte(0x3C0, 0);
593     //    out_byte(0x61, 0xFC);
594     PRINTF("Done resetting\n");
595 #if defined(DEBUG) && defined(SINGLESTEP)
596 #ifndef FORCE_SINGLESTEP
597     s = _getenv("x86_singlestep");
598     if (s && strcmp(s, "on")==0)
599     {
600 #endif
601 		PRINTF("Enabling single stepping for debug\n");
602 		X86EMU_trace_on();
603 #ifndef FORCE_SINGLESTEP
604     }
605 #endif
606 #endif
607 
608 #ifdef DEBUG
609 //	icache_disable();
610 //    dcache_disable();
611 #endif
612     // Ready set go...
613     PRINTF("Running emulator\n");
614     setup_tlb_for_cache(1);
615     X86EMU_exec();
616     setup_tlb_for_cache(0);
617     //	find_radeon_values(gr_dev, (u8 *)(M.mem_base + EMULATOR_BIOS_OFFSET));
618     PRINTF("Done running emulator\n");
619 
620 /* FIXME: Remove me */
621     pal_reset = getenv("x86_palette_reset");
622     if (pal_reset && strcmp(pal_reset, "on") == 0)
623     {
624 	PRINTF("Palette reset\n");
625 	//(void)in_byte(0x3da);
626 	//out_byte(0x3c0, 0);
627 
628 	out_byte(0x3C8, 0);
629 	out_byte(0x3C9, 0);
630 	out_byte(0x3C9, 0);
631 	out_byte(0x3C9, 0);
632 	for (i=0; i<254; i++)
633 	{
634 	    out_byte(0x3C9, 63);
635 	    out_byte(0x3C9, 63);
636 	    out_byte(0x3C9, 63);
637 	}
638 
639 	out_byte(0x3c0, 0x20);
640     }
641 /* FIXME: remove me */
642 #ifdef EASTEREGG
643     if (easteregg_active)
644     {
645 	extern void video_easteregg(void);
646 	video_easteregg();
647     }
648 #endif
649 /*
650     current_attr = video_get_attr();
651     fb = (u8 *)VIDEO_BASE;
652     for (i=0; i<video_rows()*video_cols()*2; i+=2)
653     {
654 	*(fb+i) = ' ';
655 	*(fb+i+1) = current_attr;
656     }
657 
658     fb = (u8 *)VIDEO_BASE + (video_rows())-1*(video_cols()*2);
659     for (i=0; i<video_cols(); i++)
660     {
661 	*(fb + 2*i)     = 32;
662 	*(fb + 2*i + 1) = 0x17;
663     }
664 
665     msg = done_msg;
666     while (*msg)
667     {
668 	*fb = *msg;
669 	fb  += 2;
670 	msg ++;
671     }
672 */
673 #ifdef DEBUG
674     //if (getenv("x86_do_inout")) do_inout();
675 #endif
676 
677     return 1;
678 }
679 
680 // Clean up the x86 mess
shutdown_bios(void)681 void shutdown_bios(void)
682 {
683 //    disable_compatibility_hole();
684     // Free the memory associated
685 //    free(M.mem_base);
686 //    setup_tlb_for_cache(0);
687 }
688 
to_int(char * buffer)689 int to_int(char *buffer)
690 {
691     int base = 0;
692     int res  = 0;
693 
694     if (*buffer == '$')
695     {
696 	base = 16;
697 	buffer++;
698     }
699     else base = 10;
700 
701     for (;;)
702     {
703 	switch(*buffer)
704 	{
705 	case '0' ... '9':
706 	    res *= base;
707 	    res += *buffer - '0';
708 	    break;
709 	case 'A':
710 	case 'a':
711 	    res *= base;
712 	    res += 10;
713 	    break;
714 	case 'B':
715 	case 'b':
716 	    res *= base;
717 	    res += 11;
718 	    break;
719 	case 'C':
720 	case 'c':
721 	    res *= base;
722 	    res += 12;
723 	    break;
724 	case 'D':
725 	case 'd':
726 	    res *= base;
727 	    res += 13;
728 	    break;
729 	case 'E':
730 	case 'e':
731 	    res *= base;
732 	    res += 14;
733 	    break;
734 	case 'F':
735 	case 'f':
736 	    res *= base;
737 	    res += 15;
738 	    break;
739 	default:
740 	    return res;
741 	}
742 	buffer++;
743     }
744     return res;
745 }
746 /*
747 void one_arg(char *buffer, int *a)
748 {
749     while (*buffer && *buffer != '\n')
750     {
751 	if (*buffer == ' ') buffer++;
752 	else break;
753     }
754 
755     *a = to_int(buffer);
756 }
757 
758 void two_args(char *buffer, int *a, int *b)
759 {
760     while (*buffer && *buffer != '\n')
761     {
762 	if (*buffer == ' ') buffer++;
763 	else break;
764     }
765 
766     *a = to_int(buffer);
767 
768     while (*buffer && *buffer != '\n')
769     {
770 	if (*buffer != ' ') buffer++;
771 	else break;
772     }
773 
774     while (*buffer && *buffer != '\n')
775     {
776 	if (*buffer == ' ') buffer++;
777 	else break;
778     }
779 
780     *b = to_int(buffer);
781 }
782 */
783 /*
784 void do_inout(void)
785 {
786     char buffer[256];
787     char *arg1;
788     //char *arg2;
789     int a,b;
790 
791     printf("In/Out Session\nUse 'i[bwl]' for in, 'o[bwl]' for out and 'q' to quit\n");
792 
793     do
794     {
795 	cons_gets(buffer);
796 	printf("\n");
797 
798 	arg1 = buffer;
799 	while (*arg1 != ' ' ) arg1++;
800 	while (*arg1 == ' ') arg1++;
801 
802 	if (buffer[0] == 'i')
803 	{
804 	    one_arg(buffer+2, &a);
805 	    switch (buffer[1])
806 	    {
807 	    case 'b':
808 		printf("in_byte(%xh) = %xh\n", a, A1_inb(a));
809 		break;
810 	    case 'w':
811 		printf("in_word(%xh) = %xh\n", a, A1_inw(a));
812 		break;
813 	    case 'l':
814 		printf("in_dword(%xh) = %xh\n", a, A1_inl(a));
815 		break;
816 	    default:
817 		printf("Invalid length '%c'\n", buffer[1]);
818 		break;
819 	    }
820 	}
821 	else if (buffer[0] == 'o')
822 	{
823 	    two_args(buffer+2, &a, &b);
824 	    switch (buffer[1])
825 	    {
826 	    case 'b':
827 		printf("out_byte(%d, %d)\n", a, b);
828 		A1_outb(a,b);
829 		break;
830 	    case 'w':
831 		printf("out_word(%d, %d)\n", a, b);
832 		A1_outw(a, b);
833 		break;
834 	    case 'l':
835 		printf("out_long(%d, %d)\n", a, b);
836 		A1_outl(a, b);
837 		break;
838 	    default:
839 		printf("Invalid length '%c'\n", buffer[1]);
840 		break;
841 	    }
842 	} else if (buffer[0] == 'q') return;
843     } while (1);
844 }
845 
846 #include <command.h>
847 
848 void do_vmode(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
849 {
850 	if (argc != 2)
851 	{
852 		printf("Usage: %s\n", cmdtp->usage);
853 		return;
854 	}
855 
856 	int mode = simple_strtoul(argv[1], NULL, 16);
857 	bios_set_mode(mode);
858 }
859 U_BOOT_CMD( vmode,
860 		2,      0,      do_vmode,
861 		"vmode - set vga mode\n",
862 		"set vga mode\n");
863 
864 typedef unsigned long uint32;
865 // TLB definitions
866 typedef struct tlb440
867 {
868 	// Word 0
869 	uint32 	EPN:22;		// Effective page number
870 	uint32	V:1;		// Entry valid
871 	uint32	TS:1;		// Translation space
872 	uint32	SIZE:4;		// Size, see below
873 	uint32	TPAR:4;		// Tag parity
874 
875 	// Word 1
876 	uint32	RPN:22;		// Real (physical) page number
877 	uint32	PAR1:2;		// Parity
878 	uint32	RES1:4;		// Unused
879 	uint32	ERPN:4;		// Extended real page number, for 36 bit memory addressing
880 
881 	// Word 2
882 	uint32	PAR2:2;		// Parity
883 	uint32	RES2:14;	// Unused
884 	uint32	U03:4;		// Bits U0 - U3
885 	uint32	WIMG:4;		// Memory attributes
886 	uint32	E:1;		// Endian flag
887 	uint32	RES3:1;		// Unused
888 	uint32	XWRXWR:6;	// Protection bits
889 } tlb440_t;
890 
891 void do_tlb(void)
892 {
893 	int i;
894 	uint32 tlba[3];
895 	tlb440_t *tlb = (tlb440_t *)tlba;
896 
897 	printf("\nDump of all active TLB's\n");
898 
899 	for (i = 0; i < 64; i++)
900 	{
901 		__asm volatile("tlbre	%0, %3, 0			\n\
902 						tlbre	%1, %3, 1			\n\
903 						tlbre	%2, %3, 2"
904 					: "=r" (tlba[0]), "=r" (tlba[1]), "=r" (tlba[2])
905 					: "r" (i));
906 		if (tlb->V)
907 		{
908 			printf("TLB %2d: EPN = %p TS = %d, SIZE = %d\n", i, tlb->EPN, tlb->TS, tlb->SIZE);
909 			printf("        RPN = %p, WIMG = 0x%x XWRXWR = 0x%x\n", tlb->RPN, tlb->WIMG, tlb->XWRXWR);
910 			printf("        (Maps %p to %p)\n", tlb->EPN << 10, tlb->RPN << 10);
911 		}
912 	}
913 }
914 
915 U_BOOT_CMD( tlb,      1,      0,      do_tlb,  "tlb - dump all tlbs\n", "dump all tlbs\n");
916 */
917