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