Переглянути джерело

* 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 21 роки тому
батько
коміт
c7de829c79
100 змінених файлів з 11034 додано та 1 видалено
  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

Деякі файли не було показано, через те що забагато файлів було змінено