Browse Source

* Patch by Thomas Frieden, 13 Nov 2002:
Add code for AmigaOne board
(preliminary merge to U-Boot, still WIP)

* Patch by Jon Diekema, 12 Nov 2002:
- Adding URL for IEEE OUI lookup
- Making the autoboot #defines dependent on CONFIG_AUTOBOOT_KEYED
being defined.
- In the CONFIG_EXTRA_ENV_SETTINGS #define, the root-on-initrd and
root-on-nfs macros are designed to switch how the default boot
method gets defined.

wdenk 22 năm trước cách đây
mục cha
commit
c7de829c79
100 tập tin đã thay đổi với 11034 bổ sung1 xóa
  1. 12 0
      CHANGELOG
  2. 4 0
      CREDITS
  3. 4 1
      MAINTAINERS
  4. 3 0
      Makefile
  5. 116 0
      board/MAI/AmigaOneG3SE/AmigaOneG3SE.c
  6. 53 0
      board/MAI/AmigaOneG3SE/Makefile
  7. 704 0
      board/MAI/AmigaOneG3SE/articiaS.c
  8. 143 0
      board/MAI/AmigaOneG3SE/articiaS.h
  9. 573 0
      board/MAI/AmigaOneG3SE/articiaS_pci.c
  10. 157 0
      board/MAI/AmigaOneG3SE/board_asm_init.S
  11. 123 0
      board/MAI/AmigaOneG3SE/cmd_boota.c
  12. 33 0
      board/MAI/AmigaOneG3SE/config.mk
  13. 886 0
      board/MAI/AmigaOneG3SE/enet.c
  14. 35 0
      board/MAI/AmigaOneG3SE/flash.c
  15. 652 0
      board/MAI/AmigaOneG3SE/flash_new.c
  16. 230 0
      board/MAI/AmigaOneG3SE/i8259.c
  17. 56 0
      board/MAI/AmigaOneG3SE/i8259.h
  18. 268 0
      board/MAI/AmigaOneG3SE/interrupts.c
  19. 84 0
      board/MAI/AmigaOneG3SE/macros.h
  20. 74 0
      board/MAI/AmigaOneG3SE/memio.S
  21. 113 0
      board/MAI/AmigaOneG3SE/memio.h
  22. 30 0
      board/MAI/AmigaOneG3SE/memory_dump
  23. 37 0
      board/MAI/AmigaOneG3SE/nvram.c
  24. 699 0
      board/MAI/AmigaOneG3SE/ps2kbd.c
  25. 41 0
      board/MAI/AmigaOneG3SE/ps2kbd.h
  26. 247 0
      board/MAI/AmigaOneG3SE/serial.c
  27. 36 0
      board/MAI/AmigaOneG3SE/short_types.h
  28. 206 0
      board/MAI/AmigaOneG3SE/smbus.c
  29. 22 0
      board/MAI/AmigaOneG3SE/smbus.h
  30. 201 0
      board/MAI/AmigaOneG3SE/start.txt
  31. 3 0
      board/MAI/AmigaOneG3SE/todo.txt
  32. 131 0
      board/MAI/AmigaOneG3SE/u-boot.lds
  33. 1179 0
      board/MAI/AmigaOneG3SE/usb_uhci.c
  34. 194 0
      board/MAI/AmigaOneG3SE/usb_uhci.h
  35. 299 0
      board/MAI/AmigaOneG3SE/via686.c
  36. 29 0
      board/MAI/AmigaOneG3SE/via686.h
  37. 539 0
      board/MAI/AmigaOneG3SE/video.c
  38. 335 0
      board/MAI/bios_emulator/bios.c
  39. 528 0
      board/MAI/bios_emulator/glue.c
  40. 57 0
      board/MAI/bios_emulator/glue.h
  41. BIN
      board/MAI/bios_emulator/scitech/bin-linux/glibc/dmake
  42. BIN
      board/MAI/bios_emulator/scitech/bin-linux/glibc/k_cp
  43. BIN
      board/MAI/bios_emulator/scitech/bin-linux/glibc/k_echo
  44. BIN
      board/MAI/bios_emulator/scitech/bin-linux/glibc/k_rm
  45. BIN
      board/MAI/bios_emulator/scitech/bin-linux/glibc/makedep
  46. BIN
      board/MAI/bios_emulator/scitech/bin-linux/glibc/nasm
  47. BIN
      board/MAI/bios_emulator/scitech/bin-linux/glibc/ndisasm
  48. BIN
      board/MAI/bios_emulator/scitech/bin-linux/glibc/trans
  49. BIN
      board/MAI/bios_emulator/scitech/bin-linux/libc/dmake
  50. BIN
      board/MAI/bios_emulator/scitech/bin-linux/libc/nasm
  51. BIN
      board/MAI/bios_emulator/scitech/bin-linux/libc/ndisasm
  52. BIN
      board/MAI/bios_emulator/scitech/bin-linux/libc/trans
  53. 28 0
      board/MAI/bios_emulator/scitech/bin/bc31-d16.bat
  54. 37 0
      board/MAI/bios_emulator/scitech/bin/bc45-c32.bat
  55. 32 0
      board/MAI/bios_emulator/scitech/bin/bc45-d16.bat
  56. 33 0
      board/MAI/bios_emulator/scitech/bin/bc45-d32.bat
  57. 32 0
      board/MAI/bios_emulator/scitech/bin/bc45-snp.bat
  58. 46 0
      board/MAI/bios_emulator/scitech/bin/bc45-tnt.bat
  59. 32 0
      board/MAI/bios_emulator/scitech/bin/bc45-vxd.bat
  60. 32 0
      board/MAI/bios_emulator/scitech/bin/bc45-w16.bat
  61. 37 0
      board/MAI/bios_emulator/scitech/bin/bc45-w32.bat
  62. 40 0
      board/MAI/bios_emulator/scitech/bin/bc50-c32.bat
  63. 34 0
      board/MAI/bios_emulator/scitech/bin/bc50-d16.bat
  64. 35 0
      board/MAI/bios_emulator/scitech/bin/bc50-d32.bat
  65. 35 0
      board/MAI/bios_emulator/scitech/bin/bc50-smx.bat
  66. 34 0
      board/MAI/bios_emulator/scitech/bin/bc50-snp.bat
  67. 48 0
      board/MAI/bios_emulator/scitech/bin/bc50-tnt.bat
  68. 34 0
      board/MAI/bios_emulator/scitech/bin/bc50-vxd.bat
  69. 34 0
      board/MAI/bios_emulator/scitech/bin/bc50-w16.bat
  70. 40 0
      board/MAI/bios_emulator/scitech/bin/bc50-w32.bat
  71. 34 0
      board/MAI/bios_emulator/scitech/bin/bc50-x11.bat
  72. 40 0
      board/MAI/bios_emulator/scitech/bin/bcb5-c32.bat
  73. 34 0
      board/MAI/bios_emulator/scitech/bin/bcb5-d16.bat
  74. 35 0
      board/MAI/bios_emulator/scitech/bin/bcb5-d32.bat
  75. 35 0
      board/MAI/bios_emulator/scitech/bin/bcb5-smx.bat
  76. 34 0
      board/MAI/bios_emulator/scitech/bin/bcb5-snp.bat
  77. 48 0
      board/MAI/bios_emulator/scitech/bin/bcb5-tnt.bat
  78. 34 0
      board/MAI/bios_emulator/scitech/bin/bcb5-vxd.bat
  79. 34 0
      board/MAI/bios_emulator/scitech/bin/bcb5-w16.bat
  80. 40 0
      board/MAI/bios_emulator/scitech/bin/bcb5-w32.bat
  81. 34 0
      board/MAI/bios_emulator/scitech/bin/bcb5-x11.bat
  82. 22 0
      board/MAI/bios_emulator/scitech/bin/build
  83. 4 0
      board/MAI/bios_emulator/scitech/bin/build.bat
  84. 4 0
      board/MAI/bios_emulator/scitech/bin/build_db.bat
  85. 432 0
      board/MAI/bios_emulator/scitech/bin/build_it.bat
  86. 6 0
      board/MAI/bios_emulator/scitech/bin/cddrv.bat
  87. 10 0
      board/MAI/bios_emulator/scitech/bin/cdit
  88. 5 0
      board/MAI/bios_emulator/scitech/bin/cdit.bat
  89. 46 0
      board/MAI/bios_emulator/scitech/bin/djgpp.env
  90. 46 0
      board/MAI/bios_emulator/scitech/bin/djgpp_db.env
  91. 1 0
      board/MAI/bios_emulator/scitech/bin/findint3.bat
  92. 16 0
      board/MAI/bios_emulator/scitech/bin/gcc-beos.sh
  93. 16 0
      board/MAI/bios_emulator/scitech/bin/gcc-freebsd.sh
  94. 19 0
      board/MAI/bios_emulator/scitech/bin/gcc-linux.sh
  95. 26 0
      board/MAI/bios_emulator/scitech/bin/gcc2-c32.bat
  96. 28 0
      board/MAI/bios_emulator/scitech/bin/gcc2-dos.bat
  97. 26 0
      board/MAI/bios_emulator/scitech/bin/gcc2-linux.bat
  98. 26 0
      board/MAI/bios_emulator/scitech/bin/gcc2-w32.bat
  99. 97 0
      board/MAI/bios_emulator/scitech/bin/makelib.bat
  100. 23 0
      board/MAI/bios_emulator/scitech/bin/meltobjs.sh

+ 12 - 0
CHANGELOG

@@ -2,6 +2,18 @@
 Changes since for U-Boot 0.1.0:
 ======================================================================
 
+* Patch by Thomas Frieden, 13 Nov 2002:
+  Add code for AmigaOne board
+  (preliminary merge to U-Boot, still WIP)
+
+* Patch by Jon Diekema, 12 Nov 2002:
+  - Adding URL for IEEE OUI lookup
+  - Making the autoboot #defines dependent on CONFIG_AUTOBOOT_KEYED
+    being defined.
+  - In the CONFIG_EXTRA_ENV_SETTINGS #define, the root-on-initrd and
+    root-on-nfs macros are designed to switch how the default boot
+    method gets defined.
+
 * Patch by Daniel Engström, 13 Nov 2002:
   Add support for i386 architecture and AMD SC520 board
 

+ 4 - 0
CREDITS

@@ -92,6 +92,10 @@ E: wg@denx.de
 D: Support for Interphase 4539 T1/E1/J1 PMC, PN62, CCM, SCM boards
 W: www.denx.de
 
+N: Thomas Frieden
+E: ThomasF@hyperion-entertainment.com
+D: Support for AmigaOne
+
 N: Frank Gottschling
 E: fgottschling@eltec.de
 D: Support for ELTEC MHPC/BAB7xx/ELPPC boards, cfb-console, i8042, SMI LynxEM

+ 4 - 1
MAINTAINERS

@@ -33,7 +33,6 @@ Jerry Van Baren <vanbaren_gerald@si.com>
 
 Oliver Brown <obrown@adventnetworks.com>
 
-	sbc8260			MPC8260
 	gw8260			MPC8260
 
 Conn Clark <clark@esteem.com>
@@ -91,6 +90,10 @@ Dave Ellis <DGE@sixnetio.com>
 
 	SXNI855T		MPC8xx
 
+Thomas Frieden <ThomasF@hyperion-entertainment.com>
+
+	AmigaOneG3SE		MPC7xx
+
 Frank Gottschling <fgottschling@eltec.de>
 
 	MHPC			MPC8xx

+ 3 - 0
Makefile

@@ -564,6 +564,9 @@ TQM8260_300MHz_config:	unconfig
 ## 74xx/7xx Systems
 #########################################################################
 
+AmigaOneG3SE_config:	unconfig
+	@./mkconfig $(@:_config=) ppc 74xx_7xx AmigaOneG3SE MAI
+
 EVB64260_config	\
 EVB64260_750CX_config:	unconfig
 	@./mkconfig EVB64260 ppc 74xx_7xx evb64260

+ 116 - 0
board/MAI/AmigaOneG3SE/AmigaOneG3SE.c

@@ -0,0 +1,116 @@
+/*
+ * (C) Copyright 2002
+ * Hyperion Entertainment, ThomasF@hyperion-entertainment.com
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <pci.h>
+#include "articiaS.h"
+#include "memio.h"
+#include "via686.h"
+
+__asm(" .globl send_kb                                      \n
+        send_kb:                                            \n
+                lis     r9, 0xfe00                          \n
+                                                            \n
+                li      r4, 0x10        # retries           \n
+                mtctr   r4                                  \n
+                                                            \n
+        idle:                                               \n
+                lbz     r4, 0x64(r9)                        \n
+                andi.   r4, r4, 0x02                        \n
+                bne     idle                                \n
+                                                            \n
+        ready:                                              \n
+                stb     r3, 0x60(r9)                        \n
+                                                            \n
+        check:                                              \n
+                lbz     r4, 0x64(r9)                        \n
+                andi.   r4, r4, 0x01                        \n
+                beq     check                               \n
+                                                            \n
+                lbz     r4, 0x60(r9)                        \n
+                cmpwi   r4, 0xfa                            \n
+                beq     done                                \n
+                                                            \n
+                bdnz    idle                                \n
+                                                            \n
+                li      r3, 0                               \n
+                blr                                         \n
+                                                            \n
+        done:                                               \n
+                li      r3, 1                               \n
+                blr                                         \n
+                                                            \n
+        .globl test_kb                                      \n
+        test_kb:                                            \n
+                mflr    r10                                 \n
+	        li      r3, 0xed                            \n
+                bl      send_kb                             \n
+                li      r3, 0x01                            \n
+                bl      send_kb                             \n
+                mtlr    r10                                 \n
+                blr                                         \n
+");
+
+
+int checkboard (void)
+{
+	printf ("AmigaOneG3SE\n");
+
+	return 1;
+}
+
+long initdram (int board_type)
+{
+	return articiaS_ram_init ();
+}
+
+
+
+void after_reloc (ulong dest_addr)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	board_init_r (gd, dest_addr);
+}
+
+
+int misc_init_r (void)
+{
+	extern pci_dev_t video_dev;
+	extern void drv_video_init (void);
+
+	if (video_dev != ~0)
+		drv_video_init ();
+
+	return (0);
+}
+
+
+void pci_init (void)
+{
+#ifndef CONFIG_RAMBOOT
+	articiaS_pci_init ();
+#endif
+}

+ 53 - 0
board/MAI/AmigaOneG3SE/Makefile

@@ -0,0 +1,53 @@
+#
+# (C) Copyright 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= lib$(BOARD).a
+
+COBJS	= $(BOARD).o articiaS.o flash.o serial.o smbus.o articiaS_pci.o \
+		via686.o i8259.o ../bios_emulator/x86interface.o 	\
+		../bios_emulator/bios.o ../bios_emulator/glue.o		\
+		interrupts.o ps2kbd.o video.o usb_uhci.o enet.o	        \
+		../menu/cmd_menu.o cmd_boota.o nvram.o
+
+AOBJS	= board_asm_init.o memio.o
+
+OBJS	= $(COBJS) $(AOBJS) 
+
+## FIXME !!!
+# EMUOBJS = ../bios_emulator/scitech/src/x86emu/*.o
+
+
+$(LIB):	.depend $(OBJS) $(EMUOBJS)
+	-rm $(LIB)
+	$(AR) crv $@ $(OBJS) $(EMUOBJS)
+
+#########################################################################
+
+.depend: Makefile $(AOBJS:.o=.S) $(COBJS:.o=.c)
+	$(CC) -M $(CFLAGS) $(AOBJS:.o=.S) $(COBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################

+ 704 - 0
board/MAI/AmigaOneG3SE/articiaS.c

@@ -0,0 +1,704 @@
+/*
+ * (C) Copyright 2002
+ * Hyperion Entertainment, ThomasF@hyperion-entertainment.com 
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <asm/processor.h>
+#include "memio.h"
+#include "articiaS.h"
+#include "smbus.h"
+#include "via686.h"
+
+#undef DEBUG
+
+struct dimm_bank {
+	uint8 used;			/* Bank is populated */
+	uint32 rows;			/* Number of row addresses */
+	uint32 columns;			/* Number of column addresses */
+	uint8 registered;		/* SIMM is registered */
+	uint8 ecc;			/* SIMM has ecc */
+	uint8 burst_len;		/* Supported burst lengths */
+	uint32 cas_lat;			/* Supported CAS latencies */
+	uint32 cas_used;		/* CAS to use (not set by user) */
+	uint32 trcd;			/* RAS to CAS latency */
+	uint32 trp;			/* Precharge latency */
+	uint32 tclk_hi;			/* SDRAM cycle time (highest CAS latency) */
+	uint32 tclk_2hi;		/* SDRAM second highest CAS latency */
+	uint32 size;			/* Size of bank in bytes */
+	uint8 auto_refresh;		/* Module supports auto refresh */
+	uint32 refresh_time;		/* Refresh time (in ns) */
+};
+
+
+/*
+** Based in part on the evb64260 code
+*/
+
+/*
+ * translate ns.ns/10 coding of SPD timing values
+ * into 10 ps unit values
+ */
+static inline unsigned short NS10to10PS (unsigned char spd_byte)
+{
+	unsigned short ns, ns10;
+
+	/* isolate upper nibble */
+	ns = (spd_byte >> 4) & 0x0F;
+	/* isolate lower nibble */
+	ns10 = (spd_byte & 0x0F);
+
+	return (ns * 100 + ns10 * 10);
+}
+
+/*
+ * translate ns coding of SPD timing values
+ * into 10 ps unit values
+ */
+static inline unsigned short NSto10PS (unsigned char spd_byte)
+{
+	return (spd_byte * 100);
+}
+
+
+long detect_sdram (uint8 * rom, int dimmNum, struct dimm_bank *banks)
+{
+	int dimm_address = (dimmNum == 0) ? SM_DIMM0_ADDR : SM_DIMM1_ADDR;
+	uint32 busclock = get_bus_freq (0);
+	uint32 memclock = busclock;
+	uint32 tmemclock = 1000000000 / (memclock / 100);
+	uint32 datawidth;
+
+	if (sm_get_data (rom, dimm_address) == 0) {
+		/* Nothing in slot, make both banks empty */
+		debug ("Slot %d: vacant\n", dimmNum);
+		banks[0].used = 0;
+		banks[1].used = 0;
+		return 0;
+	}
+
+	if (rom[2] != 0x04) {
+		debug ("Slot %d: No SDRAM\n", dimmNum);
+		banks[0].used = 0;
+		banks[1].used = 0;
+		return 0;
+	}
+
+	/* Determine number of banks/rows */
+	if (rom[5] == 1) {
+		banks[0].used = 1;
+		banks[1].used = 0;
+	} else {
+		banks[0].used = 1;
+		banks[1].used = 1;
+	}
+
+	/* Determine number of row addresses */
+	if (rom[3] & 0xf0) {
+		/* Different banks sizes */
+		banks[0].rows = rom[3] & 0x0f;
+		banks[1].rows = (rom[3] & 0xf0) >> 4;
+	} else {
+		/* Equal sized banks */
+		banks[0].rows = rom[3] & 0x0f;
+		banks[1].rows = banks[0].rows;
+	}
+
+	/* Determine number of column addresses */
+	if (rom[4] & 0xf0) {
+		/* Different bank sizes */
+		banks[0].columns = rom[4] & 0x0f;
+		banks[1].columns = (rom[4] & 0xf0) >> 4;
+	} else {
+		banks[0].columns = rom[4] & 0x0f;
+		banks[1].columns = banks[0].columns;
+	}
+
+	/* Check Jedec revision, and modify row/column accordingly */
+	if (rom[62] > 0x10) {
+		if (banks[0].rows <= 3)
+			banks[0].rows += 15;
+		if (banks[1].rows <= 3)
+			banks[1].rows += 15;
+		if (banks[0].columns <= 3)
+			banks[0].columns += 15;
+		if (banks[0].columns <= 3)
+			banks[0].columns += 15;
+	}
+
+	/* Check registered/unregisterd */
+	if (rom[21] & 0x12) {
+		banks[0].registered = 1;
+		banks[1].registered = 1;
+	} else {
+		banks[0].registered = 0;
+		banks[1].registered = 0;
+	}
+
+#ifdef CONFIG_ECC
+	/* Check parity/ECC */
+	banks[0].ecc = (rom[11] == 0x02);
+	banks[1].ecc = (rom[11] == 0x02);
+#endif
+
+	/* Find burst lengths supported */
+	banks[0].burst_len = rom[16] & 0x8f;
+	banks[1].burst_len = rom[16] & 0x8f;
+
+	/* Find possible cas latencies */
+	banks[0].cas_lat = rom[18] & 0x7F;
+	banks[1].cas_lat = rom[18] & 0x7F;
+
+	/* RAS/CAS latency */
+	banks[0].trcd = (NSto10PS (rom[29]) + (tmemclock - 1)) / tmemclock;
+	banks[1].trcd = (NSto10PS (rom[29]) + (tmemclock - 1)) / tmemclock;
+
+	/* Precharge latency */
+	banks[0].trp = (NSto10PS (rom[27]) + (tmemclock - 1)) / tmemclock;
+	banks[1].trp = (NSto10PS (rom[27]) + (tmemclock - 1)) / tmemclock;
+
+	/* highest CAS latency */
+	banks[0].tclk_hi = NS10to10PS (rom[9]);
+	banks[1].tclk_hi = NS10to10PS (rom[9]);
+
+	/* second highest CAS latency */
+	banks[0].tclk_2hi = NS10to10PS (rom[23]);
+	banks[1].tclk_2hi = NS10to10PS (rom[23]);
+
+	/* bank sizes */
+	datawidth = rom[13] & 0x7f;
+	banks[0].size =
+			(1L << (banks[0].rows + banks[0].columns)) *
+			/* FIXME datawidth */ 8 * rom[17];
+	if (rom[13] & 0x80)
+		banks[1].size = 2 * banks[0].size;
+	else
+		banks[1].size = (1L << (banks[1].rows + banks[1].columns)) *
+				/* FIXME datawidth */ 8 * rom[17];
+
+	/* Refresh */
+	if (rom[12] & 0x80) {
+		banks[0].auto_refresh = 1;
+		banks[1].auto_refresh = 1;
+	} else {
+		banks[0].auto_refresh = 0;
+		banks[1].auto_refresh = 0;
+	}
+
+	switch (rom[12] & 0x7f) {
+	case 0:
+		banks[0].refresh_time = (1562500 + (tmemclock - 1)) / tmemclock;
+		banks[1].refresh_time = (1562500 + (tmemclock - 1)) / tmemclock;
+		break;
+	case 1:
+		banks[0].refresh_time = (390600 + (tmemclock - 1)) / tmemclock;
+		banks[1].refresh_time = (390600 + (tmemclock - 1)) / tmemclock;
+		break;
+	case 2:
+		banks[0].refresh_time = (781200 + (tmemclock - 1)) / tmemclock;
+		banks[1].refresh_time = (781200 + (tmemclock - 1)) / tmemclock;
+		break;
+	case 3:
+		banks[0].refresh_time = (3125000 + (tmemclock - 1)) / tmemclock;
+		banks[1].refresh_time = (3125000 + (tmemclock - 1)) / tmemclock;
+		break;
+	case 4:
+		banks[0].refresh_time = (6250000 + (tmemclock - 1)) / tmemclock;
+		banks[1].refresh_time = (6250000 + (tmemclock - 1)) / tmemclock;
+		break;
+	case 5:
+		banks[0].refresh_time = (12500000 + (tmemclock - 1)) / tmemclock;
+		banks[1].refresh_time = (12500000 + (tmemclock - 1)) / tmemclock;
+		break;
+	default:
+		banks[0].refresh_time = 0x100;	/* Default of Articia S */
+		banks[1].refresh_time = 0x100;
+		break;
+	}
+
+#ifdef DEBUG
+	printf ("\nInformation for SIMM bank %ld:\n", dimmNum);
+	printf ("Number of banks: %ld\n", banks[0].used + banks[1].used);
+	printf ("Number of row addresses: %ld\n", banks[0].rows);
+	printf ("Number of coumns addresses: %ld\n", banks[0].columns);
+	printf ("SIMM is %sregistered\n",
+			banks[0].registered == 0 ? "not " : "");
+#ifdef CONFIG_ECC
+	printf ("SIMM %s ECC\n",
+			banks[0].ecc == 1 ? "supports" : "doesn't support");
+#endif
+	printf ("Supported burst lenghts: %s %s %s %s %s\n",
+			banks[0].burst_len & 0x08 ? "8" : " ",
+			banks[0].burst_len & 0x04 ? "4" : " ",
+			banks[0].burst_len & 0x02 ? "2" : " ",
+			banks[0].burst_len & 0x01 ? "1" : " ",
+			banks[0].burst_len & 0x80 ? "PAGE" : "    ");
+	printf ("Supported CAS latencies: %s %s %s\n",
+			banks[0].cas_lat & 0x04 ? "CAS 3" : "     ",
+			banks[0].cas_lat & 0x02 ? "CAS 2" : "     ",
+			banks[0].cas_lat & 0x01 ? "CAS 1" : "     ");
+	printf ("RAS to CAS latency: %ld\n", banks[0].trcd);
+	printf ("Precharge latency: %ld\n", banks[0].trp);
+	printf ("SDRAM highest CAS latency: %ld\n", banks[0].tclk_hi);
+	printf ("SDRAM 2nd highest CAS latency: %ld\n", banks[0].tclk_2hi);
+	printf ("SDRAM data width: %ld\n", datawidth);
+	printf ("Auto Refresh %ssupported\n",
+			banks[0].auto_refresh ? "" : "not ");
+	printf ("Refresh time: %ld clocks\n", banks[0].refresh_time);
+	if (banks[0].used)
+		printf ("Bank 0 size: %ld MB\n", banks[0].size / 1024 / 1024);
+	if (banks[1].used)
+		printf ("Bank 1 size: %ld MB\n", banks[1].size / 1024 / 1024);
+
+	printf ("\n");
+#endif
+
+	sm_term ();
+	return 1;
+}
+
+void select_cas (struct dimm_bank *banks, uint8 fast)
+{
+	if (!banks[0].used) {
+		banks[0].cas_used = 0;
+		banks[0].cas_used = 0;
+		return;
+	}
+
+	if (fast) {
+		/* Search for fast CAS */
+		uint32 i;
+		uint32 c = 0x01;
+
+		for (i = 1; i < 5; i++) {
+			if (banks[0].cas_lat & c) {
+				banks[0].cas_used = i;
+				banks[1].cas_used = i;
+				debug ("Using CAS %d (fast)\n", i);
+				return;
+			}
+			c <<= 1;
+		}
+
+		/* Default to CAS 3 */
+		banks[0].cas_used = 3;
+		banks[1].cas_used = 3;
+		debug ("Using CAS 3 (fast)\n");
+
+		return;
+	} else {
+		/* Search for slow cas */
+		uint32 i;
+		uint32 c = 0x08;
+
+		for (i = 4; i > 1; i--) {
+			if (banks[0].cas_lat & c) {
+				banks[0].cas_used = i;
+				banks[1].cas_used = i;
+				debug ("Using CAS %d (slow)\n", i);
+				return;
+			}
+			c >>= 1;
+		}
+
+		/* Default to CAS 3 */
+		banks[0].cas_used = 3;
+		banks[1].cas_used = 3;
+		debug ("Using CAS 3 (slow)\n");
+
+		return;
+	}
+
+	banks[0].cas_used = 3;
+	banks[1].cas_used = 3;
+	debug ("Using CAS 3\n");
+
+	return;
+}
+
+uint32 get_reg_setting (uint32 banks, uint32 rows, uint32 columns, uint32 size)
+{
+	uint32 i;
+
+	struct RowColumnSize {
+		uint32 banks;
+		uint32 rows;
+		uint32 columns;
+		uint32 size;
+		uint32 register_value;
+	};
+
+	struct RowColumnSize rcs_map[] = {
+		/*  Sbk Radr Cadr   MB     Value */
+		{1, 11, 8, 8, 0x00840f00},
+		{1, 11, 9, 16, 0x00925f00},
+		{1, 11, 10, 32, 0x00a64f00},
+		{2, 12, 8, 32, 0x00c55f00},
+		{2, 12, 9, 64, 0x00d66f00},
+		{2, 12, 10, 128, 0x00e77f00},
+		{2, 12, 11, 256, 0x00ff8f00},
+		{2, 13, 11, 512, 0x00ff9f00},
+		{0, 0, 0, 0, 0x00000000}
+	};
+
+
+	i = 0;
+
+	while (rcs_map[i].banks != 0) {
+		if (rows == rcs_map[i].rows
+			&& columns == rcs_map[i].columns
+			&& (size / 1024 / 1024) == rcs_map[i].size)
+			return rcs_map[i].register_value;
+
+		i++;
+	}
+
+	return 0;
+}
+
+uint32 burst_to_len (uint32 support)
+{
+	if (support & 0x80)
+		return 0x7;
+	else if (support & 0x8)
+		return 0x3;
+	else if (support & 0x4)
+		return 0x2;
+	else if (support & 0x2)
+		return 0x1;
+	else if (support & 0x1)
+		return 0x0;
+
+	return 0;
+}
+
+long articiaS_ram_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	register uint32 i;
+	register uint32 value1;
+	register uint32 value2;
+	uint8 rom[128];
+	uint32 burst_len;
+	uint32 burst_support;
+	uint32 total_ram = 0;
+
+	struct dimm_bank banks[4];	/* FIXME: Move to initram */
+	uint32 busclock = get_bus_freq (0);
+	uint32 memclock = busclock;
+	uint32 reg32;
+	uint32 refresh_clocks;
+	uint8 auto_refresh;
+
+	memset (banks, 0, sizeof (struct dimm_bank) * 4);
+
+	detect_sdram (rom, 0, &banks[0]);
+	detect_sdram (rom, 1, &banks[2]);
+
+	for (i = 0; i < 4; i++) {
+		total_ram = total_ram + (banks[i].used * banks[i].size);
+	}
+
+	pci_write_cfg_long (0, 0, GLOBALINFO0, 0x117430c0);
+	pci_write_cfg_long (0, 0, HBUSACR0, 0x1f0100b0);
+	pci_write_cfg_long (0, 0, SRAM_CR, 0x00f12000);	/* Note: Might also try 0x00f10000 (original: 0x00f12000) */
+	pci_write_cfg_byte (0, 0, DRAM_RAS_CTL0, 0x3f);
+	pci_write_cfg_byte (0, 0, DRAM_RAS_CTL1, 0x00);	/*  was: 0x04); */
+	pci_write_cfg_word (0, 0, DRAM_ECC0, 0x2020);	/*  was: 0x2400);  No ECC yet */
+
+	/* FIXME: Move this stuff to seperate function, like setup_dimm_bank */
+	if (banks[0].used) {
+		value1 = get_reg_setting (banks[0].used + banks[1].used,
+					  banks[0].rows, banks[0].columns,
+					  banks[0].size);
+	} else {
+		value1 = 0;
+	}
+
+	if (banks[1].used) {
+		value2 = get_reg_setting (banks[0].used + banks[1].used,
+					  banks[1].rows, banks[1].columns,
+					  banks[1].size);
+	} else {
+		value2 = 0;
+	}
+
+	pci_write_cfg_long (0, 0, DIMM0_B0_SCR0, value1);
+	pci_write_cfg_long (0, 0, DIMM0_B1_SCR0, value2);
+
+	debug ("DIMM0_B0_SCR0 = 0x%08x\n", value1);
+	debug ("DIMM0_B1_SCR0 = 0x%08x\n", value2);
+
+	if (banks[2].used) {
+		value1 = get_reg_setting (banks[2].used + banks[3].used,
+					  banks[2].rows, banks[2].columns,
+					  banks[2].size);
+	} else {
+		value1 = 0;
+	}
+
+	if (banks[3].used) {
+		value2 = get_reg_setting (banks[2].used + banks[3].used,
+					  banks[3].rows, banks[3].columns,
+					  banks[3].size);
+	} else {
+		value2 = 0;
+	}
+
+	pci_write_cfg_long (0, 0, DIMM1_B2_SCR0, value1);
+	pci_write_cfg_long (0, 0, DIMM1_B3_SCR0, value2);
+
+	debug ("DIMM0_B2_SCR0 = 0x%08x\n", value1);
+	debug ("DIMM0_B3_SCR0 = 0x%08x\n", value2);
+
+	pci_write_cfg_long (0, 0, DIMM2_B4_SCR0, 0);
+	pci_write_cfg_long (0, 0, DIMM2_B5_SCR0, 0);
+	pci_write_cfg_long (0, 0, DIMM3_B6_SCR0, 0);
+	pci_write_cfg_long (0, 0, DIMM3_B7_SCR0, 0);
+
+	/* Determine timing */
+	select_cas (&banks[0], 0);
+	select_cas (&banks[2], 0);
+
+	/* FIXME: What about write recovery */
+	/*                    Auto refresh    Precharge */
+#if 0
+	reg32 = (0x3 << 13) | (0x7 << 10) | ((banks[0].trp - 2) << 8) |
+	/*    Write recovery  CAS Latency */
+		(0x1 << 6) | (banks[0].cas_used << 4) |
+	/*      RAS/CAS latency */
+		((banks[0].trcd - 1) << 0);
+
+	reg32 |= ((0x3 << 13) | (0x7 << 10) | ((banks[2].trp - 2) << 8) |
+		  (0x1 << 6) | (banks[2].cas_used << 4) |
+		  ((banks[2].trcd - 1) << 0)) << 16;
+#else
+	if (100000000 == gd->bus_clk)
+		reg32 = 0x71737173;
+	else
+		reg32 = 0x69736973;
+#endif
+	pci_write_cfg_long (0, 0, DIMM0_TCR0, reg32);
+	debug ("DIMM0_TCR0 = 0x%08x\n", reg32);
+
+	/* Write default in DIMM2/3 (not used on A1) */
+	pci_write_cfg_long (0, 0, DIMM2_TCR0, 0x7d737d73);
+
+
+	/* Determine buffered/unbuffered mode for each SIMM. Uses first bank as reference (second, if present, uses the same) */
+	reg32 = pci_read_cfg_long (0, 0, DRAM_GCR0);
+	reg32 &= 0xFF00FFFF;
+
+#if 0
+	if (banks[0].used && banks[0].registered)
+		reg32 |= 0x1 << 16;
+
+	if (banks[2].used && banks[2].registered)
+		reg32 |= 0x1 << 18;
+#else
+	if (banks[0].registered || banks[2].registered)
+		reg32 |= 0x55 << 16;
+#endif
+	pci_write_cfg_long (0, 0, DRAM_GCR0, reg32);
+	debug ("DRAM_GCR0 = 0x%08x\n", reg32);
+
+	/* Determine refresh */
+	refresh_clocks = 0xffffffff;
+	auto_refresh = 1;
+
+	for (i = 0; i < 4; i++) {
+		if (banks[i].used) {
+			if (banks[i].auto_refresh == 0)
+				auto_refresh = 0;
+			if (banks[i].refresh_time < refresh_clocks)
+				refresh_clocks = banks[i].refresh_time;
+		}
+	}
+
+
+#if 1
+	/*  It seems this is suggested by the ArticiaS data book */
+	if (100000000 == gd->bus_clk)
+		refresh_clocks = 1561;
+	else
+		refresh_clocks = 2083;
+#endif
+
+
+	debug ("Refresh set to %ld clocks, auto refresh %s\n",
+		   refresh_clocks, auto_refresh ? "on" : "off");
+
+	pci_write_cfg_long (0, 0, DRAM_REFRESH0,
+			(1 << 16) | (1 << 15) | (auto_refresh << 12) |
+			(refresh_clocks));
+	debug ("DRAM_REFRESH0 = 0x%08x\n",
+			(1 << 16) | (1 << 15) | (auto_refresh << 12) |
+			(refresh_clocks));
+
+/*     pci_write_cfg_long(0, 0, DRAM_REFRESH0,   0x00019400);  */
+
+	/* Set mode registers */
+	/* FIXME: For now, set same burst len for all modules. Dunno if that's necessary */
+	/* Find a common burst len */
+	burst_support = 0xff;
+
+	if (banks[0].used)
+		burst_support = banks[0].burst_len;
+	if (banks[1].used)
+		burst_support = banks[1].burst_len;
+	if (banks[2].used)
+		burst_support = banks[2].burst_len;
+	if (banks[3].used)
+		burst_support = banks[3].burst_len;
+
+	/* 
+	   ** Mode register:
+	   ** Bits         Use
+	   ** 0-2          Burst len
+	   ** 3            Burst type (0 = sequential, 1 = interleave)
+	   ** 4-6          CAS latency
+	   ** 7-8          Operation mode (0 = default, all others invalid)
+	   ** 9            Write burst
+	   ** 10-11        Reserved
+	   **
+	   ** Mode register burst table:
+	   ** A2 A1 A0     lenght
+	   ** 0  0  0      1
+	   ** 0  0  1      2
+	   ** 0  1  0      4
+	   ** 0  1  1      8
+	   ** 1  0  0      invalid
+	   ** 1  0  1      invalid
+	   ** 1  1  0      invalid
+	   ** 1  1  1      page (only valid for non-interleaved)
+	 */
+
+	burst_len = burst_to_len (burst_support);
+	burst_len = 2;				/* FIXME */
+
+	if (banks[0].used) {
+		pci_write_cfg_word (0, 0, DRAM_PCR0,
+			0x8000 | burst_len | (banks[0].cas_used << 4));
+		debug ("Mode bank 0: 0x%08x\n",
+			0x8000 | burst_len | (banks[0].cas_used << 4));
+	} else {
+		/*  Seems to be needed to disable the bank */
+		pci_write_cfg_word (0, 0, DRAM_PCR0, 0x0000 | 0x032);
+	}
+
+	if (banks[1].used) {
+		pci_write_cfg_word (0, 0, DRAM_PCR0,
+			0x9000 | burst_len | (banks[1].cas_used << 4));
+		debug ("Mode bank 1: 0x%08x\n",
+			0x8000 | burst_len | (banks[1].cas_used << 4));
+	} else {
+		/*  Seems to be needed to disable the bank */
+		pci_write_cfg_word (0, 0, DRAM_PCR0, 0x1000 | 0x032);
+	}
+
+
+	if (banks[2].used) {
+		pci_write_cfg_word (0, 0, DRAM_PCR0,
+			0xa000 | burst_len | (banks[2].cas_used << 4));
+		debug ("Mode bank 2: 0x%08x\n",
+			0x8000 | burst_len | (banks[2].cas_used << 4));
+	} else {
+		/*  Seems to be needed to disable the bank */
+		pci_write_cfg_word (0, 0, DRAM_PCR0, 0x2000 | 0x032);
+	}
+
+
+	if (banks[3].used) {
+		pci_write_cfg_word (0, 0, DRAM_PCR0,
+			0xb000 | burst_len | (banks[3].cas_used << 4));
+		debug ("Mode bank 3: 0x%08x\n",
+			0x8000 | burst_len | (banks[3].cas_used << 4));
+	} else {
+		/*  Seems to be needed to disable the bank */
+		pci_write_cfg_word (0, 0, DRAM_PCR0, 0x3000 | 0x032);
+	}
+
+
+	pci_write_cfg_word (0, 0, 0xba, 0x00);
+
+	return total_ram;
+}
+
+extern int drv_isa_kbd_init (void);
+
+int last_stage_init (void)
+{
+	drv_isa_kbd_init ();
+	return 0;
+}
+
+int overwrite_console (void)
+{
+	return (0);
+}
+
+#define in_8 read_byte
+#define out_8 write_byte
+
+static __inline__ unsigned long get_msr (void)
+{
+	unsigned long msr;
+
+	asm volatile ("mfmsr %0":"=r" (msr):);
+
+	return msr;
+}
+
+static __inline__ void set_msr (unsigned long msr)
+{
+	asm volatile ("mtmsr %0"::"r" (msr));
+}
+
+int board_pre_init (void)
+{
+	unsigned char c_value = 0;
+	unsigned long msr;
+
+	/* Basic init of PS/2 keyboard (needed for some reason)... */
+	/* Ripped from John's code */
+	while ((in_8 ((unsigned char *) 0xfe000064) & 0x02) != 0);
+	out_8 ((unsigned char *) 0xfe000064, 0xaa);
+	while ((in_8 ((unsigned char *) 0xfe000064) & 0x01) == 0);
+	c_value = in_8 ((unsigned char *) 0xfe000060);
+	while ((in_8 ((unsigned char *) 0xfe000064) & 0x02) != 0);
+	out_8 ((unsigned char *) 0xfe000064, 0xab);
+	while ((in_8 ((unsigned char *) 0xfe000064) & 0x01) == 0);
+	c_value = in_8 ((unsigned char *) 0xfe000060);
+	while ((in_8 ((unsigned char *) 0xfe000064) & 0x02) != 0);
+	out_8 ((unsigned char *) 0xfe000064, 0xae);
+/*     while ((in_8((unsigned char *)0xfe000064) & 0x01) == 0); */
+/*     c_value = in_8((unsigned char *)0xfe000060); */
+
+	/*  Enable FPU */
+	msr = get_msr ();
+	set_msr (msr | MSR_FP);
+
+	via_calibrate_bus_freq ();
+
+	return 0;
+}

+ 143 - 0
board/MAI/AmigaOneG3SE/articiaS.h

@@ -0,0 +1,143 @@
+#ifndef ARTICIAS_H
+#define ARTICIAS_H
+
+#include "short_types.h"
+#include <common.h>
+
+#define REG_GROUP       0xF0
+
+/* ArticiaS registers */
+#define GLOBALINFO0     0x50
+#define GLOBALINFO1     0x51
+#define GLOBALINFO2     0x52
+#define GLOBALINFO3     0x53
+#define GLOBALCTL0      0x54
+#define GLOBALCTL1      0x55
+#define NVRAMCTL        0x56
+#define PCI1ACR0        0x58
+#define PCI1ACR1        0x59
+#define PCI1ACR2        0x5a
+#define PCI1ACR3        0x5b
+#define HBUSACR0        0x5c
+#define HBUSACR1        0x5d
+#define HBUSACR2        0x5e
+#define HBUSACR3        0x5f
+#define HOSTINT0        0x68
+#define HOSTINT1        0x69
+#define HOSTINT2        0x6a
+#define HOSTINT3        0x6b
+#define HOSTRBCR        0x70
+#define XDBCR           0x74
+
+#define LBSBCR2         0xd2
+
+
+/* Memory controller */
+
+#define DIMM0_B0_SCR0   0x90
+#define DIMM0_B1_SCR0   0x94
+#define DIMM1_B2_SCR0   0x98
+#define DIMM1_B3_SCR0   0x9c
+#define DIMM2_B4_SCR0   0xa0
+#define DIMM2_B5_SCR0   0xa4
+#define DIMM3_B6_SCR0   0xa8
+#define DIMM3_B7_SCR0   0xac
+
+#define DIMM0_TCR0      0xb0
+#define DIMM1_TCR0      0xb2
+#define DIMM2_TCR0      0xb4
+#define DIMM3_TCR0      0xb6
+
+#define DRAM_REFRESH0   0xb8
+#define DRAM_GCR0       0xc0
+#define DRAM_PCR0       0xc6
+#define DRAM_ECC0       0xc4
+#define SRAM_CR         0xc8
+#define DRAM_RAS_CTL0   0xcc
+#define DRAM_RAS_CTL1   0xcd
+
+/* Bits for REG_GROUP */
+#define REG_GROUP_MULTI       (1<<1)
+#define REG_GROUP_SPECIAL     (1<<3)
+#define REG_GROUP_DIAG        (0x1<<4)
+#define REG_GROUP_POWER       (0x2<<4)
+
+
+#define GLOBALINFO0_BO        (1<<7)
+
+
+#define GLOBALINFO2_B1ARBITER (1<<6)
+
+
+#define HBUSACR0_CPUAPC       (1<<0)
+#define HBUSACR0_NUMREQ_2     (0<<1)
+#define HBUSACR0_NUMREQ_3     (1<<1)
+#define HBUSACR0_NUMREQ_4     (2<<1)
+#define HBUSACR0_NUMREQ_MASK  (7<<1)
+#define HBUSACR0_RAW          (1<<6)
+#define HBUSACR0_WAIT         (1<<7)
+#define HBUSACR0_RESERVED     (0x30)
+
+
+#define HBUSACR2_BURST        (1<<0)
+#define HBUSACR2_LAT          (1<<1)
+
+
+#define HBUSACR3_LMWC_SM      (1<<0)
+#define HBUSACR3_LMWC_PCI1    (1<<1)
+#define HBUSACR3_LMWC_PCI0    (1<<2)
+#define HBUSACR3_PMWC_PCI1    (1<<3)
+#define HBUSACR3_PMWC_PCI0    (1<<4)
+#define HBUSACR3_FKH          (1<<5)
+#define HBUSACR3_92H_EN       (1<<6)
+#define HBUSACR3_60H_64H_EN   (1<<7)
+
+
+#define HOSTRBCR_PREFETCH     (1<<4)
+
+
+#define XDBCR_HWTOXD          (1<<0)
+#define XDBCR_KBTOXD          (1<<1)
+#define XDBCR_RTCTOXD         (1<<2)
+#define XDBCR_SCALE_1_1       (0x0<<3)       
+#define XDBCR_SCALE_2_2       (0x1<<3)       
+#define XDBCR_SCALE_3_2       (0x2<<3)       
+#define XDBCR_SCALE_4_4       (0x3<<3)       
+#define XDBCR_SCALE_5_8       (0x4<<3)       
+#define XDBCR_SCALE_6_8       (0x5<<3)       
+#define XDBCR_SCALE_8_8       (0x6<<3)       
+#define XDBCR_SCALE_0_16      (0x7<<3)       
+#define XDBCR_XDPROM          (1<<7)
+
+
+#define LBSBCR2_1_RWAC        (1<<2)
+
+
+/* PCI controller */
+#define ARTICIAS_PCI_CFGADDR  0xfec00cf8
+#define ARTICIAS_PCI_CFGDATA  0xfee00cfc
+
+#define ARTICIAS_PCI_BUS       0x80000000
+#define ARTICIAS_PCI_MAXSIZE   0x7cffffff
+#define ARTICIAS_PCI_PHYS      0x80000000
+
+#define ARTICIAS_SYS_BUS       0x00000000
+#define ARTICIAS_SYS_MAXSIZE   0x7fffffff
+#define ARTICIAS_SYS_PHYS      0x00000000
+
+#define ARTICIAS_PCIIO_BUS     0x00800000
+#define ARTICIAS_PCIIO_MAXSIZE 0x003fffff
+#define ARTICIAS_PCIIO_PHYS    0xfe800000
+
+#define ARTICIAS_ISAIO_BUS     0x00002000
+#define ARTICIAS_ISAIO_MAXSIZE 0x0000d000
+#define ARTICIAS_ISAIO_PHYS    0xfe002000
+
+
+
+/* Prototypes */
+long articiaS_ram_init(void);
+void articiaS_pci_init(void);
+
+
+#endif

+ 573 - 0
board/MAI/AmigaOneG3SE/articiaS_pci.c

@@ -0,0 +1,573 @@
+/*
+ * (C) Copyright 2002
+ * Hyperion Entertainment, Hans-JoergF@hyperion-entertainment.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <pci.h>
+#include "memio.h"
+#include "articiaS.h"
+
+//#define ARTICIA_PCI_DEBUG
+
+#ifdef  ARTICIA_PCI_DEBUG
+#define PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+struct pci_controller articiaS_hose;
+
+long irq_alloc(long wanted);
+
+static pci_dev_t pci_hose_find_class(struct pci_controller *hose, int bus, short find_class, int index);
+static int articiaS_init_vga(void);
+static void pci_cfgfunc_dummy(struct pci_controller *host, pci_dev_t dev, struct pci_config_table *table);
+unsigned char pci_irq_alloc(void);
+
+extern void via_cfgfunc_via686(struct pci_controller * host, pci_dev_t dev, struct pci_config_table *table);
+extern void via_cfgfunc_ide_init(struct pci_controller *host, pci_dev_t dev, struct pci_config_table *table);
+extern void via_init_irq_routing(uint8 []);
+extern void via_init_afterscan(void);
+
+#define cfgfunc_via686      1
+#define cfgfunc_dummy  2
+#define cfgfunc_ide_init    3
+
+static struct pci_config_table config_table[] =
+{
+    {
+	0x1106, PCI_ANY_ID, PCI_CLASS_BRIDGE_ISA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	(void *)cfgfunc_via686, {0, 0, 0}
+    },
+    {
+	0x1106, PCI_ANY_ID, PCI_ANY_ID, 0,7,4,
+	(void *)cfgfunc_dummy, {0,0,0}
+    },
+    {
+	0x1106, 0x3068, PCI_ANY_ID, 0, 7, PCI_ANY_ID,
+	(void *)cfgfunc_dummy, {0,0,0}
+    },
+    {
+	0x1106, PCI_ANY_ID, PCI_ANY_ID, 0,7,1,
+	(void *)cfgfunc_ide_init, {0,0,0}
+    },
+    {
+	0,
+    }
+};
+
+
+void pci_cfgfunc_dummy(struct pci_controller *host, pci_dev_t dev, struct pci_config_table *table)
+{
+
+
+}
+
+unsigned long irq_penalties[16] =
+{
+    1000,    /* 0:timer */
+    1000,    /* 1:keyboard */
+    1000,    /* 2:cascade */
+    50,      /* 3:serial (COM2) */
+    50,      /* 4:serial (COM1) */
+    4,       /* 5:USB2 */
+    100,     /* 6:floppy */
+    3,       /* 7:parallel */
+    50,      /* 8:AC97/MC97 */
+    0,       /* 9: */
+    3,       /* 10:: */
+    0,       /* 11: */
+    3,       /* 12: USB1 */
+    0,       /* 13: */
+    100,     /* 14: ide0 */
+    100,     /* 15: ide1 */
+};
+
+
+/*
+ * The following defines a hard-coded interrupt mapping for the
+ * know devices on the board.
+ * If a device isn't found here, assumed to be a device that's
+ * plugged into a PCI or AGP slot
+ * NOTE: This table is machine dependant.
+ */
+
+struct pci_irq_fixup_table
+{
+    uint8   bus;             /* Bus number */
+    uint8   device;          /* Device number */
+    uint8   func;            /* Function number */
+    uint8   interrupt;       /* Interrupt to use (0xff to disable) */
+};
+
+struct pci_irq_fixup_table fixuptab [] =
+{
+    { 0, 0, 0, 0xff},        /* Articia S host bridge */
+    { 0, 1, 0, 0xff},        /* Articia S AGP bridge */
+//    { 0, 6, 0, 0x05},        /* 3COM ethernet */
+    { 0, 7, 0, 0xff},        /* VIA southbridge */
+    { 0, 7, 1, 0x0e},        /* IDE controller in legacy mode */
+//    { 0, 7, 2, 0x05},        /* First USB controller */
+//    { 0, 7, 3, 0x0c},        /* Second USB controller (shares interrupt with ethernet) */
+    { 0, 7, 4, 0xff},        /* ACPI Power Management */
+//    { 0, 7, 5, 0x08},        /* AC97 */
+//    { 0, 7, 6, 0x08},        /* MC97 */
+    { 0xff, 0xff, 0xff, 0xff}
+};
+
+
+/*
+ * This table maps IRQ's to PCI interrupts
+ */
+
+uint8 pci_intmap[4] = {0, 0, 0, 0};
+
+/*
+ * Map PCI slots to interrupt routings
+ * This table lists the device number assigned to a card inserted
+ * into the slot, along with a permutation for the slot's IRQ routing.
+ * NOTE: This table is machine dependant.
+ */
+
+struct pci_slot_irq_routing
+{
+    uint8 bus;
+    uint8 device;
+
+    uint8 ints[4];
+};
+
+struct pci_slot_irq_routing amigaone_pci_routing[] =
+{
+    {0,  8,   {0, 1, 2, 3}},       /* Slot 1 (left of riser slot) */
+    {0,  9,   {1, 2, 3, 0}},       /* Slot 2 (middle slot) */
+    {0, 10,   {2, 3, 0, 1}},       /* Slot 3 (leftmost slot) */
+    {1,  0,   {1, 0, 2, 3}},       /* AGP slot (only IRQA and IRQB) */
+    {1,  1,   {1, 2, 3, 0}},       /* PCI slot on AGP bus */
+    {0,  6,   {3, 3, 3, 3}},       /* On board ethernet */
+    {0,  7,   {0, 1, 2, 3}},       /* Southbridge */
+    {0xff, 0, {0, 0, 0, 0}}
+};
+
+void articiaS_pci_irq_init(void)
+{
+    char *s;
+
+    s = getenv("pci_irqa");
+    if (s)
+	pci_intmap[0] = simple_strtoul (s, NULL, 10);
+    else
+	pci_intmap[0] = pci_irq_alloc();
+
+    s = getenv("pci_irqb");
+    if (s)
+	pci_intmap[1] = simple_strtoul (s, NULL, 10);
+    else
+	pci_intmap[1] = pci_irq_alloc();
+
+    s = getenv("pci_irqc");
+    if (s)
+	pci_intmap[2] = simple_strtoul (s, NULL, 10);
+    else
+	pci_intmap[2] = pci_irq_alloc();
+
+    s = getenv("pci_irqd");
+    if (s)
+	pci_intmap[3] = simple_strtoul (s, NULL, 10);
+    else
+	pci_intmap[3] = pci_irq_alloc();
+}
+
+
+unsigned char pci_irq_alloc(void)
+{
+    int i;
+    int interrupt = 10;
+    unsigned long min_penalty = 1000;
+
+    /* Search for the minimal penalty, favoring interrupts at the end */
+    for (i = 0; i < 16; i++)
+    {
+	if (irq_penalties[i] <= min_penalty)
+	{
+	    interrupt = i;
+	    min_penalty = irq_penalties[i];
+	}
+    }
+
+    PRINTF("pci_irq_alloc: Minimal penalty is %ld for %d\n", min_penalty, interrupt);
+
+    irq_penalties[interrupt]++;
+
+    return interrupt;
+}
+
+
+void articiaS_pci_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
+{
+    int8 bus, device, func, pin, line;
+    int i;
+
+    bus = PCI_BUS(dev);
+    device = PCI_DEV(dev);
+    func = PCI_FUNC(dev);
+
+    PRINTF("Fixup irq of %d:%d.%d\n", bus, device, func);
+
+    /* Search for the device in the table */
+    for (i = 0; fixuptab[i].bus != 0xff; i++)
+    {
+	if (bus == fixuptab[i].bus && device == fixuptab[i].device && func == fixuptab[i].func)
+	{
+	    /* If the device needs an interrupt, write it */
+	    if (fixuptab[i].interrupt != 0xff)
+	    {
+		PRINTF("Assigning IRQ %d (fixed)\n", fixuptab[i].interrupt);
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, fixuptab[i].interrupt);
+	    }
+	    else
+	    {
+		/* Otherwise, see if it wants an interrupt, and disable it if needed */
+		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+		if (pin)
+		{
+		    PRINTF("Disabling IRQ\n");
+		    pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 0xff);
+		}
+	    }
+
+	    return;
+	}
+    }
+
+    /* If we get here, we have another PCI device in a slot... find the appropriate IRQ */
+
+    /* Find matching pin */
+    pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+    pin--;
+
+    /* Search for it's map */
+    for (i = 0; amigaone_pci_routing[i].bus != 0xff; i++)
+    {
+	if (bus == amigaone_pci_routing[i].bus && device == amigaone_pci_routing[i].device)
+	{
+	    line = pci_intmap[amigaone_pci_routing[i].ints[pin]];
+	    PRINTF("Assigning IRQ %d (pin %d)\n", line, pin);
+	    pci_write_config_byte(dev, PCI_INTERRUPT_LINE, line);
+	    return;
+	}
+    }
+
+    PRINTF("Unkonwn PCI device found\n");
+}
+
+void articiaS_pci_init (void)
+{
+    int i;
+    char *s;
+
+    PRINTF("atriciaS_pci_init\n");
+
+    // Why aren't these relocated??
+    for (i=0; config_table[i].config_device; i++)
+    {
+	switch((int)config_table[i].config_device)
+	{
+	case cfgfunc_via686:     config_table[i].config_device = via_cfgfunc_via686;      break;
+	case cfgfunc_dummy:      config_table[i].config_device = pci_cfgfunc_dummy;       break;
+	case cfgfunc_ide_init:   config_table[i].config_device = via_cfgfunc_ide_init;    break;
+	default: PRINTF("Error: Unknown constant\n");
+	}
+    }
+
+    articiaS_hose.first_busno = 0;
+    articiaS_hose.last_busno = 0xff;
+    articiaS_hose.config_table = config_table;
+    articiaS_hose.fixup_irq = articiaS_pci_fixup_irq;
+
+    articiaS_pci_irq_init();
+
+    /* System memory */
+    pci_set_region(articiaS_hose.regions + 0,
+		   ARTICIAS_SYS_BUS,
+		   ARTICIAS_SYS_PHYS,
+		   ARTICIAS_SYS_MAXSIZE,
+		   PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+    /* PCI memory space */
+    pci_set_region(articiaS_hose.regions + 1,
+		   ARTICIAS_PCI_BUS,
+		   ARTICIAS_PCI_PHYS,
+		   ARTICIAS_PCI_MAXSIZE,
+		   PCI_REGION_MEM);
+
+    /* PCI io space */
+    pci_set_region(articiaS_hose.regions + 2,
+		   ARTICIAS_PCIIO_BUS,
+		   ARTICIAS_PCIIO_PHYS,
+		   ARTICIAS_PCIIO_MAXSIZE,
+		   PCI_REGION_IO);
+
+    /* PCI/ISA io space */
+    pci_set_region(articiaS_hose.regions + 3,
+		   ARTICIAS_ISAIO_BUS,
+		   ARTICIAS_ISAIO_PHYS,
+		   ARTICIAS_ISAIO_MAXSIZE,
+		   PCI_REGION_IO);
+
+
+
+    articiaS_hose.region_count = 4;
+
+    pci_setup_indirect(&articiaS_hose, ARTICIAS_PCI_CFGADDR, ARTICIAS_PCI_CFGDATA);
+    PRINTF("Registering articia hose...\n");
+    pci_register_hose(&articiaS_hose);
+    PRINTF("Enabling AGP...\n");
+    pci_write_config_byte(PCI_BDF(0,0,0), 0x58, 0x01);
+    PRINTF("Scanning bus...\n");
+    articiaS_hose.last_busno = pci_hose_scan(&articiaS_hose);
+
+    via_init_irq_routing(pci_intmap);
+
+    PRINTF("After-Scan results:\n");
+    PRINTF("Bus range: %d - %d\n", articiaS_hose.first_busno , articiaS_hose.last_busno);
+
+    via_init_afterscan();
+
+    pci_write_config_byte(PCI_BDF(0,1,0), PCI_INTERRUPT_LINE, 0xFF);
+
+    s = getenv("as_irq");
+    if (s)
+    {
+	pci_write_config_byte(PCI_BDF(0,0,0), PCI_INTERRUPT_LINE, simple_strtoul (s, NULL, 10));
+    }
+
+    s = getenv("x86_run_bios");
+    if (!s || (s && strcmp(s, "on")==0))
+    {
+	if (articiaS_init_vga() == -1)
+	{
+	    /* If the VGA didn't init and we have stdout set to VGA, reset to serial */
+/* 	    s = getenv("stdout"); */
+/* 	    if (s && strcmp(s, "vga") == 0) */
+/* 	    { */
+/* 		setenv("stdout", "serial"); */
+/* 	    } */
+	}
+    }
+    pci_write_config_byte(PCI_BDF(0,1,0), PCI_INTERRUPT_LINE, 0xFF);
+
+}
+
+pci_dev_t pci_hose_find_class(struct pci_controller *hose, int bus, short find_class, int index)
+{
+    unsigned int sub_bus, found_multi=0;
+    unsigned short vendor, class;
+    unsigned char header_type;
+    pci_dev_t dev;
+    u8 c1, c2;
+
+    sub_bus = bus;
+
+    for (dev =  PCI_BDF(bus,0,0);
+	 dev <  PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1);
+	 dev += PCI_BDF(0,0,1))
+    {
+	if ( dev == PCI_BDF(hose->first_busno,0,0) )
+	    continue;
+
+	if (PCI_FUNC(dev) && !found_multi)
+	    continue;
+
+	pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);
+
+	pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor);
+
+	if (vendor != 0xffff && vendor != 0x0000)
+	{
+
+	    if (!PCI_FUNC(dev))
+		found_multi = header_type & 0x80;
+	    pci_hose_read_config_byte(hose, dev, 0x0B, &c1);
+	    pci_hose_read_config_byte(hose, dev, 0x0A, &c2);
+	    class = c1<<8 | c2;
+	    //printf("At %02x:%02x:%02x: class %x\n",
+	    //	   PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev), class);
+	    if (class == find_class)
+	    {
+		if (index == 0)
+		    return dev;
+		else index--;
+	    }
+	}
+    }
+
+    return ~0;
+}
+
+
+/*
+ * For a given bus number, find the bridge on this hose that provides this
+ * bus number. The function scans for bridges and peeks config space offset
+ * 0x19 (PCI_SECONDARY_BUS).
+ */
+pci_dev_t pci_find_bridge_for_bus(struct pci_controller *hose, int busnr)
+{
+    pci_dev_t dev;
+    int bus;
+    unsigned int found_multi=0;
+    unsigned char header_type;
+    unsigned short vendor;
+    unsigned char secondary_bus;
+
+    if (hose == NULL) hose = &articiaS_hose;
+
+    if (busnr < hose->first_busno || busnr > hose->last_busno) return PCI_ANY_ID; // Not in range
+
+    /*
+     * The bridge must be on a lower bus number
+     */
+    for (bus = hose->first_busno; bus < busnr; bus++)
+    {
+	for (dev =  PCI_BDF(bus,0,0);
+	     dev <  PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1);
+	     dev += PCI_BDF(0,0,1))
+	{
+	    if ( dev == PCI_BDF(hose->first_busno,0,0) )
+		continue;
+
+	    if (PCI_FUNC(dev) && !found_multi)
+		continue;
+
+	    pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);
+
+	    pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor);
+
+	    if (vendor != 0xffff && vendor != 0x0000)
+	    {
+
+		if (!PCI_FUNC(dev))
+		    found_multi = header_type & 0x80;
+		if (header_type == 1) // Bridge device header
+		{
+		    pci_hose_read_config_byte(hose, dev, PCI_SECONDARY_BUS, &secondary_bus);
+		    if ((int)secondary_bus == busnr) return dev;
+		}
+
+	    }
+	}
+    }
+    return PCI_ANY_ID;
+}
+
+static short classes[] =
+{
+    PCI_CLASS_DISPLAY_VGA,
+    PCI_CLASS_DISPLAY_XGA,
+    PCI_CLASS_DISPLAY_3D,
+    PCI_CLASS_DISPLAY_OTHER,
+    ~0
+};
+
+extern int execute_bios(pci_dev_t gr_dev, void *);
+
+pci_dev_t video_dev;
+
+int articiaS_init_vga (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+    extern void shutdown_bios(void);
+    pci_dev_t dev = ~0;
+    int busnr = 0;
+    int classnr = 0;
+
+    video_dev = PCI_ANY_ID;
+
+    printf("VGA:   ");
+
+    PRINTF("Trying to initialize x86 VGA Card(s)\n");
+
+    while (dev == ~0)
+    {
+	PRINTF("Searching for class 0x%x on bus %d\n", classes[classnr], busnr);
+	/* Find the first of this class on this bus */
+	dev = pci_hose_find_class(&articiaS_hose, busnr, classes[classnr], 0);
+	if (dev != ~0) break;
+	busnr++;
+	if (busnr > articiaS_hose.last_busno)
+	{
+	    busnr = 0;
+	    classnr ++;
+	    if (classes[classnr] == ~0)
+	    {
+		printf("NOT PRESENT\n");
+		return -1;
+	    }
+	}
+    }
+
+    /*
+     * If we get here we have found the first graphics card.
+     * If the bus number is not 0, then it is probably behind a bridge, and the
+     * bridge needs to be told to forward VGA access.
+     */
+
+    if (PCI_BUS(dev) != 0)
+    {
+	pci_dev_t bridge;
+	PRINTF("Behind bridge, looking for bridge\n");
+	bridge = pci_find_bridge_for_bus(&articiaS_hose, PCI_BUS(dev));
+	if (dev != PCI_ANY_ID)
+	{
+	    unsigned char agp_control_0;
+	    PRINTF("Got the bridge at %02x:%02x:%02x\n",
+		   PCI_BUS(bridge), PCI_DEV(bridge), PCI_FUNC(bridge));
+	    pci_hose_read_config_byte(&articiaS_hose, bridge, 0x3E, &agp_control_0);
+	    agp_control_0 |= 0x18;
+	    pci_hose_write_config_byte(&articiaS_hose, bridge, 0x3E, agp_control_0);
+	    PRINTF("Configured for VGA forwarding\n");
+	}
+    }
+
+    /*
+     * Now try to run the bios
+     */
+
+    if (execute_bios(dev, gd->relocaddr))
+    {
+	printf("OK\n");
+	video_dev = dev;
+    }
+    else
+    {
+	printf("ERROR\n");
+    }
+
+    PRINTF("Done scanning.\n");
+
+    shutdown_bios();
+
+    if (dev == PCI_ANY_ID) return -1;
+    else return 0;
+
+}

+ 157 - 0
board/MAI/AmigaOneG3SE/board_asm_init.S

@@ -0,0 +1,157 @@
+	#include	"macros.h"
+	
+	
+
+#define GLOBALINFO0	      0x50	
+#define GLOBALINFO0_BO        (1<<7)
+#define GLOBALINFO2_B1ARBITER (1<<6)
+#define HBUSACR0              0x5c
+#define HBUSACR2_BURST        (1<<0)
+#define HBUSACR2_LAT          (1<<1)
+	
+#define RECEIVER_HOLDING 0
+#define TRANSMITTER_HOLDING 0
+#define INTERRUPT_ENABLE 1
+#define INTERRUPT_STATUS 2
+#define FIFO_CONTROL 2
+#define LINE_CONTROL 3
+#define MODEM_CONTROL 4
+#define LINE_STATUS 5
+#define MODEM_STATUS 6
+#define SCRATCH_PAD 7
+
+#define DIVISOR_LATCH_LSB 0
+#define DIVISOR_LATCH_MSB 1
+#define PRESCALER_DIVISION 5
+
+#define UART(x) (0x3f8+(x))
+
+#define GLOBALINFO0           0x50
+#define GLOBALINFO0_BO        (1<<7)
+#define GLOBALINFO2_B1ARBITER (1<<6)
+#define HBUSACR0              0x5c
+#define HBUSACR2_BURST        (1<<0)
+#define HBUSACR2_LAT          (1<<1)
+
+#define SUPERIO_1               ((7 << 3) | (0))
+#define SUPERIO_2               ((7 << 3) | (1))
+	
+	.globl	board_asm_init
+	
+board_asm_init:
+	mflr	r29
+	/* Set 'Must-set' register */
+	li	r3, 0
+	li	r4, 0
+	li	r5, 0x5e
+	bl	pci_read_cfg_byte
+	ori	r3, r3, (1<<1)
+	xori	r6, r3, (1<<1)
+	li	r3, 0
+	bl	pci_write_cfg_byte
+
+	li	r3, 0
+	li	r5, 0x52
+	bl	pci_read_cfg_byte
+	ori	r6, r3, (1<<6)
+	li	r3, 0
+	bl	pci_write_cfg_byte
+
+	li	r3, 0
+	li	r4, 0x08
+	li	r5, 0xd2
+	bl	pci_read_cfg_byte
+	ori	r6, r3, (1<<2)
+	li	r3, 0
+	bl	pci_write_cfg_byte
+
+
+	/* Do PCI reset */
+/*	li	r3, 0
+	li	r4, 0x38
+	li	r5, 0x47
+	bl	pci_read_cfg_byte
+	ori	r6, r3, 0x01
+	li	r3, 0
+	li	r4, 0x38
+	li	r5, 0x47
+	bl	pci_write_cfg_byte*/
+
+	
+	/* Enable NVRAM for environment */
+	li	r3, 0
+	li	r4, 0
+	li	r5, 0x56
+	li	r6, 0x0B
+	bl	pci_write_cfg_byte
+
+
+	/* Init Super-I/O chips */
+
+	siowb	0x40, 0x08
+	siowb	0x41, 0x01
+	siowb	0x45, 0x80
+	siowb	0x46, 0x60	
+	siowb	0x47, 0x20
+	siowb	0x48, 0x01
+	siowb	0x4a, 0xc4
+	siowb	0x50, 0x0e
+	siowb	0x51, 0x76
+	siowb	0x52, 0x34
+	siowb	0x54, 0x00
+	siowb	0x55, 0x90
+	siowb	0x56, 0x99
+	siowb	0x57, 0x90
+	siowb	0x85, 0x01
+		
+	/* Enable configuration mode for SuperIO */
+	li	r3, 0
+	li	r4, (7<<3)
+	li	r5, 0x85
+	bl	pci_read_cfg_byte
+	ori	r6, r3, 0x02
+	mr	r31, r6
+	li	r3,0
+	bl	pci_write_cfg_byte
+
+	/* COM1 as 3f8 */
+	outb	0x3f0, 0xe7
+	outb	0x3f1, 0xfe
+
+	/* COM2 as 2f8 */
+	outb	0x3f0, 0xe8
+	outb	0x3f1, 0xeb
+
+	/* Enable */
+	outb	0x3f0, 0xe2
+	inb	r3, 0x3f1
+	ori	r3, r3, 0x0c
+	outb	0x3f0, 0xe2
+	outbr	0x3f1, r3
+	
+	/* Disable configuration mode */
+	li	r3, 0
+	li	r4, (7<<3)
+	li	r5, 0x85
+	mr	r6, r31
+	bl	pci_write_cfg_byte
+
+	/* Set line control */
+	outb	UART(LINE_CONTROL), 0x83
+	outb	UART(DIVISOR_LATCH_LSB), 0x0c
+	outb	UART(DIVISOR_LATCH_MSB), 0x00
+	outb	UART(LINE_CONTROL), 0x3
+
+	mtlr	r29
+	blr
+
+		
+	.globl	new_reset
+	.globl	new_reset_end
+new_reset:
+	li	r0, 0x100
+	oris	r0, r0, 0xFFF0
+	mtlr	r0
+	blr
+	
+new_reset_end:	

+ 123 - 0
board/MAI/AmigaOneG3SE/cmd_boota.c

@@ -0,0 +1,123 @@
+#include <common.h>
+#include <command.h>
+#include <cmd_boota.h>
+#include "../disk/part_amiga.h"
+#include <asm/cache.h>
+
+
+#undef BOOTA_DEBUG
+
+#ifdef BOOTA_DEBUG
+#define PRINTF(fmt,args...)	printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+struct block_header {
+	u32 id;
+	u32 summed_longs;
+	s32 chk_sum;
+};
+
+extern block_dev_desc_t *ide_get_dev (int dev);
+extern struct bootcode_block *get_bootcode (block_dev_desc_t * dev_desc);
+extern int sum_block (struct block_header *header);
+
+struct bootcode_block bblk;
+
+int do_boota (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	unsigned char *load_address = (unsigned char *) CFG_LOAD_ADDR;
+	unsigned char *base_address;
+	unsigned long offset;
+
+	unsigned long part_number = 0;
+	block_dev_desc_t *boot_disk;
+	char *s;
+	struct bootcode_block *boot_code;
+
+	/* Get parameters */
+
+	switch (argc) {
+	case 2:
+		load_address = (unsigned char *) simple_strtol (argv[1], NULL, 16);
+		part_number = 0;
+		break;
+	case 3:
+		load_address = (unsigned char *) simple_strtol (argv[1], NULL, 16);
+		part_number = simple_strtol (argv[2], NULL, 16);
+		break;
+	}
+
+	base_address = load_address;
+
+	PRINTF ("Loading boot code from disk %d to %p\n", part_number,
+			load_address);
+
+	/* Find the appropriate disk device */
+	boot_disk = ide_get_dev (part_number);
+	if (!boot_disk) {
+		PRINTF ("Unknown disk %d\n", part_number);
+		return 1;
+	}
+
+	/* Find the bootcode block */
+	boot_code = get_bootcode (boot_disk);
+	if (!boot_code) {
+		PRINTF ("Not a bootable disk %d\n", part_number);
+		return 1;
+	}
+
+	/* Only use the offset from the first block */
+	offset = boot_code->load_data[0];
+	memcpy (load_address, &boot_code->load_data[1], 122 * 4);
+	load_address += 122 * 4;
+
+	/* Setup for the loop */
+	bblk.next = boot_code->next;
+	boot_code = &bblk;
+
+	/* Scan the chain, and copy the loader succesively into the destination area */
+	while (0xffffffff != boot_code->next) {
+		PRINTF ("Loading block %d\n", boot_code->next);
+
+		/* Load block */
+		if (1 !=
+			boot_disk->block_read (boot_disk->dev, boot_code->next, 1,
+								   (ulong *) & bblk)) {
+			PRINTF ("Read error\n");
+			return 1;
+		}
+
+		/* check sum */
+		if (sum_block ((struct block_header *) (ulong *) & bblk) != 0) {
+			PRINTF ("Checksum error\n");
+			return 1;
+		}
+
+		/* Ok, concatenate it to the already loaded code */
+		memcpy (load_address, boot_code->load_data, 123 * 4);
+		load_address += 123 * 4;
+	}
+
+	printf ("Bootcode loaded to %p (size %d)\n", base_address,
+			load_address - base_address);
+	printf ("Entry point at %p\n", base_address + offset);
+
+	flush_cache (base_address, load_address - base_address);
+
+
+	s = getenv ("autostart");
+	if (s && strcmp (s, "yes") == 0) {
+		DECLARE_GLOBAL_DATA_PTR;
+
+		void (*boot) (bd_t *, char *, block_dev_desc_t *);
+		char *args;
+
+		boot = (void (*)(bd_t *, char *, block_dev_desc_t *)) (base_address + offset);
+		boot (gd->bd, getenv ("amiga_bootargs"), boot_disk);
+	}
+
+
+	return 0;
+}

+ 33 - 0
board/MAI/AmigaOneG3SE/config.mk

@@ -0,0 +1,33 @@
+#
+# (C) Copyright 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+#
+# AmigaOneG3SE boards
+#
+
+X86EMU =  -I../bios_emulator/scitech/include -I../bios_emulator/scitech/src/x86emu
+
+TEXT_BASE = 0xfff00000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -Wa,-mregnames -DEASTEREGG $(X86EMU) #-DDEBUG
+

+ 886 - 0
board/MAI/AmigaOneG3SE/enet.c

@@ -0,0 +1,886 @@
+/*
+ * (C) Copyright 2002
+ * Adam Kowalczyk, ACK Software Controls Inc. akowalczyk@cogeco.ca
+ *
+ * Some portions taken from 3c59x.c Written 1996-1999 by Donald Becker.
+ *
+ * Outline of the program based on eepro100.c which is
+ *
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#include "articiaS.h"
+#include "memio.h"
+
+/* 3Com Ethernet PCI definitions*/
+
+// #define PCI_VENDOR_ID_3COM		0x10B7
+#define PCI_DEVICE_ID_3COM_3C905C	0x9200
+
+/* 3Com Commands, top 5 bits are command and bottom 11 bits are parameters */
+
+#define TotalReset 		(0<<11) 
+#define SelectWindow 		(1<<11)
+#define StartCoax 		(2<<11)
+#define RxDisable 		(3<<11) 
+#define RxEnable 		(4<<11) 
+#define RxReset 		(5<<11)
+#define UpStall 		(6<<11) 
+#define UpUnstall 		(6<<11)+1
+#define DownStall 		(6<<11)+2 
+#define DownUnstall 		(6<<11)+3
+#define RxDiscard 		(8<<11)
+#define TxEnable 		(9<<11)
+#define TxDisable 		(10<<11) 
+#define TxReset 		(11<<11)
+#define FakeIntr 		(12<<11) 
+#define AckIntr 		(13<<11) 
+#define SetIntrEnb 		(14<<11)
+#define SetStatusEnb 		(15<<11) 
+#define SetRxFilter 		(16<<11)
+#define SetRxThreshold 		(17<<11)
+#define SetTxThreshold 		(18<<11) 
+#define SetTxStart 		(19<<11)
+#define StartDMAUp 		(20<<11)
+#define StartDMADown 		(20<<11)+1
+#define StatsEnable		(21<<11)
+#define StatsDisable		(22<<11) 
+#define StopCoax 		(23<<11)
+#define SetFilterBit 		(25<<11)
+
+/* The SetRxFilter command accepts the following classes */
+
+#define RxStation 		1 
+#define RxMulticast		2 
+#define RxBroadcast		4 
+#define RxProm 			8
+
+/* 3Com status word defnitions */
+
+#define IntLatch 		0x0001
+#define HostError 		0x0002
+#define TxComplete 		0x0004
+#define TxAvailable 		0x0008
+#define RxComplete 		0x0010 
+#define RxEarly 		0x0020
+#define IntReq 			0x0040
+#define StatsFull 		0x0080
+#define DMADone 		(1<<8)
+#define DownComplete 		(1<<9) 
+#define UpComplete 		(1<<10)
+#define DMAInProgress 		(1<<11)			/* DMA controller is still busy.*/
+#define CmdInProgress 		(1<<12)           	/* EL3_CMD is still busy.*/
+
+/* Polling Registers */
+
+#define DnPoll			0x2d
+#define UpPoll			0x3d
+
+/* Register window 0 offets */
+
+#define Wn0EepromCmd 		10	          	/* Window 0: EEPROM command register. */
+#define Wn0EepromData 		12             		/* Window 0: EEPROM results register. */
+#define IntrStatus		0x0E	                /* Valid in all windows. */
+
+/* Register window 0 EEPROM bits */
+
+#define EEPROM_Read 		0x80
+#define EEPROM_WRITE 		0x40
+#define EEPROM_ERASE 		0xC0
+#define EEPROM_EWENB 		0x30            	/* Enable erasing/writing for 10 msec. */
+#define EEPROM_EWDIS 		0x00            	/* Disable EWENB before 10 msec timeout. */
+
+/* EEPROM locations. */
+
+#define PhysAddr01		0 
+#define PhysAddr23		1
+#define PhysAddr45		2 
+#define ModelID			3
+#define EtherLink3ID		7 
+#define IFXcvrIO		8 
+#define IRQLine			9
+#define NodeAddr01		10 
+#define NodeAddr23		11 
+#define NodeAddr45		12
+#define DriverTune		13 
+#define Checksum		15
+
+/* Register window 1 offsets, the window used in normal operation */
+
+#define TX_FIFO 		0x10  
+#define RX_FIFO 		0x10  
+#define RxErrors 		0x14
+#define RxStatus 		0x18  
+#define Timer			0x1A 
+#define TxStatus 		0x1B
+#define TxFree 			0x1C	 		/* Remaining free bytes in Tx buffer. */
+
+/* Register Window 2 */
+        
+#define Wn2_ResetOptions	12
+
+/* Register Window 3: MAC/config bits */
+
+#define Wn3_Config		0			/* Internal Configuration */
+#define Wn3_MAC_Ctrl		6
+#define Wn3_Options		8
+
+#define BFEXT(value, offset, bitcount)  					\
+    	((((unsigned long)(value)) >> (offset)) & ((1 << (bitcount)) - 1))
+
+#define BFINS(lhs, rhs, offset, bitcount)                                       \
+        (((lhs) & ~((((1 << (bitcount)) - 1)) << (offset))) |   		\
+        (((rhs) & ((1 << (bitcount)) - 1)) << (offset)))
+
+#define RAM_SIZE(v)             BFEXT(v, 0, 3)
+#define RAM_WIDTH(v)    	BFEXT(v, 3, 1)
+#define RAM_SPEED(v)    	BFEXT(v, 4, 2)
+#define ROM_SIZE(v)             BFEXT(v, 6, 2)
+#define RAM_SPLIT(v)    	BFEXT(v, 16, 2)
+#define XCVR(v)                 BFEXT(v, 20, 4)
+#define AUTOSELECT(v)   	BFEXT(v, 24, 1)
+
+/* Register Window 4: Xcvr/media bits */
+        
+#define Wn4_FIFODiag 		4
+#define Wn4_NetDiag 		6
+#define Wn4_PhysicalMgmt	8
+#define Wn4_Media 		10
+
+#define Media_SQE 		0x0008     		/* Enable SQE error counting for AUI. */
+#define Media_10TP 		0x00C0			/* Enable link beat and jabber for 10baseT. */
+#define Media_Lnk 		0x0080			/* Enable just link beat for 100TX/100FX. */
+#define Media_LnkBeat 		0x0800
+
+/* Register Window 7: Bus Master control */
+
+#define Wn7_MasterAddr 		0
+#define Wn7_MasterLen 		6
+#define Wn7_MasterStatus 	12
+
+/* Boomerang bus master control registers. */
+
+#define PktStatus 		0x20
+#define DownListPtr		0x24
+#define FragAddr 		0x28
+#define FragLen 		0x2c
+#define TxFreeThreshold 	0x2f
+#define UpPktStatus 		0x30
+#define UpListPtr 		0x38
+
+/* The Rx and Tx descriptor lists. */
+
+#define LAST_FRAG       0x80000000                      /* Last Addr/Len pair in descriptor. */
+#define DN_COMPLETE     0x00010000                      /* This packet has been downloaded */
+
+struct rx_desc_3com {
+        u32 next;                                       /* Last entry points to 0	   	*/
+        u32 status;					/* FSH -> Frame Start Header 		*/
+        u32 addr;                                       /* Up to 63 addr/len pairs possible 	*/
+        u32 length;                                     /* Set LAST_FRAG to indicate last pair	*/
+};
+
+/* Values for the Rx status entry. */
+
+#define RxDComplete		0x00008000
+#define RxDError		0x4000
+#define IPChksumErr		(1<<25) 
+#define TCPChksumErr		(1<<26) 
+#define UDPChksumErr		(1<<27)
+#define IPChksumValid		(1<<29) 
+#define TCPChksumValid		(1<<30)
+#define UDPChksumValid		(1<<31)
+
+struct tx_desc_3com {
+        u32 next;                                       /* Last entry points to 0		*/
+        u32 status;                                     /* bits 0:12 length, others see below	*/
+        u32 addr;
+        u32 length;
+};
+
+/* Values for the Tx status entry. */
+
+#define CRCDisable		0x2000
+#define TxDComplete		0x8000
+#define AddIPChksum		0x02000000
+#define AddTCPChksum		0x04000000
+#define AddUDPChksum		0x08000000
+#define TxIntrUploaded		0x80000000              /* IRQ when in FIFO, but maybe not sent. */
+
+/* XCVR Types */
+
+#define XCVR_10baseT		0
+#define XCVR_AUI		1 
+#define XCVR_10baseTOnly	2
+#define XCVR_10base2		3 
+#define XCVR_100baseTx		4
+#define XCVR_100baseFx		5
+#define XCVR_MII		6
+#define XCVR_NWAY		8
+#define XCVR_ExtMII		9
+#define XCVR_Default		10			/* I don't think this is correct -> should have been 0x10 if Auto Negotiate */
+
+struct descriptor {			    		/* A generic descriptor. */
+        u32 next;                                       /* Last entry points to 0	   	*/
+        u32 status;					/* FSH -> Frame Start Header 		*/
+        u32 addr;                                       /* Up to 63 addr/len pairs possible 	*/
+        u32 length;                                     /* Set LAST_FRAG to indicate last pair	*/
+};
+
+/* Misc. definitions */
+
+#define NUM_RX_DESC 		PKTBUFSRX * 10
+#define NUM_TX_DESC 		1            /* Number of TX descriptors   */
+
+#define TOUT_LOOP		1000000
+
+#define ETH_ALEN		6
+
+#define EL3WINDOW(dev, win_num) ETH_OUTW(dev, SelectWindow + (win_num), EL3_CMD)
+#define EL3_CMD 0x0e
+#define EL3_STATUS 0x0e
+
+
+#undef ETH_DEBUG
+
+#ifdef ETH_DEBUG
+#define PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+
+static struct rx_desc_3com *rx_ring;		 	/* RX descriptor ring         		*/
+static struct tx_desc_3com *tx_ring;		 	/* TX descriptor ring         		*/
+static u8 rx_buffer[NUM_RX_DESC][PKTSIZE_ALIGN];	/* storage for the incoming messages 	*/
+static int rx_next = 0;                      		/* RX descriptor ring pointer 		*/
+static int tx_next = 0;                      		/* TX descriptor ring pointer 		*/
+static int tx_threshold;
+
+static void  init_rx_ring(struct eth_device* dev);
+static void  purge_tx_ring(struct eth_device* dev);
+
+static void  read_hw_addr(struct eth_device* dev, bd_t * bis);
+
+static int eth_3com_init(struct eth_device* dev, bd_t *bis);
+static int eth_3com_send(struct eth_device* dev, volatile void *packet, int length);
+static int eth_3com_recv(struct eth_device* dev);
+static void eth_3com_halt(struct eth_device* dev);
+
+#define io_to_phys(a)	pci_io_to_phys((pci_dev_t)dev->priv, a)
+#define phys_to_io(a)	pci_phys_to_io((pci_dev_t)dev->priv, a)
+#define mem_to_phys(a)	pci_mem_to_phys((pci_dev_t)dev->priv, a)
+#define phys_to_mem(a)	pci_phys_to_mem((pci_dev_t)dev->priv, a)
+
+static inline int ETH_INL(struct eth_device* dev, u_long addr)
+{
+    __asm volatile ("eieio");
+	return le32_to_cpu(*(volatile u32 *)io_to_phys(addr + dev->iobase));
+}
+
+static inline int ETH_INW(struct eth_device* dev, u_long addr)
+{
+    __asm volatile ("eieio");
+	return le16_to_cpu(*(volatile u16 *)io_to_phys(addr + dev->iobase));
+}
+
+static inline int ETH_INB(struct eth_device* dev, u_long addr)
+{
+    __asm volatile ("eieio");
+	return *(volatile u8 *)io_to_phys(addr + dev->iobase);
+}
+
+static inline void ETH_OUTB(struct eth_device* dev, int command, u_long addr)
+{
+	*(volatile u8 *)io_to_phys(addr + dev->iobase) = command;
+    __asm volatile ("eieio");
+}
+
+static inline void ETH_OUTW(struct eth_device* dev, int command, u_long addr)
+{
+	*(volatile u16 *)io_to_phys(addr + dev->iobase) = cpu_to_le16(command);
+    __asm volatile ("eieio");
+}
+
+static inline void ETH_OUTL(struct eth_device* dev, int command, u_long addr)
+{
+	*(volatile u32 *)io_to_phys(addr + dev->iobase) = cpu_to_le32(command);
+    __asm volatile ("eieio");
+}
+
+static inline int ETH_STATUS(struct eth_device* dev)
+{
+    __asm volatile ("eieio");
+	return le16_to_cpu(*(volatile u16 *)io_to_phys(EL3_STATUS + dev->iobase));
+}
+
+static inline void ETH_CMD(struct eth_device* dev, int command)
+{
+	*(volatile u16 *)io_to_phys(EL3_CMD + dev->iobase) = cpu_to_le16(command); 
+    __asm volatile ("eieio");
+}
+
+/* Command register is always in the same spot in all the register windows */
+/* This function issues a command and waits for it so complete by checking the CmdInProgress bit */
+
+static int issue_and_wait(struct eth_device* dev, int command)
+{
+
+        int i, status;
+
+	ETH_CMD(dev, command);
+        for (i = 0; i < 2000; i++) {
+                status = ETH_STATUS(dev);
+		//printf ("Issue: status 0x%4x.\n", status);
+		if (!(status & CmdInProgress))
+                        return 1;
+        }
+
+        /* OK, that didn't work.  Do it the slow way.  One second */
+        for (i = 0; i < 100000; i++) {
+                status = ETH_STATUS(dev);
+		//printf ("Issue: status 0x%4x.\n", status);
+                        return 1;
+                udelay(10);
+        }
+        PRINTF("Ethernet command: 0x%4x did not complete! Status: 0x%4x\n", command, ETH_STATUS(dev) );
+	return 0;
+}
+
+/* Determine network media type and set up 3com accordingly           */
+/* I think I'm going to start with something known first like 10baseT */
+
+static int auto_negotiate(struct eth_device* dev)
+{
+    int i;
+
+    EL3WINDOW(dev, 1);
+
+    // Wait for Auto negotiation to complete
+    for (i = 0; i <= 1000; i++)
+    {
+	if (ETH_INW(dev, 2) & 0x04)
+	    break;
+	udelay(100);
+
+	if (i == 1000)
+	{
+	    PRINTF("Error: Auto negotiation failed\n");
+	    return 0;
+	}
+    }
+    
+
+
+    return 1;
+}
+
+void eth_interrupt(struct eth_device *dev)
+{
+    u16 status = ETH_STATUS(dev);
+
+    printf("eth0: status = 0x%04x\n", status);
+
+    if (!(status & IntLatch))
+	return;
+
+    if (status & (1<<6))
+    {
+	ETH_CMD(dev, AckIntr | (1<<6));
+	printf("Acknowledged Interrupt command\n");
+    }
+
+    if (status & DownComplete)
+    {
+	ETH_CMD(dev, AckIntr | DownComplete);
+	printf("Acknowledged DownComplete\n");
+    }
+
+    if (status & UpComplete)
+    {
+	ETH_CMD(dev, AckIntr | UpComplete);
+	printf("Acknowledged UpComplete\n");
+    }
+
+    ETH_CMD(dev, AckIntr | IntLatch);
+    printf("Acknowledged IntLatch\n");
+}
+
+int eth_3com_initialize(bd_t *bis)
+{
+        u32 eth_iobase = 0, status;
+        int card_number = 0, ret;
+        struct eth_device* dev;
+        pci_dev_t devno;
+	char *s;
+
+	s = getenv("3com_base");
+
+	/* Find ethernet controller on the PCI bus */
+
+	if ((devno = pci_find_device(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905C, 0)) < 0)
+	{
+		PRINTF("Error: Cannot find the ethernet device on the PCI bus\n");
+		goto Done;
+	}
+
+	if (s)
+	{
+	    unsigned long base = atoi(s);
+	    pci_write_config_dword(devno, PCI_BASE_ADDRESS_0, base | 0x01);
+	}
+
+	ret = pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &eth_iobase);
+        eth_iobase &= ~0xf;
+
+	PRINTF("eth: 3Com Found at Address: 0x%x\n", eth_iobase);
+  
+	pci_write_config_dword(devno, PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+	 /* Check if I/O accesses and Bus Mastering are enabled */
+
+	ret = pci_read_config_dword(devno, PCI_COMMAND, &status);
+
+	if (!(status & PCI_COMMAND_IO))
+	{
+		printf("Error: Cannot enable IO access.\n");
+		goto Done;
+	}
+
+	if (!(status & PCI_COMMAND_MEMORY))
+	{
+		printf("Error: Cannot enable MEMORY access.\n");
+		goto Done;
+	}
+
+	if (!(status & PCI_COMMAND_MASTER))
+	{
+		printf("Error: Cannot enable Bus Mastering.\n");
+		goto Done;
+	}
+
+        dev = (struct eth_device*) malloc(sizeof(*dev)); //struct eth_device));
+
+        sprintf(dev->name, "3Com 3c920c#%d", card_number);
+        dev->iobase = eth_iobase;
+        dev->priv   = (void*) devno;
+        dev->init   = eth_3com_init;
+        dev->halt   = eth_3com_halt;
+        dev->send   = eth_3com_send;
+        dev->recv   = eth_3com_recv;
+
+        eth_register(dev);
+
+/* 	{ */
+/* 	    char interrupt; */
+/* 	    devno = pci_find_device(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905C, 0); */
+/* 	    pci_read_config_byte(devno, PCI_INTERRUPT_LINE, &interrupt); */
+	    
+/* 	    printf("Installing eth0 interrupt handler to %d\n", interrupt); */
+/* 	    irq_install_handler(interrupt, eth_interrupt, dev); */
+/* 	} */
+
+        card_number++;
+
+	/* Set the latency timer for value */
+	s = getenv("3com_latency");
+	if (s)
+	{
+	    ret = pci_write_config_byte(devno, PCI_LATENCY_TIMER, (unsigned char)atoi(s));
+	}
+	else ret = pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x0a);
+
+	read_hw_addr(dev, bis); 				/* get the MAC address from Window 2*/
+
+	/* Reset the ethernet controller */
+
+	PRINTF ("Issuing reset command....\n");
+	if (!issue_and_wait(dev, TotalReset))
+	{
+		printf("Error: Cannot reset ethernet controller.\n");
+		goto Done;
+	}
+	else
+		PRINTF ("Ethernet controller reset.\n");
+
+	/* allocate memory for rx and tx rings */
+
+	if(!(rx_ring = memalign(sizeof(struct rx_desc_3com) * NUM_RX_DESC, 16)))
+	{
+		PRINTF ("Cannot allocate memory for RX_RING.....\n");
+		goto Done;
+	}
+	
+	if (!(tx_ring = memalign(sizeof(struct tx_desc_3com) * NUM_TX_DESC, 16)))
+	{
+		PRINTF ("Cannot allocate memory for TX_RING.....\n");
+		goto Done;
+	}
+	
+Done:
+	return status;
+}
+
+
+static int eth_3com_init(struct eth_device* dev, bd_t *bis)
+{
+	int i, status = 0;
+	int tx_cur, loop;
+	u16 status_enable, intr_enable;
+	struct descriptor *ias_cmd;
+
+	/* Determine what type of network the machine is connected to	*/
+	/* presently drops the connect to 10Mbps			*/	     
+
+	if (!auto_negotiate(dev))
+	{
+		printf("Error: Cannot determine network media.\n");
+		goto Done;
+	}
+
+        issue_and_wait(dev, TxReset);
+        issue_and_wait(dev, RxReset|0x04);
+
+        /* Switch to register set 7 for normal use. */
+        EL3WINDOW(dev, 7);
+
+	/* Initialize Rx and Tx rings */
+
+	init_rx_ring(dev);
+	purge_tx_ring(dev);
+
+ 	ETH_CMD(dev, SetRxFilter | RxStation | RxBroadcast | RxProm);
+
+        issue_and_wait(dev,SetTxStart|0x07ff);
+
+        /* Below sets which indication bits to be seen. */
+
+        status_enable = SetStatusEnb | HostError | DownComplete | UpComplete | (1<<6);
+        ETH_CMD(dev, status_enable);
+
+	/* Below sets no bits are to cause an interrupt since this is just polling */
+
+        intr_enable   = SetIntrEnb;
+//	intr_enable = SetIntrEnb | (1<<9) | (1<<10) | (1<<6);
+        ETH_CMD(dev, intr_enable);
+	ETH_OUTB(dev, 127, UpPoll);
+
+        /* Ack all pending events, and set active indicator mask */
+
+        ETH_CMD(dev, AckIntr | IntLatch | TxAvailable | RxEarly | IntReq);
+        ETH_CMD(dev, intr_enable);
+
+	/* Tell the adapter where the RX ring is located */
+
+	issue_and_wait(dev,UpStall);				/* Stall and set the UplistPtr 		*/
+	ETH_OUTL(dev, (u32)&rx_ring[rx_next], UpListPtr);
+        ETH_CMD(dev, RxEnable); 				/* Enable the receiver. 		*/
+	issue_and_wait(dev,UpUnstall);
+
+	/* Send the Individual Address Setup frame */
+
+	tx_cur       = tx_next;
+	tx_next      = ((tx_next+1) % NUM_TX_DESC);
+
+	ias_cmd             = (struct descriptor *)&tx_ring[tx_cur];
+	ias_cmd->status     = cpu_to_le32(1<<31);		/* set DnIndicate bit. 			*/
+	ias_cmd->next       = 0;
+	ias_cmd->addr       = cpu_to_le32((u32)&bis->bi_enetaddr[0]);
+	ias_cmd->length     = cpu_to_le32(6 | LAST_FRAG);
+
+	/* Tell the adapter where the TX ring is located */
+
+        ETH_CMD(dev, TxEnable); 				/* Enable transmitter. 			*/
+	issue_and_wait(dev, DownStall);				/* Stall and set the DownListPtr. 	*/
+	ETH_OUTL(dev, (u32)&tx_ring[tx_cur], DownListPtr);
+	issue_and_wait(dev, DownUnstall);
+	for (i=0; !(ETH_STATUS(dev) & DownComplete); i++)
+	{
+		if (i >= TOUT_LOOP)
+		{
+			PRINTF("TX Ring status (Init):  0x%4x\n", le32_to_cpu(tx_ring[tx_cur].status));
+			PRINTF("ETH_STATUS: 0x%x\n", ETH_STATUS(dev));
+			goto Done;
+		}
+	}
+	if (ETH_STATUS(dev) & DownComplete)			/* If DownLoad Complete ACK the bit 	*/
+	{
+        	ETH_CMD(dev, AckIntr | DownComplete);		/* acknowledge the indication bit	*/
+ 		issue_and_wait(dev, DownStall);			/* stall and clear DownListPtr 		*/
+		ETH_OUTL(dev, 0, DownListPtr);
+		issue_and_wait(dev, DownUnstall);
+	}
+	status = 1;
+	    
+Done:
+	return status;
+}
+
+int eth_3com_send(struct eth_device* dev, volatile void *packet, int length)
+{
+	int i, status = 0;
+	int tx_cur;
+
+	if (length <= 0)
+	{
+		PRINTF("eth: bad packet size: %d\n", length);
+		goto Done;
+	}
+
+	tx_cur  = tx_next;
+	tx_next = (tx_next+1) % NUM_TX_DESC;
+
+	tx_ring[tx_cur].status  = cpu_to_le32(1<<31);		/* set DnIndicate bit 			*/
+	tx_ring[tx_cur].next    = 0;
+	tx_ring[tx_cur].addr    = cpu_to_le32(((u32) packet));
+	tx_ring[tx_cur].length  = cpu_to_le32(length | LAST_FRAG);
+
+	/* Send the packet */
+
+	issue_and_wait(dev, DownStall);				/* stall and set the DownListPtr 	*/
+	ETH_OUTL(dev, (u32) &tx_ring[tx_cur], DownListPtr);
+	issue_and_wait(dev, DownUnstall);
+
+	for (i=0; !(ETH_STATUS(dev) & DownComplete); i++)
+	{
+		if (i >= TOUT_LOOP)
+		{
+			PRINTF("TX Ring status (send): 0x%4x\n", le32_to_cpu(tx_ring[tx_cur].status));
+			goto Done;
+		}
+	}
+	if (ETH_STATUS(dev) & DownComplete)			/* If DownLoad Complete ACK the bit 	*/
+	{
+        	ETH_CMD(dev, AckIntr | DownComplete);		/* acknowledge the indication bit	*/
+ 		issue_and_wait(dev, DownStall);			/* stall and clear DownListPtr 		*/
+		ETH_OUTL(dev, 0, DownListPtr);
+		issue_and_wait(dev, DownUnstall);
+	}
+	status=1;
+ Done:
+	return status;
+}
+
+void PrintPacket (uchar *packet, int length)
+{
+int loop;
+uchar *ptr;
+
+	printf ("Printing packet of length %x.\n\n", length);
+	ptr = packet;
+	for (loop = 1; loop <= length; loop++)
+	{
+		printf ("%2x ", *ptr++);
+		if ((loop % 40)== 0)
+			printf ("\n");
+	}
+}
+
+int eth_3com_recv(struct eth_device* dev)
+{
+	u16 stat = 0;
+	u32 status;
+	int rx_prev, length = 0;
+
+	while (!(ETH_STATUS(dev) & UpComplete))			/* wait on receipt of packet 	*/
+		;
+
+	status = le32_to_cpu(rx_ring[rx_next].status);		/* packet status		*/
+
+	while (status & (1<<15))
+	{		
+		/* A packet has been received */
+
+		if (status & (1<<15))		
+		{
+			/* A valid frame received  */
+			
+			length = le32_to_cpu(rx_ring[rx_next].status) & 0x1fff;		/* length is in bits 0 - 12 	*/
+			
+			/* Pass the packet up to the protocol layers */
+
+			NetReceive((uchar *)le32_to_cpu(rx_ring[rx_next].addr), length);
+			rx_ring[rx_next].status = 0;					/* clear the status word 	*/
+			ETH_CMD(dev, AckIntr | UpComplete);
+			issue_and_wait(dev, UpUnstall);
+		}
+		else
+		if (stat & HostError)
+		{
+			/* There was an error */
+
+			printf("Rx error status:  0x%4x\n", stat);
+			init_rx_ring(dev);
+			goto Done;
+		}
+
+		rx_prev = rx_next;
+		rx_next = (rx_next + 1) % NUM_RX_DESC;
+		stat = ETH_STATUS(dev);					/* register status 	*/
+		status = le32_to_cpu(rx_ring[rx_next].status);		/* packet status 	*/
+	}
+
+Done:
+	return length;
+}
+
+void eth_3com_halt(struct eth_device* dev)
+{
+	if (!(dev->iobase)) 
+	{
+		goto Done;
+	}
+
+	issue_and_wait(dev, DownStall);		/* shut down transmit and receive */
+	issue_and_wait(dev, UpStall);
+	issue_and_wait(dev, RxDisable);
+	issue_and_wait(dev, TxDisable);
+
+//	free(tx_ring);				/* release memory allocated to the DPD and UPD rings */
+//	free(rx_ring);
+
+Done:
+	return;
+}
+
+static void init_rx_ring(struct eth_device* dev) 
+{
+	int i;
+
+	PRINTF("Initializing rx_ring. rx_buffer = %p\n", rx_buffer);
+	issue_and_wait(dev, UpStall);
+
+	for (i = 0; i < NUM_RX_DESC; i++)
+	{
+		rx_ring[i].next    = cpu_to_le32(((u32) &rx_ring[(i+1) % NUM_RX_DESC]));
+		rx_ring[i].status  = 0;
+		rx_ring[i].addr    = cpu_to_le32(((u32) &rx_buffer[i][0]));
+		rx_ring[i].length  = cpu_to_le32(PKTSIZE_ALIGN | LAST_FRAG);
+	}
+	rx_next = 0;
+}
+
+static void purge_tx_ring(struct eth_device* dev) 
+{
+	int i;
+
+	PRINTF("Purging tx_ring.\n");
+
+	tx_next      = 0;
+
+	for (i = 0; i < NUM_TX_DESC; i++)
+	{
+		tx_ring[i].next    = 0;
+		tx_ring[i].status  = 0;
+		tx_ring[i].addr    = 0;
+		tx_ring[i].length  = 0;
+	}
+}
+
+static void read_hw_addr(struct eth_device* dev, bd_t *bis) 
+{
+	u8 hw_addr[ETH_ALEN];
+	unsigned int eeprom[0x40];
+	unsigned int checksum = 0;
+	int i, j, timer;
+
+        /* Read the station address from the EEPROM. */
+
+        EL3WINDOW(dev, 0);
+	for (i = 0; i < 0x40; i++)
+	{
+        	ETH_OUTW(dev, EEPROM_Read + i, Wn0EepromCmd);
+                /* Pause for at least 162 us. for the read to take place. */
+                for (timer = 10; timer >= 0; timer--) 
+		{
+                	udelay(162);
+                        if ((ETH_INW(dev, Wn0EepromCmd) & 0x8000) == 0)
+                        	break;
+                }
+                eeprom[i] = ETH_INW(dev, Wn0EepromData);
+        }
+
+	/* Checksum calculation.  I'm not sure about this part and there seems to be a bug on the 3com side of things */
+
+        for (i = 0; i < 0x21; i++)
+                checksum  ^= eeprom[i];
+        checksum = (checksum ^ (checksum >> 8)) & 0xff;
+
+        if (checksum != 0xbb)
+                printf(" *** INVALID EEPROM CHECKSUM %4.4x *** \n", checksum);
+
+        for (i = 0, j = 0; i < 3; i++)
+	{
+		hw_addr[j++] = (u8)((eeprom[i+10] >> 8) & 0xff);
+		hw_addr[j++] = (u8)(eeprom[i+10] & 0xff);
+	}
+
+	/*  MAC Address is in window 2, write value from EEPROM to window 2 */
+
+        EL3WINDOW(dev, 2);
+        for (i = 0; i < 6; i++)
+                ETH_OUTB(dev, hw_addr[i], i);
+
+	for (j = 0; j < ETH_ALEN; j+=2)
+	{
+		hw_addr[j]   = (u8)(ETH_INW(dev, j) & 0xff);
+		hw_addr[j+1] = (u8)((ETH_INW(dev, j) >> 8) & 0xff);
+	}
+
+	for (i=0;i<ETH_ALEN;i++) 
+	{
+		if (hw_addr[i] != bis->bi_enetaddr[i]) 
+		{
+/* 			printf("Warning: HW address don't match:\n"); */
+/* 			printf("Address in 3Com Window 2 is         " */
+/* 			       "%02X:%02X:%02X:%02X:%02X:%02X\n", */
+/* 			       hw_addr[0], hw_addr[1], hw_addr[2], */
+/* 			       hw_addr[3], hw_addr[4], hw_addr[5]); */
+/* 			printf("Address used by U-Boot is " */
+/* 			       "%02X:%02X:%02X:%02X:%02X:%02X\n", */
+/* 			       bis->bi_enetaddr[0], bis->bi_enetaddr[1],  */
+/* 			       bis->bi_enetaddr[2], bis->bi_enetaddr[3],  */
+/* 			       bis->bi_enetaddr[4], bis->bi_enetaddr[5]); */
+/* 			goto Done; */
+		    char buffer[256];
+		    if (bis->bi_enetaddr[0] == 0 && bis->bi_enetaddr[1] == 0 &&
+			bis->bi_enetaddr[2] == 0 && bis->bi_enetaddr[3] == 0 &&
+			bis->bi_enetaddr[4] == 0 && bis->bi_enetaddr[5] == 0)
+		    {
+
+			sprintf(buffer, "%02X:%02X:%02X:%02X:%02X:%02X", 
+				hw_addr[0], hw_addr[1], hw_addr[2], 
+				hw_addr[3], hw_addr[4], hw_addr[5]); 
+			setenv("ethaddr", buffer);
+		    }
+		}
+	}
+
+	for(i=0; i<ETH_ALEN; i++) dev->enetaddr[i] = hw_addr[i];
+
+Done:
+	return;
+}
+

+ 35 - 0
board/MAI/AmigaOneG3SE/flash.c

@@ -0,0 +1,35 @@
+#include <common.h>
+#include <flash.h>
+
+flash_info_t    flash_info[CFG_MAX_FLASH_BANKS];
+
+
+unsigned long flash_init(void)
+{
+    int i;
+
+    for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
+    {
+	flash_info[i].flash_id = FLASH_UNKNOWN;
+	flash_info[i].sector_count = 0;
+	flash_info[i].size = 0;
+    }
+
+
+    return 1;
+}
+
+int flash_erase(flash_info_t *info, int s_first, int s_last)
+{
+    return 1;
+}
+
+void flash_print_info(flash_info_t *info)
+{
+    printf("No flashrom installed\n");
+}
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+    return 0;
+}

+ 652 - 0
board/MAI/AmigaOneG3SE/flash_new.c

@@ -0,0 +1,652 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <flash.h>
+#include <asm/io.h>
+#include "memio.h" 
+
+/*---------------------------------------------------------------------*/
+#undef DEBUG_FLASH
+//#define DEBUG_FLASH
+
+#ifdef DEBUG_FLASH
+#define DEBUGF(fmt,args...) printf(fmt ,##args)
+#else
+#define DEBUGF(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+flash_info_t	flash_info[CFG_MAX_FLASH_BANKS];
+
+static ulong flash_get_size (ulong addr, flash_info_t *info);
+static int flash_get_offsets (ulong base, flash_info_t *info);
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+static void flash_reset (ulong addr);
+
+int flash_xd_nest;
+
+static void flash_to_xd(void)
+{
+    unsigned char x;
+
+    flash_xd_nest ++;
+
+    if (flash_xd_nest == 1)
+    {
+	DEBUGF("Flash on XD\n");
+	x = pci_read_cfg_byte(0, 0, 0x74);
+	pci_write_cfg_byte(0, 0, 0x74, x|1);
+    }
+}
+
+static void flash_to_mem(void)
+{
+    unsigned char x;
+
+    flash_xd_nest --;
+   
+    if (flash_xd_nest == 0)
+    {
+	DEBUGF("Flash on memory bus\n");
+	x = pci_read_cfg_byte(0, 0, 0x74);
+	pci_write_cfg_byte(0, 0, 0x74, x&0xFE);
+    }
+}
+
+unsigned long flash_init_old(void)
+{
+    int i;
+
+    for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
+    {
+	flash_info[i].flash_id = FLASH_UNKNOWN;
+	flash_info[i].sector_count = 0;
+	flash_info[i].size = 0;
+    }
+
+
+    return 1;
+}
+
+unsigned long flash_init (void)
+{
+	unsigned int i;
+	unsigned long flash_size = 0;
+
+	flash_xd_nest = 0;
+
+	flash_to_xd();
+
+	/* Init: no FLASHes known */
+	for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+		flash_info[i].flash_id = FLASH_UNKNOWN;
+		flash_info[i].sector_count = 0;
+		flash_info[i].size = 0;
+	}
+
+	DEBUGF("\n## Get flash size @ 0x%08x\n", CFG_FLASH_BASE);
+
+	flash_size = flash_get_size (CFG_FLASH_BASE, flash_info);
+
+	DEBUGF("## Flash bank size: %08lx\n", flash_size);
+
+	if (flash_size) {
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE && \
+    CFG_MONITOR_BASE < CFG_FLASH_BASE + CFG_FLASH_MAX_SIZE
+		/* monitor protection ON by default */
+		flash_protect(FLAG_PROTECT_SET,
+			      CFG_MONITOR_BASE,
+			      CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1,
+			      &flash_info[0]);
+#endif
+
+#ifdef CFG_ENV_IS_IN_FLASH
+		/* ENV protection ON by default */
+		flash_protect(FLAG_PROTECT_SET,
+			      CFG_ENV_ADDR,
+			      CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
+			      &flash_info[0]);
+#endif
+
+	} else {
+		puts ("Warning: the BOOT Flash is not initialised !");
+	}
+
+	flash_to_mem();
+
+	return flash_size;
+}
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+static ulong flash_get_size (ulong addr, flash_info_t *info)
+{
+	short i;
+	uchar value;
+	uchar *x = (uchar *)addr;
+
+	flash_to_xd();
+
+	/* Write auto select command: read Manufacturer ID */
+	x[0x0555] =  0xAA;
+	__asm volatile ("sync\n eieio");
+	x[0x02AA] =  0x55;
+	__asm volatile ("sync\n eieio");
+	x[0x0555] =  0x90;
+	__asm volatile ("sync\n eieio");
+
+	value = x[0];
+	__asm volatile ("sync\n eieio");
+
+	DEBUGF("Manuf. ID @ 0x%08lx: 0x%08x\n", (ulong)addr, value);
+
+	switch (value | (value << 16)) {
+		case AMD_MANUFACT:
+			info->flash_id = FLASH_MAN_AMD;
+			break;
+
+		case FUJ_MANUFACT:
+			info->flash_id = FLASH_MAN_FUJ;
+			break;
+
+		case STM_MANUFACT:
+			info->flash_id = FLASH_MAN_STM;
+			break;
+
+		default:
+			info->flash_id = FLASH_UNKNOWN;
+			info->sector_count = 0;
+			info->size = 0;
+			flash_reset (addr);
+			return 0;
+	}
+
+	value = x[1];
+	__asm volatile ("sync\n eieio");
+
+	DEBUGF("Device ID @ 0x%08lx: 0x%08x\n", addr+1, value);
+
+	switch (value) {
+		case AMD_ID_F040B:
+			DEBUGF("Am29F040B\n");
+			info->flash_id += FLASH_AM040;
+			info->sector_count = 8;
+			info->size = 0x00080000;
+			break;			/* => 512 kB		*/
+
+		case AMD_ID_LV040B:
+			DEBUGF("Am29LV040B\n");
+			info->flash_id += FLASH_AM040;
+			info->sector_count = 8;
+			info->size = 0x00080000;
+			break;			/* => 512 kB		*/
+
+		case AMD_ID_LV400T:
+			DEBUGF("Am29LV400T\n");
+			info->flash_id += FLASH_AM400T;
+			info->sector_count = 11;
+			info->size = 0x00100000;
+			break;			/* => 1 MB		*/
+
+		case AMD_ID_LV400B:
+			DEBUGF("Am29LV400B\n");
+			info->flash_id += FLASH_AM400B;
+			info->sector_count = 11;
+			info->size = 0x00100000;
+			break;			/* => 1 MB		*/
+
+		case AMD_ID_LV800T:
+			DEBUGF("Am29LV800T\n");
+			info->flash_id += FLASH_AM800T;
+			info->sector_count = 19;
+			info->size = 0x00200000;
+			break;			/* => 2 MB		*/
+
+		case AMD_ID_LV800B:
+			DEBUGF("Am29LV400B\n");
+			info->flash_id += FLASH_AM800B;
+			info->sector_count = 19;
+			info->size = 0x00200000;
+			break;			/* => 2 MB		*/
+
+		case AMD_ID_LV160T:
+			DEBUGF("Am29LV160T\n");
+			info->flash_id += FLASH_AM160T;
+			info->sector_count = 35;
+			info->size = 0x00400000;
+			break;			/* => 4 MB		*/
+
+		case AMD_ID_LV160B:
+			DEBUGF("Am29LV160B\n");
+			info->flash_id += FLASH_AM160B;
+			info->sector_count = 35;
+			info->size = 0x00400000;
+			break;			/* => 4 MB		*/
+
+		case AMD_ID_LV320T:
+			DEBUGF("Am29LV320T\n");
+			info->flash_id += FLASH_AM320T;
+			info->sector_count = 67;
+			info->size = 0x00800000;
+			break;			/* => 8 MB		*/
+
+#if 0
+		/* Has the same ID as AMD_ID_LV320T, to be fixed */
+		case AMD_ID_LV320B:
+			DEBUGF("Am29LV320B\n");
+			info->flash_id += FLASH_AM320B;
+			info->sector_count = 67;
+			info->size = 0x00800000;
+			break;			/* => 8 MB		*/
+#endif
+
+		case AMD_ID_LV033C:
+			DEBUGF("Am29LV033C\n");
+			info->flash_id += FLASH_AM033C;
+			info->sector_count = 64;
+			info->size = 0x01000000;
+			break;			/* => 16Mb		*/
+
+		case STM_ID_F040B:
+			DEBUGF("M29F040B\n");
+			info->flash_id += FLASH_AM040;
+			info->sector_count = 8;
+			info->size = 0x00080000;
+			break;			/* => 512 kB		*/
+
+		default:
+			info->flash_id = FLASH_UNKNOWN;
+			flash_reset (addr);
+			flash_to_mem();
+			return (0);		/* => no or unknown flash */
+
+	}
+
+	if (info->sector_count > CFG_MAX_FLASH_SECT) {
+		printf ("** ERROR: sector count %d > max (%d) **\n",
+			info->sector_count, CFG_MAX_FLASH_SECT);
+		info->sector_count = CFG_MAX_FLASH_SECT;
+	}
+
+	if (! flash_get_offsets (addr, info)) {
+		flash_reset (addr);
+		flash_to_mem();
+		return 0;
+	}
+
+	/* check for protected sectors */
+	for (i = 0; i < info->sector_count; i++) {
+		/* read sector protection at sector address, (A7 .. A0) = 0x02 */
+		/* D0 = 1 if protected */
+		value = in8(info->start[i] + 2);
+		iobarrier_rw();
+		info->protect[i] = (value & 1) != 0;
+	}
+
+	/*
+	 * Reset bank to read mode
+	 */
+	flash_reset (addr);
+
+	flash_to_mem();
+
+	return (info->size);
+}
+
+static int flash_get_offsets (ulong base, flash_info_t *info)
+{
+	unsigned int i;
+
+	switch (info->flash_id & FLASH_TYPEMASK) {
+		case FLASH_AM040:
+			/* set sector offsets for uniform sector type	*/
+			for (i = 0; i < info->sector_count; i++) {
+				info->start[i] = base + i * info->size /
+				                            info->sector_count;
+			}
+			break;
+		default:
+			return 0;
+	}
+
+	return 1;
+}
+
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+	volatile ulong addr = info->start[0];
+	int flag, prot, sect, l_sect;
+	ulong start, now, last;
+
+	flash_to_xd();
+
+	if (s_first < 0 || s_first > s_last) {
+		if (info->flash_id == FLASH_UNKNOWN) {
+			printf ("- missing\n");
+		} else {
+			printf ("- no sectors to erase\n");
+		}
+		flash_to_mem();
+		return 1;
+	}
+
+	if (info->flash_id == FLASH_UNKNOWN) {
+		printf ("Can't erase unknown flash type %08lx - aborted\n",
+			info->flash_id);
+		flash_to_mem();
+		return 1;
+	}
+
+	prot = 0;
+	for (sect=s_first; sect<=s_last; ++sect) {
+		if (info->protect[sect]) {
+			prot++;
+		}
+	}
+
+	if (prot) {
+		printf ("- Warning: %d protected sectors will not be erased!\n",
+			prot);
+	} else {
+		printf ("\n");
+	}
+
+	l_sect = -1;
+
+	/* Disable interrupts which might cause a timeout here */
+	flag = disable_interrupts();
+
+	out8(addr + 0x555, 0xAA);
+	iobarrier_rw();
+	out8(addr + 0x2AA, 0x55);
+	iobarrier_rw();
+	out8(addr + 0x555, 0x80);
+	iobarrier_rw();
+	out8(addr + 0x555, 0xAA);
+	iobarrier_rw();
+	out8(addr + 0x2AA, 0x55);
+	iobarrier_rw();
+
+	/* Start erase on unprotected sectors */
+	for (sect = s_first; sect<=s_last; sect++) {
+		if (info->protect[sect] == 0) {	/* not protected */
+			addr = info->start[sect];
+			out8(addr, 0x30);
+			iobarrier_rw();
+			l_sect = sect;
+		}
+	}
+
+	/* re-enable interrupts if necessary */
+	if (flag)
+		enable_interrupts();
+
+	/* wait at least 80us - let's wait 1 ms */
+	udelay (1000);
+
+	/*
+	 * We wait for the last triggered sector
+	 */
+	if (l_sect < 0)
+		goto DONE;
+
+	start = get_timer (0);
+	last  = start;
+	addr = info->start[l_sect];
+
+	DEBUGF ("Start erase timeout: %d\n", CFG_FLASH_ERASE_TOUT);
+
+	while ((in8(addr) & 0x80) != 0x80) {
+		if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+			printf ("Timeout\n");
+			flash_reset (info->start[0]);
+			flash_to_mem();
+			return 1;
+		}
+		/* show that we're waiting */
+		if ((now - last) > 1000) {	/* every second */
+			putc ('.');
+			last = now;
+		}
+		iobarrier_rw();
+	}
+
+DONE:
+	/* reset to read mode */
+	flash_reset (info->start[0]);
+	flash_to_mem();
+
+	printf (" done\n");
+	return 0;
+}
+
+/*
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+	ulong cp, wp, data;
+	int i, l, rc;
+
+	flash_to_xd();
+
+	wp = (addr & ~3);	/* get lower word aligned address */
+
+	/*
+	 * handle unaligned start bytes
+	 */
+	if ((l = addr - wp) != 0) {
+		data = 0;
+		for (i=0, cp=wp; i<l; ++i, ++cp) {
+			data = (data << 8) | (*(uchar *)cp);
+		}
+		for (; i<4 && cnt>0; ++i) {
+			data = (data << 8) | *src++;
+			--cnt;
+			++cp;
+		}
+		for (; cnt==0 && i<4; ++i, ++cp) {
+			data = (data << 8) | (*(uchar *)cp);
+		}
+
+		if ((rc = write_word(info, wp, data)) != 0) {
+		        flash_to_mem();
+			return (rc);
+		}
+		wp += 4;
+	}
+
+	/*
+	 * handle word aligned part
+	 */
+	while (cnt >= 4) {
+		data = 0;
+		for (i=0; i<4; ++i) {
+			data = (data << 8) | *src++;
+		}
+		if ((rc = write_word(info, wp, data)) != 0) {
+		        flash_to_mem();
+			return (rc);
+		}
+		wp  += 4;
+		cnt -= 4;
+	}
+
+	if (cnt == 0) {
+		flash_to_mem();
+		return (0);
+	}
+
+	/*
+	 * handle unaligned tail bytes
+	 */
+	data = 0;
+	for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+		data = (data << 8) | *src++;
+		--cnt;
+	}
+	for (; i<4; ++i, ++cp) {
+		data = (data << 8) | (*(uchar *)cp);
+	}
+
+
+	flash_to_mem();
+	return (write_word(info, wp, data));
+}
+
+/*
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+	volatile ulong addr = info->start[0];
+	ulong start;
+	int i;
+
+	flash_to_xd();
+
+	/* Check if Flash is (sufficiently) erased */
+	if ((in32(dest) & data) != data) {
+		flash_to_mem();
+		return (2);
+	}
+
+	/* write each byte out */
+	for (i = 0; i < 4; i++) {
+		char *data_ch = (char *)&data;
+		int flag = disable_interrupts();
+
+		out8(addr + 0x555, 0xAA);
+		iobarrier_rw();
+		out8(addr + 0x2AA, 0x55);
+		iobarrier_rw();
+		out8(addr + 0x555, 0xA0);
+		iobarrier_rw();
+		out8(dest+i, data_ch[i]);
+		iobarrier_rw();
+
+		/* re-enable interrupts if necessary */
+		if (flag)
+			enable_interrupts();
+
+		/* data polling for D7 */
+		start = get_timer (0);
+		while ((in8(dest+i) & 0x80) != (data_ch[i] & 0x80)) {
+			if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+				flash_reset (addr);
+				flash_to_mem();
+				return (1);
+			}
+			iobarrier_rw();
+		}
+	}
+
+	flash_reset (addr);
+	flash_to_mem();
+	return (0);
+}
+
+/*
+ * Reset bank to read mode
+ */
+static void flash_reset (ulong addr)
+{
+        flash_to_xd();
+	out8(addr, 0xF0);	/* reset bank */
+	iobarrier_rw();
+	flash_to_mem();
+}
+
+void flash_print_info (flash_info_t *info)
+{
+	int i;
+
+	if (info->flash_id == FLASH_UNKNOWN) {
+		printf ("missing or unknown FLASH type\n");
+		return;
+	}
+
+	switch (info->flash_id & FLASH_VENDMASK) {
+	case FLASH_MAN_AMD:	printf ("AMD ");		break;
+	case FLASH_MAN_FUJ:	printf ("FUJITSU ");		break;
+	case FLASH_MAN_BM:	printf ("BRIGHT MICRO ");	break;
+	case FLASH_MAN_STM:	printf ("SGS THOMSON ");	break;
+	default:		printf ("Unknown Vendor ");	break;
+	}
+
+	switch (info->flash_id & FLASH_TYPEMASK) {
+	case FLASH_AM040:	printf ("29F040 or 29LV040 (4 Mbit, uniform sectors)\n");
+				break;
+	case FLASH_AM400B:	printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
+				break;
+	case FLASH_AM400T:	printf ("AM29LV400T (4 Mbit, top boot sector)\n");
+				break;
+	case FLASH_AM800B:	printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
+				break;
+	case FLASH_AM800T:	printf ("AM29LV800T (8 Mbit, top boot sector)\n");
+				break;
+	case FLASH_AM160B:	printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
+				break;
+	case FLASH_AM160T:	printf ("AM29LV160T (16 Mbit, top boot sector)\n");
+				break;
+	case FLASH_AM320B:	printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
+				break;
+	case FLASH_AM320T:	printf ("AM29LV320T (32 Mbit, top boot sector)\n");
+				break;
+	default:		printf ("Unknown Chip Type\n");
+				break;
+	}
+
+	if (info->size % 0x100000 == 0) {
+		printf ("  Size: %ld MB in %d Sectors\n",
+			info->size / 0x100000, info->sector_count);
+	} else if (info->size % 0x400 == 0) {
+		printf ("  Size: %ld KB in %d Sectors\n",
+		        info->size / 0x400, info->sector_count);
+	} else {
+		printf ("  Size: %ld B in %d Sectors\n",
+		        info->size, info->sector_count);
+	}
+
+	printf ("  Sector Start Addresses:");
+	for (i=0; i<info->sector_count; ++i) {
+		if ((i % 5) == 0)
+			printf ("\n   ");
+		printf (" %08lX%s",
+			info->start[i],
+			info->protect[i] ? " (RO)" : "     "
+		);
+	}
+	printf ("\n");
+}

+ 230 - 0
board/MAI/AmigaOneG3SE/i8259.c

@@ -0,0 +1,230 @@
+/*
+ * (C) Copyright 2002
+ * John W. Linville, linville@tuxdriver.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include "i8259.h"
+
+#undef  IRQ_DEBUG
+
+#ifdef  IRQ_DEBUG
+#define PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+static inline unsigned char read_byte(volatile unsigned char* from)
+{
+    int x;
+    asm volatile ("lbz %0,%1\n eieio" : "=r" (x) : "m" (*from));
+    return (unsigned char)x;
+}
+
+static inline void write_byte(volatile unsigned char *to, int x)
+{
+    asm volatile ("stb %1,%0\n eieio" : "=m" (*to) : "r" (x));
+}
+
+static inline unsigned long read_long_little(volatile unsigned long *from)
+{
+    unsigned long x;
+    asm volatile ("lwbrx %0,0,%1\n eieio\n sync" : "=r" (x) : "r" (from), "m"(*from));
+    return (unsigned long)x;
+}
+
+#ifdef out8
+#undef out8
+#endif
+
+#ifdef in8
+#undef in8
+#endif
+
+#define out8(addr, byte) write_byte(0xFE000000 | addr, byte)
+#define in8(addr) read_byte(0xFE000000 | addr)
+
+/*
+ * This contains the irq mask for both 8259A irq controllers,
+ */
+static char cached_imr[2] = {0xff, 0xff};
+
+#define cached_imr1	(cached_imr[0])
+#define cached_imr2	(cached_imr[1])
+
+void i8259_init(void)
+{
+	char dummy;
+	PRINTF("Initializing Interrupt controller\n");
+	/* init master interrupt controller */
+	out8(0x20, 0x11); //0x19); // was: 0x11); /* Start init sequence */
+	out8(0x21, 0x00); /* Vector base */
+	out8(0x21, 0x04); /* edge tiggered, Cascade (slave) on IRQ2 */
+	out8(0x21, 0x11); // was: 0x01); /* Select 8086 mode */
+
+	/* init slave interrupt controller */
+	out8(0xA0, 0x11); //0x19); // was: 0x11); /* Start init sequence */
+	out8(0xA1, 0x08); /* Vector base */
+	out8(0xA1, 0x02); /* edge triggered, Cascade (slave) on IRQ2 */
+	out8(0xA1, 0x11); // was: 0x01); /* Select 8086 mode */
+
+	/* always read ISR */
+	out8(0x20, 0x0B);
+	dummy = in8(ISR_1);
+	out8(0xA0, 0x0B);
+	dummy = in8(ISR_2);
+
+/*     out8(0x43, 0x30); */
+/*     out8(0x40, 0); */
+/*     out8(0x40, 0); */
+/*     out8(0x43, 0x70); */
+/*     out8(0x41, 0); */
+/*     out8(0x41, 0); */
+/*     out8(0x43, 0xb0); */
+/*     out8(0x42, 0); */
+/*     out8(0x42, 0); */
+
+	/* Mask all interrupts */
+	out8(IMR_2, cached_imr2);
+	out8(IMR_1, cached_imr1);
+
+	i8259_unmask_irq(2);
+#if 0
+	{
+	    int i;
+	    for (i=0; i<16; i++)
+	    {
+		i8259_unmask_irq(i);
+	    }
+	}
+#endif
+}
+
+static volatile char *pci_intack = (void *)0xFEF00000;
+
+int i8259_irq(void)
+{
+	int irq;
+
+	irq = read_long_little(pci_intack) & 0xff;
+	if (irq==7) {
+		/*
+		 * This may be a spurious interrupt.
+		 *
+		 * Read the interrupt status register (ISR). If the most
+		 * significant bit is not set then there is no valid
+		 * interrupt.
+		 */
+		if(~in8(0x20)&0x80) {
+			irq = -1;
+		}
+	}
+
+	return irq;
+}
+int i8259_get_irq(struct pt_regs *regs)
+{
+	unsigned char irq;
+
+	/*
+	 * Perform an interrupt acknowledge cycle on controller 1
+	 */
+	out8(OCW3_1, 0x0C); /* prepare for poll */
+	irq = in8(IPL_1) & 7;
+	if (irq == 2) {
+		/*
+		 * Interrupt is cascaded so perform interrupt
+		 * acknowledge on controller 2
+		 */
+		out8(OCW3_2, 0x0C); /* prepare for poll */
+		irq = (in8(IPL_2) & 7) + 8;
+		if (irq == 15) {
+			/*
+			 * This may be a spurious interrupt
+			 *
+			 * Read the interrupt status register. If the most
+			 * significant bit is not set then there is no valid
+			 * interrupt
+			 */
+			out8(OCW3_2, 0x0b);
+			if (~(in8(ISR_2) & 0x80)) {
+				return -1;
+			}
+		}
+	} else if (irq == 7) {
+		/*
+		 * This may be a spurious interrupt
+		 *
+		 * Read the interrupt status register. If the most
+		 * significant bit is not set then there is no valid
+		 * interrupt
+		 */
+		out8(OCW3_1, 0x0b);
+		if (~(in8(ISR_1) & 0x80)) {
+			return -1;
+		}
+	}
+	return irq;
+}
+
+/*
+ * Careful! The 8259A is a fragile beast, it pretty
+ * much _has_ to be done exactly like this (mask it
+ * first, _then_ send the EOI, and the order of EOI
+ * to the two 8259s is important!
+ */
+void i8259_mask_and_ack(int irq)
+{
+	if (irq > 7) {
+		cached_imr2 |= (1 << (irq - 8));
+		in8(IMR_2); /* DUMMY */
+		out8(IMR_2, cached_imr2);
+		out8(OCW2_2, 0x20); /* Non-specific EOI */
+		out8(OCW2_1, 0x20); /* Non-specific EOI to cascade */
+	} else {
+		cached_imr1 |= (1 << irq);
+		in8(IMR_1); /* DUMMY */
+		out8(IMR_1, cached_imr1);
+		out8(OCW2_1, 0x20); /* Non-specific EOI */
+	}
+}
+
+void i8259_mask_irq(int irq)
+{
+	if (irq & 8) {
+		cached_imr2 |= (1 << (irq & 7));
+		out8(IMR_2, cached_imr2);
+	} else {
+		cached_imr1 |= (1 << irq);
+		out8(IMR_1, cached_imr1);
+	}
+}
+
+void i8259_unmask_irq(int irq)
+{
+	if (irq & 8) {
+		cached_imr2 &= ~(1 << (irq & 7));
+		out8(IMR_2, cached_imr2);
+	} else {
+		cached_imr1 &= ~(1 << irq);
+		out8(IMR_1, cached_imr1);
+	}
+}

+ 56 - 0
board/MAI/AmigaOneG3SE/i8259.h

@@ -0,0 +1,56 @@
+/*
+ * (C) Copyright 2002
+ * John W. Linville, linville@tuxdriver.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#define ICW1_1  CFG_ISA_IO_BASE_ADDRESS + ISA_INT1_ICW1
+#define ICW1_2  CFG_ISA_IO_BASE_ADDRESS + ISA_INT2_ICW1
+#define ICW2_1  CFG_ISA_IO_BASE_ADDRESS + ISA_INT1_ICW2
+#define ICW2_2  CFG_ISA_IO_BASE_ADDRESS + ISA_INT2_ICW2
+#define ICW3_1  CFG_ISA_IO_BASE_ADDRESS + ISA_INT1_ICW3
+#define ICW3_2  CFG_ISA_IO_BASE_ADDRESS + ISA_INT2_ICW3
+#define ICW4_1  CFG_ISA_IO_BASE_ADDRESS + ISA_INT1_ICW4
+#define ICW4_2  CFG_ISA_IO_BASE_ADDRESS + ISA_INT2_ICW4
+#define OCW1_1  CFG_ISA_IO_BASE_ADDRESS + ISA_INT1_OCW1
+#define OCW1_2  CFG_ISA_IO_BASE_ADDRESS + ISA_INT2_OCW1
+#define OCW2_1  CFG_ISA_IO_BASE_ADDRESS + ISA_INT1_OCW2
+#define OCW2_2  CFG_ISA_IO_BASE_ADDRESS + ISA_INT2_OCW2
+#define OCW3_1  CFG_ISA_IO_BASE_ADDRESS + ISA_INT1_OCW3
+#define OCW3_2  CFG_ISA_IO_BASE_ADDRESS + ISA_INT2_OCW3
+
+#define IMR_1   OCW1_1
+#define IMR_2   OCW1_2
+
+#define ISR_1   ICW1_1
+#define ISR_2   ICW1_2
+
+#define IPL_1   ICW1_1
+#define IPL_2   ICW1_2
+
+extern void i8259_init(void);
+
+extern int i8259_get_irq(struct pt_regs *regs);
+
+extern void i8259_mask_and_ack(int irq);
+
+extern void i8259_mask_irq(int irq);
+
+extern void i8259_unmask_irq(int irq);

+ 268 - 0
board/MAI/AmigaOneG3SE/interrupts.c

@@ -0,0 +1,268 @@
+/*
+ * (C) Copyright 2002
+ * John W. Linville <linville@tuxdriver.com>
+ *
+ *    Copied and modified from original code by Josh Huber.  Original
+ *    copyright notice preserved below.
+ *
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * interrupts.c - just enough support for the decrementer/timer
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <command.h>
+#include "i8259.h"
+
+#undef DEBUG
+#ifdef  DEBUG
+#define PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+#define NR_IRQS	16
+
+void irq_alloc_init(void);
+long irq_alloc(long wanted);
+
+/****************************************************************************/
+
+unsigned decrementer_count;	     /* count value for 1e6/HZ microseconds */
+
+struct irq_action {
+    interrupt_handler_t *handler;
+    void *arg;
+    ulong count;
+};
+
+static struct irq_action irq_handlers[NR_IRQS];
+
+/****************************************************************************/
+
+static __inline__ unsigned long
+get_msr(void)
+{
+	unsigned long msr;
+
+	asm volatile("mfmsr %0" : "=r" (msr) :);
+	return msr;
+}
+
+static __inline__ void
+set_msr(unsigned long msr)
+{
+	asm volatile("mtmsr %0" : : "r" (msr)); 
+}
+
+static __inline__ unsigned long
+get_dec(void)
+{
+	unsigned long val;
+
+	asm volatile("mfdec %0" : "=r" (val) :);
+	return val;
+}
+
+
+static __inline__ void
+set_dec(unsigned long val)
+{
+	asm volatile("mtdec %0" : : "r" (val)); 
+}
+
+
+void
+enable_interrupts(void)
+{
+    set_msr (get_msr() | MSR_EE);
+}
+
+/* returns flag if MSR_EE was set before */
+int
+disable_interrupts(void)
+{
+    ulong msr;
+
+    msr = get_msr();
+    set_msr (msr & ~MSR_EE);
+    return ((msr & MSR_EE) != 0);
+}
+
+/****************************************************************************/
+
+int interrupt_init (void)
+{
+    extern void new_reset(void);
+    extern void new_reset_end(void);
+#ifdef DEBUG
+	puts("interrupt_init: setting decrementer_count\n");
+#endif
+	decrementer_count = get_tbclk() / CFG_HZ;
+
+#ifdef DEBUG
+	puts("interrupt_init: setting actual decremter\n");
+#endif
+	set_dec (get_tbclk() / CFG_HZ);
+
+#ifdef DEBUG
+	puts("interrupt_init: clearing external interrupt table\n");
+#endif
+	/* clear external interrupt table here */
+	memset(irq_handlers, 0, sizeof(irq_handlers));
+
+#ifdef DEBUG
+	puts("interrupt_init: initializing interrupt controller\n");
+#endif
+	i8259_init();
+
+#ifdef DEBUG
+	puts("Copying reset trampoline\n");
+#endif
+	/* WARNING: Assmues that the first megabyte is CACHEINHIBIT! */
+	memcpy((void *)0x100, new_reset, new_reset_end - new_reset);
+
+#ifdef DEBUG
+	PRINTF("interrupt_init: enabling interrupts (msr = %08x)\n",
+		get_msr());
+#endif
+	set_msr (get_msr() | MSR_EE);
+
+#ifdef DEBUG
+	PRINTF("interrupt_init: done. (msr = %08x)\n", get_msr());
+#endif
+
+}
+
+/****************************************************************************/
+
+/*
+ * Handle external interrupts
+ */
+void
+external_interrupt(struct pt_regs *regs)
+{
+    extern int i8259_irq(void);
+
+	int irq, unmask = 1;
+
+	irq = i8259_irq(); //i8259_get_irq(regs);
+//	printf("irq = %d, handler at %p ack=%d\n", irq, irq_handlers[irq].handler, *(volatile unsigned char *)0xFEF00000);
+	i8259_mask_and_ack(irq);
+
+	if (irq_handlers[irq].handler != NULL)
+		(*irq_handlers[irq].handler)(irq_handlers[irq].arg);
+	else {
+		PRINTF ("\nBogus External Interrupt IRQ %d\n", irq);
+		/*
+	 	* turn off the bogus interrupt, otherwise it
+	 	* might repeat forever
+	 	*/
+		unmask = 0;
+	}
+
+	if (unmask) i8259_unmask_irq(irq);
+}
+
+volatile ulong timestamp = 0;
+
+/*
+ * timer_interrupt - gets called when the decrementer overflows,
+ * with interrupts disabled.
+ * Trivial implementation - no need to be really accurate.
+ */
+void
+timer_interrupt(struct pt_regs *regs)
+{
+	set_dec(decrementer_count);
+	timestamp++;
+}
+
+/****************************************************************************/
+
+void
+reset_timer(void)
+{
+	timestamp = 0;
+}
+
+ulong
+get_timer(ulong base)
+{
+	return (timestamp - base);
+}
+
+void
+set_timer(ulong t)
+{
+	timestamp = t;
+}
+
+/****************************************************************************/
+
+/*
+ * Install and free a interrupt handler.
+ */
+
+void
+irq_install_handler(int irq, interrupt_handler_t *handler, void *arg)
+{
+	if (irq < 0 || irq >= NR_IRQS) {
+		PRINTF("irq_install_handler: bad irq number %d\n", irq);
+		return;
+	}
+
+	if (irq_handlers[irq].handler != NULL)
+		PRINTF("irq_install_handler: 0x%08lx replacing 0x%08lx\n",
+		       (ulong)handler, (ulong)irq_handlers[irq].handler);
+
+	irq_handlers[irq].handler = handler;
+	irq_handlers[irq].arg     = arg;
+
+	i8259_unmask_irq(irq);
+}
+
+void
+irq_free_handler(int irq)
+{
+	if (irq < 0 || irq >= NR_IRQS) {
+		PRINTF("irq_free_handler: bad irq number %d\n", irq);
+		return;
+	}
+
+	i8259_mask_irq(irq);
+
+	irq_handlers[irq].handler = NULL;
+	irq_handlers[irq].arg     = NULL;
+}
+
+/****************************************************************************/
+
+void
+do_irqinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+	puts("IRQ related functions are unimplemented currently.\n");
+}
+
+

+ 84 - 0
board/MAI/AmigaOneG3SE/macros.h

@@ -0,0 +1,84 @@
+
+#ifndef _MACROS_H
+#define _MACROS_H
+
+	/*
+	** Load a long integer into a register
+	*/
+      	.macro liw reg, value
+                lis \reg, \value@h
+                ori \reg, \reg, \value@l
+        .endm
+
+
+	/* 
+	** Generate config_addr request
+	** This macro expects the values in registers:
+	** r3 - bus
+	** r4 - devfn
+	** r5 - offset
+	*/
+	.macro config_addr 	
+		rlwinm	r9, r5, 24, 0, 6
+		rlwinm	r8, r4, 16, 0, 31
+		rlwinm	r7, r3, 8, 0, 31
+		or	r9, r8, r9
+		or	r9, r7, r9
+		ori	r9, r9, 0x80
+		liw	r10, 0xfec00cf8
+		stw	r9, 0(r10)
+		eieio
+		sync
+	.endm
+
+	
+	/*
+	** Generate config_data address
+	*/
+	.macro config_data mask
+		andi.	r9, r5, \mask
+		addi	r9, r9, 0xcfc
+		oris	r9, r9, 0xfee0
+	.endm
+
+
+	/*
+	** Write a byte value to an output port
+	*/
+        .macro outb port, value
+                lis     r2, 0xfe00
+                li      r0, \value
+                stb     r0, \port(r2)
+        .endm
+
+
+	/*
+	** Write a register byte value to an output port
+	*/
+        .macro outbr port, value
+                lis     r2, 0xfe00
+                stb     \value, \port(r2)
+        .endm
+
+
+	/* 
+	** Read a byte value from a port into a specified register
+	*/
+        .macro inb reg, port
+                lis     r2, 0xfe00
+                lbz     \reg, \port(r2)
+        .endm
+
+
+	/*
+	** Write a byte to the SuperIO config area
+	*/
+        .macro siowb offset, value
+                li      r3, 0
+                li      r4, (7<<3)
+                li      r5, \offset
+                li      r6, \value
+                bl      pci_write_cfg_byte
+        .endm
+
+#endif

+ 74 - 0
board/MAI/AmigaOneG3SE/memio.S

@@ -0,0 +1,74 @@
+#include	"macros.h"
+
+	
+
+	.globl pci_read_cfg_byte
+	
+pci_read_cfg_byte:
+	config_addr
+	config_data	3
+	eieio
+	sync
+	lbz	r3, 0(r9)
+	blr
+
+	
+
+	.globl pci_write_cfg_byte
+	
+pci_write_cfg_byte:	
+	config_addr
+	config_data	3
+	stb	r6, 0(r9)
+	eieio
+	sync
+	blr
+
+
+
+	.globl pci_read_cfg_word
+	
+pci_read_cfg_word:
+	config_addr
+	config_data	2
+	lhbrx	r3, 0, r9
+	eieio
+	sync
+	blr
+
+
+	
+	.globl pci_write_cfg_word
+	
+pci_write_cfg_word:
+	config_addr
+	config_data	2
+	sthbrx	r6, 0, r9
+	eieio
+	sync
+	blr
+
+	
+
+	.globl pci_read_cfg_long
+	
+pci_read_cfg_long:
+	config_addr
+	config_data	0
+	lwbrx	r3, 0, r9
+	eieio
+	sync
+	blr
+
+
+
+	.globl pci_write_cfg_long
+	
+pci_write_cfg_long:
+	config_addr
+	config_data	0
+	stwbrx	r6, 0, r9
+	eieio
+	sync
+	blr
+

+ 113 - 0
board/MAI/AmigaOneG3SE/memio.h

@@ -0,0 +1,113 @@
+/*
+ * Memory mapped IO
+ *
+ * (C) Copyright 2002
+ * Hyperion Entertainment, ThomasF@hyperion-entertainment.com 
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ * You may also use this under a BSD license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	
+ *
+ */ 
+
+#ifndef _MEMIO_H
+#define _MEMIO_H
+
+#include "short_types.h"
+
+#define IOBASE 0xFE000000
+
+#define in_byte(from) read_byte( (uint8 *)(IOBASE | (from)))
+#define in_word(from) read_word_little((uint16 *)(IOBASE | (from)))
+#define in_long(from) read_long_little((uint32 *)(IOBASE | (from)))
+#define out_byte(to, val) write_byte((uint8 *)(IOBASE | (to)), val)
+#define out_word(to, val) write_word_little((uint16 *)(IOBASE | (to)), val)
+#define out_long(to, val) write_long_little((uint32 *)(IOBASE | (to)), val)
+
+
+static inline uint8 read_byte(volatile uint8 *from)
+{
+    int x;
+    asm volatile ("lbz %0,%1\n eieio\n sync" : "=r" (x) : "m" (*from));
+    return (uint8)x;
+}
+
+
+static inline void write_byte(volatile uint8 *to, uint8 x)
+{
+    asm volatile ("stb %1,%0\n eieio\n sync" : "=m" (*to) : "r" (x));
+}
+
+static inline uint16 read_word_little(volatile uint16 *from)
+{
+    int x;
+    asm volatile ("lhbrx %0,0,%1\n eieio\n sync" : "=r" (x) : "r" (from), "m" (*from));
+    return (uint16)x;
+}
+
+static inline uint16 read_word_big(volatile uint16 *from)
+{
+    int x;
+    asm volatile ("lhz %0,%1\n eieio\n sync" : "=r" (x) : "m" (*from));
+    return (uint16)x;
+}
+
+static inline void write_word_little(volatile uint16 *to, int x)
+{
+    asm volatile ("sthbrx %1,0,%2\n eieio\n sync" : "=m" (*to) : "r" (x), "r" (to));
+}
+
+static inline void write_word_big(volatile uint16 *to, int x)
+{
+    asm volatile ("sth %1,%0\n eieio\n sync" : "=m" (*to) : "r" (x));
+}
+
+static inline uint32 read_long_little(volatile uint32 *from)
+{
+    unsigned long x;
+    asm volatile ("lwbrx %0,0,%1\n eieio\n sync" : "=r" (x) : "r" (from), "m"(*from));
+    return (uint32)x;
+}
+
+static inline uint32 read_long_big(volatile uint32 *from)
+{
+    unsigned long x;
+    asm volatile ("lwz %0,%1\n eieio\n sync" : "=r" (x) : "m" (*from));
+    return (uint32)x;
+}
+
+static inline void write_long_little(volatile uint32 *to, uint32 x)
+{
+    asm volatile ("stwbrx %1,0,%2\n eieio\n sync" : "=m" (*to) : "r" (x), "r" (to));
+}
+
+static inline void write_long_big(volatile uint32 *to, uint32 x)
+{
+    asm volatile ("stw %1,%0\n eieio\n sync" : "=m" (*to) : "r" (x));
+}
+
+#define CONFIG_ADDR(bus, devfn, offset) \
+    write_long_big((uint32 *)0xFEC00CF8,           \
+                   ((offset & 0xFC)<<24) | (devfn << 16)  \
+                   | (bus<<8) | 0x80);
+#define CONFIG_DATA(offset,mask) ((void *)(0xFEE00CFC+(offset & mask)))
+
+
+uint8 pci_read_cfg_byte(int32 bus, int32 devfn, int32 offset);
+void pci_write_cfg_byte(int32 bus, int32 devfn, int32 offset, uint8 x);
+uint16 pci_read_cfg_word(int32 bus, int32 devfn, int32 offset);
+void pci_write_cfg_word(int32 bus, int32 devfn, int32 offset, uint16 x);
+uint32 pci_read_cfg_long(int32 bus, int32 devfn, int32 offset);
+void pci_write_cfg_long(int32 bus, int32 devfn, int32 offset, uint32 x);
+
+
+#endif

+ 30 - 0
board/MAI/AmigaOneG3SE/memory_dump

@@ -0,0 +1,30 @@
+64 MB:
+0x00: 80 08 04 0c 09 01 40 00 01 a0 60 00 80 08 00 01
+0x10: 8f 04 04 01 01 00 06 a0 60 00 00 14 10 14 2d 10
+0x20: 20 10 20 10 00 00 00 00 00 00 00 00 00 00 00 00
+0x30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12 f2
+0x40: 7f 61 00 00 00 00 00 00 46 04 00 ff ff ff ff ff
+0x50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+0x60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+0x70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff 64 f4
+
+512 MB:
+0x00: 80 08 04 0d 0a 02 40 00 01 75 54 00 82 08 00 01
+0x10: 8f 04 04 01 01 00 0f 00 00 00 00 14 0f 14 2d 40
+0x20: 15 08 15 08 00 00 00 00 00 00 00 00 00 00 00 00
+0x30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12 d2
+0x40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+0x50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+0x60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+0x70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 64 fd
+
+256 MB:
+0x00: 80 08 04 0c 0a 02 40 00 01 75 54 00 80 08 00 01
+0x10: 8f 04 06 01 01 00 0e a0 60 00 00 14 0f 14 2d 20
+0x20: 15 08 15 08 00 00 00 00 00 00 00 00 00 00 00 00
+0x30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12 b0
+0x40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+0x50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+0x60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+0x70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 64 f6
+

+ 37 - 0
board/MAI/AmigaOneG3SE/nvram.c

@@ -0,0 +1,37 @@
+/*
+ * (C) Copyright 2002
+ * Thomas Frieden, Hyperion Entertainment 
+ * ThomasF@hyperion-entertainment.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include "memio.h"
+
+void enable_nvram(void)
+{
+    pci_write_cfg_byte(0, 0, 0x56, 0x0b);
+}
+
+void disable_nvram(void)
+{
+    pci_write_cfg_byte(0, 0, 0x56, 0x0);
+}
+

+ 699 - 0
board/MAI/AmigaOneG3SE/ps2kbd.c

@@ -0,0 +1,699 @@
+/*
+ * (C) Copyright 2002
+ * John W. Linville, linville@tuxdriver.com
+ * 
+ * Modified from code for support of MIP405 and PIP405 boards.  Previous
+ * copyright follows.
+ *
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Source partly derived from:
+ * linux/drivers/char/pc_keyb.c
+ *
+ *
+ */
+#include <common.h>
+#include <asm/processor.h>
+#include <devices.h>
+#include "ps2kbd.h"
+
+
+unsigned char kbd_read_status(void);
+unsigned char kbd_read_input(void);
+void kbd_send_data(unsigned char data);
+void i8259_mask_irq(unsigned int irq);
+void i8259_unmask_irq(unsigned int irq);
+
+/* used only by send_data - set by keyboard_interrupt */
+
+
+#undef KBG_DEBUG
+//#define KBG_DEBUG
+
+#ifdef KBG_DEBUG
+#define	PRINTF(fmt,args...)	printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#define KBD_STAT_KOBF		0x01
+#define KBD_STAT_IBF		0x02
+#define KBD_STAT_SYS		0x04
+#define KBD_STAT_CD			0x08
+#define KBD_STAT_LOCK		0x10
+#define KBD_STAT_MOBF		0x20
+#define KBD_STAT_TI_OUT	0x40
+#define KBD_STAT_PARERR	0x80
+
+#define KBD_INIT_TIMEOUT 2000		/* Timeout in ms for initializing the keyboard */
+#define KBC_TIMEOUT 250			/* Timeout in ms for sending to keyboard controller */
+#define KBD_TIMEOUT 2000		/* Timeout in ms for keyboard command acknowledge */
+/*
+ *	Keyboard Controller Commands
+ */
+
+#define KBD_CCMD_READ_MODE			0x20	/* Read mode bits */
+#define KBD_CCMD_WRITE_MODE			0x60	/* Write mode bits */
+#define KBD_CCMD_GET_VERSION		0xA1	/* Get controller version */
+#define KBD_CCMD_MOUSE_DISABLE	0xA7	/* Disable mouse interface */
+#define KBD_CCMD_MOUSE_ENABLE		0xA8	/* Enable mouse interface */
+#define KBD_CCMD_TEST_MOUSE			0xA9	/* Mouse interface test */
+#define KBD_CCMD_SELF_TEST			0xAA	/* Controller self test */
+#define KBD_CCMD_KBD_TEST				0xAB	/* Keyboard interface test */
+#define KBD_CCMD_KBD_DISABLE		0xAD	/* Keyboard interface disable */
+#define KBD_CCMD_KBD_ENABLE			0xAE	/* Keyboard interface enable */
+#define KBD_CCMD_WRITE_AUX_OBUF	0xD3    /* Write to output buffer as if
+					   initiated by the auxiliary device */
+#define KBD_CCMD_WRITE_MOUSE		0xD4	/* Write the following byte to the mouse */
+
+/*
+ *	Keyboard Commands
+ */
+
+#define KBD_CMD_SET_LEDS				0xED	/* Set keyboard leds */
+#define KBD_CMD_SET_RATE				0xF3	/* Set typematic rate */
+#define KBD_CMD_ENABLE					0xF4	/* Enable scanning */
+#define KBD_CMD_DISABLE					0xF5	/* Disable scanning */
+#define KBD_CMD_RESET						0xFF	/* Reset */
+
+/*
+ *	Keyboard Replies
+ */
+
+#define KBD_REPLY_POR						0xAA	/* Power on reset */
+#define KBD_REPLY_ACK						0xFA	/* Command ACK */
+#define KBD_REPLY_RESEND				0xFE	/* Command NACK, send the cmd again */
+
+/*
+ *	Status Register Bits
+ */
+
+#define KBD_STAT_OBF 						0x01	/* Keyboard output buffer full */
+#define KBD_STAT_IBF 						0x02	/* Keyboard input buffer full */
+#define KBD_STAT_SELFTEST				0x04	/* Self test successful */
+#define KBD_STAT_CMD						0x08	/* Last write was a command write (0=data) */
+#define KBD_STAT_UNLOCKED				0x10	/* Zero if keyboard locked */
+#define KBD_STAT_MOUSE_OBF			0x20	/* Mouse output buffer full */
+#define KBD_STAT_GTO 						0x40	/* General receive/xmit timeout */
+#define KBD_STAT_PERR 					0x80	/* Parity error */
+
+#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
+
+/*
+ *	Controller Mode Register Bits
+ */
+
+#define KBD_MODE_KBD_INT				0x01	/* Keyboard data generate IRQ1 */
+#define KBD_MODE_MOUSE_INT			0x02	/* Mouse data generate IRQ12 */
+#define KBD_MODE_SYS 						0x04	/* The system flag (?) */
+#define KBD_MODE_NO_KEYLOCK			0x08	/* The keylock doesn't affect the keyboard if set */
+#define KBD_MODE_DISABLE_KBD		0x10	/* Disable keyboard interface */
+#define KBD_MODE_DISABLE_MOUSE	0x20	/* Disable mouse interface */
+#define KBD_MODE_KCC 						0x40	/* Scan code conversion to PC format */
+#define KBD_MODE_RFU						0x80
+
+
+#define KDB_DATA_PORT			0x60
+#define KDB_COMMAND_PORT	0x64
+
+#define 	LED_SCR		0x01	/* scroll lock led */
+#define 	LED_CAP		0x04	/* caps lock led */
+#define 	LED_NUM		0x02	/* num lock led */
+
+#define 	KBD_BUFFER_LEN 0x20  /* size of the keyboardbuffer */
+
+
+
+
+static volatile char kbd_buffer[KBD_BUFFER_LEN];
+static volatile int in_pointer = 0;
+static volatile int out_pointer = 0;
+
+
+static unsigned char num_lock = 0;
+static unsigned char caps_lock = 0;
+static unsigned char scroll_lock = 0;
+static unsigned char shift = 0;
+static unsigned char ctrl = 0;
+static unsigned char alt = 0;
+static unsigned char e0 = 0;
+static unsigned char leds = 0;
+
+#define DEVNAME "ps2kbd"
+
+/* Simple translation table for the keys */
+
+static unsigned char kbd_plain_xlate[] = {
+	0xff,0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=','\b','\t',	/* 0x00 - 0x0f */
+	 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']','\r',0xff, 'a', 's',	/* 0x10 - 0x1f */
+	 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', '`',0xff,'\\', 'z', 'x', 'c', 'v',	/* 0x20 - 0x2f */
+	 'b', 'n', 'm', ',', '.', '/',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff,	/* 0x30 - 0x3f */
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1',	/* 0x40 - 0x4f */
+	 '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,  /* 0x50 - 0x5F */
+	'\r',0xff,0xff
+	};
+	  	  
+static unsigned char kbd_shift_xlate[] = {
+	0xff,0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+','\b','\t',	/* 0x00 - 0x0f */
+	 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}','\r',0xff, 'A', 'S',	/* 0x10 - 0x1f */
+	 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',0xff, '|', 'Z', 'X', 'C', 'V',	/* 0x20 - 0x2f */
+	 'B', 'N', 'M', '<', '>', '?',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff,	/* 0x30 - 0x3f */
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1',	/* 0x40 - 0x4f */
+	 '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,  /* 0x50 - 0x5F */
+	'\r',0xff,0xff
+	};
+
+static unsigned char kbd_ctrl_xlate[] = {
+	0xff,0x1b, '1',0x00, '3', '4', '5',0x1E, '7', '8', '9', '0',0x1F, '=','\b','\t',	/* 0x00 - 0x0f */
+	0x11,0x17,0x05,0x12,0x14,0x18,0x15,0x09,0x0f,0x10,0x1b,0x1d,'\n',0xff,0x01,0x13,	/* 0x10 - 0x1f */
+	0x04,0x06,0x08,0x09,0x0a,0x0b,0x0c, ';','\'', '~',0x00,0x1c,0x1a,0x18,0x03,0x16,	/* 0x20 - 0x2f */
+	0x02,0x0e,0x0d, '<', '>', '?',0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,	/* 0x30 - 0x3f */
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1',	/* 0x40 - 0x4f */
+	 '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,  /* 0x50 - 0x5F */
+	'\r',0xff,0xff
+	};
+
+/******************************************************************
+ * Init 
+ ******************************************************************/
+
+int isa_kbd_init(void)
+{
+	char* result;
+	result=kbd_initialize();
+	if (result != NULL)
+	{
+	    result = kbd_initialize();
+	}
+	if(result==NULL) {
+		printf("AT Keyboard initialized\n");
+		irq_install_handler(KBD_INTERRUPT, (interrupt_handler_t *)kbd_interrupt, NULL);
+		return (1);
+	}
+	else {
+		printf("%s\n",result);
+		return (-1);
+	}
+}
+
+#ifdef CFG_CONSOLE_OVERWRITE_ROUTINE
+extern int overwrite_console (void);
+#else
+int overwrite_console (void)
+{
+	return (0);
+}
+#endif
+
+int drv_isa_kbd_init (void)
+{
+	int error;
+  	device_t kbddev ;
+	char *stdinname  = getenv ("stdin");
+
+	if(isa_kbd_init()==-1)
+		return -1;
+  	memset (&kbddev, 0, sizeof(kbddev));
+  	strcpy(kbddev.name, DEVNAME);
+  	kbddev.flags =  DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+  	kbddev.putc = NULL ;
+	kbddev.puts = NULL ;
+	kbddev.getc = kbd_getc ;
+	kbddev.tstc = kbd_testc ;
+
+ 	error = device_register (&kbddev);
+	if(error==0) {
+		/* check if this is the standard input device */
+		if(strcmp(stdinname,DEVNAME)==0) {
+			/* reassign the console */
+			if(overwrite_console()) {
+				return 1;
+			}
+			error=console_assign(stdin,DEVNAME);
+			if(error==0)
+				return 1;
+			else 
+				return error;
+		}
+		return 1;
+	}
+	return error;
+}
+
+/******************************************************************
+ * Queue handling 
+ ******************************************************************/
+/* puts character in the queue and sets up the in and out pointer */
+void kbd_put_queue(char data)
+{
+	if((in_pointer+1)==KBD_BUFFER_LEN) {
+		if(out_pointer==0) {
+			return; /* buffer full */
+		} else{
+			in_pointer=0;
+		}
+	} else {
+		if((in_pointer+1)==out_pointer)
+			return; /* buffer full */
+		in_pointer++;
+	}
+	kbd_buffer[in_pointer]=data;
+	return;
+}
+
+/* test if a character is in the queue */
+int kbd_testc(void)
+{
+	if(in_pointer==out_pointer)
+		return(0); /* no data */
+	else
+		return(1);	
+}
+/* gets the character from the queue */
+int kbd_getc(void)
+{
+	char c;
+
+	while(in_pointer==out_pointer);
+	if((out_pointer+1)==KBD_BUFFER_LEN) 
+		out_pointer=0;
+	else
+		out_pointer++;
+	c=kbd_buffer[out_pointer];
+	return (int)c;
+	
+}
+
+
+/* set LEDs */
+
+void kbd_set_leds(void)
+{
+	if(caps_lock==0)
+		leds&=~LED_CAP; /* switch caps_lock off */
+	else
+		leds|=LED_CAP; /* switch on LED */
+	if(num_lock==0)
+		leds&=~LED_NUM; /* switch LED off */
+	else
+		leds|=LED_NUM;  /* switch on LED */
+	if(scroll_lock==0)
+		leds&=~LED_SCR; /* switch LED off */
+	else
+		leds|=LED_SCR; /* switch on LED */
+	kbd_send_data(KBD_CMD_SET_LEDS);
+	kbd_send_data(leds);
+}
+	
+
+void handle_keyboard_event(unsigned char scancode)
+{
+	unsigned char keycode;
+
+	/*  Convert scancode to keycode */
+	PRINTF("scancode %x\n",scancode);
+	if(scancode==0xe0) {
+		e0=1; /* special charakters */
+		return;
+	}
+	if(e0==1) {
+		e0=0; /* delete flag */
+		if(!(	((scancode&0x7F)==0x38)|| /* the right ctrl key */
+			((scancode&0x7F)==0x1D)|| /* the right alt key */
+			((scancode&0x7F)==0x35)||	/* the right '/' key */
+			((scancode&0x7F)==0x1C)||  /* the right enter key */
+			((scancode)==0x48)|| /* arrow up */
+			((scancode)==0x50)|| /* arrow down */
+			((scancode)==0x4b)|| /* arrow left */
+			((scancode)==0x4d)))  /* arrow right */
+			/* we swallow unknown e0 codes */
+			return;
+	}
+	/* special cntrl keys */
+	switch(scancode)
+	{
+	case 0x48:
+	    kbd_put_queue(27);
+	    kbd_put_queue(91);
+	    kbd_put_queue('A');
+	    return;
+	case 0x50:
+	    kbd_put_queue(27);
+	    kbd_put_queue(91);
+	    kbd_put_queue('B');
+	    return;
+	case 0x4b:
+	    kbd_put_queue(27);
+	    kbd_put_queue(91);
+	    kbd_put_queue('D');
+	    return;
+	case 0x4D:
+	    kbd_put_queue(27);
+	    kbd_put_queue(91);
+	    kbd_put_queue('C');
+	    return;
+	case 0x58: /* F12 key */
+	    if (ctrl == 1)
+	    {
+		extern int console_changed;
+		setenv("stdin", DEVNAME);
+		setenv("stdout", "vga");
+		console_changed = 1;
+	    }
+	    return;
+	case 0x2A: 
+		case 0x36: /* shift pressed */
+			shift=1;
+			return; /* do nothing else */
+		case 0xAA: 
+		case 0xB6: /* shift released */
+			shift=0;
+			return; /* do nothing else */
+		case 0x38: /* alt pressed */
+			alt=1;
+			return; /* do nothing else */
+		case 0xB8: /* alt released */
+			alt=0;
+			return; /* do nothing else */
+		case 0x1d: /* ctrl pressed */
+			ctrl=1;
+			return; /* do nothing else */
+		case 0x9d: /* ctrl released */
+			ctrl=0;
+			return; /* do nothing else */
+		case 0x46: /* scrollock pressed */
+			scroll_lock=~scroll_lock;
+			kbd_set_leds();
+			return; /* do nothing else */
+		case 0x3A: /* capslock pressed */
+			caps_lock=~caps_lock;
+			kbd_set_leds();
+			return; 
+		case 0x45: /* numlock pressed */
+			num_lock=~num_lock;
+			kbd_set_leds();
+			return; 
+		case 0xC6: /* scroll lock released */
+		case 0xC5: /* num lock released */
+		case 0xBA: /* caps lock released */
+			return; /* just swallow */ 
+	}
+	if((scancode&0x80)==0x80) /* key released */
+		return;
+	/* now, decide which table we need */
+	if(scancode > (sizeof(kbd_plain_xlate)/sizeof(kbd_plain_xlate[0]))) { /* scancode not in list */
+		PRINTF("unkown scancode %X\n",scancode);
+		return; /* swallow it */
+	}
+	/* setup plain code first */
+	keycode=kbd_plain_xlate[scancode];
+	if(caps_lock==1) { /* caps_lock is pressed, overwrite plain code */
+		if(scancode > (sizeof(kbd_shift_xlate)/sizeof(kbd_shift_xlate[0]))) { /* scancode not in list */
+			PRINTF("unkown caps-locked scancode %X\n",scancode);
+			return; /* swallow it */
+		}
+		keycode=kbd_shift_xlate[scancode];
+		if(keycode<'A') { /* we only want the alphas capital */
+			keycode=kbd_plain_xlate[scancode];
+		}
+	}
+	if(shift==1) { /* shift overwrites caps_lock */
+		if(scancode > (sizeof(kbd_shift_xlate)/sizeof(kbd_shift_xlate[0]))) { /* scancode not in list */
+			PRINTF("unkown shifted scancode %X\n",scancode);
+			return; /* swallow it */
+		}
+		keycode=kbd_shift_xlate[scancode];
+	}
+	if(ctrl==1) { /* ctrl overwrites caps_lock and shift */
+		if(scancode > (sizeof(kbd_ctrl_xlate)/sizeof(kbd_ctrl_xlate[0]))) { /* scancode not in list */
+			PRINTF("unkown ctrl scancode %X\n",scancode);
+			return; /* swallow it */
+		}
+		keycode=kbd_ctrl_xlate[scancode];
+	}
+	/* check if valid keycode */
+	if(keycode==0xff) {
+		PRINTF("unkown scancode %X\n",scancode);
+		return; /* swallow unknown codes */
+	}
+	
+	kbd_put_queue(keycode);
+	PRINTF("%x\n",keycode);
+}
+
+/*
+ * This reads the keyboard status port, and does the
+ * appropriate action.
+ *
+ */
+unsigned char handle_kbd_event(void)
+{
+	unsigned char status = kbd_read_status();
+	unsigned int work = 10000;
+
+	while ((--work > 0) && (status & KBD_STAT_OBF)) {
+		unsigned char scancode;
+
+		scancode = kbd_read_input();
+
+		/* Error bytes must be ignored to make the
+		   Synaptics touchpads compaq use work */
+		/* Ignore error bytes */
+		if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR)))
+		{
+			if (status & KBD_STAT_MOUSE_OBF)
+				; /* not supported: handle_mouse_event(scancode); */
+			else
+				handle_keyboard_event(scancode);
+		}
+		status = kbd_read_status();
+	}
+	if (!work)
+		PRINTF("pc_keyb: controller jammed (0x%02X).\n", status);
+	return status;
+}
+
+
+
+/******************************************************************************
+ * Lowlevel Part of keyboard section
+ */  
+unsigned char kbd_read_status(void)
+{
+	return(in8(CFG_ISA_IO_BASE_ADDRESS + KDB_COMMAND_PORT));
+} 
+  
+unsigned char kbd_read_input(void)
+{
+	return(in8(CFG_ISA_IO_BASE_ADDRESS + KDB_DATA_PORT));
+} 
+
+void kbd_write_command(unsigned char cmd)
+{
+	out8(CFG_ISA_IO_BASE_ADDRESS + KDB_COMMAND_PORT,cmd);
+} 
+  
+void kbd_write_output(unsigned char data)
+{
+	out8(CFG_ISA_IO_BASE_ADDRESS + KDB_DATA_PORT, data);
+} 
+ 
+int kbd_read_data(void)
+{
+	int val;
+	unsigned char status;
+
+	val=-1;
+	status = kbd_read_status();
+	if (status & KBD_STAT_OBF) {
+		val = kbd_read_input();
+		if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
+			val = -2;
+	}
+	return val;
+}
+
+int kbd_wait_for_input(void)
+{
+	unsigned long timeout;
+	int val;
+	
+	timeout = KBD_TIMEOUT;
+	val=kbd_read_data();
+	while(val < 0)
+	{
+		if(timeout--==0)
+			return -1;
+		udelay(1000);
+		val=kbd_read_data();
+	}
+	return val;
+}
+
+
+int kb_wait(void)
+{
+	unsigned long timeout = KBC_TIMEOUT * 10;
+
+	do {
+		unsigned char status = handle_kbd_event();
+		if (!(status & KBD_STAT_IBF))
+			return 0; /* ok */
+		udelay(1000);
+		timeout--;
+	} while (timeout);
+	return 1;
+}
+
+void kbd_write_command_w(int data)
+{
+	if(kb_wait())
+		PRINTF("timeout in kbd_write_command_w\n");
+	kbd_write_command(data);
+}
+
+void kbd_write_output_w(int data)
+{
+	if(kb_wait())
+		PRINTF("timeout in kbd_write_output_w\n");
+	kbd_write_output(data);
+}
+
+void kbd_send_data(unsigned char data)
+{
+	unsigned char status;
+	i8259_mask_irq(KBD_INTERRUPT); /* disable interrupt */
+	kbd_write_output_w(data);
+	status = kbd_wait_for_input();
+	if (status == KBD_REPLY_ACK)
+		i8259_unmask_irq(KBD_INTERRUPT); /* enable interrupt */
+}
+
+
+char * kbd_initialize(void)
+{
+	int status;
+
+	in_pointer = 0; /* delete in Buffer */
+	out_pointer = 0;
+	/*
+	 * Test the keyboard interface.
+	 * This seems to be the only way to get it going.
+	 * If the test is successful a x55 is placed in the input buffer.
+	 */
+	kbd_write_command_w(KBD_CCMD_SELF_TEST);
+	if (kbd_wait_for_input() != 0x55) 
+		return "Kbd:   failed self test";
+	/*
+	 * Perform a keyboard interface test.  This causes the controller
+	 * to test the keyboard clock and data lines.  The results of the
+	 * test are placed in the input buffer.
+	 */
+	kbd_write_command_w(KBD_CCMD_KBD_TEST);
+	if (kbd_wait_for_input() != 0x00) 
+		return "Kbd:   interface failed self test";
+	/*
+	 * Enable the keyboard by allowing the keyboard clock to run.
+	 */
+	kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
+	status = kbd_wait_for_input();
+	/*
+	 * Reset keyboard. If the read times out
+	 * then the assumption is that no keyboard is
+	 * plugged into the machine.
+	 * This defaults the keyboard to scan-code set 2.
+	 *
+	 * Set up to try again if the keyboard asks for RESEND.
+	 */
+	do {
+		kbd_write_output_w(KBD_CMD_RESET);
+		status = kbd_wait_for_input();
+		if (status == KBD_REPLY_ACK) 
+			break;
+		if (status != KBD_REPLY_RESEND)
+		{
+			PRINTF("status: %X\n",status);
+			return "Kbd:   reset failed, no ACK";
+		}
+	} while (1);
+	if (kbd_wait_for_input() != KBD_REPLY_POR)
+		return "Kbd:   reset failed, no POR";
+
+	/*
+	 * Set keyboard controller mode. During this, the keyboard should be
+	 * in the disabled state.
+	 *
+	 * Set up to try again if the keyboard asks for RESEND.
+	 */
+	do {
+		kbd_write_output_w(KBD_CMD_DISABLE);
+		status = kbd_wait_for_input();
+		if (status == KBD_REPLY_ACK)
+			break;
+		if (status != KBD_REPLY_RESEND)
+			return "Kbd:   disable keyboard: no ACK";
+	} while (1);
+
+	kbd_write_command_w(KBD_CCMD_WRITE_MODE);
+	kbd_write_output_w(KBD_MODE_KBD_INT
+			      | KBD_MODE_SYS
+			      | KBD_MODE_DISABLE_MOUSE
+			      | KBD_MODE_KCC);
+
+	/* ibm powerpc portables need this to use scan-code set 1 -- Cort */
+	kbd_write_command_w(KBD_CCMD_READ_MODE);
+	if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
+		/*
+		 * If the controller does not support conversion,
+		 * Set the keyboard to scan-code set 1.
+		 */
+		kbd_write_output_w(0xF0);
+		kbd_wait_for_input();
+		kbd_write_output_w(0x01);
+		kbd_wait_for_input();
+	}
+	kbd_write_output_w(KBD_CMD_ENABLE);
+	if (kbd_wait_for_input() != KBD_REPLY_ACK)
+		return "Kbd:   enable keyboard: no ACK";
+
+	/*
+	 * Finally, set the typematic rate to maximum.
+	 */
+	kbd_write_output_w(KBD_CMD_SET_RATE);
+	if (kbd_wait_for_input() != KBD_REPLY_ACK)
+		return "Kbd:   Set rate: no ACK";
+	kbd_write_output_w(0x00);
+	if (kbd_wait_for_input() != KBD_REPLY_ACK)
+		return "Kbd:   Set rate: no ACK";
+	return NULL;
+}
+
+void kbd_interrupt(void)
+{
+	handle_kbd_event();
+}
+
+
+
+/* eof */
+

+ 41 - 0
board/MAI/AmigaOneG3SE/ps2kbd.h

@@ -0,0 +1,41 @@
+/*
+ * (C) Copyright 2002
+ * John W. Linville, linville@tuxdriver.com
+ * 
+ * Modified from code for support of MIP405 and PIP405 boards.  Previous
+ * copyright follows.
+ *
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef _KBD_H_
+#define _KBD_H_
+   
+extern int kbd_testc(void);
+extern int kbd_getc(void);
+extern void kbd_interrupt(void);
+extern char *kbd_initialize(void);
+
+unsigned char kbd_is_init(void);
+#define KBD_INTERRUPT 1
+#endif

+ 247 - 0
board/MAI/AmigaOneG3SE/serial.c

@@ -0,0 +1,247 @@
+#include <common.h>
+#include <ns16550.h>
+#include "short_types.h"
+#include "memio.h"
+#include "articiaS.h"
+
+#ifndef CFG_NS16550
+static uint32 ComPort1;
+
+uint16 SerialEcho = 1;
+
+
+#define RECEIVER_HOLDING 0
+#define TRANSMITTER_HOLDING 0
+#define INTERRUPT_ENABLE 1
+#define INTERRUPT_STATUS 2
+#define FIFO_CONTROL 2
+#define LINE_CONTROL 3
+#define MODEM_CONTROL 4
+#define LINE_STATUS 5
+#define MODEM_STATUS 6
+#define SCRATCH_PAD 7
+
+#define DIVISOR_LATCH_LSB 0
+#define DIVISOR_LATCH_MSB 1
+#define PRESCALER_DIVISION 5
+
+#define COM_WRITE_BYTE(reg, byte) out_byte((ComPort1+reg), byte)
+#define COM_READ_BYTE(reg) in_byte((ComPort1+reg))
+
+static int serial_init_done = 0;
+
+void serial_init (void)
+{
+#if 0
+	uint32 clock_divisor = 115200 / baudrate;
+	uint8 cfg;
+	uint8 a;
+	uint16 devfn = 7 << 3;
+
+	if (serial_init_done)
+		return;
+
+	/*  Enter configuration mode */
+	cfg = pci_read_cfg_byte (0, devfn, 0x85);
+	pci_write_cfg_byte (0, devfn, 0x85, cfg | 0x02);
+
+	/* Set serial port COM1 as 3F8 */
+	out_byte (0x3F0, 0xE7);
+	out_byte (0x3f1, 0xfe);
+
+	/* Set serial port COM2 as 2F8 */
+	out_byte (0x3f0, 0xe8);
+	out_byte (0x3f1, 0xeb);
+
+	/* Enable */
+	out_byte (0x3f0, 0xe2);
+	a = in_byte (0x3f1);
+	a |= 0xc;
+	out_byte (0x3f0, 0xe2);
+	out_byte (0x3f1, a);
+
+	/*  Reset the configuration mode */
+	pci_write_cfg_byte (0, devfn, 0x85, cfg);
+#endif
+
+	ComPort1 = 0x3F8;
+
+	/*  Disable interrupts */
+	COM_WRITE_BYTE (INTERRUPT_ENABLE, 0x00);
+
+	/*  Set baud rate */
+	/* COM_WRITE_BYTE(LINE_CONTROL, 0x83); */
+	/* COM_WRITE_BYTE(DIVISOR_LATCH_LSB, (uint8)(clock_divisor & 0xFF)); */
+	/* COM_WRITE_BYTE(DIVISOR_LATCH_MSB, (uint8)(clock_divisor >> 8)); */
+	/* __asm("eieio"); */
+
+	/*  Set 8-N-1 */
+	COM_WRITE_BYTE (LINE_CONTROL, 0x03);
+	__asm ("eieio");
+
+	/*  Disable FIFO */
+	COM_WRITE_BYTE (MODEM_CONTROL, 0x03);
+	COM_WRITE_BYTE (FIFO_CONTROL, 0x07);
+
+	__asm ("eieio");
+	serial_init_done = 1;
+}
+
+extern int console_changed;
+
+void serial_putc (const char sendme)
+{
+	if (sendme == '\n') {
+		while ((in_byte (0x3FD) & 0x40) == 0);
+		out_byte (0x3f8, 0x0D);
+	}
+
+	while ((in_byte (0x3FD) & 0x40) == 0);
+	out_byte (0x3f8, sendme);
+}
+
+int serial_getc (void)
+{
+#if 0
+	uint8 c;
+
+	for (;;) {
+		uint8 x = in_byte (0x3FD);
+
+		if (x & 0x01)
+			break;
+
+		if (x & 0x0C)
+			out_byte (0x3fd, 0x0c);
+	}
+
+	c = in_byte (0x3F8);
+
+	return c;
+#else
+	while ((in_byte (0x3FD) & 0x01) == 0) {
+		if (console_changed != 0) {
+			printf ("Console changed\n");
+			console_changed = 0;
+			return 0;
+		}
+	}
+	return in_byte (0x3F8);
+#endif
+}
+
+int serial_tstc (void)
+{
+	return (in_byte (0x03FD) & 0x01) != 0;
+}
+
+void serial_debug_putc (int c)
+{
+	serial_puts ("DBG");
+	serial_putc (c);
+	serial_putc (0x0d);
+	serial_putc (0x0A);
+}
+
+#else
+
+const NS16550_t Com0 = (NS16550_t) CFG_NS16550_COM1;
+const NS16550_t Com1 = (NS16550_t) CFG_NS16550_COM2;
+
+int serial_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	uint32 clock_divisor = 115200 / gd->baudrate;
+
+	NS16550_init (Com0, clock_divisor);
+	/* NS16550_reinit(Com1, clock_divisor); */
+	/* serial_puts("COM1: 3F8h initalized"); */
+
+	return (0);
+}
+
+#if 0
+void serial_putc (const char c)
+{
+	NS16550_putc (Com0, c);
+	if (c == '\n')
+		NS16550_putc (Com0, 0x0D);
+}
+
+int serial_getc (void)
+{
+	return (int) NS16550_getc (Com0);
+}
+
+int serial_tstc (void)
+{
+	return NS16550_tstc (Com0);
+}
+#else
+void serial_putc (const char sendme)
+{
+	if (sendme == '\n') {
+		while ((in_byte (0x3FD) & 0x40) == 0);
+		out_byte (0x3f8, 0x0D);
+	}
+
+	while ((in_byte (0x3FD) & 0x40) == 0);
+	out_byte (0x3f8, sendme);
+}
+
+
+extern int console_changed;
+
+int serial_getc (void)
+{
+#if 0
+	uint8 c;
+
+	for (;;) {
+		uint8 x = in_byte (0x3FD);
+
+		if (x & 0x01)
+			break;
+
+		if (x & 0x0C)
+			out_byte (0x3fd, 0x0c);
+	}
+
+	c = in_byte (0x3F8);
+
+	return c;
+#else
+	while ((in_byte (0x3FD) & 0x01) == 0) {
+		if (console_changed != 0) {
+			console_changed = 0;
+			return 0;
+		}
+	}
+
+	return in_byte (0x3F8);
+#endif
+}
+
+int serial_tstc (void)
+{
+	return (in_byte (0x03FD) & 0x01) != 0;
+}
+#endif
+
+#endif
+
+void serial_puts (const char *string)
+{
+	while (*string)
+		serial_putc (*string++);
+}
+
+void serial_setbrg (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	uint32 clock_divisor = 115200 / gd->baudrate;
+
+	NS16550_init (Com0, clock_divisor);
+}

+ 36 - 0
board/MAI/AmigaOneG3SE/short_types.h

@@ -0,0 +1,36 @@
+/*
+ * short type names
+ *
+ * (C) Copyright 2002
+ * Hyperion Entertainment, ThomasF@hyperion-entertainment.com 
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _SHORT_TYPES_H
+#define _SHORT_TYPES_H
+
+typedef unsigned long  uint32;
+typedef long           int32;
+typedef unsigned short uint16;
+typedef short          int16;
+typedef unsigned char  uint8;
+typedef signed char    int8;
+
+#endif

+ 206 - 0
board/MAI/AmigaOneG3SE/smbus.c

@@ -0,0 +1,206 @@
+#include "memio.h"
+#include "articiaS.h"
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+
+void sm_write_mode(void)
+{
+    out_byte(0xA539, 0x00);
+    out_byte(0xA53A, 0x03);
+}
+
+void sm_read_mode(void)
+{
+    out_byte(0xA53A, 0x02);
+    out_byte(0xA539, 0x02);
+}
+
+void sm_write_byte(uint8 writeme)
+{
+    int i;
+    int level;
+    
+    out_byte(0xA539, 0x00);
+
+    level = 0;
+
+    for (i=0; i<8; i++)
+    {
+	if ((writeme & 0x80) == (level<<7)) 
+        {
+	    /* Bit did not change, rewrite strobe */
+	    out_byte(0xA539, level | 0x02);
+	    out_byte(0xA539, level); 
+	}
+	else
+	{
+	    /* Bit changed, set bit, then strobe */
+	    level = (writeme & 0x80) >> 7;
+	    out_byte(0xA539, level);
+	    out_byte(0xA539, level | 0x02);
+	    out_byte(0xA539, level);
+	}
+	writeme <<= 1;
+    }
+    out_byte(0xA539, 0x00);
+}
+
+uint8 sm_read_byte(void)
+{
+    uint8 retme, r;
+    int i;
+
+    retme = 0;
+    for (i=0; i<8; i++)
+    {
+	retme <<= 1;
+	out_byte(0xA539, 0x00);
+	out_byte(0xA539, 0x02);
+	r = in_byte(0xA538) & 0x01;
+	retme |= r;
+    }
+
+    return retme;
+} 
+
+int sm_get_ack(void)
+{
+    uint8 r;
+    r = in_byte(0xA538);
+    if ((r&0x01) == 0) return TRUE;
+    else return FALSE;
+}
+
+void sm_write_ack(void)
+{
+    out_byte(0xA539, 0x00);
+    out_byte(0xA539, 0x02);
+    out_byte(0xA539, 0x00);
+}
+
+void sm_write_nack(void)
+{
+    out_byte(0xA539, 0x01);
+    out_byte(0xA539, 0x03);
+    out_byte(0xA539, 0x01);
+}
+
+void sm_send_start(void)
+{
+    out_byte(0xA539, 0x03);
+    out_byte(0xA539, 0x02);
+}
+
+void sm_send_stop(void)
+{
+    out_byte(0xA539, 0x02);
+    out_byte(0xA539, 0x03);
+}
+
+int sm_read_byte_from_device(uint8 addr, uint8 reg, uint8 *storage)
+{
+    // S Addr Wr
+    sm_write_mode();
+    sm_send_start();
+    sm_write_byte((addr<<1));
+    
+    // [A]
+    sm_read_mode();
+    if (sm_get_ack() == FALSE) return FALSE;
+
+    // Comm
+    sm_write_mode();
+    sm_write_byte(reg);
+    
+    // [A]
+    sm_read_mode();
+    if (sm_get_ack() == FALSE) return FALSE;
+
+    // S Addr Rd
+    sm_write_mode();
+    sm_send_start();
+    sm_write_byte((addr<<1)|1);
+    
+    // [A]
+    sm_read_mode();
+    if (sm_get_ack() == FALSE) return FALSE;
+
+    // [Data]
+    *storage = sm_read_byte();
+    
+    // NA
+    sm_write_mode();
+    sm_write_nack();
+    sm_send_stop();
+
+    return TRUE;
+}
+
+void sm_init(void)
+{  
+    /* Switch to PMC mode */
+    pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER));
+ 
+    /* Set GPIO Base */
+    pci_write_cfg_long(0, 0, 0x40, 0xa500);
+
+    /* Enable GPIO */
+    pci_write_cfg_byte(0, 0, 0x44, 0x11);
+
+    /* Set both GPIO 0 and 1 as output */
+    out_byte(0xA53A, 0x03); 
+}
+
+
+void sm_term(void)
+{  
+    /* Switch to normal mode */
+    pci_write_cfg_byte(0, 0, REG_GROUP, 0);
+}
+
+
+int sm_get_data(uint8 *DataArray, int dimm_socket)
+{
+    int j;
+
+#if 0
+    /* Switch to PMC mode */
+    pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER));
+ 
+    /* Set GPIO Base */
+    pci_write_cfg_long(0, 0, 0x40, 0xa500);
+
+    /* Enable GPIO */
+    pci_write_cfg_byte(0, 0, 0x44, 0x11);
+
+    /* Set both GPIO 0 and 1 as output */
+    out_byte(0xA53A, 0x03); 
+#endif
+
+    sm_init();
+    /* Start reading the rom */
+
+    j = 0;
+
+    do
+    {
+	if (sm_read_byte_from_device(dimm_socket, (uint8)j, DataArray) == FALSE)
+	{
+	    sm_term();
+	    return FALSE;
+	}
+
+	DataArray++;
+	j++;
+    } while (j < 128);
+
+    sm_term();
+    return TRUE;
+}

+ 22 - 0
board/MAI/AmigaOneG3SE/smbus.h

@@ -0,0 +1,22 @@
+#ifndef _SMBUS_H_
+#define _SMBUS_H_
+
+#include "short_types.h"
+
+#define SM_DIMM0_ADDR 0x51
+#define SM_DIMM1_ADDR 0x52
+
+void sm_write_mode(void);
+void sm_read_mode(void);
+void sm_write_byte(uint8 writeme);
+uint8 sm_read_byte(void);
+int sm_get_ack(void);
+void sm_write_ack(void);
+void sm_write_nack(void);
+void sm_send_start(void);
+void sm_send_stop(void);
+int sm_read_byte_from_device(uint8 addr, uint8 reg, uint8 *storage);
+int sm_get_data(uint8 *DataArray, int dimm_socket);
+void sm_init(void);
+void sm_term(void);
+#endif

+ 201 - 0
board/MAI/AmigaOneG3SE/start.txt

@@ -0,0 +1,201 @@
+
+	/*------------------------------------------------------*/
+        /*              TERON Articia / SDRAM Init              */
+        /*------------------------------------------------------*/
+
+*       XD_CTL  = 0x81000000			(0x74)
+
+*       HBUS_ACC_CTL_0 &= 0xFFFFFDFF		(0x5c)
+                       /* host bus access ctl reg 2(5e) */
+                       /* set - CPU read from memory data one clock after data is latched */
+
+*       GLOBL_INFO_0 |= 0x00004000		(0x50)
+                      /* global info register 2 (52), AGP/PCI bus 1 arbiter is addressed in Articia S */
+
+        PCI_1_SB_CONFIG_0 |= 0x00000400         (0x80d0)
+                        /* PCI1 side band config reg 2 (d2), enable read acces while write buffer not empty */
+
+        MEM_RAS_CTL_0 |= 0x3f000000		(0xcc)
+		      &= 0x3fffffff
+                      /* RAS park control reg 0(cc), park access enable is set */
+		      
+        HOST_RDBUF_CTL |= 0x10000000		(0x70)
+	               &= 0x10ffffff
+                      /* host read buffer control reg, enable prefetch for CPU read from DRAM control */
+
+        HBUS_ACC_CTL_0 |= 0x0100001f		(0x5c)
+		       &= 0xf1ffffff
+                      /* host bus access control register, enable CPU address bus pipe control	*/
+                      /* two outstanding requests,  *** changed to 2 from 3				*/
+                      /* enable line merge write control for CPU write to system memory, PCI 1	*/
+                      /* and PCI 0 bus memory; enable page merge write control for write to		*/
+                      /* PCI bus 0 & bus 1 memory							*/
+
+        SRAM_CTL |= 0x00004000			(0xc8)
+		 &= 0xffbff7ff
+                      /* DRAM detail timing control register 1 (ca), bit 3 set to 0	*/
+                      /* DRAM start access latency control - wait for one clock	*/
+                      /* ff9f changed to ffbf						*/
+    
+        DIM0_TIM_CTL_0 = 0x737d737d             (0xc9)
+                      /* DRAM timing control for dimm0 & dimm1; set wait one clock	*/
+                      /* cycle for next data access 					*/
+
+        DIM2_TIM_CTL_0 = 0x737d737d             (0xca)
+                      /* DRAM timing control for dimm2 & dimm3; set wait one clock	*/
+                      /* cycle for next data access 					*/
+
+        DIM0_BNK0_CTL_0 = BNK0_RAM_SIZ_128MB    (0x90)
+	              /* set dimm0 bank0 for 128 MB	*/
+
+        DIM0_BNK1_CTL_0 = BNK1_RAM_SIZ_128MB    (0x94)
+                      /* set dimm0 for  bank1		*/
+
+        DIM0_TIM_CTL_0 = 0xf3bf0000             (0xc9)
+                      /* dimm0 timing control register; RAS - CAS latency - 4 clock		*/
+                      /* CAS access latency - 3 wait; pre-charge latency - 3 wait		*/
+                      /* pre-charge command period control - 5 clock; wait one clock		*/
+                      /* cycle for next data access; read to write access latency control	*/
+                      /* - 2 clock cycles							*/
+
+        DRAM_GBL_CTL_0 |= 0x00000100            (0xc0)
+		       &= 0xffff01ff
+                      /* memory global control register - support buffer sdram on bank 0	*/
+
+        DRAM_ECC_CTL_0 |= 0x00260000		(0xc4)
+		       &= 0xff26ffff
+                      /* enable ECC; enable read, modify, write control	*/
+ 
+        DRAM_REF_CTL_0 = DRAM_REF_DATA          (0xb8)
+		      /* set DRAM refresh parameters *** changed to 00940100	*/
+
+        nop
+        nop
+        nop
+        nop
+        nop
+
+        DRAM_ECC_CTL_0 |= 0x20243280		(0xc4)
+                      /* turn off ecc		*/
+                      /* for SDRAM bank 0	*/
+
+        DRAM_ECC_CTL_0 |= 0x20243290            (0xc4) ?
+                      /* for SDRAM bank 1	*/
+ 
+
+/* Additional Stuff...*/
+
+        GLOBL_CTRL |= 0x20000b00		(0x54)
+
+        PCI_0_SB_CONFIG |= 0x04100007		(0xd0)
+                      /* PCI 0 Side band config reg*/
+
+        0x8000083c |= 0x00080000
+                      /* Disable VGA decode on PCI Bus 1 */
+
+
+/*End Additional Stuff..*/
+
+        /*--------------------------------------------------------------*/
+        /*              TERON serial port initialization code           */
+        /*--------------------------------------------------------------*/
+
+	0x84380080 |= 0x00030000
+                     /* enable super IO configuration VIA chip Register 85	*/
+		     /* Enable super I/O config mode */
+
+        0xfe0003f0 = 0xe2
+        bl delay1
+
+        0xfe0003f1 = 0x0f
+	bl delay1
+	            /* enable com1 & com2, parallel port disabled */ 
+	
+	0xfe0003f0 = 0xe7
+        bl delay1
+	            /* let's make com1 base as 0x3f8 */
+        
+        0xfe0003f1 = 0xfe
+        bl delay1
+
+        0xfe0003f0 = 0xe8
+        bl delay1           
+		    /* let's make com2 base as 0x2f8 */
+
+	0xfe0003f1 = 0xbe
+
+	0x84380080 &= 0xfffdffff
+                    /* closing super IO configuration VIA chip Register 85   */
+     
+
+/* -------------------------------*/
+
+        0xfe0003fb = 0x83
+	bl delay1
+                   /*latch enable word length -8 bit */         /* set mslab bit	*/
+        0xfe0003f8 = 0x0c
+	bl delay1
+                   /* set baud rate lsb for 9600 baud	*/
+        0xfe0003f9 = 0x0
+	bl delay1
+                   /* set baud rate msb for 9600 baud	*/
+        0xfe0003fb  = 0x03
+	bl delay1
+                      /* reset mslab	*/
+
+	/*--------------------------------------------------------------*/
+        /*              END TERON Serial Port Initialization Code       */
+        /*--------------------------------------------------------------*/
+
+   
+
+        /*--------------------------------------------------------------*/
+        /*      END TERON Articia / SDRAM Initialization code           */
+        /*--------------------------------------------------------------*/
+
+Proposed from Documentation:
+
+write dmem 0xfec00cf8 0x50000080
+write dmem 0xfee00cfc 0xc0305411
+
+      Writes to index 0x50-0x53. 
+      0x50: Global Information Register 0
+	    0xC0 = Little Endian CPU, Sequential order Burst
+      0x51: Global Information Register 1
+	    Read only, 0x30 = Provides PowerPC and X86 support
+      0x52: Global Information Register 2
+	    0x05 = 64/128 bit CPU bus support
+      0x53: Global Information Register 3
+	    0x80 = PCI Bus 0 grant active time is 1 clock after REQ# deasserted
+
+write dmem 0xfec00cf8 0x5c000080
+write dmem 0xfee00cfc 0xb300011F
+
+write dmem 0xfec00cf8 0xc8000080
+write dmem 0xfee00cfc 0x0020f100
+
+write dmem 0xfec00cf8 0x90000080
+write dmem 0xfee00cfc 0x007fe700
+
+write dmem 0xfec00cf8 0x9400080
+write dmem 0xfee00cfc 0x007fe700
+
+write dmem 0xfec00cf8 0xb0000080
+write dmem 0xfee00cfc 0x737d737d
+
+write dmem 0xfec00cf8 0xb4000080
+write dmem 0xfee00cfc 0x737d737d
+
+write dmem 0xfec00cf8 0xc0000080
+write dmem 0xfee00cfc 0x40005500
+
+write dmem 0xfec00cf8 0xb8000080
+write dmem 0xfee00cfc 0x00940100
+
+write dmem 0xfec00cf8 0xc4000080
+write dmem 0xfee00cfc 0x00003280
+
+write dmem 0xfec00cf8 0xc4000080
+write dmem 0xfee00cfc 0x00003290
+
+

+ 3 - 0
board/MAI/AmigaOneG3SE/todo.txt

@@ -0,0 +1,3 @@
+- Init interrupt controller
+- init sdram
+- init ide controller

+ 131 - 0
board/MAI/AmigaOneG3SE/u-boot.lds

@@ -0,0 +1,131 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * u-boot.lds - linker script for U-Boot on the AmigaOneG3SE Board.
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+  .init          : { *(.init)	}
+  .plt : { *(.plt) }
+  .text      :
+  {
+    cpu/74xx_7xx/start.o	(.text)
+/* store the environment in a seperate sector in the boot flash */
+/*    . = env_offset; */
+    common/environment.o(.text) 
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got) 
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = ALIGN(4) /*.*/ ;
+  PROVIDE (end = ALIGN(4) /*.*/);
+}

+ 1179 - 0
board/MAI/AmigaOneG3SE/usb_uhci.c

@@ -0,0 +1,1179 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Note: Part of this code has been derived from linux
+ *
+ */
+
+/**********************************************************************
+ * How it works:
+ * -------------
+ * The framelist / Transfer descriptor / Queue Heads are similar like
+ * in the linux usb_uhci.c.
+ *
+ * During initialization, the following skeleton is allocated in init_skel:
+ *
+ *         framespecific           |           common chain
+ *
+ * framelist[]
+ * [  0 ]-----> TD ---------\
+ * [  1 ]-----> TD ----------> TD ------> QH -------> QH -------> QH ---> NULL
+ *   ...        TD ---------/
+ * [1023]-----> TD --------/
+ *
+ *              ^^             ^^         ^^          ^^          ^^
+ *              7 TDs for      1 TD for   Start of    Start of    End Chain
+ *              INT (2-128ms)  1ms-INT    CTRL Chain  BULK Chain
+ *
+ *
+ * Since this is a bootloader, the isochronous transfer descriptor have been removed.
+ *
+ * Interrupt Transfers.
+ * --------------------
+ * For Interupt transfers USB_MAX_TEMP_INT_TD Transfer descriptor are available. They
+ * will be inserted after the appropriate (depending the interval setting) skeleton TD.
+ * If an interrupt has been detected the dev->irqhandler is called. The status and number
+ * of transfered bytes is stored in dev->irq_status resp. dev->irq_act_len. If the
+ * dev->irqhandler returns 0, the interrupt TD is removed and disabled. If an 1 is returned,
+ * the interrupt TD will be reactivated.
+ *
+ * Control Transfers
+ * -----------------
+ * Control Transfers are issued by filling the tmp_td with the appropriate data and connect
+ * them to the qh_cntrl queue header. Before other control/bulk transfers can be issued,
+ * the programm has to wait for completion. This does not allows asynchronous data transfer.
+ *
+ * Bulk Transfers
+ * --------------
+ * Bulk Transfers are issued by filling the tmp_td with the appropriate data and connect
+ * them to the qh_bulk queue header. Before other control/bulk transfers can be issued,
+ * the programm has to wait for completion. This does not allows asynchronous data transfer.
+ *
+ *
+ */
+
+#include <common.h>
+#include <pci.h>
+
+#ifdef CONFIG_USB_UHCI
+
+#include <usb.h>
+#include "usb_uhci.h"
+
+#define USB_MAX_TEMP_TD      128  /* number of temporary TDs for bulk and control transfers */
+#define USB_MAX_TEMP_INT_TD  32   /* number of temporary TDs for Interrupt transfers */
+
+
+//#define USB_UHCI_DEBUG
+
+#ifdef	USB_UHCI_DEBUG
+#define	USB_UHCI_PRINTF(fmt,args...)	printf (fmt ,##args)
+#else
+#define USB_UHCI_PRINTF(fmt,args...)
+#endif
+
+
+static int irqvec = -1;            /* irq vector, if -1 uhci is stopped / reseted */
+unsigned int usb_base_addr;       /* base address */
+
+static uhci_td_t td_int[8];        /* Interrupt Transfer descriptors */
+static uhci_qh_t qh_cntrl;         /* control Queue Head */
+static uhci_qh_t qh_bulk;          /*  bulk Queue Head */
+static uhci_qh_t qh_end;           /* end Queue Head */
+static uhci_td_t td_last;          /* last TD (linked with end chain) */
+
+/* temporary tds */
+static uhci_td_t tmp_td[USB_MAX_TEMP_TD];          /* temporary bulk/control td's  */
+static uhci_td_t tmp_int_td[USB_MAX_TEMP_INT_TD];  /* temporary interrupt td's  */
+
+static unsigned long framelist[1024] __attribute__ ((aligned (0x1000))); /* frame list */
+
+static struct virt_root_hub rh;   /* struct for root hub */
+
+/**********************************************************************
+ * some forward decleration
+ */
+int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
+						void *buffer, int transfer_len,struct devrequest *setup);
+
+/* fill a td with the approproiate data. Link, status, info and buffer
+ * are used by the USB controller itselfes, dev is used to identify the
+ * "connected" device
+ */
+void usb_fill_td(uhci_td_t* td,unsigned long link,unsigned long status,
+					unsigned long info, unsigned long buffer, unsigned long dev)
+{
+	td->link=swap_32(link);
+	td->status=swap_32(status);
+	td->info=swap_32(info);
+	td->buffer=swap_32(buffer);
+	td->dev_ptr=dev;
+}
+
+/* fill a qh with the approproiate data. Head and element are used by the USB controller
+ * itselfes. As soon as a valid dev_ptr is filled, a td chain is connected to the qh.
+ * Please note, that after completion of the td chain, the entry element is removed /
+ * marked invalid by the USB controller.
+ */
+void usb_fill_qh(uhci_qh_t* qh,unsigned long head,unsigned long element)
+{
+	qh->head=swap_32(head);
+	qh->element=swap_32(element);
+	qh->dev_ptr=0L;
+}
+
+/* get the status of a td->status
+ */
+unsigned long usb_uhci_td_stat(unsigned long status)
+{
+	unsigned long result=0;
+	result |= (status & TD_CTRL_NAK)      ? USB_ST_NAK_REC : 0;
+	result |= (status & TD_CTRL_STALLED)  ? USB_ST_STALLED : 0;
+	result |= (status & TD_CTRL_DBUFERR)  ? USB_ST_BUF_ERR : 0;
+	result |= (status & TD_CTRL_BABBLE)   ? USB_ST_BABBLE_DET : 0;
+	result |= (status & TD_CTRL_CRCTIMEO) ? USB_ST_CRC_ERR : 0;
+	result |= (status & TD_CTRL_BITSTUFF) ? USB_ST_BIT_ERR : 0;
+	result |= (status & TD_CTRL_ACTIVE)   ? USB_ST_NOT_PROC : 0;
+	return result;
+}
+
+/* get the status and the transfered len of a td chain.
+ * called from the completion handler
+ */
+int usb_get_td_status(uhci_td_t *td,struct usb_device *dev)
+{
+	unsigned long temp,info;
+	unsigned long stat;
+	uhci_td_t *mytd=td;
+
+	if(dev->devnum==rh.devnum)
+		return 0;
+	dev->act_len=0;
+	stat=0;
+	do {
+		temp=swap_32((unsigned long)mytd->status);
+		stat=usb_uhci_td_stat(temp);
+		info=swap_32((unsigned long)mytd->info);
+		if(((info & 0xff)!= USB_PID_SETUP) &&
+				(((info >> 21) & 0x7ff)!= 0x7ff) &&
+				(temp & 0x7FF)!=0x7ff)
+		{  /* if not setup and not null data pack */
+			dev->act_len+=(temp & 0x7FF) + 1; /* the transfered len is act_len + 1 */
+		}
+		if(stat) {           /* status no ok */
+			dev->status=stat;
+			return -1;
+		}
+		temp=swap_32((unsigned long)mytd->link);
+		mytd=(uhci_td_t *)(temp & 0xfffffff0);
+	}while((temp & 0x1)==0); /* process all TDs */
+	dev->status=stat;
+	return 0; /* Ok */
+}
+
+
+/*-------------------------------------------------------------------
+ *                         LOW LEVEL STUFF
+ *          assembles QHs und TDs for control, bulk and iso
+ *-------------------------------------------------------------------*/
+
+/* Submits a control message. That is a Setup, Data and Status transfer.
+ * Routine does not wait for completion.
+ */
+int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+										int transfer_len,struct devrequest *setup)
+{
+	unsigned long destination, status;
+	int maxsze = usb_maxpacket(dev, pipe);
+	unsigned long dataptr;
+	int len;
+	int pktsze;
+	int i=0;
+
+	if (!maxsze) {
+		USB_UHCI_PRINTF("uhci_submit_control_urb: pipesize for pipe %lx is zero\n", pipe);
+		return -1;
+	}
+	if(((pipe>>8)&0x7f)==rh.devnum) {
+		/* this is the root hub -> redirect it */
+		return uhci_submit_rh_msg(dev,pipe,buffer,transfer_len,setup);
+	}
+	USB_UHCI_PRINTF("uhci_submit_control start len %x, maxsize %x\n",transfer_len,maxsze);
+	/* The "pipe" thing contains the destination in bits 8--18 */
+	destination = (pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; /* Setup stage */
+	/* 3 errors */
+	status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27);
+	/* (urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD); */
+	/*  Build the TD for the control request, try forever, 8 bytes of data */
+	usb_fill_td(&tmp_td[i],UHCI_PTR_TERM ,status, destination | (7 << 21),(unsigned long)setup,(unsigned long)dev);
+#if 0
+	{
+		char *sp=(char *)setup;
+		printf("SETUP to pipe %lx: %x %x %x %x %x %x %x %x\n", pipe,
+		    sp[0],sp[1],sp[2],sp[3],sp[4],sp[5],sp[6],sp[7]);
+	}
+#endif
+	dataptr = (unsigned long)buffer;
+	len=transfer_len;
+
+	/* If direction is "send", change the frame from SETUP (0x2D)
+	   to OUT (0xE1). Else change it from SETUP to IN (0x69). */
+	destination = (pipe & PIPE_DEVEP_MASK) | ((pipe & USB_DIR_IN)==0 ? USB_PID_OUT : USB_PID_IN);
+	while (len > 0) {
+		/* data stage */
+		pktsze = len;
+		i++;
+		if (pktsze > maxsze)
+			pktsze = maxsze;
+		destination ^= 1 << TD_TOKEN_TOGGLE;	/* toggle DATA0/1 */
+		usb_fill_td(&tmp_td[i],UHCI_PTR_TERM, status, destination | ((pktsze - 1) << 21),dataptr,(unsigned long)dev);	/* Status, pktsze bytes of data */
+		tmp_td[i-1].link=swap_32((unsigned long)&tmp_td[i]);
+
+		dataptr += pktsze;
+		len -= pktsze;
+	}
+
+	/*  Build the final TD for control status */
+	/* It's only IN if the pipe is out AND we aren't expecting data */
+
+	destination &= ~UHCI_PID;
+	if (((pipe & USB_DIR_IN)==0) || (transfer_len == 0))
+		destination |= USB_PID_IN;
+	else
+		destination |= USB_PID_OUT;
+	destination |= 1 << TD_TOKEN_TOGGLE;	/* End in Data1 */
+	i++;
+	status &=~TD_CTRL_SPD;
+	/* no limit on errors on final packet , 0 bytes of data */
+	usb_fill_td(&tmp_td[i],UHCI_PTR_TERM, status | TD_CTRL_IOC, destination | (UHCI_NULL_DATA_SIZE << 21),0,(unsigned long)dev);
+	tmp_td[i-1].link=swap_32((unsigned long)&tmp_td[i]);	/* queue status td */
+	/*	usb_show_td(i+1);*/
+	USB_UHCI_PRINTF("uhci_submit_control end (%d tmp_tds used)\n",i);
+	/* first mark the control QH element terminated */
+	qh_cntrl.element=0xffffffffL;
+	/* set qh active */
+	qh_cntrl.dev_ptr=(unsigned long)dev;
+	/* fill in tmp_td_chain */
+	qh_cntrl.element=swap_32((unsigned long)&tmp_td[0]);
+	return 0;
+}
+
+/*-------------------------------------------------------------------
+ * Prepare TDs for bulk transfers.
+ */
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len)
+{
+	unsigned long destination, status,info;
+	unsigned long dataptr;
+	int maxsze = usb_maxpacket(dev, pipe);
+	int len;
+	int i=0;
+
+	if(transfer_len < 0) {
+		printf("Negative transfer length in submit_bulk\n");
+		return -1;
+	}
+	if (!maxsze)
+		return -1;
+	/* The "pipe" thing contains the destination in bits 8--18. */
+	destination = (pipe & PIPE_DEVEP_MASK) | usb_packetid (pipe);
+	/* 3 errors */
+	status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27);
+	/*	((urb->transfer_flags & USB_DISABLE_SPD) ? 0 : TD_CTRL_SPD) | (3 << 27); */
+	/* Build the TDs for the bulk request */
+	len = transfer_len;
+	dataptr = (unsigned long)buffer;
+	do {
+		int pktsze = len;
+		if (pktsze > maxsze)
+			pktsze = maxsze;
+		/* pktsze bytes of data  */
+		info = destination | (((pktsze - 1)&UHCI_NULL_DATA_SIZE) << 21) |
+			(usb_gettoggle (dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)) << TD_TOKEN_TOGGLE);
+
+		if((len-pktsze)==0)
+			status |= TD_CTRL_IOC;	/* last one generates INT */
+
+		usb_fill_td(&tmp_td[i],UHCI_PTR_TERM, status, info,dataptr,(unsigned long)dev);	/* Status, pktsze bytes of data */
+		if(i>0)
+			tmp_td[i-1].link=swap_32((unsigned long)&tmp_td[i]);
+		i++;
+		dataptr += pktsze;
+		len -= pktsze;
+		usb_dotoggle (dev, usb_pipeendpoint (pipe), usb_pipeout (pipe));
+	} while (len > 0);
+	/* first mark the bulk QH element terminated */
+	qh_bulk.element=0xffffffffL;
+	/* set qh active */
+	qh_bulk.dev_ptr=(unsigned long)dev;
+	/* fill in tmp_td_chain */
+	qh_bulk.element=swap_32((unsigned long)&tmp_td[0]);
+	return 0;
+}
+
+
+/* search a free interrupt td
+ */
+uhci_td_t *uhci_alloc_int_td(void)
+{
+	int i;
+	for(i=0;i<USB_MAX_TEMP_INT_TD;i++) {
+		if(tmp_int_td[i].dev_ptr==0) /* no device assigned -> free TD */
+			return &tmp_int_td[i];
+	}
+	return NULL;
+}
+
+#if 0
+void uhci_show_temp_int_td(void)
+{
+	int i;
+	for(i=0;i<USB_MAX_TEMP_INT_TD;i++) {
+		if((tmp_int_td[i].dev_ptr&0x01)!=0x1L) /* no device assigned -> free TD */
+			printf("temp_td %d is assigned to dev %lx\n",i,tmp_int_td[i].dev_ptr);
+	}
+	printf("all others temp_tds are free\n");
+}
+#endif
+/*-------------------------------------------------------------------
+ * submits USB interrupt (ie. polling ;-)
+ */
+int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len, int interval)
+{
+	int nint, n;
+	unsigned long status, destination;
+	unsigned long info,tmp;
+	uhci_td_t *mytd;
+	if (interval < 0 || interval >= 256)
+		return -1;
+
+	if (interval == 0)
+		nint = 0;
+	else {
+		for (nint = 0, n = 1; nint <= 8; nint++, n += n)	/* round interval down to 2^n */
+		 {
+			if(interval < n) {
+				interval = n / 2;
+				break;
+			}
+		}
+		nint--;
+	}
+
+	USB_UHCI_PRINTF("Rounded interval to %i, chain  %i\n", interval, nint);
+	mytd=uhci_alloc_int_td();
+	if(mytd==NULL) {
+		printf("No free INT TDs found\n");
+		return -1;
+	}
+	status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_IOC | (3 << 27);
+/*		(urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (3 << 27);
+*/
+
+	destination =(pipe & PIPE_DEVEP_MASK) | usb_packetid (pipe) | (((transfer_len - 1) & 0x7ff) << 21);
+
+	info = destination | (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) << TD_TOKEN_TOGGLE);
+	tmp = swap_32(td_int[nint].link);
+	usb_fill_td(mytd,tmp,status, info,(unsigned long)buffer,(unsigned long)dev);
+	/* Link it */
+	tmp = swap_32((unsigned long)mytd);
+	td_int[nint].link=tmp;
+
+	usb_dotoggle (dev, usb_pipeendpoint (pipe), usb_pipeout (pipe));
+
+	return 0;
+}
+
+/**********************************************************************
+ * Low Level functions
+ */
+
+
+void reset_hc(void)
+{
+
+	/* Global reset for 100ms */
+	out16r( usb_base_addr + USBPORTSC1,0x0204);
+	out16r( usb_base_addr + USBPORTSC2,0x0204);
+	out16r( usb_base_addr + USBCMD,USBCMD_GRESET | USBCMD_RS);
+	/* Turn off all interrupts */
+	out16r(usb_base_addr + USBINTR,0);
+	wait_ms(50);
+	out16r( usb_base_addr + USBCMD,0);
+	wait_ms(10);
+}
+
+void start_hc(void)
+{
+	int timeout = 1000;
+
+	while(in16r(usb_base_addr + USBCMD) & USBCMD_HCRESET) {
+		if (!--timeout) {
+			printf("USBCMD_HCRESET timed out!\n");
+			break;
+		}
+	}
+	/* Turn on all interrupts */
+	out16r(usb_base_addr + USBINTR,USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP);
+	/* Start at frame 0 */
+	out16r(usb_base_addr + USBFRNUM,0);
+	/* set Framebuffer base address */
+	out32r(usb_base_addr+USBFLBASEADD,(unsigned long)&framelist);
+	/* Run and mark it configured with a 64-byte max packet */
+	out16r(usb_base_addr + USBCMD,USBCMD_RS | USBCMD_CF | USBCMD_MAXP);
+}
+
+/* Initialize the skeleton
+ */
+void usb_init_skel(void)
+{
+	unsigned long temp;
+	int n;
+
+	for(n=0;n<USB_MAX_TEMP_INT_TD;n++)
+		tmp_int_td[n].dev_ptr=0L; /* no devices connected */
+	/* last td */
+	usb_fill_td(&td_last,UHCI_PTR_TERM,TD_CTRL_IOC ,0,0,0L);
+  /* usb_fill_td(&td_last,UHCI_PTR_TERM,0,0,0); */
+	/* End Queue Header */
+	usb_fill_qh(&qh_end,UHCI_PTR_TERM,(unsigned long)&td_last);
+	/* Bulk Queue Header */
+	temp=(unsigned long)&qh_end;
+	usb_fill_qh(&qh_bulk,temp | UHCI_PTR_QH,UHCI_PTR_TERM);
+	/* Control Queue Header */
+	temp=(unsigned long)&qh_bulk;
+	usb_fill_qh(&qh_cntrl, temp | UHCI_PTR_QH,UHCI_PTR_TERM);
+	/* 1ms Interrupt td */
+	temp=(unsigned long)&qh_cntrl;
+	usb_fill_td(&td_int[0],temp | UHCI_PTR_QH,0,0,0,0L);
+	temp=(unsigned long)&td_int[0];
+	for(n=1; n<8; n++)
+		usb_fill_td(&td_int[n],temp,0,0,0,0L);
+	for (n = 0; n < 1024; n++) {
+	/* link all framelist pointers to one of the interrupts */
+		int m, o;
+		if ((n&127)==127)
+			framelist[n]= swap_32((unsigned long)&td_int[0]);
+		else
+			for (o = 1, m = 2; m <= 128; o++, m += m)
+				if ((n & (m - 1)) == ((m - 1) / 2))
+						framelist[n]= swap_32((unsigned long)&td_int[o]);
+	}
+}
+
+/* check the common skeleton for completed transfers, and update the status
+ * of the "connected" device. Called from the IRQ routine.
+ */
+void usb_check_skel(void)
+{
+	struct usb_device *dev;
+	/* start with the control qh */
+	if(qh_cntrl.dev_ptr!=0) /* it's a device assigned check if this caused IRQ */
+	{
+		dev=(struct usb_device *)qh_cntrl.dev_ptr;
+		usb_get_td_status(&tmp_td[0],dev); /* update status */
+		if(!(dev->status & USB_ST_NOT_PROC)) { /* is not active anymore, disconnect devices */
+			qh_cntrl.dev_ptr=0;
+		}
+	}
+	/* now process the bulk */
+	if(qh_bulk.dev_ptr!=0) /* it's a device assigned check if this caused IRQ */
+	{
+		dev=(struct usb_device *)qh_bulk.dev_ptr;
+		usb_get_td_status(&tmp_td[0],dev); /* update status */
+		if(!(dev->status & USB_ST_NOT_PROC)) { /* is not active anymore, disconnect devices */
+			qh_bulk.dev_ptr=0;
+		}
+	}
+}
+
+/* check the interrupt chain, ubdate the status of the appropriate device,
+ * call the appropriate irqhandler and reactivate the TD if the irqhandler
+ * returns with 1
+ */
+void usb_check_int_chain(void)
+{
+	int i,res;
+	unsigned long link,status;
+	struct usb_device *dev;
+	uhci_td_t *td,*prevtd;
+
+	for(i=0;i<8;i++) {
+		prevtd=&td_int[i]; /* the first previous td is the skeleton td */
+		link=swap_32(td_int[i].link) & 0xfffffff0; /* next in chain */
+		td=(uhci_td_t *)link; /* assign it */
+		/* all interrupt TDs are finally linked to the td_int[0].
+ 		 * so we process all until we find the td_int[0].
+		 * if int0 chain points to a QH, we're also done
+	   */
+		while(((i>0) && (link != (unsigned long)&td_int[0])) ||
+					((i==0) && !(swap_32(td->link) &  UHCI_PTR_QH)))
+		{
+			/* check if a device is assigned with this td */
+			status=swap_32(td->status);
+			if((td->dev_ptr!=0L) && !(status & TD_CTRL_ACTIVE)) {
+				/* td is not active and a device is assigned -> call irqhandler */
+				dev=(struct usb_device *)td->dev_ptr;
+				dev->irq_act_len=((status & 0x7FF)==0x7FF) ? 0 : (status & 0x7FF) + 1; /* transfered length */
+				dev->irq_status=usb_uhci_td_stat(status); /* get status */
+				res=dev->irq_handle(dev); /* call irqhandler */
+				if(res==1) {
+					/* reactivate */
+					status|=TD_CTRL_ACTIVE;
+					td->status=swap_32(status);
+					prevtd=td; /* previous td = this td */
+				}
+				else {
+					prevtd->link=td->link; /* link previous td directly to the nex td -> unlinked */
+					/* remove device pointer */
+					td->dev_ptr=0L;
+				}
+			} /* if we call the irq handler */
+			link=swap_32(td->link) & 0xfffffff0; /* next in chain */
+			td=(uhci_td_t *)link; /* assign it */
+		} /* process all td in this int chain */
+	} /* next interrupt chain */
+}
+
+
+/* usb interrupt service routine.
+ */
+void handle_usb_interrupt(void)
+{
+	unsigned short status;
+
+	/*
+	 * Read the interrupt status, and write it back to clear the
+	 * interrupt cause
+	 */
+
+	status = in16r(usb_base_addr + USBSTS);
+
+	if (!status)		/* shared interrupt, not mine */
+		return;
+	if (status != 1) {
+		/* remove host controller halted state */
+		if ((status&0x20) && ((in16r(usb_base_addr+USBCMD) && USBCMD_RS)==0)) {
+			out16r(usb_base_addr + USBCMD, USBCMD_RS | in16r(usb_base_addr + USBCMD));
+		}
+	}
+	usb_check_int_chain(); /* call interrupt handlers for int tds */
+	usb_check_skel(); /* call completion handler for common transfer routines */
+	out16r(usb_base_addr+USBSTS,status);
+}
+
+
+/* init uhci
+ */
+int usb_lowlevel_init(void)
+{
+	unsigned char temp;
+	int	busdevfunc;
+/*
+ * HJF - configure IRQ and base from variables optionally.
+ */
+	char *s;
+
+
+	busdevfunc=pci_find_device(USB_UHCI_VEND_ID,USB_UHCI_DEV_ID,0); /* get PCI Device ID */
+	if(busdevfunc==-1) {
+		printf("Error USB UHCI (%04X,%04X) not found\n",USB_UHCI_VEND_ID,USB_UHCI_DEV_ID);
+		return -1;
+	}
+	
+#if 1
+	s = getenv("usb_irq");
+	if (s)
+	{
+	    temp = atoi(s);
+	    pci_write_config_byte(busdevfunc, PCI_INTERRUPT_LINE, temp);
+	}
+	else
+#endif
+	    pci_read_config_byte(busdevfunc,PCI_INTERRUPT_LINE,&temp);
+
+	s = getenv("usb_base");
+	if (s)
+	{
+	    unsigned long temp2;
+	    temp2 = atoi(s);
+	    pci_write_config_dword(busdevfunc, PCI_BASE_ADDRESS_4, temp2|0x01);
+	}
+
+	irqvec = temp;
+	irq_free_handler(irqvec);
+	USB_UHCI_PRINTF("Interrupt Line = %d\n",irqvec);
+	pci_read_config_byte(busdevfunc,PCI_INTERRUPT_PIN,&temp);
+	USB_UHCI_PRINTF("Interrupt Pin = %ld\n",temp);
+	pci_read_config_dword(busdevfunc,PCI_BASE_ADDRESS_4,&usb_base_addr);
+	USB_UHCI_PRINTF("IO Base Address = 0x%lx\n",usb_base_addr);
+	usb_base_addr&=0xFFFFFFF0;
+	usb_base_addr+=CFG_ISA_IO_BASE_ADDRESS;
+	rh.devnum = 0;
+	usb_init_skel();
+	reset_hc();
+	start_hc();
+	irq_install_handler(irqvec, (interrupt_handler_t *)handle_usb_interrupt, NULL);
+	irq_install_handler(0, (interrupt_handler_t *)handle_usb_interrupt, NULL);
+
+	return 0;
+}
+
+/* stop uhci
+ */
+int usb_lowlevel_stop(void)
+{
+	if(irqvec==-1)
+		return 1;
+	irq_free_handler(irqvec);
+	irq_free_handler(0);
+	reset_hc();
+	irqvec=-1;
+	return 0;
+}
+
+/*******************************************************************************************
+ * Virtual Root Hub
+ * Since the uhci does not have a real HUB, we simulate one ;-)
+ */
+#undef	USB_RH_DEBUG
+
+#ifdef	USB_RH_DEBUG
+#define	USB_RH_PRINTF(fmt,args...)	printf (fmt ,##args)
+static void usb_display_wValue(unsigned short wValue,unsigned short wIndex);
+static void usb_display_Req(unsigned short req);
+#else
+#define USB_RH_PRINTF(fmt,args...)
+static void usb_display_wValue(unsigned short wValue,unsigned short wIndex) {}
+static void usb_display_Req(unsigned short req) {}
+#endif
+
+static unsigned char root_hub_dev_des[] =
+{
+	0x12,			/*  __u8  bLength; */
+	0x01,			/*  __u8  bDescriptorType; Device */
+	0x00,			/*  __u16 bcdUSB; v1.0 */
+	0x01,
+	0x09,			/*  __u8  bDeviceClass; HUB_CLASSCODE */
+	0x00,			/*  __u8  bDeviceSubClass; */
+	0x00,			/*  __u8  bDeviceProtocol; */
+	0x08,			/*  __u8  bMaxPacketSize0; 8 Bytes */
+	0x00,			/*  __u16 idVendor; */
+	0x00,
+	0x00,			/*  __u16 idProduct; */
+	0x00,
+	0x00,			/*  __u16 bcdDevice; */
+	0x00,
+	0x01,			/*  __u8  iManufacturer; */
+	0x00,			/*  __u8  iProduct; */
+	0x00,			/*  __u8  iSerialNumber; */
+	0x01			/*  __u8  bNumConfigurations; */
+};
+
+
+/* Configuration descriptor */
+static unsigned char root_hub_config_des[] =
+{
+	0x09,			/*  __u8  bLength; */
+	0x02,			/*  __u8  bDescriptorType; Configuration */
+	0x19,			/*  __u16 wTotalLength; */
+	0x00,
+	0x01,			/*  __u8  bNumInterfaces; */
+	0x01,			/*  __u8  bConfigurationValue; */
+	0x00,			/*  __u8  iConfiguration; */
+	0x40,			/*  __u8  bmAttributes;
+				   Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
+	0x00,			/*  __u8  MaxPower; */
+
+     /* interface */
+	0x09,			/*  __u8  if_bLength; */
+	0x04,			/*  __u8  if_bDescriptorType; Interface */
+	0x00,			/*  __u8  if_bInterfaceNumber; */
+	0x00,			/*  __u8  if_bAlternateSetting; */
+	0x01,			/*  __u8  if_bNumEndpoints; */
+	0x09,			/*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
+	0x00,			/*  __u8  if_bInterfaceSubClass; */
+	0x00,			/*  __u8  if_bInterfaceProtocol; */
+	0x00,			/*  __u8  if_iInterface; */
+
+     /* endpoint */
+	0x07,			/*  __u8  ep_bLength; */
+	0x05,			/*  __u8  ep_bDescriptorType; Endpoint */
+	0x81,			/*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
+	0x03,			/*  __u8  ep_bmAttributes; Interrupt */
+	0x08,			/*  __u16 ep_wMaxPacketSize; 8 Bytes */
+	0x00,
+	0xff			/*  __u8  ep_bInterval; 255 ms */
+};
+
+
+static unsigned char root_hub_hub_des[] =
+{
+	0x09,			/*  __u8  bLength; */
+	0x29,			/*  __u8  bDescriptorType; Hub-descriptor */
+	0x02,			/*  __u8  bNbrPorts; */
+	0x00,			/* __u16  wHubCharacteristics; */
+	0x00,
+	0x01,			/*  __u8  bPwrOn2pwrGood; 2ms */
+	0x00,			/*  __u8  bHubContrCurrent; 0 mA */
+	0x00,			/*  __u8  DeviceRemovable; *** 7 Ports max *** */
+	0xff			/*  __u8  PortPwrCtrlMask; *** 7 ports max *** */
+};
+
+static unsigned char root_hub_str_index0[] =
+{
+	0x04,			/*  __u8  bLength; */
+	0x03,			/*  __u8  bDescriptorType; String-descriptor */
+	0x09,			/*  __u8  lang ID */
+	0x04,			/*  __u8  lang ID */
+};
+
+static unsigned char root_hub_str_index1[] =
+{
+	28,			/*  __u8  bLength; */
+	0x03,			/*  __u8  bDescriptorType; String-descriptor */
+	'U',			/*  __u8  Unicode */
+	0,				/*  __u8  Unicode */
+	'H',			/*  __u8  Unicode */
+	0,				/*  __u8  Unicode */
+	'C',			/*  __u8  Unicode */
+	0,				/*  __u8  Unicode */
+	'I',			/*  __u8  Unicode */
+	0,				/*  __u8  Unicode */
+	' ',			/*  __u8  Unicode */
+	0,				/*  __u8  Unicode */
+	'R',			/*  __u8  Unicode */
+	0,				/*  __u8  Unicode */
+	'o',			/*  __u8  Unicode */
+	0,				/*  __u8  Unicode */
+	'o',			/*  __u8  Unicode */
+	0,				/*  __u8  Unicode */
+	't',			/*  __u8  Unicode */
+	0,				/*  __u8  Unicode */
+	' ',			/*  __u8  Unicode */
+	0,				/*  __u8  Unicode */
+	'H',			/*  __u8  Unicode */
+	0,				/*  __u8  Unicode */
+	'u',			/*  __u8  Unicode */
+	0,				/*  __u8  Unicode */
+	'b',			/*  __u8  Unicode */
+	0,				/*  __u8  Unicode */
+};
+
+
+/*
+ * Root Hub Control Pipe (interrupt Pipes are not supported)
+ */
+
+
+int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len,struct devrequest *cmd)
+{
+	void *data = buffer;
+	int leni = transfer_len;
+	int len = 0;
+	int status = 0;
+	int stat = 0;
+	int i;
+
+	unsigned short cstatus;
+
+	unsigned short bmRType_bReq;
+	unsigned short wValue;
+	unsigned short wIndex;
+	unsigned short wLength;
+
+	if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
+		printf("Root-Hub submit IRQ: NOT implemented\n");
+#if 0
+		uhci->rh.urb = urb;
+		uhci->rh.send = 1;
+		uhci->rh.interval = urb->interval;
+		rh_init_int_timer (urb);
+#endif
+		return 0;
+	}
+	bmRType_bReq = cmd->requesttype | cmd->request << 8;
+	wValue = swap_16(cmd->value);
+	wIndex = swap_16(cmd->index);
+	wLength = swap_16(cmd->length);
+	usb_display_Req(bmRType_bReq);
+	for (i = 0; i < 8; i++)
+		rh.c_p_r[i] = 0;
+	USB_RH_PRINTF("Root-Hub: adr: %2x cmd(%1x): %02x%02x %04x %04x %04x\n",
+	     dev->devnum, 8, cmd->requesttype,cmd->request, wValue, wIndex, wLength);
+
+	switch (bmRType_bReq) {
+		/* Request Destination:
+		   without flags: Device,
+		   RH_INTERFACE: interface,
+		   RH_ENDPOINT: endpoint,
+		   RH_CLASS means HUB here,
+		   RH_OTHER | RH_CLASS  almost ever means HUB_PORT here
+		 */
+
+	case RH_GET_STATUS:
+		*(unsigned short *) data = swap_16(1);
+		len=2;
+		break;
+	case RH_GET_STATUS | RH_INTERFACE:
+		*(unsigned short *) data = swap_16(0);
+		len=2;
+		break;
+	case RH_GET_STATUS | RH_ENDPOINT:
+		*(unsigned short *) data = swap_16(0);
+		len=2;
+		break;
+	case RH_GET_STATUS | RH_CLASS:
+		*(unsigned long *) data = swap_32(0);
+		len=4;
+		break;	/* hub power ** */
+	case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+
+		status = in16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1));
+		cstatus = ((status & USBPORTSC_CSC) >> (1 - 0)) |
+			((status & USBPORTSC_PEC) >> (3 - 1)) |
+			(rh.c_p_r[wIndex - 1] << (0 + 4));
+		status = (status & USBPORTSC_CCS) |
+			((status & USBPORTSC_PE) >> (2 - 1)) |
+			((status & USBPORTSC_SUSP) >> (12 - 2)) |
+			((status & USBPORTSC_PR) >> (9 - 4)) |
+			(1 << 8) |	/* power on ** */
+			((status & USBPORTSC_LSDA) << (-8 + 9));
+
+		*(unsigned short *) data = swap_16(status);
+		*(unsigned short *) (data + 2) = swap_16(cstatus);
+		len=4;
+		break;
+	case RH_CLEAR_FEATURE | RH_ENDPOINT:
+		switch (wValue) {
+		case (RH_ENDPOINT_STALL):
+			len=0;
+			break;
+		}
+		break;
+
+	case RH_CLEAR_FEATURE | RH_CLASS:
+		switch (wValue) {
+		case (RH_C_HUB_OVER_CURRENT):
+			len=0;	/* hub power over current ** */
+			break;
+		}
+		break;
+
+	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+		usb_display_wValue(wValue,wIndex);
+		switch (wValue) {
+		case (RH_PORT_ENABLE):
+			status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+			status = (status & 0xfff5) & ~USBPORTSC_PE;
+			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+			len=0;
+			break;
+		case (RH_PORT_SUSPEND):
+			status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+			status = (status & 0xfff5) & ~USBPORTSC_SUSP;
+			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+			len=0;
+			break;
+		case (RH_PORT_POWER):
+			len=0;	/* port power ** */
+			break;
+		case (RH_C_PORT_CONNECTION):
+			status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+			status = (status & 0xfff5) | USBPORTSC_CSC;
+			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+			len=0;
+			break;
+		case (RH_C_PORT_ENABLE):
+			status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+			status = (status & 0xfff5) | USBPORTSC_PEC;
+			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+			len=0;
+			break;
+		case (RH_C_PORT_SUSPEND):
+/*** WR_RH_PORTSTAT(RH_PS_PSSC); */
+			len=0;
+			break;
+		case (RH_C_PORT_OVER_CURRENT):
+			len=0;
+			break;
+		case (RH_C_PORT_RESET):
+			rh.c_p_r[wIndex - 1] = 0;
+			len=0;
+			break;
+		}
+		break;
+	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+		usb_display_wValue(wValue,wIndex);
+		switch (wValue) {
+		case (RH_PORT_SUSPEND):
+			status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+			status = (status & 0xfff5) | USBPORTSC_SUSP;
+			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+			len=0;
+			break;
+		case (RH_PORT_RESET):
+			status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+			status = (status & 0xfff5) | USBPORTSC_PR;
+			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+			wait_ms(10);
+			status = (status & 0xfff5) & ~USBPORTSC_PR;
+			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+			udelay(10);
+			status = (status & 0xfff5) | USBPORTSC_PE;
+			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+			wait_ms(10);
+			status = (status & 0xfff5) | 0xa;
+			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+			len=0;
+			break;
+		case (RH_PORT_POWER):
+			len=0;	/* port power ** */
+			break;
+		case (RH_PORT_ENABLE):
+			status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+			status = (status & 0xfff5) | USBPORTSC_PE;
+			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+			len=0;
+			break;
+		}
+		break;
+
+	case RH_SET_ADDRESS:
+		rh.devnum = wValue;
+		len=0;
+		break;
+	case RH_GET_DESCRIPTOR:
+		switch ((wValue & 0xff00) >> 8) {
+		case (0x01):	/* device descriptor */
+			i=sizeof(root_hub_config_des);
+			status=i > wLength ? wLength : i;
+			len = leni > status ? status : leni;
+			memcpy (data, root_hub_dev_des, len);
+			break;
+		case (0x02):	/* configuration descriptor */
+			i=sizeof(root_hub_config_des);
+			status=i > wLength ? wLength : i;
+			len = leni > status ? status : leni;
+			memcpy (data, root_hub_config_des, len);
+			break;
+		case (0x03):	/*string descriptors */
+			if(wValue==0x0300) {
+				i=sizeof(root_hub_str_index0);
+				status = i > wLength ? wLength : i;
+				len = leni > status ? status : leni;
+				memcpy (data, root_hub_str_index0, len);
+				break;
+			}
+			if(wValue==0x0301) {
+				i=sizeof(root_hub_str_index1);
+				status = i > wLength ? wLength : i;
+				len = leni > status ? status : leni;
+				memcpy (data, root_hub_str_index1, len);
+				break;
+			}
+			stat = USB_ST_STALLED;
+		}
+		break;
+
+	case RH_GET_DESCRIPTOR | RH_CLASS:
+		root_hub_hub_des[2] = 2;
+		i=sizeof(root_hub_hub_des);
+		status= i > wLength ? wLength : i;
+		len = leni > status ? status : leni;
+		memcpy (data, root_hub_hub_des, len);
+		break;
+	case RH_GET_CONFIGURATION:
+		*(unsigned char *) data = 0x01;
+		len = 1;
+		break;
+	case RH_SET_CONFIGURATION:
+		len=0;
+		break;
+	default:
+		stat = USB_ST_STALLED;
+	}
+	USB_RH_PRINTF("Root-Hub stat %lx port1: %x port2: %x\n\n",stat,
+	     in16r(usb_base_addr + USBPORTSC1), in16r(usb_base_addr + USBPORTSC2));
+	dev->act_len=len;
+	dev->status=stat;
+	return stat;
+
+}
+
+/********************************************************************************
+ * Some Debug Routines
+ */
+
+#ifdef	USB_RH_DEBUG
+
+static void usb_display_Req(unsigned short req)
+{
+	USB_RH_PRINTF("- Root-Hub Request: ");
+	switch (req) {
+	case RH_GET_STATUS:
+		USB_RH_PRINTF("Get Status ");
+		break;
+	case RH_GET_STATUS | RH_INTERFACE:
+		USB_RH_PRINTF("Get Status Interface ");
+		break;
+	case RH_GET_STATUS | RH_ENDPOINT:
+		USB_RH_PRINTF("Get Status Endpoint ");
+		break;
+	case RH_GET_STATUS | RH_CLASS:
+		USB_RH_PRINTF("Get Status Class");
+		break;	/* hub power ** */
+	case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+		USB_RH_PRINTF("Get Status Class Others");
+		break;
+	case RH_CLEAR_FEATURE | RH_ENDPOINT:
+		USB_RH_PRINTF("Clear Feature Endpoint ");
+		break;
+	case RH_CLEAR_FEATURE | RH_CLASS:
+		USB_RH_PRINTF("Clear Feature Class ");
+		break;
+	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+		USB_RH_PRINTF("Clear Feature Other Class ");
+		break;
+	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+		USB_RH_PRINTF("Set Feature Other Class ");
+		break;
+	case RH_SET_ADDRESS:
+		USB_RH_PRINTF("Set Address ");
+		break;
+	case RH_GET_DESCRIPTOR:
+		USB_RH_PRINTF("Get Descriptor ");
+		break;
+	case RH_GET_DESCRIPTOR | RH_CLASS:
+		USB_RH_PRINTF("Get Descriptor Class ");
+		break;
+	case RH_GET_CONFIGURATION:
+		USB_RH_PRINTF("Get Configuration ");
+		break;
+	case RH_SET_CONFIGURATION:
+		USB_RH_PRINTF("Get Configuration ");
+		break;
+	default:
+		USB_RH_PRINTF("****UNKNOWN**** 0x%04X ",req);
+	}
+	USB_RH_PRINTF("\n");
+
+}
+
+static void usb_display_wValue(unsigned short wValue,unsigned short wIndex)
+{
+	switch (wValue) {
+		case (RH_PORT_ENABLE):
+			USB_RH_PRINTF("Root-Hub: Enable Port %d\n",wIndex);
+			break;
+		case (RH_PORT_SUSPEND):
+			USB_RH_PRINTF("Root-Hub: Suspend Port %d\n",wIndex);
+			break;
+		case (RH_PORT_POWER):
+			USB_RH_PRINTF("Root-Hub: Port Power %d\n",wIndex);
+			break;
+		case (RH_C_PORT_CONNECTION):
+			USB_RH_PRINTF("Root-Hub: C Port Connection Port %d\n",wIndex);
+			break;
+		case (RH_C_PORT_ENABLE):
+			USB_RH_PRINTF("Root-Hub: C Port Enable Port %d\n",wIndex);
+			break;
+		case (RH_C_PORT_SUSPEND):
+			USB_RH_PRINTF("Root-Hub: C Port Suspend Port %d\n",wIndex);
+			break;
+		case (RH_C_PORT_OVER_CURRENT):
+			USB_RH_PRINTF("Root-Hub: C Port Over Current Port %d\n",wIndex);
+			break;
+		case (RH_C_PORT_RESET):
+			USB_RH_PRINTF("Root-Hub: C Port reset Port %d\n",wIndex);
+			break;
+		default:
+			USB_RH_PRINTF("Root-Hub: unknown %x %x\n",wValue,wIndex);
+			break;
+	}
+}
+
+#endif
+
+
+
+#ifdef	USB_UHCI_DEBUG
+
+static int usb_display_td(uhci_td_t *td)
+{
+	unsigned long tmp;
+	int valid;
+
+	printf("TD at %p:\n",td);
+
+	tmp=swap_32(td->link);
+	printf("Link points to 0x%08lX, %s first, %s, %s\n",tmp&0xfffffff0,
+		((tmp & 0x4)==0x4) ? "Depth" : "Breath",
+		((tmp & 0x2)==0x2) ? "QH" : "TD",
+		((tmp & 0x1)==0x1) ? "invalid" : "valid");
+	valid=((tmp & 0x1)==0x0);
+	tmp=swap_32(td->status);
+	printf("     %s %ld Errors %s %s %s \n     %s %s %s %s %s %s\n     Len 0x%lX\n",
+		(((tmp>>29)&0x1)==0x1) ? "SPD Enable" : "SPD Disable",
+		((tmp>>28)&0x3),
+		(((tmp>>26)&0x1)==0x1) ? "Low Speed" : "Full Speed",
+		(((tmp>>25)&0x1)==0x1) ? "ISO " : "",
+		(((tmp>>24)&0x1)==0x1) ? "IOC " : "",
+		(((tmp>>23)&0x1)==0x1) ? "Active " : "Inactive ",
+		(((tmp>>22)&0x1)==0x1) ? "Stalled" : "",
+		(((tmp>>21)&0x1)==0x1) ? "Data Buffer Error" : "",
+		(((tmp>>20)&0x1)==0x1) ? "Babble" : "",
+		(((tmp>>19)&0x1)==0x1) ? "NAK" : "",
+		(((tmp>>18)&0x1)==0x1) ? "Bitstuff Error" : "",
+		(tmp&0x7ff));
+	tmp=swap_32(td->info);
+	printf("     MaxLen 0x%lX\n",((tmp>>21)&0x7FF));
+	printf("     %s Endpoint 0x%lX Dev Addr 0x%lX PID 0x%lX\n",((tmp>>19)&0x1)==0x1 ? "TOGGLE" : "",
+		((tmp>>15)&0xF),((tmp>>8)&0x7F),tmp&0xFF);
+	tmp=swap_32(td->buffer);
+	printf("     Buffer 0x%08lX\n",tmp);
+	printf("     DEV %08lX\n",td->dev_ptr);
+	return valid;
+}
+
+
+void usb_show_td(int max)
+{
+	int i;
+	if(max>0) {
+		for(i=0;i<max;i++) {
+			usb_display_td(&tmp_td[i]);
+		}
+	}
+	else {
+		i=0;
+		do {
+			printf("tmp_td[%d]\n",i);
+		}while(usb_display_td(&tmp_td[i++]));
+	}
+}
+
+
+#endif
+#endif /* CONFIG_USB_UHCI */
+
+/* EOF */

+ 194 - 0
board/MAI/AmigaOneG3SE/usb_uhci.h

@@ -0,0 +1,194 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Note: Part of this code has been derived from linux
+ *
+ */
+#ifndef _USB_UHCI_H_
+#define _USB_UHCI_H_
+
+#undef USB_UHCI_VEND_ID
+#define USB_UHCI_VEND_ID PCI_VENDOR_ID_VIA
+#undef USB_UHCI_DEV_ID
+#define USB_UHCI_DEV_ID 0x3038
+
+/* Command register */
+#define USBCMD		0
+#define   USBCMD_RS       0x0001	/* Run/Stop */
+#define   USBCMD_HCRESET  0x0002	/* Host reset */
+#define   USBCMD_GRESET   0x0004	/* Global reset */
+#define   USBCMD_EGSM     0x0008	/* Global Suspend Mode */
+#define   USBCMD_FGR      0x0010	/* Force Global Resume */
+#define   USBCMD_SWDBG    0x0020	/* SW Debug mode */
+#define   USBCMD_CF       0x0040	/* Config Flag (sw only) */
+#define   USBCMD_MAXP     0x0080	/* Max Packet (0 = 32, 1 = 64) */
+
+/* Status register */
+#define USBSTS		2
+#define   USBSTS_USBINT   0x0001	/* Interrupt due to IOC */
+#define   USBSTS_ERROR    0x0002	/* Interrupt due to error */
+#define   USBSTS_RD       0x0004	/* Resume Detect */
+#define   USBSTS_HSE      0x0008	/* Host System Error - basically PCI problems */
+#define   USBSTS_HCPE     0x0010	/* Host Controller Process Error - the scripts were buggy */
+#define   USBSTS_HCH      0x0020	/* HC Halted */
+
+/* Interrupt enable register */
+#define USBINTR		4
+#define   USBINTR_TIMEOUT 0x0001	/* Timeout/CRC error enable */
+#define   USBINTR_RESUME  0x0002	/* Resume interrupt enable */
+#define   USBINTR_IOC     0x0004	/* Interrupt On Complete enable */
+#define   USBINTR_SP      0x0008	/* Short packet interrupt enable */
+
+#define USBFRNUM      6
+#define USBFLBASEADD  8
+#define USBSOF        12
+
+/* USB port status and control registers */
+#define USBPORTSC1	16
+#define USBPORTSC2	18
+#define   USBPORTSC_CCS   0x0001	/* Current Connect Status ("device present") */
+#define   USBPORTSC_CSC   0x0002	/* Connect Status Change */
+#define   USBPORTSC_PE    0x0004	/* Port Enable */
+#define   USBPORTSC_PEC   0x0008	/* Port Enable Change */
+#define   USBPORTSC_LS    0x0030	/* Line Status */
+#define   USBPORTSC_RD    0x0040	/* Resume Detect */
+#define   USBPORTSC_LSDA  0x0100	/* Low Speed Device Attached */
+#define   USBPORTSC_PR    0x0200	/* Port Reset */
+#define   USBPORTSC_SUSP  0x1000	/* Suspend */
+
+/* Legacy support register */
+#define USBLEGSUP 0xc0
+#define USBLEGSUP_DEFAULT 0x2000	/* only PIRQ enable set */
+
+#define UHCI_NULL_DATA_SIZE 0x7ff	/* for UHCI controller TD */
+#define UHCI_PID            0xff	/* PID MASK */
+
+#define UHCI_PTR_BITS       0x000F
+#define UHCI_PTR_TERM       0x0001
+#define UHCI_PTR_QH         0x0002
+#define UHCI_PTR_DEPTH      0x0004
+
+/* for TD <status>: */
+#define TD_CTRL_SPD         (1 << 29)	/* Short Packet Detect */
+#define TD_CTRL_C_ERR_MASK  (3 << 27)	/* Error Counter bits */
+#define TD_CTRL_LS          (1 << 26)	/* Low Speed Device */
+#define TD_CTRL_IOS         (1 << 25)	/* Isochronous Select */
+#define TD_CTRL_IOC         (1 << 24)	/* Interrupt on Complete */
+#define TD_CTRL_ACTIVE      (1 << 23)	/* TD Active */
+#define TD_CTRL_STALLED     (1 << 22)	/* TD Stalled */
+#define TD_CTRL_DBUFERR     (1 << 21)	/* Data Buffer Error */
+#define TD_CTRL_BABBLE      (1 << 20)	/* Babble Detected */
+#define TD_CTRL_NAK         (1 << 19)	/* NAK Received */
+#define TD_CTRL_CRCTIMEO    (1 << 18)	/* CRC/Time Out Error */
+#define TD_CTRL_BITSTUFF    (1 << 17)	/* Bit Stuff Error */
+#define TD_CTRL_ACTLEN_MASK 0x7ff	/* actual length, encoded as n - 1 */
+
+#define TD_CTRL_ANY_ERROR	(TD_CTRL_STALLED | TD_CTRL_DBUFERR | \
+				 TD_CTRL_BABBLE | TD_CTRL_CRCTIME | TD_CTRL_BITSTUFF)
+
+#define TD_TOKEN_TOGGLE		19
+
+/* ------------------------------------------------------------------------------------
+   Virtual Root HUB
+   ------------------------------------------------------------------------------------ */
+/* destination of request */
+#define RH_INTERFACE               0x01
+#define RH_ENDPOINT                0x02
+#define RH_OTHER                   0x03
+
+#define RH_CLASS                   0x20
+#define RH_VENDOR                  0x40
+
+/* Requests: bRequest << 8 | bmRequestType */
+#define RH_GET_STATUS           0x0080
+#define RH_CLEAR_FEATURE        0x0100
+#define RH_SET_FEATURE          0x0300
+#define RH_SET_ADDRESS          0x0500
+#define RH_GET_DESCRIPTOR       0x0680
+#define RH_SET_DESCRIPTOR       0x0700
+#define RH_GET_CONFIGURATION    0x0880
+#define RH_SET_CONFIGURATION    0x0900
+#define RH_GET_STATE            0x0280
+#define RH_GET_INTERFACE        0x0A80
+#define RH_SET_INTERFACE        0x0B00
+#define RH_SYNC_FRAME           0x0C80
+/* Our Vendor Specific Request */
+#define RH_SET_EP               0x2000
+
+/* Hub port features */
+#define RH_PORT_CONNECTION         0x00
+#define RH_PORT_ENABLE             0x01
+#define RH_PORT_SUSPEND            0x02
+#define RH_PORT_OVER_CURRENT       0x03
+#define RH_PORT_RESET              0x04
+#define RH_PORT_POWER              0x08
+#define RH_PORT_LOW_SPEED          0x09
+#define RH_C_PORT_CONNECTION       0x10
+#define RH_C_PORT_ENABLE           0x11
+#define RH_C_PORT_SUSPEND          0x12
+#define RH_C_PORT_OVER_CURRENT     0x13
+#define RH_C_PORT_RESET            0x14
+
+/* Hub features */
+#define RH_C_HUB_LOCAL_POWER       0x00
+#define RH_C_HUB_OVER_CURRENT      0x01
+
+#define RH_DEVICE_REMOTE_WAKEUP    0x00
+#define RH_ENDPOINT_STALL          0x01
+
+/* Our Vendor Specific feature */
+#define RH_REMOVE_EP               0x00
+
+
+#define RH_ACK                     0x01
+#define RH_REQ_ERR                 -1
+#define RH_NACK                    0x00
+
+
+/* Transfer descriptor structure */
+typedef struct {
+	unsigned long link;     /* next td/qh (LE)*/
+	unsigned long status;   /* status of the td */
+	unsigned long info;     /* Max Lenght / Endpoint / device address and PID */
+	unsigned long buffer;   /* pointer to data buffer (LE) */
+	unsigned long dev_ptr;  /* pointer to the assigned device (BE) */
+	unsigned long res[3];   /* reserved (TDs must be 8Byte aligned) */
+} uhci_td_t, *puhci_td_t;
+
+/* Queue Header structure */
+typedef struct {
+	unsigned long head;       /* Next QH (LE)*/
+	unsigned long element;		/* Queue element pointer (LE) */
+	unsigned long res[5];     /* reserved */
+	unsigned long dev_ptr;    /* if 0 no tds have been assigned to this qh */
+} uhci_qh_t, *puhci_qh_t;
+
+struct virt_root_hub {
+	int devnum;		            /* Address of Root Hub endpoint */
+	int numports;             /* number of ports */
+	int c_p_r[8];             /* C_PORT_RESET */
+};
+
+
+#endif /* _USB_UHCI_H_ */
+
+

+ 299 - 0
board/MAI/AmigaOneG3SE/via686.c

@@ -0,0 +1,299 @@
+/*
+ * (C) Copyright 2002
+ * Hyperion Entertainment, Hans-JoergF@hyperion-entertainment.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <pci.h>
+#include <ata.h>
+#include "memio.h"
+#include "articiaS.h"
+#include "via686.h"
+#include "i8259.h"
+
+#undef VIA_DEBUG
+
+#ifdef  VIA_DEBUG
+#define PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+
+/*  Setup the ISA-to-PCI host bridge */
+void via_isa_init(pci_dev_t dev, struct pci_config_table *table)
+{
+    char regval;
+    if (PCI_FUNC(dev) == 0)
+    {
+	PRINTF("... PCI-to-ISA bridge, dev=0x%X\n", dev);
+
+	/*  Enable I/O Recovery time */
+	pci_write_config_byte(dev, 0x40, 0x08);
+
+	/*  Enable ISA refresh */
+	pci_write_config_byte(dev, 0x41, 0x41); /*  was 01 */
+
+	/*  Enable ISA line buffer */
+	pci_write_config_byte(dev, 0x45, 0x80);
+
+	/*  Gate INTR, and flush line buffer */
+	pci_write_config_byte(dev, 0x46, 0x60);
+
+	/*  Enable EISA ports 4D0/4D1. Do we need this ? */
+	pci_write_config_byte(dev, 0x47, 0xe6); /*  was 20 */
+
+	/*  512 K PCI Decode */
+	pci_write_config_byte(dev, 0x48, 0x01);
+
+	/*  Wait for PGNT before grant to ISA Master/DMA */
+	/*  ports 0-FF to SDBus */
+	/*  IRQ 14 and 15 for ide 0/1 */
+	pci_write_config_byte(dev, 0x4a, 0x04); /*  Was c4 */
+
+	/*  Plug'n'Play */
+	/*  Parallel DRQ 3, Floppy DRQ 2 (default) */
+	pci_write_config_byte(dev, 0x50, 0x0e);
+
+	/*  IRQ Routing for Floppy and Parallel port */
+	/*  IRQ 6 for floppy, IRQ 7 for parallel port */
+	pci_write_config_byte(dev, 0x51, 0x76);
+
+	/*  IRQ Routing for serial ports (take IRQ 3 and 4) */
+	pci_write_config_byte(dev, 0x52, 0x34);
+
+	/*  All IRQ's level triggered. */
+	pci_write_config_byte(dev, 0x54, 0x00);
+
+	/*  PCI IRQ's all at IRQ 9 */
+	pci_write_config_byte(dev, 0x55, 0x90);
+	pci_write_config_byte(dev, 0x56, 0x99);
+	pci_write_config_byte(dev, 0x57, 0x90);
+
+	/*  Enable Keyboard */
+	pci_read_config_byte(dev, 0x5A, &regval);
+	regval |= 0x01;
+	pci_write_config_byte(dev, 0x5A, regval);
+
+	pci_write_config_byte(dev, 0x80, 0);
+	pci_write_config_byte(dev, 0x85, 0x01);
+
+/* 	pci_write_config_byte(dev, 0x77, 0x00); */
+    }
+}
+
+/*
+ * Initialize PNP irq routing
+ */
+
+void via_init_irq_routing(uint8 irq_map[])
+{
+    char *s;
+    uint8 level_edge_bits = 0xf;
+
+    /* Set irq routings */
+    pci_write_cfg_byte(0, 7<<3, 0x55, irq_map[0]<<4);
+    pci_write_cfg_byte(0, 7<<3, 0x56, irq_map[1] | irq_map[2]<<4);
+    pci_write_cfg_byte(0, 7<<3, 0x57, irq_map[3]<<4);
+
+    /*
+     * Gather level/edge bits
+     * Default is to assume level triggered
+     */
+
+    s = getenv("pci_irqa_select");
+    if (s && strcmp(s, "level") == 0)
+	level_edge_bits &= ~0x01;
+
+    s = getenv("pci_irqb_select");
+    if (s && strcmp(s, "level") == 0)
+	level_edge_bits &= ~0x02;
+
+    s = getenv("pci_irqc_select");
+    if (s && strcmp(s, "level") == 0)
+	level_edge_bits &= ~0x04;
+
+    s = getenv("pci_irqd_select");
+    if (s && strcmp(s, "level") == 0)
+	level_edge_bits &= ~0x08;
+
+    PRINTF("IRQ map\n");
+    PRINTF("%d: %s\n", irq_map[0], level_edge_bits&0x1 ? "edge" : "level");
+    PRINTF("%d: %s\n", irq_map[1], level_edge_bits&0x2 ? "edge" : "level");
+    PRINTF("%d: %s\n", irq_map[2], level_edge_bits&0x4 ? "edge" : "level");
+    PRINTF("%d: %s\n", irq_map[3], level_edge_bits&0x8 ? "edge" : "level");
+    pci_write_cfg_byte(0, 7<<3, 0x54, level_edge_bits);
+
+    PRINTF("%02x %02x %02x %02x\n", pci_read_cfg_byte(0, 7<<3, 0x54),
+	   pci_read_cfg_byte(0, 7<<3, 0x55), pci_read_cfg_byte(0, 7<<3, 0x56),
+	   pci_read_cfg_byte(0, 7<<3, 0x57));
+}
+
+
+/*  Setup the IDE controller. This doesn't seem to work yet. I/O to an IDE controller port */
+/*  always return the last character output on the serial port (!) */
+/*  This function is called by the pnp-library when it encounters 0:7:1 */
+void via_cfgfunc_ide_init(struct pci_controller *host, pci_dev_t dev, struct pci_config_table *table)
+{
+    PRINTF("... IDE controller, dev=0x%X\n", dev);
+
+    /*  Enable both IDE channels. */
+    pci_write_config_byte(dev, 0x40, 0x03);
+    /*  udelay(10000); */
+    /*  udelay(10000); */
+
+    /*  Enable IO Space */
+    pci_write_config_word(dev, 0x04, 0x03);
+
+    /*  Set to compatibility mode */
+    pci_write_config_byte(dev, 0x09, 0x8A); /*  WAS: 0x8f); */
+
+    /*  Set to legacy interrupt mode */
+    pci_write_config_byte(dev, 0x3d, 0x00); /* WAS: 0x01); */
+
+}
+
+
+/*  Set the base address of the floppy controller to 0x3F0 */
+void via_fdc_init(pci_dev_t dev)
+{
+    unsigned char c;
+    /*  Enable Configuration mode */
+    pci_read_config_byte(dev, 0x85, &c);
+    c |= 0x02;
+    pci_write_config_byte(dev, 0x85, c);
+
+    /*  Set floppy controller port to 0x3F0. */
+    SIO_WRITE_CONFIG(0xE3, (0x3F<<2));
+
+    /*  Enable floppy controller */
+    SIO_READ_CONFIG(0xE2, c);
+    c |= 0x10;
+    SIO_WRITE_CONFIG(0xE2, c);
+
+    /*  Switch of configuration mode */
+    pci_read_config_byte(dev, 0x85, &c);
+    c &= ~0x02;
+    pci_write_config_byte(dev, 0x85, c);
+}
+
+/*  Init function 0 of the via southbridge. Called by the pnp-library */
+void via_cfgfunc_via686(struct pci_controller *host, pci_dev_t dev, struct pci_config_table *table)
+{
+    if (PCI_FUNC(dev) == 0)
+    {
+	/* FIXME: Try to generate a PCI reset */
+	/* unsigned char c; */
+	/* pci_read_config_byte(dev, 0x47, &c); */
+	/* pci_write_config_byte(dev, 0x47, c | 0x01); */
+
+	via_isa_init(dev, table);
+	via_fdc_init(dev);
+    }
+}
+
+__asm         ("    .globl via_calibrate_time_base \n"
+	       "via_calibrate_time_base: 	   \n"
+               "   lis     9, 0xfe00		   \n"
+               "   li      0, 0x00		   \n"
+	       "   mttbu   0			   \n"
+	       "   mttbl   0			   \n"
+	       "ctb_loop:			   \n"
+               "   lbz     0, 0x61(9)		   \n"
+               "   eieio			   \n"
+               "   andi.   0, 0, 0x20		   \n"
+               "   beq     ctb_loop		   \n"
+               "ctb_done:			   \n"
+               "   mftb    3			   \n"
+               "   blr");
+
+extern unsigned long via_calibrate_time_base(void);
+
+void via_calibrate_bus_freq(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+    unsigned long tb;
+
+    /* This is 20 microseconds */
+    #define CALIBRATE_TIME 28636
+
+
+    /* Enable the timer (and disable speaker) */
+    unsigned char c;
+    c = in_byte(0x61);
+    out_byte(0x61, ((c & ~0x02) | 0x01));
+
+    /* Set timer 2 to low/high writing */
+    out_byte(0x43, 0xb0);
+    out_byte(0x42, CALIBRATE_TIME & 0xff);
+    out_byte(0x42, CALIBRATE_TIME >>8);
+
+    /* Read the time base */
+    tb = via_calibrate_time_base();
+
+    if (tb >= 700000)
+	gd->bus_clk = 133333333;
+    else
+	gd->bus_clk = 100000000;
+
+}
+
+
+void ide_led(uchar led, uchar status)
+{
+/*     unsigned char c = in_byte(0x92); */
+
+/*     if (!status) */
+/* 	out_byte(0x92, c | 0xC0); */
+/*     else */
+/* 	out_byte(0x92, c & ~0xC0); */
+}
+
+
+void via_init_afterscan(void)
+{
+    /* Modify IDE controller setup */
+    pci_write_cfg_byte(0, 7<<3|1, PCI_LATENCY_TIMER, 0x20);
+    pci_write_cfg_byte(0, 7<<3|1, PCI_COMMAND, PCI_COMMAND_IO|PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER);
+    pci_write_cfg_byte(0, 7<<3|1, PCI_INTERRUPT_LINE, 0xff);
+    pci_write_cfg_byte(0, 7<<3|1, 0x40, 0x0b);   /* FIXME: Might depend on drives connected */
+    pci_write_cfg_byte(0, 7<<3|1, 0x41, 0x42);   /* FIXME: Might depend on drives connected */
+    pci_write_cfg_byte(0, 7<<3|1, 0x43, 0x05);
+    pci_write_cfg_byte(0, 7<<3|1, 0x44, 0x18);
+    pci_write_cfg_byte(0, 7<<3|1, 0x45, 0x10);
+    pci_write_cfg_byte(0, 7<<3|1, 0x4e, 0x22);   /* FIXME: Not documented, but set in PC bios */
+    pci_write_cfg_byte(0, 7<<3|1, 0x4f, 0x20);   /* FIXME: Not documented */
+
+    /* Modify some values in the USB controller */
+    pci_write_cfg_byte(0, 7<<3|2, 0x05, 0x17);
+    pci_write_cfg_byte(0, 7<<3|2, 0x06, 0x01);
+    pci_write_cfg_byte(0, 7<<3|2, 0x41, 0x12);
+    pci_write_cfg_byte(0, 7<<3|2, 0x42, 0x03);
+    pci_write_cfg_byte(0, 7<<3|2, PCI_LATENCY_TIMER, 0x40);
+
+    pci_write_cfg_byte(0, 7<<3|3, 0x05, 0x17);
+    pci_write_cfg_byte(0, 7<<3|3, 0x06, 0x01);
+    pci_write_cfg_byte(0, 7<<3|3, 0x41, 0x12);
+    pci_write_cfg_byte(0, 7<<3|3, 0x42, 0x03);
+    pci_write_cfg_byte(0, 7<<3|3, PCI_LATENCY_TIMER, 0x40);
+
+
+}

+ 29 - 0
board/MAI/AmigaOneG3SE/via686.h

@@ -0,0 +1,29 @@
+#ifndef VIA686_H_
+#define VIA686_H_
+
+
+#define CMOS_ADDR         0x70
+#define CMOS_DATA         0x71
+
+#define I8259_MASTER_CONTROL 0x20
+#define I8259_MASTER_MASK    0x21
+
+#define I8259_SLAVE_CONTROL  0xA0
+#define I8259_SLAVE_MASK     0xA1
+
+#define SIO_CONFIG_ADDR 0x3F0
+#define SIO_CONFIG_DATA 0x3F1
+
+#define SIO_WRITE_CONFIG(addr, byte) \
+   out_byte(SIO_CONFIG_ADDR, addr);  \
+   out_byte(SIO_CONFIG_DATA, byte);
+
+#define SIO_READ_CONFIG(addr, byte) \
+   out_byte(SIO_CONFIG_ADDR, addr); \
+   byte = in_byte(SIO_CONFIG_DATA);
+
+void via_init(void);
+
+void via_calibrate_bus_freq(void);
+
+#endif

+ 539 - 0
board/MAI/AmigaOneG3SE/video.c

@@ -0,0 +1,539 @@
+/*
+ * (C) Copyright 2002
+ * Hyperion Entertainment, Hans-JoergF@hyperion-entertainment.com 
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <devices.h>
+#include "memio.h"
+#include <part.h>
+
+unsigned char *cursor_position;
+unsigned int cursor_row;
+unsigned int cursor_col;
+
+unsigned char current_attr;
+
+unsigned int video_numrows = 25;
+unsigned int video_numcols = 80;
+unsigned int video_scrolls = 0;
+
+#define VIDEO_BASE (unsigned char *)0xFD0B8000
+#define VIDEO_ROWS video_numrows
+#define VIDEO_COLS video_numcols
+#define VIDEO_PITCH (2 * video_numcols)
+#define VIDEO_SIZE (video_numrows * video_numcols * 2)
+#define VIDEO_NAME "vga"
+
+void video_test(void);
+void video_putc(char ch);
+void video_puts(char *string);
+void video_scroll(int rows);
+void video_banner(void);
+int  video_init(void);
+int  video_start(void);
+int  video_rows(void);
+int  video_cols(void);
+
+char *prompt_string = "=>";
+
+void video_set_color(unsigned char attr)
+{
+    unsigned char *fb = (unsigned char *)VIDEO_BASE;
+    int i;
+
+    current_attr = video_get_attr();
+
+    for (i=0; i<VIDEO_SIZE; i+=2)
+    {
+	*(fb+i+1) = current_attr;
+    }
+}
+
+unsigned char video_get_attr(void)
+{
+    char *s;
+    unsigned char attr;
+
+    attr = 0x0f;
+
+    s = getenv("vga_fg_color");
+    if (s)
+    {
+	attr = atoi(s);
+    }
+
+    s = getenv("vga_bg_color");
+    if (s)
+    {
+	attr |= atoi(s)<<4;
+    }
+
+    return attr;
+}
+
+int video_inited = 0;
+
+int drv_video_init(void)
+{
+    int error, devices = 1 ;
+    device_t vgadev ;
+    if (video_inited) return 1;
+    video_inited = 1;
+    video_init();
+    memset (&vgadev, 0, sizeof(vgadev));
+    
+    strcpy(vgadev.name, VIDEO_NAME);
+    vgadev.flags =  DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM;
+    vgadev.putc = video_putc;
+    vgadev.puts = video_puts;
+    vgadev.getc = NULL;
+    vgadev.tstc = NULL;
+    vgadev.start = video_start;
+    
+    error = device_register (&vgadev);
+
+    if (error == 0)
+    {
+	char *s = getenv("stdout");
+	if (s && strcmp(s, VIDEO_NAME)==0)
+	{
+	    if (overwrite_console()) return 1;
+	    error = console_assign(stdout, VIDEO_NAME);
+	    if (error == 0) return 1;
+	    else return error;
+	}
+	return 1;
+    }
+
+    return error;
+}
+
+int video_init(void)
+{
+    cursor_position = VIDEO_BASE; // Color text display base
+    cursor_row = 0;
+    cursor_col = 0;
+    current_attr = video_get_attr(); // Currently selected value for attribute.
+//    video_test();
+    video_set_color(current_attr);
+
+    return 0;
+}
+
+void video_set_cursor(int line, int column)
+{
+    unsigned short offset = line*video_numcols + column;
+    cursor_position = VIDEO_BASE +  line*VIDEO_PITCH + column*2;
+    out_byte(0x3D4, 0x0E);
+    out_byte(0x3D5, offset/256);
+    out_byte(0x3D4, 0x0F);
+    out_byte(0x3D5, offset%256);
+}
+
+void video_write_char(int character)
+{
+    *cursor_position = character;
+    *(cursor_position+1) = current_attr;
+}
+
+void video_test(void)
+{
+
+}
+
+void video_putc(char ch)
+{
+    switch(ch)
+    {
+    case '\n':
+	cursor_col = 0;
+	cursor_row += 1;
+	break;
+    case '\r':
+	cursor_col = 0;
+	break;
+    case '\b':
+	if (cursor_col) cursor_col--;
+	else return;
+	break;
+    case '\t':
+	cursor_col = (cursor_col/8+1)*8;
+	break;
+    default:
+	video_write_char(ch);
+	cursor_col++;
+	if (cursor_col > VIDEO_COLS-1)
+	{
+	    cursor_row++;
+	    cursor_col=0;
+	}
+    }
+
+    if (cursor_row > VIDEO_ROWS-1)
+	video_scroll(1);
+    video_set_cursor(cursor_row, cursor_col);
+}
+
+void video_scroll(int rows)
+{
+    unsigned short clear = ((unsigned short)current_attr) | (' '<<8);
+    unsigned short* addr16 = &((unsigned short *)VIDEO_BASE)[(VIDEO_ROWS-rows)*VIDEO_COLS];
+    int i;
+    char *s;
+
+    s = getenv("vga_askscroll");
+    video_scrolls += rows;
+
+    if (video_scrolls >= video_numrows)
+    {
+	if (s && strcmp(s, "yes"))
+	{
+	    while (-1 == tstc());
+	}
+
+	video_scrolls = 0;
+    }
+
+
+    memcpy(VIDEO_BASE, VIDEO_BASE+rows*(VIDEO_COLS*2), (VIDEO_ROWS-rows)*(VIDEO_COLS*2));
+    for (i = 0 ; i < rows * VIDEO_COLS ; i++)
+	addr16[i] = clear;
+    cursor_row-=rows;
+    cursor_col=0;
+}
+
+void video_puts(char *string)
+{
+    while (*string)
+    {
+	video_putc(*string);
+	string++;
+    }
+}
+
+int video_start(void)
+{
+    return 0;
+}
+
+unsigned char video_single_box[] =
+{
+    218, 196, 191,
+    179,      179,
+    192, 196, 217
+};
+
+unsigned char video_double_box[] =
+{
+    201, 205, 187,
+    186,      186,
+    200, 205, 188
+};
+
+unsigned char video_single_title[] =
+{
+    195, 196, 180, 180, 195
+};
+
+unsigned char video_double_title[] =
+{
+    204, 205, 185, 181, 198
+};
+
+#define SINGLE_BOX 0
+#define DOUBLE_BOX 1
+
+unsigned char *video_addr(int x, int y)
+{
+    return VIDEO_BASE + 2*(VIDEO_COLS*y) + 2*x;
+}
+
+void video_bios_print_string(char *s, int x, int y, int attr, int count)
+{
+    int cattr = current_attr;
+    if (attr != -1) current_attr = attr;
+    video_set_cursor(x,y);
+    while (count)
+    {
+	char c = *s++;
+	if (attr == -1) current_attr = *s++;
+	video_putc(c);
+	count--;
+    }
+}
+
+void video_draw_box(int style, int attr, char *title, int separate, int x, int y, int w, int h)
+{
+    unsigned char *fb, *fb2; 
+    unsigned char *st = (style == SINGLE_BOX)?video_single_box : video_double_box;
+    unsigned char *ti = (style == SINGLE_BOX)?video_single_title : video_double_title;
+    int i;
+
+    fb = video_addr(x,y);
+    *(fb) = st[0];
+    *(fb+1) = attr;
+    fb += 2;
+
+    fb2 = video_addr(x,y+h-1);
+    *(fb2) = st[5];
+    *(fb2+1) = attr;
+    fb2 += 2;
+
+    for (i=0; i<w-2;i++)
+    {
+	*fb = st[1];
+	fb++;
+	*fb = attr;
+	fb++;
+
+	*fb2 = st[6];
+	fb2++;
+	*fb2 = attr;
+	fb2++;
+
+    }
+    *fb = st[2];
+    *(fb+1) = attr;
+
+    *fb2 = st[7];
+    *(fb2+1) = attr;
+
+    fb  = video_addr(x, y+1);
+    fb2 = video_addr(x+w-1, y+1);
+    for (i=0; i<h-2; i++)
+    {
+	*fb = st[3];
+	*(fb+1) = attr; fb += 2*VIDEO_COLS;
+
+	*fb2 = st[4]; 
+	*(fb2+1) = attr; fb2 += 2*VIDEO_COLS;
+    }
+    
+    // Draw title
+    if (title)
+    {
+	if (separate == 0)
+	{
+	    fb = video_addr(x+1, y);
+	    *fb = ti[3];
+	    fb += 2;
+	    *fb = ' ';
+	    fb += 2;
+	    while (*title)
+	    {
+		*fb = *title;
+		fb ++;
+		*fb = attr;
+		fb++; title++;
+	    }
+	    *fb = ' ';
+	    fb += 2;
+	    *fb = ti[4];
+	}
+	else
+	{
+	    fb = video_addr(x, y+2);
+	    *fb = ti[0];
+	    fb += 2;
+	    for (i=0; i<w-2; i++)
+	    {
+		*fb = ti[1];
+		*(fb+1) = attr;
+		fb += 2;
+	    }
+	    *fb = ti[2];
+	    *(fb+1) = attr;
+	    fb = video_addr(x+1, y+1);
+	    for (i=0; i<w-2; i++)
+	    {
+		*fb = ' ';
+		*(fb+1) = attr;
+		fb += 2;
+	    }
+	    fb = video_addr(x+2, y+1);
+	    
+	    while (*title)
+	    {
+		*fb = *title;
+		*(fb+1) = attr;
+		fb += 2;
+		title++;
+	    }
+	}
+    }
+
+}
+
+void video_draw_text(int x, int y, int attr, char *text)
+{
+    unsigned char *fb = video_addr(x,y);
+    while (*text)
+    {
+	*fb++ = *text++;
+	*fb++ = attr;
+    }
+}
+
+void video_save_rect(int x, int y, int w, int h, void *save_area, int clearchar, int clearattr)
+{
+    unsigned char *save = (unsigned char *)save_area;
+    unsigned char *fb = video_addr(x,y);
+    int i,j;
+    for (i=0; i<h; i++)
+    {
+	unsigned char *fbb = fb;
+	for (j=0; j<w; j++)
+	{
+	    *save ++ = *fb;
+	    if (clearchar > 0) *fb = clearchar;
+	    fb ++;
+	    *save ++ = *fb;
+	    if (clearattr > 0) *fb = clearattr;
+	}
+	fb = fbb + 2*VIDEO_COLS;
+    }
+}
+
+void video_restore_rect(int x, int y, int w, int h, void *save_area)
+{   
+    unsigned char *save = (unsigned char *)save_area;
+    unsigned char *fb = video_addr(x,y);
+    int i,j;
+    for (i=0; i<h; i++)
+    {
+	unsigned char *fbb = fb;
+	for (j=0; j<w; j++)
+	{
+	    *fb ++ = *save ++;
+	    *fb ++ = *save ++;
+	}
+	fb = fbb + 2*VIDEO_COLS;
+    }
+
+}
+
+int video_rows(void)
+{
+    return VIDEO_ROWS;
+}
+
+int video_cols(void)
+{
+    return VIDEO_COLS;
+}
+
+void video_size(int cols, int rows)
+{
+    video_numrows = rows;
+    video_numcols = cols;
+}
+
+void video_clear(void)
+{
+    unsigned short *fbb = (unsigned short *)0xFD0B8000;
+    int i,j;
+    unsigned short val = 0x2000 | current_attr;
+
+    for (i=0; i<video_rows(); i++)
+    {
+	for (j=0; j<video_cols(); j++)
+	{
+	    *fbb++ = val;
+	}
+    }
+    video_set_cursor(0,0);
+    cursor_row = 0;
+    cursor_col = 0;
+}
+
+#ifdef EASTEREGG
+int video_easteregg_active = 0;
+
+void video_easteregg(void)
+{
+    video_easteregg_active = 1;
+}
+#endif
+
+extern bd_t *bd_global;
+extern block_dev_desc_t * ide_get_dev(int dev);
+extern char version_string[];
+
+void video_banner(void)
+{
+    block_dev_desc_t *ide;
+    int i;
+    char *s;
+    int maxdev;
+    
+
+    if (video_inited == 0) return;
+#ifdef EASTEREGG
+    if (video_easteregg_active)
+    {
+	prompt_string="";
+	video_clear();
+	printf("\n");
+	printf("    **** COMMODORE 64 BASIC X2 ****\n\n");
+	printf(" 64K RAM SYSTEM  38911 BASIC BYTES FREE\n\n");
+	printf("READY\n");
+    }
+    else
+    {
+#endif
+	s = getenv("ide_maxbus");
+	if (s)
+	    maxdev = atoi(s) * 2;
+	else
+	    maxdev = 4;
+
+	s = getenv("stdout");
+	if (s && strcmp(s, "serial") == 0)
+	    return;
+
+	video_clear();
+	printf("%s\n\nCPU: ", version_string);
+	checkcpu();
+	printf("DRAM: %ld MB\n", bd_global->bi_memsize/(1024*1024));
+	printf("FSB: %ld MHz\n", bd_global->bi_busfreq/1000000);
+
+	printf("\n---- Disk summary ----\n");
+	for (i = 0; i < maxdev; i++)
+	{
+	    ide = ide_get_dev(i);
+	    printf("Device %d: ", i);
+	    dev_print(ide);
+	}
+
+/*
+    video_draw_box(SINGLE_BOX, 0x0F, "Test 1", 0, 0,18, 72, 4);
+    video_draw_box(DOUBLE_BOX, 0x0F, "Test 2", 1, 4,10, 50, 6);
+    video_draw_box(DOUBLE_BOX, 0x0F, "Test 3", 0, 40, 3, 20, 5);
+
+    video_draw_text(1, 4, 0x2F, "Highlighted options");
+    video_draw_text(1, 5, 0x0F, "Non-selected option");
+    video_draw_text(1, 6, 0x07, "disabled option");
+*/
+#ifdef EASTEREGG
+    }
+#endif
+}

+ 335 - 0
board/MAI/bios_emulator/bios.c

@@ -0,0 +1,335 @@
+/*
+ * Mostly done after the Scitech Bios emulation
+ * Written by Hans-Jörg Frieden
+ * Hyperion Entertainment
+ */
+#include "x86emu.h"
+#include "glue.h"
+
+#undef DEBUG
+#ifdef DEBUG
+#define PRINTF(fmt, args...) printf(fmt, ## args)
+#else
+#define PRINTF(fmt, args...)
+#endif
+
+#define BIOS_SEG 0xFFF0
+#define PCIBIOS_SUCCESSFUL 0
+#define PCIBIOS_DEVICE_NOT_FOUND 0x86
+
+typedef unsigned char UBYTE;
+typedef unsigned short UWORD;
+typedef unsigned long ULONG;
+
+typedef char BYTE;
+typedef short WORT;
+typedef long LONG;
+
+static inline UBYTE read_byte(volatile UBYTE* from)
+{
+    int x;
+    asm volatile ("lbz %0,%1\n eieio" : "=r" (x) : "m" (*from));
+    return (UBYTE)x;
+}
+
+static inline void write_byte(volatile UBYTE *to, int x)
+{
+    asm volatile ("stb %1,%0\n eieio" : "=m" (*to) : "r" (x));
+}
+
+static inline UWORD read_word_little(volatile UWORD *from)
+{
+    int x;
+    asm volatile ("lhbrx %0,0,%1\n eieio" : "=r" (x) : "r" (from), "m" (*from));
+    return (UWORD)x;
+}
+
+static inline UWORD read_word_big(volatile UWORD *from)
+{
+    int x;
+    asm volatile ("lhz %0,%1\n eieio" : "=r" (x) : "m" (*from));
+    return (UWORD)x;
+}
+
+static inline void write_word_little(volatile UWORD *to, int x)
+{
+    asm volatile ("sthbrx %1,0,%2\n eieio" : "=m" (*to) : "r" (x), "r" (to));
+}
+
+static inline void write_word_big(volatile UWORD *to, int x)
+{
+    asm volatile ("sth %1,%0\n eieio" : "=m" (*to) : "r" (x));
+}
+
+static inline ULONG read_long_little(volatile ULONG *from)
+{
+    unsigned long x;
+    asm volatile ("lwbrx %0,0,%1\n eieio" : "=r" (x) : "r" (from), "m"(*from));
+    return (ULONG)x;
+}
+
+static inline ULONG read_long_big(volatile ULONG *from)
+{
+    unsigned long x;
+    asm volatile ("lwz %0,%1\n eieio" : "=r" (x) : "m" (*from));
+    return (ULONG)x;
+}
+
+static inline void write_long_little(volatile ULONG *to, ULONG x)
+{
+    asm volatile ("stwbrx %1,0,%2\n eieio" : "=m" (*to) : "r" (x), "r" (to));
+}
+
+static inline void write_long_big(volatile ULONG *to, ULONG x)
+{
+    asm volatile ("stw %1,%0\n eieio" : "=m" (*to) : "r" (x));
+}
+
+#define port_to_mem(from) (0xFE000000|(from))
+#define in_byte(from) read_byte( (UBYTE *)port_to_mem(from))
+#define in_word(from) read_word_little((UWORD *)port_to_mem(from))
+#define in_long(from) read_long_little((ULONG *)port_to_mem(from))
+#define out_byte(to, val) write_byte((UBYTE *)port_to_mem(to), val)
+#define out_word(to, val) write_word_little((UWORD *)port_to_mem(to), val)
+#define out_long(to, val) write_long_little((ULONG *)port_to_mem(to), val)
+
+static void X86API undefined_intr(int intno)
+{
+    extern u16 A1_rdw(u32 addr);
+    if (A1_rdw(intno * 4 + 2) == BIOS_SEG)
+    {
+	PRINTF("Undefined interrupt %xh called AX = %xh, BX = %xh, CX = %xh, DX = %xh\n",
+	   intno, M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, M.x86.R_DX);
+	X86EMU_halt_sys();
+    }
+    else
+    {
+	PRINTF("Calling interrupt %xh, AL=%xh, AH=%xh\n", intno, M.x86.R_AL, M.x86.R_AH);
+	X86EMU_prepareForInt(intno);
+    }
+}
+
+static void X86API int42(int intno);
+static void X86API int15(int intno);
+
+static void X86API int10(int intno)
+{
+    if (A1_rdw(intno*4+2) == BIOS_SEG)
+	int42(intno);
+    else
+    {
+	PRINTF("int10: branching to %04X:%04X, AL=%xh, AH=%xh\n", A1_rdw(intno*4+2), A1_rdw(intno*4),
+	       M.x86.R_AL, M.x86.R_AH);
+	X86EMU_prepareForInt(intno);
+    }
+}
+
+static void X86API int1A(int intno)
+{
+    int device;
+
+    switch(M.x86.R_AX)
+    {
+    case 0xB101: // PCI Bios Present?
+	M.x86.R_AL  = 0x00;
+	M.x86.R_EDX = 0x20494350;
+	M.x86.R_BX  = 0x0210;
+	M.x86.R_CL  = 3;
+	CLEAR_FLAG(F_CF);
+	break;
+    case 0xB102: // Find device
+	device = mypci_find_device(M.x86.R_DX, M.x86.R_CX, M.x86.R_SI);
+	if (device != -1)
+	{
+	    M.x86.R_AH = PCIBIOS_SUCCESSFUL;
+	    M.x86.R_BH = mypci_bus(device);
+	    M.x86.R_BL = mypci_devfn(device);
+	}
+	else
+	{
+	    M.x86.R_AH = PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	CONDITIONAL_SET_FLAG((M.x86.R_AH != PCIBIOS_SUCCESSFUL), F_CF);
+	break;
+    case 0xB103: // Find PCI class code
+	M.x86.R_AH = PCIBIOS_DEVICE_NOT_FOUND;
+	//printf("Find by class not yet implmented");
+	CONDITIONAL_SET_FLAG((M.x86.R_AH != PCIBIOS_SUCCESSFUL), F_CF);
+	break;
+    case 0xB108: // read config byte
+	M.x86.R_CL = mypci_read_cfg_byte(M.x86.R_BH, M.x86.R_BL, M.x86.R_DI);
+	M.x86.R_AH = PCIBIOS_SUCCESSFUL;
+	CONDITIONAL_SET_FLAG((M.x86.R_AH != PCIBIOS_SUCCESSFUL), F_CF);
+	//printf("read_config_byte %x,%x,%x -> %x\n", M.x86.R_BH, M.x86.R_BL, M.x86.R_DI,
+	//	    M.x86.R_CL);
+	break;
+    case 0xB109: // read config word
+	M.x86.R_CX = mypci_read_cfg_word(M.x86.R_BH, M.x86.R_BL, M.x86.R_DI);
+	M.x86.R_AH = PCIBIOS_SUCCESSFUL;
+	CONDITIONAL_SET_FLAG((M.x86.R_AH != PCIBIOS_SUCCESSFUL), F_CF);
+	//printf("read_config_word %x,%x,%x -> %x\n", M.x86.R_BH, M.x86.R_BL, M.x86.R_DI,
+	//	    M.x86.R_CX);
+	break;
+    case 0xB10A: // read config dword
+	M.x86.R_ECX = mypci_read_cfg_long(M.x86.R_BH, M.x86.R_BL, M.x86.R_DI);
+	M.x86.R_AH = PCIBIOS_SUCCESSFUL;
+	CONDITIONAL_SET_FLAG((M.x86.R_AH != PCIBIOS_SUCCESSFUL), F_CF);
+	//printf("read_config_long %x,%x,%x -> %x\n", M.x86.R_BH, M.x86.R_BL, M.x86.R_DI,
+	//    M.x86.R_ECX);
+	break;
+    case 0xB10B: // write config byte
+	mypci_write_cfg_byte(M.x86.R_BH, M.x86.R_BL, M.x86.R_DI, M.x86.R_CL);
+	M.x86.R_AH = PCIBIOS_SUCCESSFUL;
+	CONDITIONAL_SET_FLAG((M.x86.R_AH != PCIBIOS_SUCCESSFUL), F_CF);
+	//printf("write_config_byte %x,%x,%x <- %x\n", M.x86.R_BH, M.x86.R_BL, M.x86.R_DI,
+	//    M.x86.R_CL);
+	break;
+    case 0xB10C: // write config word
+	mypci_write_cfg_word(M.x86.R_BH, M.x86.R_BL, M.x86.R_DI, M.x86.R_CX);
+	M.x86.R_AH = PCIBIOS_SUCCESSFUL;
+	CONDITIONAL_SET_FLAG((M.x86.R_AH != PCIBIOS_SUCCESSFUL), F_CF);
+	//printf("write_config_word %x,%x,%x <- %x\n", M.x86.R_BH, M.x86.R_BL, M.x86.R_DI,
+	//	    M.x86.R_CX);
+	break;
+    case 0xB10D: // write config dword
+	mypci_write_cfg_long(M.x86.R_BH, M.x86.R_BL, M.x86.R_DI, M.x86.R_ECX);
+	M.x86.R_AH = PCIBIOS_SUCCESSFUL;
+	CONDITIONAL_SET_FLAG((M.x86.R_AH != PCIBIOS_SUCCESSFUL), F_CF);
+	//printf("write_config_long %x,%x,%x <- %x\n", M.x86.R_BH, M.x86.R_BL, M.x86.R_DI,
+	//	    M.x86.R_ECX);
+	break;
+    default:
+	PRINTF("BIOS int %xh: Unknown function AX=%04xh\n", intno, M.x86.R_AX);
+
+    }
+}
+
+void bios_init(void)
+{
+    int i;
+    X86EMU_intrFuncs bios_intr_tab[256];
+    
+    for (i=0; i<256; i++)
+    {
+	write_long_little(M.mem_base+i*4, BIOS_SEG<<16);
+	bios_intr_tab[i] = undefined_intr;
+    }
+
+    bios_intr_tab[0x10] = int10;
+    bios_intr_tab[0x1A] = int1A;
+    bios_intr_tab[0x42] = int42;
+    bios_intr_tab[0x15] = int15;
+
+    bios_intr_tab[0x6D] = int42;
+    
+    X86EMU_setupIntrFuncs(bios_intr_tab);
+    video_init();
+}
+
+unsigned char setup_40x25[] =
+{
+    0x38, 0x28, 0x2d, 0x0a, 0x1f, 6, 0x19,
+    0x1c, 2, 7, 6, 7, 0, 0, 0, 0
+};
+
+unsigned char setup_80x25[] =
+{
+    0x71, 0x50, 0x5a, 0x0a, 0x1f, 6, 0x19,
+    0x1c, 2, 7, 6, 7, 0, 0, 0, 0
+};
+
+unsigned char setup_graphics[] =
+{
+    0x38, 0x28, 0x20, 0x0a, 0x7f, 6, 0x64,
+    0x70, 2, 1, 6, 7, 0, 0, 0, 0
+};
+
+unsigned char setup_bw[] =
+{
+    0x61, 0x50, 0x52, 0x0f, 0x19, 6, 0x19,
+    0x19, 2, 0x0d, 0x0b, 0x0c, 0, 0, 0, 0
+};
+
+unsigned char * setup_modes[] =
+{
+    setup_40x25,     // mode 0: 40x25 bw text
+    setup_40x25,     // mode 1: 40x25 col text
+    setup_80x25,     // mode 2: 80x25 bw text
+    setup_80x25,     // mode 3: 80x25 col text
+    setup_graphics,  // mode 4: 320x200 col graphics
+    setup_graphics,  // mode 5: 320x200 bw graphics
+    setup_graphics,  // mode 6: 640x200 bw graphics
+    setup_bw         // mode 7: 80x25 mono text
+};
+
+unsigned int setup_cols[] =
+{
+    40, 40, 80, 80, 40, 40, 80, 80
+};
+
+unsigned char setup_modesets[] =
+{
+     0x2C, 0x28, 0x2D, 0x29, 0x2A, 0x2E, 0x1E, 0x29
+};
+
+unsigned int setup_bufsize[] =
+{
+    2048, 2048, 4096, 2096, 16384, 16384, 16384, 4096
+};
+
+void bios_set_mode(int mode)
+{
+    int i;
+    unsigned char mode_set = setup_modesets[mode]; // Control register value
+    unsigned char *setup_regs = setup_modes[mode]; // Register 3D4 Array
+
+    // Switch video off
+    out_byte(0x3D8, mode_set & 0x37);
+
+    // Set up parameters at 3D4h
+    for (i=0; i<16; i++)
+    {
+	out_byte(0x3D4, (unsigned char)i);
+	out_byte(0x3D5, *setup_regs);
+	setup_regs++;
+    }
+
+    // Enable video
+    out_byte(0x3D8, mode_set);
+
+    // Set overscan
+    if (mode == 6) out_byte(0x3D9, 0x3F);
+    else           out_byte(0x3D9, 0x30);
+}
+
+static void bios_print_string(void)
+{
+    extern void video_bios_print_string(char *string, int x, int y, int attr, int count);
+    char *s = (char *)(M.x86.R_ES<<4) + M.x86.R_BP;
+    int attr;
+    if (M.x86.R_AL & 0x02) attr = - 1;
+    else                   attr = M.x86.R_BL;
+    video_bios_print_string(s, M.x86.R_DH, M.x86.R_DL, attr, M.x86.R_CX);
+}
+
+static void X86API int42(int intno)
+{
+    switch (M.x86.R_AH)
+    {
+    case 0x00:
+	bios_set_mode(M.x86.R_AL);
+	break;
+    case 0x13:
+	bios_print_string();
+	break;
+    default:
+	PRINTF("Warning: VIDEO BIOS interrupt %xh unimplemented function %xh, AL = %xh\n",
+	       intno, M.x86.R_AH, M.x86.R_AL);
+    }
+}
+
+static void X86API int15(int intno)
+{
+    PRINTF("Called interrupt 15h: AX = %xh, BX = %xh, CX = %xh, DX = %xh\n",
+	   M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, M.x86.R_DX);
+}

+ 528 - 0
board/MAI/bios_emulator/glue.c

@@ -0,0 +1,528 @@
+#include <common.h>
+#include <pci.h>
+#include <74xx_7xx.h>
+
+
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+#ifdef DEBUG
+#define PRINTF(format, args...) _printf(format , ## args)
+#else
+#define PRINTF(format, argc...)
+#endif
+
+static pci_dev_t to_pci(int bus, int devfn)
+{
+    return PCI_BDF(bus, (devfn>>3), devfn&3);
+}
+
+int mypci_find_device(int vendor, int product, int index)
+{
+    return pci_find_device(vendor, product, index);
+}
+
+int mypci_bus(int device)
+{
+    return PCI_BUS(device);
+}
+
+int mypci_devfn(int device)
+{
+    return (PCI_DEV(device)<<3) | PCI_FUNC(device);
+}
+
+
+#define mypci_read_func(type, size)				\
+type mypci_read_cfg_##size##(int bus, int devfn, int offset)	\
+{								\
+    type c;							\
+    pci_read_config_##size##(to_pci(bus, devfn), offset, &c);	\
+    return c;							\
+}
+
+#define mypci_write_func(type, size)				\
+void mypci_write_cfg_##size##(int bus, int devfn, int offset, int value)	\
+{								\
+    pci_write_config_##size##(to_pci(bus, devfn), offset, value);	\
+}
+
+mypci_read_func(u8,byte);
+mypci_read_func(u16,word);
+
+mypci_write_func(u8,byte);
+mypci_write_func(u16,word);
+
+u32 mypci_read_cfg_long(int bus, int devfn, int offset)
+{
+    u32 c;
+    pci_read_config_dword(to_pci(bus, devfn), offset, &c);
+    return c;
+}
+
+void mypci_write_cfg_long(int bus, int devfn, int offset, int value)
+{
+    pci_write_config_dword(to_pci(bus, devfn), offset, value);
+}
+
+void _printf(const char *fmt, ...)
+{
+    va_list args;
+    char buf[CFG_PBSIZE];
+
+    va_start(args, fmt);
+    (void)vsprintf(buf, fmt, args);
+    va_end(args);
+
+    printf(buf);
+}
+
+char *_getenv(char *name)
+{
+    return getenv(name);
+}
+
+unsigned long get_bar_size(pci_dev_t dev, int offset)
+{
+    u32 bar_back, bar_value;
+
+    /*  Save old BAR value */
+    pci_read_config_dword(dev, offset, &bar_back);
+
+    /*  Write all 1's. */
+    pci_write_config_dword(dev, offset, ~0);
+
+    /*  Now read back the relevant bits */
+    pci_read_config_dword(dev, offset, &bar_value);
+
+    /*  Restore original value */
+    pci_write_config_dword(dev, offset, bar_back);
+
+    if (bar_value == 0) return 0xFFFFFFFF; /*  This BAR is disabled */
+
+    if ((bar_value & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY)
+    {
+	/*  This is a memory space BAR. Mask it out so we get the size of it */
+	return ~(bar_value & PCI_BASE_ADDRESS_MEM_MASK) + 1;
+    }
+
+    /*  Not suitable */
+    return 0xFFFFFFFF;
+}
+
+void enable_compatibility_hole(void)
+{
+    u8 cfg;
+    pci_dev_t art = PCI_BDF(0,0,0);
+
+    pci_read_config_byte(art, 0x54, &cfg);
+    /* cfg |= 0x08; */
+    cfg |= 0x20;
+    pci_write_config_byte(art, 0x54, cfg);
+}
+
+void disable_compatibility_hole(void)
+{
+    u8 cfg;
+    pci_dev_t art = PCI_BDF(0,0,0);
+
+    pci_read_config_byte(art, 0x54, &cfg);
+    /* cfg &= ~0x08; */
+    cfg &= ~0x20;
+    pci_write_config_byte(art, 0x54, cfg);
+}
+
+void map_rom(pci_dev_t dev, u32 address)
+{
+    pci_write_config_dword(dev, PCI_ROM_ADDRESS, address|PCI_ROM_ADDRESS_ENABLE);
+}
+
+void unmap_rom(pci_dev_t dev)
+{
+    pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
+}
+
+void bat_map(u8 batnum, u32 address, u32 length)
+{
+    u32 temp = address;
+    address &= 0xFFFE0000;
+    temp    &= 0x0001FFFF;
+    length = (length - 1 ) >> 17;
+    length <<= 2;
+
+    switch (batnum)
+    {
+    case 0:
+	__asm volatile ("mtdbatu 0, %0" : : "r" (address | length | 3));
+	__asm volatile ("mtdbatl 0, %0" : : "r" (address | 0x22));
+	break;
+    case 1:
+	__asm volatile ("mtdbatu 1, %0" : : "r" (address | length | 3));
+	__asm volatile ("mtdbatl 1, %0" : : "r" (address | 0x22));
+	break;
+    case 2:
+	__asm volatile ("mtdbatu 2, %0" : : "r" (address | length | 3));
+	__asm volatile ("mtdbatl 2, %0" : : "r" (address | 0x22));
+	break;
+    case 3:
+	__asm volatile ("mtdbatu 3, %0" : : "r" (address | length | 3));
+	__asm volatile ("mtdbatl 3, %0" : : "r" (address | 0x22));
+	break;
+    }
+}
+
+int find_image(u32 rom_address, u32 rom_size, void **image, u32 *image_size);
+
+int attempt_map_rom(pci_dev_t dev, void *copy_address)
+{
+    u32 rom_size      = 0;
+    u32 rom_address   = 0;
+    u32 bar_size      = 0;
+    u32 bar_backup    = 0;
+    int i,j;
+    void *image       = 0;
+    u32 image_size    = 0;
+    int did_correct   = 0;
+    u32 prefetch_addr = 0;
+    u32 prefetch_size = 0;
+    u32 prefetch_idx  = 0;
+
+    /*  Get the size of the expansion rom */
+    pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0xFFFFFFFF);
+    pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_size);
+    if ((rom_size & 0x01) == 0)
+    {
+	PRINTF("No ROM\n");
+	return 0;
+    }
+
+    rom_size &= 0xFFFFF800;
+    rom_size = (~rom_size)+1;
+
+    PRINTF("ROM Size is %dK\n", rom_size/1024);
+
+    /*
+     * Try to find a place for the ROM. We always attempt to use
+     * one of the card's bases for this, as this will be in any
+     * bridge's resource range as well as being free of conflicts
+     * with other cards. In a graphics card it is very unlikely
+     * that there won't be any base address that is large enough to
+     * hold the rom.
+     *
+     * FIXME: To work around this, theoretically the largest base
+     * could be used if none is found in the loop below.
+     */
+
+    for (i = PCI_BASE_ADDRESS_0; i <= PCI_BASE_ADDRESS_5; i += 4)
+    {
+	bar_size = get_bar_size(dev, i);
+	PRINTF("PCI_BASE_ADDRESS_%d is %dK large\n",
+	       (i - PCI_BASE_ADDRESS_0)/4,
+	       bar_size/1024);
+	if (bar_size != 0xFFFFFFFF && bar_size >= rom_size)
+	{
+	    PRINTF("Found a match for rom size\n");
+	    pci_read_config_dword(dev, i, &rom_address);
+	    rom_address &= 0xFFFFFFF0;
+	    if (rom_address != 0 && rom_address != 0xFFFFFFF0) break;
+	}
+    }
+
+    if (rom_address == 0 || rom_address == 0xFFFFFFF0)
+    {
+	PRINTF("No suitable rom address found\n");
+	return 0;
+    }
+
+    /*  Disable the BAR */
+    pci_read_config_dword(dev, i, &bar_backup);
+    pci_write_config_dword(dev, i, 0);
+
+    /*  Map ROM */
+    pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom_address | PCI_ROM_ADDRESS_ENABLE);
+
+    /*  Copy the rom to a place in the emulator space */
+    PRINTF("Claiming BAT 2\n");
+    bat_map(2, rom_address, rom_size);
+    /* show_bat_mapping(); */
+
+    if (0 == find_image(rom_address, rom_size, &image, &image_size))
+    {
+	PRINTF("No x86 BIOS image found\n");
+	return 0;
+    }
+
+    PRINTF("Copying %ld bytes from 0x%lx to 0x%lx\n", (long)image_size, (long)image, (long)copy_address);
+
+    /* memcpy(copy_address, rom_address, rom_size); */
+    {
+	unsigned char *from = (unsigned char *)image; /* rom_address; */
+	unsigned char *to = (unsigned char *)copy_address;
+	for (j=0; j<image_size /*rom_size*/; j++)
+	{
+	    *to++ = *from++;
+	}
+    }
+
+    PRINTF("Copy is done\n");
+
+    /*  Unmap the ROM and restore the BAR */
+    pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
+    pci_write_config_dword(dev, i, bar_backup);
+
+    /*  FIXME: */
+    bat_map(2, 0x80000000, 256*1024*1024);
+    show_bat_mapping();
+
+    /*
+     * Since most cards can probably only do 16 bit IO addressing, we
+     * correct their IO base into an appropriate value.
+     * This should do for most.
+     */
+    for (i = PCI_BASE_ADDRESS_0; i <= PCI_BASE_ADDRESS_5; i += 4)
+    {
+	unsigned long value;
+	pci_read_config_dword(dev, i, &value);
+	if (value & 0x01) /*  IO */
+	{
+	    did_correct = 1;
+	    pci_write_config_dword(dev, i, 0x1001);
+	    break;
+	}
+
+	if (value & PCI_BASE_ADDRESS_MEM_PREFETCH)
+	{
+	    prefetch_idx = i;
+	    prefetch_addr = value & PCI_BASE_ADDRESS_MEM_MASK;
+	    prefetch_size = get_bar_size(dev, i);
+	}
+    }
+
+    if (1) /* did_correct) */
+    {
+	extern pci_dev_t pci_find_bridge_for_bus(struct pci_controller *hose, int busnr);
+	int busnr = PCI_BUS(dev);
+	if (busnr)
+	{
+	    pci_dev_t bridge;
+	    PRINTF("Need to correct bridge device for IO range change\n");
+	    bridge = pci_find_bridge_for_bus(NULL, busnr);
+	    if (bridge == PCI_ANY_ID)
+	    {
+		PRINTF("Didn't find bridge. Hope that's OK\n");
+	    }
+	    else
+	    {
+		/*
+		 * Set upper I/O base/limit to 0
+		 */
+		pci_write_config_byte(bridge, 0x30, 0x00);
+		pci_write_config_byte(bridge, 0x31, 0x00);
+		pci_write_config_byte(bridge, 0x32, 0x00);
+		pci_write_config_byte(bridge, 0x33, 0x00);
+		if (did_correct)
+		{
+		    /*
+		     * set lower I/O base to 1000
+		     * That is, bits 0:3 are set to 0001 by default.
+		     * bits 7:4 contain I/O address bits 15:12
+		     * all others are assumed 0.
+		     */
+		    pci_write_config_byte(bridge, 0x1C, 0x11);
+		    /*
+		     * Set lower I/O limit to 1FFF
+		     * That is, bits 0:3 are reserved and always 0000
+		     * Bits 7:4 contain I/O address bits 15:12
+		     * All others are assumed F.
+		     */
+		    pci_write_config_byte(bridge, 0x1D, 0x10);
+		    pci_write_config_byte(bridge, 0x0D, 0x20);
+		    PRINTF("Corrected bridge resource range of bridge at %02x:%02x:%02x\n",
+			   PCI_BUS(bridge), PCI_DEV(bridge), PCI_FUNC(bridge));
+
+		}
+		else
+		{
+		    /*
+		     * This card doesn't have I/O, we disable I/O forwarding
+		     */
+		    pci_write_config_byte(bridge, 0x1C, 0x11);
+		    pci_write_config_byte(bridge, 0x1D, 0x00);
+		    pci_write_config_byte(bridge, PCI_INTERRUPT_LINE, 0);
+		    pci_write_config_byte(bridge, PCI_INTERRUPT_PIN, 0);
+		    pci_write_config_dword(bridge, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_IO);
+		    PRINTF("Disabled bridge resource range of bridge at %02x:%02x:%02x\n",
+			   PCI_BUS(bridge), PCI_DEV(bridge), PCI_FUNC(bridge));
+
+		}
+	    }
+	    /*
+	     * Correct the prefetchable memory base, which is not set correctly by
+	     * the U-Boot autoconfig stuff
+	     */
+	    if (prefetch_idx)
+	    {
+/* 		PRINTF("Setting prefetchable range to %x, %x (%x and %x)\n", */
+/* 		       prefetch_addr, prefetch_addr+prefetch_size, */
+/* 		       prefetch_addr>>16, (prefetch_addr+prefetch_size)>>16); */
+/* 		pci_write_config_word(bridge, PCI_PREF_MEMORY_BASE, (prefetch_addr>>16)); */
+/* 		pci_write_config_word(bridge, PCI_PREF_MEMORY_LIMIT, (prefetch_addr+prefetch_size)>>16); */
+	    }
+
+	    pci_write_config_word(bridge, PCI_PREF_MEMORY_BASE, 0x1000);
+	    pci_write_config_word(bridge, PCI_PREF_MEMORY_LIMIT, 0x0000);
+
+	    pci_write_config_byte(bridge, 0xD0, 0x0A);
+	    pci_write_config_byte(bridge, 0xD3, 0x04);
+
+	    /*
+	     * Set the interrupt pin to 0
+	     */
+#if 0
+	    pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 0);
+	    pci_write_config_byte(dev, PCI_INTERRUPT_PIN, 0);
+#endif
+	    pci_write_config_byte(bridge, PCI_INTERRUPT_LINE, 0);
+	    pci_write_config_byte(bridge, PCI_INTERRUPT_PIN, 0);
+
+	}
+    }
+
+    /* Finally, enable the card's IO and memory response */
+    pci_write_config_dword(dev, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
+    pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0);
+    pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0);
+
+    return 1;
+}
+
+int find_image(u32 rom_address, u32 rom_size, void **image, u32 *image_size)
+{
+    int i = 0;
+    unsigned char *rom = (unsigned char *)rom_address;
+    /* if (*rom != 0x55 || *(rom+1) != 0xAA) return 0; // No bios rom this is, yes. */
+
+    for (;;)
+    {
+	unsigned short pci_data_offset = *(rom+0x18) + 256 * *(rom+0x19);
+	unsigned short pci_image_length = (*(rom+pci_data_offset+0x10) + 256 * *(rom+pci_data_offset+0x11)) * 512;
+	unsigned char pci_image_type = *(rom+pci_data_offset+0x14);
+	if (*rom != 0x55 || *(rom+1) != 0xAA)
+	{
+	    PRINTF("Invalid header this is\n");
+	    return 0;
+	}
+	PRINTF("Image %i: Type %d (%s)\n", i++, pci_image_type,
+	       pci_image_type==0 ? "x86" :
+	       pci_image_type==1 ? "OpenFirmware" :
+	       "Unknown");
+	if (pci_image_type == 0)
+	{
+	    *image = rom;
+	    *image_size = pci_image_length;
+	    return 1;
+	}
+
+	if (*(rom+pci_data_offset+0x15) & 0x80)
+	{
+	    PRINTF("LAST image encountered, no image found\n");
+	    return 0;
+	}
+
+	rom += pci_image_length;
+    }
+}
+
+void show_bat_mapping(void)
+{
+#ifdef DEBUG
+    u32 dbat0u, dbat0l, ibat0u, ibat0l;
+    u32 dbat1u, dbat1l, ibat1u, ibat1l;
+    u32 dbat2u, dbat2l, ibat2u, ibat2l;
+    u32 dbat3u, dbat3l, ibat3u, ibat3l;
+    u32 msr, hid0, l2cr_reg;
+
+    __asm volatile ("mfdbatu %0,0" : "=r" (dbat0u));
+    __asm volatile ("mfdbatl %0,0" : "=r" (dbat0l));
+    __asm volatile ("mfibatu %0,0" : "=r" (ibat0u));
+    __asm volatile ("mfibatl %0,0" : "=r" (ibat0l));
+
+    __asm volatile ("mfdbatu %0,1" : "=r" (dbat1u));
+    __asm volatile ("mfdbatl %0,1" : "=r" (dbat1l));
+    __asm volatile ("mfibatu %0,1" : "=r" (ibat1u));
+    __asm volatile ("mfibatl %0,1" : "=r" (ibat1l));
+
+    __asm volatile ("mfdbatu %0,2" : "=r" (dbat2u));
+    __asm volatile ("mfdbatl %0,2" : "=r" (dbat2l));
+    __asm volatile ("mfibatu %0,2" : "=r" (ibat2u));
+    __asm volatile ("mfibatl %0,2" : "=r" (ibat2l));
+
+    __asm volatile ("mfdbatu %0,3" : "=r" (dbat3u));
+    __asm volatile ("mfdbatl %0,3" : "=r" (dbat3l));
+    __asm volatile ("mfibatu %0,3" : "=r" (ibat3u));
+    __asm volatile ("mfibatl %0,3" : "=r" (ibat3l));
+
+    __asm volatile ("mfmsr %0"     : "=r" (msr));
+    __asm volatile ("mfspr %0,1008": "=r" (hid0));
+    __asm volatile ("mfspr %0,1017": "=r" (l2cr_reg));
+
+    printf("dbat0u: %08x dbat0l: %08x ibat0u: %08x ibat0l: %08x\n",
+	   dbat0u, dbat0l, ibat0u, ibat0l);
+    printf("dbat1u: %08x dbat1l: %08x ibat1u: %08x ibat1l: %08x\n",
+	   dbat1u, dbat1l, ibat1u, ibat1l);
+    printf("dbat2u: %08x dbat2l: %08x ibat2u: %08x ibat2l: %08x\n",
+	   dbat2u, dbat2l, ibat2u, ibat2l);
+    printf("dbat3u: %08x dbat3l: %08x ibat3u: %08x ibat3l: %08x\n",
+	   dbat3u, dbat3l, ibat3u, ibat3l);
+
+    printf("\nMSR: %08x   HID0: %08x   L2CR: %08x \n", msr,hid0, l2cr_reg);
+#endif
+}
+
+
+
+void remove_init_data(void)
+{
+    char *s;
+    u32 batl = ((CFG_SDRAM_BASE+0x100000) | BATL_PP_RW);
+    u32 batu =((CFG_SDRAM_BASE+0x100000) | BATU_BL_256M | BATU_VS | BATU_VP);
+#if 0	/* already done in board_init_r() */
+    void *data = (void *)(CFG_INIT_RAM_ADDR+CFG_INIT_DATA_OFFSET);
+    unsigned char data2[CFG_INIT_DATA_SIZE];
+
+    /*  Make a copy of the data */
+    memcpy(data2, data, CFG_INIT_DATA_SIZE);
+#endif /* 0 */
+
+    /*  Invalidate and disable data cache */
+    invalidate_l1_data_cache();
+    dcache_disable();
+
+#if 0
+    /*  Copy to the real RAM address */
+    memcpy(data, data2, CFG_INIT_DATA_SIZE);
+#endif
+
+    /*printf("Before ICache enable\n");
+      show_bat_mapping();*/
+
+    __asm volatile ("isync        \n"
+		    "mtdbatu 2,%2 \n"
+		    "mtdbatl 2,%2 \n"
+	            "mtdbatu 1,%0 \n"
+		    "mtdbatl 1,%1 \n"
+		    "sync         \n"
+		    "isync        \n"
+		    : : "r" (batu), "r" (batl), "r" (0));
+
+    /* show_bat_mapping(); */
+    s = getenv("x86_cache");
+
+    if (!s || (s && strcmp(s, "on")==0))
+    {
+	icache_enable();
+	dcache_enable();
+    }
+
+}

+ 57 - 0
board/MAI/bios_emulator/glue.h

@@ -0,0 +1,57 @@
+#ifndef GLUE_H
+#define GLUE_H
+
+typedef unsigned int pci_dev_t;
+
+int mypci_find_device(int vendor, int product, int index);
+int mypci_bus(int device);
+int mypci_devfn(int device);
+unsigned long get_bar_size(pci_dev_t dev, int offset);
+
+u8   mypci_read_cfg_byte(int bus, int devfn, int offset);
+u16  mypci_read_cfg_word(int bus, int devfn, int offset);
+u32  mypci_read_cfg_long(int bus, int devfn, int offset);
+
+void mypci_write_cfg_byte(int bus, int devfn, int offset, u8 value);
+void mypci_write_cfg_word(int bus, int devfn, int offset, u16 value);
+void mypci_write_cfg_long(int bus, int devfn, int offset, u32 value);
+
+void _printf(const char *fmt, ...);
+char *_getenv(char *name);
+
+void *malloc(size_t size);
+void memset(void *addr, int value, size_t size);
+void memcpy(void *to, void *from, size_t numbytes);
+int  strcmp(char *, char *);
+
+void enable_compatibility_hole(void);
+void disable_compatibility_hole(void);
+
+void map_rom(pci_dev_t dev, unsigned long address);
+void unmap_rom(pci_dev_t dev);
+int  attempt_map_rom(pci_dev_t dev, void *copy_address);
+
+#define  PCI_BASE_ADDRESS_SPACE 0x01    /* 0 = memory, 1 = I/O */
+#define  PCI_BASE_ADDRESS_SPACE_IO 0x01
+#define  PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
+#define  PCI_BASE_ADDRESS_MEM_MASK      (~0x0fUL)
+
+#define PCI_BASE_ADDRESS_0      0x10    /* 32 bits */
+#define PCI_BASE_ADDRESS_1      0x14    /* 32 bits [htype 0,1 only] */
+#define PCI_BASE_ADDRESS_2      0x18    /* 32 bits [htype 0 only] */
+#define PCI_BASE_ADDRESS_3      0x1c    /* 32 bits */
+#define PCI_BASE_ADDRESS_4      0x20    /* 32 bits */
+#define PCI_BASE_ADDRESS_5      0x24    /* 32 bits */
+#define PCI_BUS(d)      (((d) >> 16) & 0xff)
+#define PCI_DEV(d)      (((d) >> 11) & 0x1f)
+#define PCI_FUNC(d)     (((d) >> 8) & 0x7)
+#define PCI_BDF(b,d,f)  ((b) << 16 | (d) << 11 | (f) << 8)
+
+#define PCI_ANY_ID (~0)
+#define PCI_ROM_ADDRESS         0x30    /* Bits 31..11 are address, 10..1 reserved */
+#define PCI_ROM_ADDRESS_ENABLE 0x01
+
+#define OFF(addr) ((addr) & 0xFFFF)
+#define SEG(addr) (((addr)>>4) &0xF000)
+
+#endif

BIN
board/MAI/bios_emulator/scitech/bin-linux/glibc/dmake


BIN
board/MAI/bios_emulator/scitech/bin-linux/glibc/k_cp


BIN
board/MAI/bios_emulator/scitech/bin-linux/glibc/k_echo


BIN
board/MAI/bios_emulator/scitech/bin-linux/glibc/k_rm


BIN
board/MAI/bios_emulator/scitech/bin-linux/glibc/makedep


BIN
board/MAI/bios_emulator/scitech/bin-linux/glibc/nasm


BIN
board/MAI/bios_emulator/scitech/bin-linux/glibc/ndisasm


BIN
board/MAI/bios_emulator/scitech/bin-linux/glibc/trans


BIN
board/MAI/bios_emulator/scitech/bin-linux/libc/dmake


BIN
board/MAI/bios_emulator/scitech/bin-linux/libc/nasm


BIN
board/MAI/bios_emulator/scitech/bin-linux/libc/ndisasm


BIN
board/MAI/bios_emulator/scitech/bin-linux/libc/trans


+ 28 - 0
board/MAI/bios_emulator/scitech/bin/bc31-d16.bat

@@ -0,0 +1,28 @@
+@echo off
+REM Setup for compiling with Borland C++ 3.1.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\DOS16\BC3;%BC3_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\DOS16\BC3;%BC3_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BC3_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC3.MK
+SET USE_DPMI16=
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_SNAP=
+PATH %SCITECH_BIN%;%BC3_PATH%\BIN;%DEFPATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC3_PATH%\BIN\turboc.cfg
+echo -L%LIB% >> %BC3_PATH%\BIN\turboc.cfg
+echo -L%LIB% > %BC3_PATH%\BIN\tlink.cfg
+
+echo Borland C++ 3.1 DOS compilation configuration set up.

+ 37 - 0
board/MAI/bios_emulator/scitech/bin/bc45-c32.bat

@@ -0,0 +1,37 @@
+@echo off
+REM Setup for compiling with Borland C++ 4.5 in 32 bit Windows mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\WIN32\BC4;%BC4_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\WIN32\BC4;%BC4_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BC4_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_WIN16=
+SET USE_WIN32=1
+SET USE_VXD=
+SET USE_TNT=
+SET USE_BC5=
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC4
+PATH %SCITECH_BIN%;%BC4_PATH%\BIN;%DEFPATH%%BC_CD_PATH%
+
+REM: Enable Win32 SDK if desired (sdk on command line)
+if NOT .%1%==.sdk goto createfiles
+call win32sdk.bat borland
+
+:createfiles
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC4_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BC4_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BC4_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ 4.5 32 bit Windows compilation configuration set up.

+ 32 - 0
board/MAI/bios_emulator/scitech/bin/bc45-d16.bat

@@ -0,0 +1,32 @@
+@echo off
+REM Setup for compiling with Borland C++ 4.5 in 16 bit mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\DOS16\BC4;%BC4_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\DOS16\BC4;%BC4_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BC4_PATH%\INCLUDE
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC16.MK
+SET USE_DPMI16=
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_VXD=
+SET USE_BC5=
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC4
+PATH %SCITECH_BIN%;%BC4_PATH%\BIN;%DEFPATH%%BC_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC4_PATH%\BIN\turboc.cfg
+echo -L%LIB% >> %BC4_PATH%\BIN\turboc.cfg
+echo -L%LIB% > %BC4_PATH%\BIN\tlink.cfg
+
+echo Borland C++ 4.5 16 bit DOS compilation configuration set up.

+ 33 - 0
board/MAI/bios_emulator/scitech/bin/bc45-d32.bat

@@ -0,0 +1,33 @@
+@echo off
+REM Setup for compiling with Borland C++ 4.5 in 32 bit mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\DOS32\BC4;%BC4_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\DOS32\BC4;%BC4_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BC4_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_DPMI16=
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_VXD=
+SET USE_TNT=
+SET USE_BC5=
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC4
+PATH %SCITECH_BIN%;%BC4_PATH%\BIN;%DEFPATH%%BC_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC4_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BC4_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BC4_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ 4.5 32 bit DOS compilation configuration set up (DPMI32).

+ 32 - 0
board/MAI/bios_emulator/scitech/bin/bc45-snp.bat

@@ -0,0 +1,32 @@
+@echo off
+REM Setup for compiling with Borland C++ 4.5 in 32 bit Windows mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\SNAP\BC4;%BC4_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\SNAP\BC4;%BC4_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_VXD=
+SET USE_TNT=
+SET USE_BC5=
+SET WIN32_GUI=
+SET USE_SNAP=1
+SET BC_LIBBASE=BC4
+PATH %SCITECH_BIN%;%BC4_PATH%\BIN;%DEFPATH%%BC_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC4_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BC4_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BC4_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ 4.5 Snap compilation configuration set up.

+ 46 - 0
board/MAI/bios_emulator/scitech/bin/bc45-tnt.bat

@@ -0,0 +1,46 @@
+@echo off
+REM Setup for compiling with Borland C++ 4.5 in 32 bit mode with Phar Lap TNT
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\DOS32\BC4;%BC4_PATH%\LIB;%TNT_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\DOS32\BC4;%BC4_PATH%\LIB;%TNT_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BC4_PATH%\INCLUDE;%TNT_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_DPMI16=
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_VXD=
+SET USE_TNT=1
+SET USE_BC5=
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC4
+PATH %SCITECH_BIN%;%BC4_PATH%\BIN;%TNT_PATH%\BIN;%DEFPATH%%BC_CD_PATH%
+
+REM If you set the following to a 1, a TNT DosStyle app will be created.
+REM Otherwise a TNT NtStyle app will be created. NtStyle apps will *only*
+REM run under real DOS when using our libraries, since we require access
+REM to functions that the Win32 API does not support (such as direct access
+REM to video memory, calling Int 10h BIOS functions etc). DosStyle apps
+REM will however run fine in both DOS and a Win95 DOS box (NT DOS boxes don't
+REM work too well).
+REM
+REM If you are using the RealTime DOS extender, your apps *must* be NtStyle,
+REM and hence will never be able to run under Win95 or WinNT, only DOS.
+
+SET DOSSTYLE=
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC4_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BC4_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BC4_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ 4.5 32 bit DOS compilation configuration set up (TNT).

+ 32 - 0
board/MAI/bios_emulator/scitech/bin/bc45-vxd.bat

@@ -0,0 +1,32 @@
+@echo off
+REM Setup for compiling with Borland C++ 4.5 in 32 bit Windows VxD mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\VXD\BC4;%BC4_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\VXD\BC4;%BC4_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BC4_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_VXD=1
+SET USE_TNT=
+SET USE_BC5=
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC4
+PATH %SCITECH_BIN%;%BC4_PATH%\BIN;%DEFPATH%%BC_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC4_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BC4_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BC4_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ 4.5 32-bit VxD compilation configuration set up.

+ 32 - 0
board/MAI/bios_emulator/scitech/bin/bc45-w16.bat

@@ -0,0 +1,32 @@
+@echo off
+REM Setup for compiling with Borland C++ 4.5 in 16 bit Windows mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\WIN16\BC4;%BC4_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\WIN16\BC4;%BC4_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BC4_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC16.MK
+SET USE_DPMI16=
+SET USE_WIN16=1
+SET USE_WIN32=
+SET USE_VXD=
+SET USE_BC5=
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC4
+PATH %SCITECH_BIN%;%BC4_PATH%\BIN;%DEFPATH%%BC_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC4_PATH%\BIN\turboc.cfg
+echo -L%LIB% >> %BC4_PATH%\BIN\turboc.cfg
+echo -L%LIB% > %BC4_PATH%\BIN\tlink.cfg
+
+echo Borland C++ 4.5 16 bit Windows compilation configuration set up.

+ 37 - 0
board/MAI/bios_emulator/scitech/bin/bc45-w32.bat

@@ -0,0 +1,37 @@
+@echo off
+REM Setup for compiling with Borland C++ 4.5 in 32 bit Windows mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\WIN32\BC4;%BC4_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\WIN32\BC4;%BC4_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BC4_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_WIN16=
+SET USE_WIN32=1
+SET USE_VXD=
+SET USE_TNT=
+SET USE_BC5=
+SET WIN32_GUI=1
+SET USE_SNAP=
+SET BC_LIBBASE=BC4
+PATH %SCITECH_BIN%;%BC4_PATH%\BIN;%DEFPATH%%BC_CD_PATH%
+
+REM: Enable Win32 SDK if desired (sdk on command line)
+if NOT .%1%==.sdk goto createfiles
+call win32sdk.bat borland
+
+:createfiles
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC4_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BC4_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BC4_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ 4.5 32 bit Windows compilation configuration set up.

+ 40 - 0
board/MAI/bios_emulator/scitech/bin/bc50-c32.bat

@@ -0,0 +1,40 @@
+@echo off
+REM Setup for compiling with Borland C++ 5.0 in 32 bit Windows mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\WIN32\BC5;%BC5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\WIN32\BC5;%BC5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET C_INCLUDE=%BC5_PATH%\INCLUDE
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%C_INCLUDE%
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_WIN16=
+SET USE_WIN32=1
+SET USE_VXD=
+SET USE_TNT=
+SET USE_SMX32=
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BC5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Enable Win32 SDK if desired (sdk on command line)
+if NOT .%1%==.sdk goto createfiles
+call win32sdk.bat borland
+
+:createfiles
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BC5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BC5_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ 5.0 32 bit Windows compilation configuration set up.

+ 34 - 0
board/MAI/bios_emulator/scitech/bin/bc50-d16.bat

@@ -0,0 +1,34 @@
+@echo off
+REM Setup for compiling with Borland C++ 5.0 in 16 bit mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\DOS16\BC5;%BC5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\DOS16\BC5;%BC5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BC5_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC16.MK
+SET USE_DPMI16=
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_VXD=
+SET USE_SMX32=
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BC5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC5_PATH%\BIN\turboc.cfg
+echo -L%LIB% >> %BC5_PATH%\BIN\turboc.cfg
+echo -L%LIB% > %BC5_PATH%\BIN\tlink.cfg
+
+echo Borland C++ 5.0 16 bit DOS compilation configuration set up.

+ 35 - 0
board/MAI/bios_emulator/scitech/bin/bc50-d32.bat

@@ -0,0 +1,35 @@
+@echo off
+REM Setup for compiling with Borland C++ 5.0 in 32 bit mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\DOS32\BC5;%BC5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\DOS32\BC5;%BC5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BC5_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_DPMI16=
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_VXD=
+SET USE_TNT=
+SET USE_SMX32=
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BC5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BC5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BC5_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ 5.0 32 bit DOS compilation configuration set up (DPMI32).

+ 35 - 0
board/MAI/bios_emulator/scitech/bin/bc50-smx.bat

@@ -0,0 +1,35 @@
+@echo off
+REM Setup for compiling with Borland C++ 5.0 in 32 bit mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\SMX32\BC5;%BC5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\SMX32\BC5;%BC5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BC5_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_DPMI16=
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_VXD=
+SET USE_TNT=
+SET USE_SMX32=1
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BC5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BC5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BC5_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ 5.0 32 bit SMX compilation configuration set up (SMX32).

+ 34 - 0
board/MAI/bios_emulator/scitech/bin/bc50-snp.bat

@@ -0,0 +1,34 @@
+@echo off
+REM Setup for compiling with Borland C++ 5.0 in 32 bit Windows mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\SNAP\BC5;%BC5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\SNAP\BC5;%BC5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_VXD=
+SET USE_TNT=
+SET USE_SMX32=
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=
+SET USE_SNAP=1
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BC5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BC5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BC5_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ 5.0 Snap compilation configuration set up.

+ 48 - 0
board/MAI/bios_emulator/scitech/bin/bc50-tnt.bat

@@ -0,0 +1,48 @@
+@echo off
+REM Setup for compiling with Borland C++ 5.0 in 32 bit mode with Phar Lap TNT
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\DOS32\BC5;%BC5_PATH%\LIB;%TNT_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\DOS32\BC5;%BC5_PATH%\LIB;%TNT_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BC5_PATH%\INCLUDE;%TNT_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_DPMI16=
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_VXD=
+SET USE_TNT=1
+SET USE_SMX32=
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BC5_PATH%\BIN;%TNT_PATH%\BIN;%DEFPATH%%BC_CD_PATH%
+
+REM If you set the following to a 1, a TNT DosStyle app will be created.
+REM Otherwise a TNT NtStyle app will be created. NtStyle apps will *only*
+REM run under real DOS when using our libraries, since we require access
+REM to functions that the Win32 API does not support (such as direct access
+REM to video memory, calling Int 10h BIOS functions etc). DosStyle apps
+REM will however run fine in both DOS and a Win95 DOS box (NT DOS boxes don't
+REM work too well).
+REM
+REM If you are using the RealTime DOS extender, your apps *must* be NtStyle,
+REM and hence will never be able to run under Win95 or WinNT, only DOS.
+
+SET DOSSTYLE=
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BC5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BC5_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ 5.0 32 bit DOS compilation configuration set up (TNT).

+ 34 - 0
board/MAI/bios_emulator/scitech/bin/bc50-vxd.bat

@@ -0,0 +1,34 @@
+@echo off
+REM Setup for compiling with Borland C++ 5.0 in 32 bit Windows mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\VXD\BC5;%BC5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\VXD\BC5;%BC5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BC5_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_VXD=1
+SET USE_TNT=
+SET USE_SMX32=
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BC5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BC5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BC5_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ 5.0 32 bit Windows (VxD) compilation configuration set up.

+ 34 - 0
board/MAI/bios_emulator/scitech/bin/bc50-w16.bat

@@ -0,0 +1,34 @@
+ @echo off
+REM Setup for compiling with Borland C++ 5.0 in 16 bit Windows mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\WIN16\BC5;%BC5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\WIN16\BC5;%BC5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BC5_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC16.MK
+SET USE_DPMI16=
+SET USE_WIN16=1
+SET USE_WIN32=
+SET USE_VXD=
+SET USE_BC5=1
+SET USE_SMX32=
+SET USE_SMX16=
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BC5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC5_PATH%\BIN\turboc.cfg
+echo -L%LIB% >> %BC5_PATH%\BIN\turboc.cfg
+echo -L%LIB% > %BC5_PATH%\BIN\tlink.cfg
+
+echo Borland C++ 5.0 16 bit Windows compilation configuration set up.

+ 40 - 0
board/MAI/bios_emulator/scitech/bin/bc50-w32.bat

@@ -0,0 +1,40 @@
+@echo off
+REM Setup for compiling with Borland C++ 5.0 in 32 bit Windows mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\WIN32\BC5;%BC5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\WIN32\BC5;%BC5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET C_INCLUDE=%BC5_PATH%\INCLUDE
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%C_INCLUDE%
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_WIN16=
+SET USE_WIN32=1
+SET USE_VXD=
+SET USE_TNT=
+SET USE_SMX32=
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=1
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BC5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Enable Win32 SDK if desired (sdk on command line)
+if NOT .%1%==.sdk goto createfiles
+call win32sdk.bat borland
+
+:createfiles
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BC5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BC5_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ 5.0 32 bit Windows compilation configuration set up.

+ 34 - 0
board/MAI/bios_emulator/scitech/bin/bc50-x11.bat

@@ -0,0 +1,34 @@
+@echo off
+REM Setup for compiling with Borland C++ 5.0 in 32 bit Windows mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\WIN32\BC5;%BC5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\WIN32\BC5;%BC5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BC5_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_WIN16=
+SET USE_WIN32=1
+SET USE_VXD=
+SET USE_TNT=
+SET USE_SMX32=
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=1
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BC5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BC5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BC5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BC5_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ 5.0 32 bit Windows compilation configuration set up.

+ 40 - 0
board/MAI/bios_emulator/scitech/bin/bcb5-c32.bat

@@ -0,0 +1,40 @@
+@echo off
+REM Setup for compiling with Borland C++ Builder 5.0 in 32 bit Windows mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\WIN32\BCB5;%BCB5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\WIN32\BCB5;%BCB5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET C_INCLUDE=%BCB5_PATH%\INCLUDE
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%C_INCLUDE%
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_WIN16=
+SET USE_WIN32=1
+SET USE_VXD=
+SET USE_TNT=
+SET USE_SMX32=
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BCB5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Enable Win32 SDK if desired (sdk on command line)
+if NOT .%1%==.sdk goto createfiles
+call win32sdk.bat borland
+
+:createfiles
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BCB5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BCB5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BCB5_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ Builder 5.0 32 bit Windows compilation configuration set up.

+ 34 - 0
board/MAI/bios_emulator/scitech/bin/bcb5-d16.bat

@@ -0,0 +1,34 @@
+@echo off
+REM Setup for compiling with Borland C++ Builder 5.0 in 16 bit mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\DOS16\BCB5;%BCB5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\DOS16\BCB5;%BCB5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BCB5_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC16.MK
+SET USE_DPMI16=
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_VXD=
+SET USE_SMX32=
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BCB5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BCB5_PATH%\BIN\turboc.cfg
+echo -L%LIB% >> %BCB5_PATH%\BIN\turboc.cfg
+echo -L%LIB% > %BCB5_PATH%\BIN\tlink.cfg
+
+echo Borland C++ Builder 5.0 16 bit DOS compilation configuration set up.

+ 35 - 0
board/MAI/bios_emulator/scitech/bin/bcb5-d32.bat

@@ -0,0 +1,35 @@
+@echo off
+REM Setup for compiling with Borland C++ Builder 5.0 in 32 bit mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\DOS32\BCB5;%BCB5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\DOS32\BCB5;%BCB5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BCB5_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_DPMI16=
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_VXD=
+SET USE_TNT=
+SET USE_SMX32=
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BCB5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BCB5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BCB5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BCB5_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ Builder 5.0 32 bit DOS compilation configuration set up (DPMI32).

+ 35 - 0
board/MAI/bios_emulator/scitech/bin/bcb5-smx.bat

@@ -0,0 +1,35 @@
+@echo off
+REM Setup for compiling with Borland C++ Builder 5.0 in 32 bit mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\SMX32\BCB5;%BCB5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\SMX32\BCB5;%BCB5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BCB5_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_DPMI16=
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_VXD=
+SET USE_TNT=
+SET USE_SMX32=1
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BCB5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BCB5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BCB5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BCB5_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ Builder 5.0 32 bit SMX compilation configuration set up (SMX32).

+ 34 - 0
board/MAI/bios_emulator/scitech/bin/bcb5-snp.bat

@@ -0,0 +1,34 @@
+@echo off
+REM Setup for compiling with Borland C++ Builder 5.0 in 32 bit Windows mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\SNAP\BCB5;%BCB5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\SNAP\BCB5;%BCB5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_VXD=
+SET USE_TNT=
+SET USE_SMX32=
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=
+SET USE_SNAP=1
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BCB5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BCB5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BCB5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BCB5_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ Builder 5.0 Snap compilation configuration set up.

+ 48 - 0
board/MAI/bios_emulator/scitech/bin/bcb5-tnt.bat

@@ -0,0 +1,48 @@
+@echo off
+REM Setup for compiling with Borland C++ Builder 5.0 in 32 bit mode with Phar Lap TNT
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\DOS32\BCB5;%BCB5_PATH%\LIB;%TNT_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\DOS32\BCB5;%BCB5_PATH%\LIB;%TNT_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BCB5_PATH%\INCLUDE;%TNT_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_DPMI16=
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_VXD=
+SET USE_TNT=1
+SET USE_SMX32=
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BCB5_PATH%\BIN;%TNT_PATH%\BIN;%DEFPATH%%BC_CD_PATH%
+
+REM If you set the following to a 1, a TNT DosStyle app will be created.
+REM Otherwise a TNT NtStyle app will be created. NtStyle apps will *only*
+REM run under real DOS when using our libraries, since we require access
+REM to functions that the Win32 API does not support (such as direct access
+REM to video memory, calling Int 10h BIOS functions etc). DosStyle apps
+REM will however run fine in both DOS and a Win95 DOS box (NT DOS boxes don't
+REM work too well).
+REM
+REM If you are using the RealTime DOS extender, your apps *must* be NtStyle,
+REM and hence will never be able to run under Win95 or WinNT, only DOS.
+
+SET DOSSTYLE=
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BCB5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BCB5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BCB5_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ Builder 5.0 32 bit DOS compilation configuration set up (TNT).

+ 34 - 0
board/MAI/bios_emulator/scitech/bin/bcb5-vxd.bat

@@ -0,0 +1,34 @@
+@echo off
+REM Setup for compiling with Borland C++ Builder 5.0 in 32 bit Windows mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\VXD\BCB5;%BCB5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\VXD\BCB5;%BCB5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BCB5_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_WIN16=
+SET USE_WIN32=
+SET USE_VXD=1
+SET USE_TNT=
+SET USE_SMX32=
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BCB5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BCB5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BCB5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BCB5_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ Builder 5.0 32 bit Windows (VxD) compilation configuration set up.

+ 34 - 0
board/MAI/bios_emulator/scitech/bin/bcb5-w16.bat

@@ -0,0 +1,34 @@
+ @echo off
+REM Setup for compiling with Borland C++ Builder 5.0 in 16 bit Windows mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\WIN16\BCB5;%BCB5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\WIN16\BCB5;%BCB5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BCB5_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC16.MK
+SET USE_DPMI16=
+SET USE_WIN16=1
+SET USE_WIN32=
+SET USE_VXD=
+SET USE_BC5=1
+SET USE_SMX32=
+SET USE_SMX16=
+SET WIN32_GUI=
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BCB5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BCB5_PATH%\BIN\turboc.cfg
+echo -L%LIB% >> %BCB5_PATH%\BIN\turboc.cfg
+echo -L%LIB% > %BCB5_PATH%\BIN\tlink.cfg
+
+echo Borland C++ Builder 5.0 16 bit Windows compilation configuration set up.

+ 40 - 0
board/MAI/bios_emulator/scitech/bin/bcb5-w32.bat

@@ -0,0 +1,40 @@
+@echo off
+REM Setup for compiling with Borland C++ Builder 5.0 in 32 bit Windows mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\WIN32\BCB5;%BCB5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\WIN32\BCB5;%BCB5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET C_INCLUDE=%BCB5_PATH%\INCLUDE
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%C_INCLUDE%
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_WIN16=
+SET USE_WIN32=1
+SET USE_VXD=
+SET USE_TNT=
+SET USE_SMX32=
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=1
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BCB5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Enable Win32 SDK if desired (sdk on command line)
+if NOT .%1%==.sdk goto createfiles
+call win32sdk.bat borland
+
+:createfiles
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BCB5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BCB5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BCB5_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ Builder 5.0 32 bit Windows compilation configuration set up.

+ 34 - 0
board/MAI/bios_emulator/scitech/bin/bcb5-x11.bat

@@ -0,0 +1,34 @@
+@echo off
+REM Setup for compiling with Borland C++ Builder 5.0 in 32 bit Windows mode.
+
+if .%CHECKED%==.1 goto checked_build
+SET LIB=%SCITECH_LIB%\LIB\RELEASE\WIN32\BCB5;%BCB5_PATH%\LIB;.
+echo Release build enabled.
+goto setvars
+
+:checked_build
+SET LIB=%SCITECH_LIB%\LIB\DEBUG\WIN32\BCB5;%BCB5_PATH%\LIB;.
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+SET INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%BCB5_PATH%\INCLUDE;
+SET MAKESTARTUP=%SCITECH%\MAKEDEFS\BC32.MK
+SET USE_WIN16=
+SET USE_WIN32=1
+SET USE_VXD=
+SET USE_TNT=
+SET USE_SMX32=
+SET USE_SMX16=
+SET USE_BC5=1
+SET WIN32_GUI=1
+SET USE_SNAP=
+SET BC_LIBBASE=BC5
+PATH %SCITECH_BIN%;%BCB5_PATH%\BIN;%DEFPATH%%BC5_CD_PATH%
+
+REM: Create Borland compile/link configuration scripts
+echo -I%INCLUDE% > %BCB5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% >> %BCB5_PATH%\BIN\bcc32.cfg
+echo -L%LIB% > %BCB5_PATH%\BIN\tlink32.cfg
+
+echo Borland C++ Builder 5.0 32 bit Windows compilation configuration set up.

+ 22 - 0
board/MAI/bios_emulator/scitech/bin/build

@@ -0,0 +1,22 @@
+#! /bin/sh
+
+if [ $# -lt 1 ] || ( [ "$1" != gcc-linux ] && [ "$1" != qnx4 ] ) ; then
+	echo Usage: $0 compiler_name [DMAKE commands]
+	echo
+	echo Current compilers:
+	echo "  gcc-linux  - GNU C/C++ 2.7 or higher, 32 bit"
+	echo "  qnx4  - Watcom C/C++ 10.6 or higher, 32 bit"
+	exit 1
+fi
+
+unset DBG OPT OPT_SIZE BUILD_DLL IMPORT_DLL FPU CHECKS BETA
+. ${1}.sh
+
+shift
+dmake $* && exit 0
+
+echo *************************************************
+echo * An error occurred while building the library. *
+echo *************************************************
+exit 1
+

+ 4 - 0
board/MAI/bios_emulator/scitech/bin/build.bat

@@ -0,0 +1,4 @@
+@echo off
+rem Disable checked build and build release code
+set CHECKED=
+call build_it.bat %1 %2 %3 %4 %5 %6 %7 %8 %9

+ 4 - 0
board/MAI/bios_emulator/scitech/bin/build_db.bat

@@ -0,0 +1,4 @@
+@echo off
+rem Enable checked build and build debug code
+set CHECKED=1
+call build_it.bat %1 %2 %3 %4 %5 %6 %7 %8 %9

+ 432 - 0
board/MAI/bios_emulator/scitech/bin/build_it.bat

@@ -0,0 +1,432 @@
+@echo off
+rem Generic batch file to build a version of the library. This batch file
+rem assumes that the correct batch files exist to setup the appropriate
+rem compilation environments, and that the DMAKE.EXE program is available
+rem somewhere on the path.
+rem
+rem Builds as release or debug depending on the value of the CHECKED
+rem environment variable.
+
+rem Unset all environment variables that change the compile process
+set DBG=
+set OPT=
+set OPT_SIZE=
+set BUILD_DLL=
+set IMPORT_DLL=
+set FPU=
+set CHECKS=
+set BETA=
+
+if %1==bc31-d16 goto bc31-d16
+if %1==bc45-d16 goto bc45-d16
+if %1==bc45-d32 goto bc45-d32
+if %1==bc45-tnt goto bc45-tnt
+if %1==bc45-w16 goto bc45-w16
+if %1==bc45-w32 goto bc45-w32
+if %1==bc45-c32 goto bc45-c32
+if %1==bc45-vxd goto bc45-vxd
+if %1==bc45-snp goto bc45-snp
+if %1==bc50-d16 goto bc50-d16
+if %1==bc50-d32 goto bc50-d32
+if %1==bc50-tnt goto bc50-tnt
+if %1==bc50-w16 goto bc50-w16
+if %1==bc50-w32 goto bc50-w32
+if %1==bc50-c32 goto bc50-c32
+if %1==bc50-vxd goto bc50-vxd
+if %1==bc50-snp goto bc50-snp
+if %1==gcc2-d32 goto gcc2-d32
+if %1==gcc2-w32 goto gcc2-w32
+if %1==gcc2-c32 goto gcc2-c32
+if %1==gcc2-linux goto gcc2-linux
+if %1==vc40-d16 goto vc40-d16
+if %1==vc40-tnt goto vc40-tnt
+if %1==vc40-w16 goto vc40-w16
+if %1==vc40-w32 goto vc40-w32
+if %1==vc40-c32 goto vc40-c32
+if %1==vc40-drv9x goto vc40-drv9x
+if %1==vc40-drvnt goto vc40-drvnt
+if %1==vc40-rtt goto vc40-rtt
+if %1==vc40-snp goto vc40-snp
+if %1==vc50-d16 goto vc50-d16
+if %1==vc50-tnt goto vc50-tnt
+if %1==vc50-w16 goto vc50-w16
+if %1==vc50-w32 goto vc50-w32
+if %1==vc50-c32 goto vc50-c32
+if %1==vc50-drv9x goto vc50-drv9x
+if %1==vc50-drvnt goto vc50-drvnt
+if %1==vc50-rtt goto vc50-rtt
+if %1==vc50-snp goto vc50-snp
+if %1==vc60-d16 goto vc60-d16
+if %1==vc60-tnt goto vc60-tnt
+if %1==vc60-w16 goto vc60-w16
+if %1==vc60-w32 goto vc60-w32
+if %1==vc60-c32 goto vc60-c32
+if %1==vc60-drv9x goto vc60-drv9x
+if %1==vc60-drvnt goto vc60-drvnt
+if %1==vc60-drvw2k goto vc60-drvw2k
+if %1==vc60-rtt goto vc60-rtt
+if %1==vc60-snp goto vc60-snp
+if %1==wc10ad16 goto wc10ad16
+if %1==wc10ad32 goto wc10ad32
+if %1==wc10atnt goto wc10atnt
+if %1==wc10aw16 goto wc10aw16
+if %1==wc10aw32 goto wc10aw32
+if %1==wc10ac32 goto wc10ac32
+if %1==wc10ao32 goto wc10ao32
+if %1==wc10ap32 goto wc10ap32
+if %1==wc10asnp goto wc10asnp
+if %1==wc10-d16 goto wc10-d16
+if %1==wc10-d32 goto wc10-d32
+if %1==wc10-tnt goto wc10-tnt
+if %1==wc10-w16 goto wc10-w16
+if %1==wc10-w32 goto wc10-w32
+if %1==wc10-c32 goto wc10-c32
+if %1==wc10-o32 goto wc10-o32
+if %1==wc10-p32 goto wc10-p32
+if %1==wc10-snp goto wc10-snp
+if %1==wc11-d16 goto wc11-d16
+if %1==wc11-d32 goto wc11-d32
+if %1==wc11-tnt goto wc11-tnt
+if %1==wc11-w16 goto wc11-w16
+if %1==wc11-w32 goto wc11-w32
+if %1==wc11-c32 goto wc11-c32
+if %1==wc11-o32 goto wc11-o32
+if %1==wc11-p32 goto wc11-p32
+if %1==wc11-snp goto wc11-snp
+
+echo Usage: BUILD 'compiler_name' [DMAKE commands]
+echo.
+echo Where 'compiler_name' is of the form comp-os, where
+echo 'comp' defines the compiler and 'os' defines the OS environment.
+echo For instance 'bc50-w32' is for Borland C++ 5.0 for Win32.
+echo The value of 'comp' can be any of the following:
+echo.
+echo    bc45 - Borland C++ 4.5x
+echo    bc50 - Borland C++ 5.x
+echo    vc40 - Visual C++ 4.x
+echo    vc50 - Visual C++ 5.x
+echo    vc60 - Visual C++ 6.x
+echo    wc10 - Watcom C++ 10.6
+echo    wc11 - Watcom C++ 11.0
+echo    gcc2 - GNU C/C++ 2.9x
+echo.
+echo The value of 'os' can be one of the following:
+echo.
+echo    d16   - 16-bit DOS
+echo    d32   - 32-bit DOS
+echo    w16   - 16-bit Windows GUI mode
+echo    c32   - 32-bit Windows console mode
+echo    w32   - 32-bit Windows GUI mode
+echo    o16   - 16-bit OS/2 console mode
+echo    o32   - 32-bit OS/2 console mode
+echo    p32   - 32-bit OS/2 Presentation Manager
+echo    snp   - 32-bit SciTech Snap application
+echo    linux - 32-bit Linux application
+goto end
+
+rem -------------------------------------------------------------------------
+rem Setup for the specified compiler
+
+:bc31-d16
+call bc31-d16.bat
+goto compileit
+
+:bc45-d16
+call bc45-d16.bat
+goto compileit
+
+:bc45-d32
+call bc45-d32.bat
+goto compileit
+
+:bc45-tnt
+call bc45-tnt.bat
+goto compileit
+
+:bc45-w16
+call bc45-w16.bat
+goto compileit
+
+:bc45-w32
+call bc45-w32.bat
+goto compileit
+
+:bc45-c32
+call bc45-c32.bat
+goto compileit
+
+:bc45-vxd
+call bc45-vxd.bat
+goto compileit
+
+:bc50-d16
+call bc50-d16.bat
+goto compileit
+
+:bc50-d32
+call bc50-d32.bat
+goto compileit
+
+:bc50-tnt
+call bc50-tnt.bat
+goto compileit
+
+:bc50-w16
+call bc50-w16.bat
+goto compileit
+
+:bc50-w32
+call bc50-w32.bat
+goto compileit
+
+:bc50-c32
+call bc50-c32.bat
+goto compileit
+
+:bc50-vxd
+call bc50-vxd.bat
+goto compileit
+
+:gcc2-d32
+call gcc2-d32.bat
+goto compileit
+
+:gcc2-w32
+call gcc2-w32.bat
+goto compileit
+
+:gcc2-c32
+call gcc2-c32.bat
+goto compileit
+
+:gcc2-linux
+call gcc2-linux.bat
+goto compileit
+
+:sc70-d16
+call sc70-d16.bat
+goto compileit
+
+:sc70-w16
+call sc70-w16.bat
+goto compileit
+
+:sc70-tnt
+call sc70-tnt.bat
+goto compileit
+
+:sc70-w32
+call sc70-w32.bat
+goto compileit
+
+:sc70-c32
+call sc70-c32.bat
+goto compileit
+
+:vc40-d16
+call vc40-d16.bat
+goto compileit
+
+:vc40-tnt
+call vc40-tnt.bat
+goto compileit
+
+:vc40-w16
+call vc40-w16.bat
+goto compileit
+
+:vc40-w32
+call vc40-w32.bat
+goto compileit
+
+:vc40-c32
+call vc40-c32.bat
+goto compileit
+
+:vc40-drv9x
+call vc40-drv9x.bat
+goto compileit
+
+:vc40-drvnt
+call vc40-drvnt.bat
+goto compileit
+
+:vc40-rtt
+call vc40-rtt.bat
+goto compileit
+
+:vc50-d16
+call vc50-d16.bat
+goto compileit
+
+:vc50-tnt
+call vc50-tnt.bat
+goto compileit
+
+:vc50-w16
+call vc50-w16.bat
+goto compileit
+
+:vc50-w32
+call vc50-w32.bat
+goto compileit
+
+:vc50-c32
+call vc50-c32.bat
+goto compileit
+
+:vc50-drv9x
+call vc50-drv9x.bat
+goto compileit
+
+:vc50-drvnt
+call vc50-drvnt.bat
+goto compileit
+
+:vc50-rtt
+call vc50-rtt.bat
+goto compileit
+
+:vc60-d16
+call vc60-d16.bat
+goto compileit
+
+:vc60-tnt
+call vc60-tnt.bat
+goto compileit
+
+:vc60-w16
+call vc60-w16.bat
+goto compileit
+
+:vc60-w32
+call vc60-w32.bat
+goto compileit
+
+:vc60-c32
+call vc60-c32.bat
+goto compileit
+
+:vc60-drv9x
+call vc60-drv9x.bat
+goto compileit
+
+:vc60-drvnt
+call vc60-drvnt.bat
+goto compileit
+
+:vc60-drvw2k
+call vc60-drvw2k.bat
+goto compileit
+
+:vc60-rtt
+call vc60-rtt.bat
+goto compileit
+
+:wc10ad16
+call wc10ad16.bat
+goto compileit
+
+:wc10ad32
+call wc10ad32.bat
+goto compileit
+
+:wc10atnt
+call wc10atnt.bat
+goto compileit
+
+:wc10aw16
+call wc10aw16.bat
+goto compileit
+
+:wc10aw32
+call wc10aw32.bat
+goto compileit
+
+:wc10ac32
+call wc10ac32.bat
+goto compileit
+
+:wc10ao32
+call wc10ao32.bat
+goto compileit
+
+:wc10ap32
+call wc10ap32.bat
+goto compileit
+
+:wc10-d16
+call wc10-d16.bat
+goto compileit
+
+:wc10-d32
+call wc10-d32.bat
+goto compileit
+
+:wc10-tnt
+call wc10-tnt.bat
+goto compileit
+
+:wc10-w16
+call wc10-w16.bat
+goto compileit
+
+:wc10-w32
+call wc10-w32.bat
+goto compileit
+
+:wc10-c32
+call wc10-c32.bat
+goto compileit
+
+:wc10-o32
+call wc10-o32.bat
+goto compileit
+
+:wc10-p32
+call wc10-p32.bat
+goto compileit
+
+:wc11-d16
+call wc11-d16.bat
+goto compileit
+
+:wc11-d32
+call wc11-d32.bat
+goto compileit
+
+:wc11-tnt
+call wc11-tnt.bat
+goto compileit
+
+:wc11-w16
+call wc11-w16.bat
+goto compileit
+
+:wc11-w32
+call wc11-w32.bat
+goto compileit
+
+:wc11-c32
+call wc11-c32.bat
+goto compileit
+
+:wc11-o32
+call wc11-o32.bat
+goto compileit
+
+:wc11-p32
+call wc11-p32.bat
+goto compileit
+
+:compileit
+k_rm -f *.lib *.a
+dmake %2 %3 %4 %5 %6 %7 %8 %9
+if errorlevel 1 goto errorend
+goto end
+
+:errorend
+echo *************************************************
+echo * An error occurred while building the library. *
+echo *************************************************
+:end

+ 6 - 0
board/MAI/bios_emulator/scitech/bin/cddrv.bat

@@ -0,0 +1,6 @@
+@echo off
+%1
+cd %3
+%4 %5 %6 %7 %8 %9
+%2
+

+ 10 - 0
board/MAI/bios_emulator/scitech/bin/cdit

@@ -0,0 +1,10 @@
+#! /bin/sh
+
+cd $1
+PROG=$2
+shift 2
+rm -f *.lib *.a
+$PROG $*
+RET=$?
+cd ..
+exit $RET

+ 5 - 0
board/MAI/bios_emulator/scitech/bin/cdit.bat

@@ -0,0 +1,5 @@
+@echo off
+cd %1
+k_rm -f *.lib *.a
+shift 1
+%1 %2 %3 %4 %5 %6 %7 %8 %9

+ 46 - 0
board/MAI/bios_emulator/scitech/bin/djgpp.env

@@ -0,0 +1,46 @@
+#= Don't edit this line unless you move djgpp.env outside
+#= of the djgpp installation directory.  If you do move
+#= it, set DJDIR to the directory you installed DJGPP in.
+#=
+DJDIR=%:/>DJGPP%
+
++USER=dosuser
++TMPDIR=%DJDIR%/tmp
++EMU387=%DJDIR%/bin/emu387.dxe
++LFN=y
+
+[bison]
+BISON_HAIRY=%DJDIR%/lib/bison.hai
+BISON_SIMPLE=%DJDIR%/lib/bison.sim
+
+[cpp]
+CPLUS_INCLUDE_PATH=%/>;CPLUS_INCLUDE_PATH%include;%SCITECH%/include;%PRIVATE%/include;.;%DJDIR%/lang/cxx;%DJDIR%/include;%DJDIR%/contrib/grx20/include
+C_INCLUDE_PATH=%/>;C_INCLUDE_PATH%include;%SCITECH%/include;%PRIVATE%/include;.;%DJDIR%/include;%DJDIR%/contrib/grx20/include
+OBJCPLUS_INCLUDE_PATH=%/>;OBJCPLUS_INCLUDE_PATH%%DJDIR%/include;%DJDIR%/lang/objc
+OBJC_INCLUDE_PATH=%/>;OBJC_INCLUDE_PATH%%DJDIR%/include;%DJDIR%/lang/objc
+
+[gcc]
+COMPILER_PATH=%/>;COMPILER_PATH%%DJDIR%/bin
+LIBRARY_PATH=%/>;LIBRARY_PATH%%DJDIR%/lib;%DJDIR%/contrib/grx20/lib;%SCITECH%/lib/release/dos32/dj2
+
+[info]
+INFOPATH=%/>;INFOPATH%%DJDIR%/info;%DJDIR%/gnu/emacs/info
+INFO_COLORS=0x1f.0x31
+
+[emacs]
+INFOPATH=%/>;INFOPATH%%DJDIR%/info;%DJDIR%/gnu/emacs/info
+
+[less]
+LESSBINFMT=*k<%X>
+LESSCHARDEF=8bcccbcc12bc5b95.b127.b
+LESS=%LESS% -h5$y5$Dd2.0$Du14.0$Ds4.7$Dk9.0$
+
+[locate]
++LOCATE_PATH=%DJDIR%/lib/locatedb.dat
+
+[ls]
++LS_COLORS=no=00:fi=00:di=36:lb=37;07:cd=40;33;01:ex=32:*.cmd=32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.deb=01;31:*.jpg=01;34:*.gif=01;34:*.bmp=01;34:*.ppm=01;34:*.tga=01;34:*.xbm=01;34:*.xpm=01;34:*.tif=01;34:*.mpg=01;37:*.avi=01;37:*.gl=01;37:*.dl=01;37:*~=08:*.bak=08:
+[dir]
++LS_COLORS=no=00:fi=00:di=36:lb=37;07:cd=40;33;01:ex=32:*.cmd=32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.deb=01;31:*.jpg=01;34:*.gif=01;34:*.bmp=01;34:*.ppm=01;34:*.tga=01;34:*.xbm=01;34:*.xpm=01;34:*.tif=01;34:*.mpg=01;37:*.avi=01;37:*.gl=01;37:*.dl=01;37:*~=08:*.bak=08:
+[vdir]
++LS_COLORS=no=00:fi=00:di=36:lb=37;07:cd=40;33;01:ex=32:*.cmd=32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.deb=01;31:*.jpg=01;34:*.gif=01;34:*.bmp=01;34:*.ppm=01;34:*.tga=01;34:*.xbm=01;34:*.xpm=01;34:*.tif=01;34:*.mpg=01;37:*.avi=01;37:*.gl=01;37:*.dl=01;37:*~=08:*.bak=08:

+ 46 - 0
board/MAI/bios_emulator/scitech/bin/djgpp_db.env

@@ -0,0 +1,46 @@
+#= Don't edit this line unless you move djgpp.env outside
+#= of the djgpp installation directory.  If you do move
+#= it, set DJDIR to the directory you installed DJGPP in.
+#=
+DJDIR=%:/>DJGPP%
+
++USER=dosuser
++TMPDIR=%DJDIR%/tmp
++EMU387=%DJDIR%/bin/emu387.dxe
++LFN=y
+
+[bison]
+BISON_HAIRY=%DJDIR%/lib/bison.hai
+BISON_SIMPLE=%DJDIR%/lib/bison.sim
+
+[cpp]
+CPLUS_INCLUDE_PATH=%/>;CPLUS_INCLUDE_PATH%include;%SCITECH%/include;%PRIVATE%/include;.;%DJDIR%/lang/cxx;%DJDIR%/include;%DJDIR%/contrib/grx20/include
+C_INCLUDE_PATH=%/>;C_INCLUDE_PATH%include;%SCITECH%/include;%PRIVATE%/include;.;%DJDIR%/include;%DJDIR%/contrib/grx20/include
+OBJCPLUS_INCLUDE_PATH=%/>;OBJCPLUS_INCLUDE_PATH%%DJDIR%/include;%DJDIR%/lang/objc
+OBJC_INCLUDE_PATH=%/>;OBJC_INCLUDE_PATH%%DJDIR%/include;%DJDIR%/lang/objc
+
+[gcc]
+COMPILER_PATH=%/>;COMPILER_PATH%%DJDIR%/bin
+LIBRARY_PATH=%/>;LIBRARY_PATH%%DJDIR%/lib;%DJDIR%/contrib/grx20/lib;%SCITECH%/lib/debug/dos32/dj2
+
+[info]
+INFOPATH=%/>;INFOPATH%%DJDIR%/info;%DJDIR%/gnu/emacs/info
+INFO_COLORS=0x1f.0x31
+
+[emacs]
+INFOPATH=%/>;INFOPATH%%DJDIR%/info;%DJDIR%/gnu/emacs/info
+
+[less]
+LESSBINFMT=*k<%X>
+LESSCHARDEF=8bcccbcc12bc5b95.b127.b
+LESS=%LESS% -h5$y5$Dd2.0$Du14.0$Ds4.7$Dk9.0$
+
+[locate]
++LOCATE_PATH=%DJDIR%/lib/locatedb.dat
+
+[ls]
++LS_COLORS=no=00:fi=00:di=36:lb=37;07:cd=40;33;01:ex=32:*.cmd=32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.deb=01;31:*.jpg=01;34:*.gif=01;34:*.bmp=01;34:*.ppm=01;34:*.tga=01;34:*.xbm=01;34:*.xpm=01;34:*.tif=01;34:*.mpg=01;37:*.avi=01;37:*.gl=01;37:*.dl=01;37:*~=08:*.bak=08:
+[dir]
++LS_COLORS=no=00:fi=00:di=36:lb=37;07:cd=40;33;01:ex=32:*.cmd=32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.deb=01;31:*.jpg=01;34:*.gif=01;34:*.bmp=01;34:*.ppm=01;34:*.tga=01;34:*.xbm=01;34:*.xpm=01;34:*.tif=01;34:*.mpg=01;37:*.avi=01;37:*.gl=01;37:*.dl=01;37:*~=08:*.bak=08:
+[vdir]
++LS_COLORS=no=00:fi=00:di=36:lb=37;07:cd=40;33;01:ex=32:*.cmd=32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.deb=01;31:*.jpg=01;34:*.gif=01;34:*.bmp=01;34:*.ppm=01;34:*.tga=01;34:*.xbm=01;34:*.xpm=01;34:*.tif=01;34:*.mpg=01;37:*.avi=01;37:*.gl=01;37:*.dl=01;37:*~=08:*.bak=08:

+ 1 - 0
board/MAI/bios_emulator/scitech/bin/findint3.bat

@@ -0,0 +1 @@
+perl c:\scitech\src\perl\findint3.per

+ 16 - 0
board/MAI/bios_emulator/scitech/bin/gcc-beos.sh

@@ -0,0 +1,16 @@
+#! /bin/sh
+
+# Setup for compiling with GCC/G++ for BeOS
+
+if [ "$CHECKED" = "1" ]; then
+    echo Checked debug build enabled.
+else
+    echo Release build enabled.
+fi
+
+export MAKESTARTUP=$SCITECH/makedefs/gcc_beos.mk
+export INCLUDE="-Iinclude -I$SCITECH/include -I$PRIVATE/include"
+export USE_X11=0
+export USE_BEOS=1
+
+echo GCC BeOS console compilation environment set up

+ 16 - 0
board/MAI/bios_emulator/scitech/bin/gcc-freebsd.sh

@@ -0,0 +1,16 @@
+#! /bin/sh
+
+# Setup for compiling with GCC/G++ for FreeBSD
+
+if [ "$CHECKED" = "1" ]; then
+    echo Checked debug build enabled.
+else
+    echo Release build enabled.
+fi
+
+export MAKESTARTUP=$SCITECH/makedefs/gcc_freebsd.mk
+export INCLUDE="-Iinclude -I$SCITECH/include -I$PRIVATE/include"
+export USE_X11=1
+export USE_FREEBSD=1
+
+echo GCC FreeBSD console compilation environment set up

+ 19 - 0
board/MAI/bios_emulator/scitech/bin/gcc-linux.sh

@@ -0,0 +1,19 @@
+#! /bin/sh
+
+# Setup for compiling with GCC/G++ for Linux
+
+if [ "$CHECKED" = "1" ]; then
+    echo Checked debug build enabled.
+else
+    echo Release build enabled.
+fi
+
+export MAKESTARTUP=$SCITECH/makedefs/gcc_linux.mk
+export INCLUDE="include;$SCITECH/include;$PRIVATE/include"
+export USE_LINUX=1
+
+if [ "x$LIBC" = x ]; then
+	echo "GCC Linux console compilation environment set up (glib)"
+else
+	echo "GCC Linux console compilation environment set up (libc5)"
+fi

+ 26 - 0
board/MAI/bios_emulator/scitech/bin/gcc2-c32.bat

@@ -0,0 +1,26 @@
+@echo off
+REM Setup for compiling with GNU C compiler
+
+if .%CHECKED%==.1 goto checked_build
+set LIB=%SCITECH_LIB%\LIB\release\win32\gcc2
+echo Release build enabled.
+goto setvars
+
+:checked_build
+set LIB=%SCITECH_LIB%\LIB\debug\win32\gcc2
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+set INCLUDE=include;%SCITECH%\include;%PRIVATE%\include
+set MAKESTARTUP=%SCITECH%\makedefs\gcc_win32.mk
+set MAKE_MODE=
+set USE_WIN16=
+set USE_WIN32=1
+set WIN32_GUI=
+set USE_SNAP=
+set GCC_LIBBASE=gcc2
+PATH %SCITECH_BIN%;%GCC2_PATH%\NATIVE\BIN;%DEFPATH%
+
+echo GCC 2.9.x 32-bit Win32 console compilation environment set up
+

+ 28 - 0
board/MAI/bios_emulator/scitech/bin/gcc2-dos.bat

@@ -0,0 +1,28 @@
+@echo off
+REM Setup for compiling with DJGPP 2.02
+
+if .%CHECKED%==.1 goto checked_build
+set LIB=%SCITECH_LIB%\LIB\release\dos32\dj2
+%SCITECH%\bin-dos\k_cp %SCITECH%\BIN\DJGPP.ENV %DJ_PATH%\DJGPP.ENV
+echo Release build enabled.
+goto setvars
+
+:checked_build
+set LIB=%SCITECH_LIB%\LIB\debug\dos32\dj2
+%SCITECH%\bin-dos\k_cp %SCITECH%\BIN\DJGPP_DB.ENV %DJ_PATH%\DJGPP.ENV
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+set DJGPP=%DJ_PATH%\DJGPP.ENV
+set INCLUDE=INCLUDE;%SCITECH%\INCLUDE;%PRIVATE%\INCLUDE;%DJ_PATH%\INCLUDE;
+set MAKESTARTUP=%SCITECH%\MAKEDEFS\DJ32.MK
+set USE_WIN16=
+set USE_WIN32=
+set WIN32_GUI=
+set USE_SNAP=
+set DJ_LIBBASE=dj2
+PATH %SCITECH_BIN%;%DJ_PATH%\BIN;%DEFPATH%
+
+echo DJGPP 2.02 32-bit DOS compilation environment set up (DPMI).
+

+ 26 - 0
board/MAI/bios_emulator/scitech/bin/gcc2-linux.bat

@@ -0,0 +1,26 @@
+@echo off
+REM Setup for compiling with GNU C cross-compiler
+
+if .%CHECKED%==.1 goto checked_build
+set LIB=%SCITECH_LIB%\LIB\release\win32\gcc2
+echo Release build enabled.
+goto setvars
+
+:checked_build
+set LIB=%SCITECH_LIB%\LIB\debug\win32\gcc2
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+set INCLUDE=include;%SCITECH%\include;%PRIVATE%\include
+set MAKESTARTUP=%SCITECH%\MAKEDEFS\gcc_linux.mk
+set MAKE_MODE=UNIX
+set USE_WIN16=
+set USE_WIN32=
+set WIN32_GUI=
+set USE_SNAP=
+set GCC_LIBBASE=gcc2
+PATH %SCITECH_BIN%;%GCC2_PATH%\cross-linux\i386-redhat-linux\BIN;%DEFPATH%
+
+echo GCC 2.9.x 32-bit Linux console cross compilation environment set up
+

+ 26 - 0
board/MAI/bios_emulator/scitech/bin/gcc2-w32.bat

@@ -0,0 +1,26 @@
+@echo off
+REM Setup for compiling with GNU C compiler
+
+if .%CHECKED%==.1 goto checked_build
+set LIB=%SCITECH_LIB%\LIB\release\win32\gcc2
+echo Release build enabled.
+goto setvars
+
+:checked_build
+set LIB=%SCITECH_LIB%\LIB\debug\win32\gcc2
+echo Checked debug build enabled.
+goto setvars
+
+:setvars
+set INCLUDE=include;%SCITECH%\include;%PRIVATE%\include
+set MAKESTARTUP=%SCITECH%\makedefs\gcc_win32.mk
+set MAKE_MODE=
+set USE_WIN16=
+set USE_WIN32=1
+set WIN32_GUI=1
+set USE_SNAP=
+set GCC_LIBBASE=gcc2
+PATH %SCITECH_BIN%;%GCC2_PATH%\NATIVE\BIN;%DEFPATH%
+
+echo GCC 2.9.x 32-bit Win32 GUI compilation environment set up
+

+ 97 - 0
board/MAI/bios_emulator/scitech/bin/makelib.bat

@@ -0,0 +1,97 @@
+call wc11-d32.bat
+
+cd c:\private\src\license
+dmake clean
+dmake depend
+dmake -u install
+cd c:\scitech\src\pm
+dmake clean
+dmake depend
+dmake -u install
+cd c:\scitech\src\console
+dmake clean
+dmake depend
+dmake -u install
+cd c:\scitech\src\nucleus
+dmake clean
+dmake depend
+dmake -u install
+cd c:\scitech\src\zlib
+dmake clean
+dmake depend
+dmake -u install
+
+cd c:\private\src\graphics\ref2d
+dmake clean
+dmake depend
+dmake -u install
+cd c:\private\src\drvlib
+dmake clean
+dmake depend
+dmake -u install
+
+call wc11-w32.bat
+
+cd c:\private\src\license
+dmake clean
+dmake depend
+dmake -u install
+cd c:\scitech\src\pm
+dmake clean
+dmake depend
+dmake -u install
+cd c:\scitech\src\console
+dmake clean
+dmake depend
+dmake -u install
+cd c:\scitech\src\nucleus
+dmake clean
+dmake depend
+dmake -u install
+cd c:\scitech\src\zlib
+dmake clean
+dmake depend
+dmake -u install
+
+cd c:\private\src\graphics\ref2d
+dmake clean
+dmake depend
+dmake -u install
+cd c:\private\src\drvlib
+dmake clean
+dmake depend
+dmake -u install
+
+call wc10-d32.bat
+
+cd c:\private\src\license
+dmake clean
+dmake depend
+dmake -u install
+cd c:\scitech\src\pm
+dmake clean
+dmake depend
+dmake -u install
+cd c:\scitech\src\console
+dmake clean
+dmake depend
+dmake -u install
+cd c:\scitech\src\nucleus
+dmake clean
+dmake depend
+dmake -u install
+cd c:\scitech\src\zlib
+dmake clean
+dmake depend
+dmake -u install
+
+cd c:\private\src\graphics\ref2d
+dmake clean
+dmake depend
+dmake -u install
+cd c:\private\src\drvlib
+dmake clean
+dmake depend
+dmake -u install
+
+cd \private\src\graphics\drivers

+ 23 - 0
board/MAI/bios_emulator/scitech/bin/meltobjs.sh

@@ -0,0 +1,23 @@
+#! /bin/sh
+#
+# This script generates a single object file from a set of libraries (*.a files)
+# Usage: meltobjs.sh target.o library1.a library2.a ...
+#
+# (C) SciTech Software, Inc. 1998
+#
+
+TMPDIR=/tmp/melt$$
+TARGET=$1
+TARGETDIR=$PWD
+shift
+mkdir $TMPDIR
+
+cd $TMPDIR
+
+for a in $*
+do
+    ar x $a
+done
+ld -r -o $TARGETDIR/$TARGET *.o
+
+rm -fr $TMPDIR

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác