* Patch by Marc Singer, 29 May 2003:
  Fixed rarp boot method for IA32 and other little-endian CPUs.

* Patch by Marc Singer, 28 May 2003:
  Added port I/O commands.

* Patch by Matthew McClintock, 28 May 2003
  - cpu/mpc824x/start.S: fix relocation code when booting from RAM
  - minor patches for utx8245

* Patch by Daniel Engström, 28 May 2003:
  x86 update

* Patch by Dave Ellis, 9 May 2003 + 27 May 2003:
  add nand flash support to SXNI855T configuration
  fix/extend nand flash support:
  - fix 'nand erase' command so does not erase bad blocks
  - fix 'nand write' command so does not write to bad blocks
  - fix nand_probe() so handles no flash detected properly
  - add doc/README.nand
  - add .jffs2 and .oob options to nand read/write
  - add 'nand bad' command to list bad blocks
  - add 'clean' option to 'nand erase' to write JFFS2 clean markers
  - make NAND read/write faster

* Patch by Rune Torgersen, 23 May 2003:
  Update for MPC8266ADS board
diff --git a/lib_i386/Makefile b/lib_i386/Makefile
index 34994e5..47c5d2c 100644
--- a/lib_i386/Makefile
+++ b/lib_i386/Makefile
@@ -25,11 +25,11 @@
 
 LIB	= lib$(ARCH).a
 
-AOBJS	= bios.o realmode_switch.o ic/sc520_asm.o
+AOBJS	= bios.o bios_pci.o realmode_switch.o 
 
 COBJS	= board.o bios_setup.o i386_linux.o zimage.o realmode.o \
-	  pci_type1.o ic/sc520.o ic/ali512x.o
-
+	  pci_type1.o pci.o video_bios.o video.o  
+	  
 OBJS	= $(AOBJS) $(COBJS)
 
 $(LIB):	.depend $(OBJS)
diff --git a/lib_i386/bios.S b/lib_i386/bios.S
index 2f5ea8c..ce6e94c 100644
--- a/lib_i386/bios.S
+++ b/lib_i386/bios.S
@@ -30,6 +30,8 @@
  *----------------------------------------------------------------------
  */
 
+#include "bios.h"
+
 /*
  * During it's initialization phase, before switching to protected
  * mode, the Linux Kernel makes a few BIOS calls. This won't work
@@ -40,29 +42,13 @@
  * a general purpose replacement for a real BIOS !!
  */
 
-#define OFFS_ES      0
-#define OFFS_GS      2
-#define OFFS_DS      4
-#define OFFS_DI      6
-#define OFFS_SI      8
-#define OFFS_BP      10
-#define OFFS_SP      12
-#define OFFS_BX      14
-#define OFFS_DX      16
-#define OFFS_CX      18
-#define OFFS_AX      20
-#define OFFS_VECTOR  22
-#define OFFS_IP      24
-#define OFFS_CS      26
-#define OFFS_FLAGS   28
-
-#define SEGMENT      0x40
-#define STACK	     0x800  			/* stack at 0x40:0x800 -> 0x800 */
 
 .section .bios, "ax"
 .code16
 .org 0
-
+      	/* a call to f000:0 should warmboot */
+	jmp	realmode_reset
+	
 .globl rm_int00
 rm_int00:
 	pushw	$0
@@ -202,30 +188,23 @@
 	 * stack.
 	 */
 any_interrupt16:
-	pusha					/* save general registers */
-	pushw	%ds				/* save some segments     */
-	pushw	%gs
-	pushw	%es
-	pushw	%ss				/* save callers stack segment .. */
-	popw	%gs				/* ... in gs */
-	movw	$SEGMENT,%ax			/* setup my segments */
-	movw	%ax,%ds
-	movw	%ax,%es
-	movw	%ax,%ss
-	movw	%sp,%bp
-	movw	$STACK,%sp			/* setup BIOS stackpointer */
+        MAKE_BIOS_STACK
 
 gs	movw	OFFS_VECTOR(%bp), %ax
 	cmpw	$0x10, %ax
 	je	Lint_10h         
 	cmpw	$0x11, %ax
 	je	Lint_11h
+	cmpw	$0x12, %ax
+	je	Lint_12h
 	cmpw	$0x13, %ax
 	je	Lint_13h
 	cmpw	$0x15, %ax
 	je	Lint_15h
 	cmpw	$0x16, %ax
 	je	Lint_16h
+	cmpw	$0x1a, %ax
+	je	Lint_1ah
 	movw	$0xffff, %ax
 	jmp	Lout
 Lint_10h:					/* VGA BIOS services */
@@ -234,6 +213,9 @@
 Lint_11h:	
 	call	bios_11h
 	jmp	Lout
+Lint_12h:	
+	call	bios_12h
+	jmp	Lout
 Lint_13h:					/* BIOS disk services */
 	call	bios_13h
 	jmp	Lout
@@ -243,6 +225,9 @@
 Lint_16h:					/* keyboard services */
 	call	bios_16h
 	jmp	Lout
+Lint_1ah:					/* PCI bios */
+	call	bios_1ah
+	jmp	Lout
 Lout:	
 	cmpw	$0, %ax
 	je	Lhandeled
@@ -256,16 +241,7 @@
 	 * we shuls make int 0x10 and int 0x16 work as well))
 	 */
 Lhandeled:
-
-	pushw	%gs				/* restore callers stack segment */
-	popw	%ss
-	movw	%bp,%sp				/* restore stackpointer */
-
-	popw	%es				/* restore segment selectors */
-	popw	%gs
-	popw	%ds
-	
-	popa					/* restore GP registers */
+	RESTORE_CALLERS_STACK
 	addw	$2,%sp				/* dump vector number */
 	iret					/* return from interrupt */
 
@@ -309,7 +285,7 @@
  */
 
 bios_11h:
-	movw	bios_equipment, %ax
+cs	movw	bios_equipment, %ax
 gs	movw	%ax, OFFS_AX(%bp)  
 	xorw	%ax, %ax
 	ret
@@ -317,6 +293,30 @@
 
 /*
  ************************************************************
+ * BIOS 	interrupt 12h -- Get Memory Size
+ ************************************************************
+ */
+bios_12h:
+cs	movw	ram_in_64kb_chunks, %ax
+	cmpw	$0xa, %ax
+	ja	b12_more_than_640k
+	shlw	$6, %ax
+	jmp	b12_return
+b12_more_than_640k:
+	movw	$0x280, %ax
+b12_return:
+gs	movw	%ax, OFFS_AX(%bp)		/* return number of kilobytes in ax */
+
+gs	movw	OFFS_FLAGS(%bp), %ax
+	andw	$0xfffe, %ax			/* clear carry -- function succeeded */
+gs	movw	%ax, OFFS_FLAGS(%bp)
+
+	xorw	%ax, %ax
+	ret
+
+
+/*
+ ************************************************************
  * BIOS interrupt 13h -- Disk services
  ************************************************************
  */
@@ -372,27 +372,28 @@
 	ret
 	
 Lfunc_e801h:					/* Get memory size for >64M Configurations */
-	movw	$ram_in_64kb_chunks, %ax
-	cmpw	$256, %ax
-	ja	Lmore_than_16mb
-	shlw	$6, %ax				/* multiply by 64 */	
-gs	movw	%ax, OFFS_AX(%bp)   		/* return memory size in 1kb chunks in AX and CX */
+cs	movw	ram_in_64kb_chunks, %ax
+	cmpw	$0x100, %ax
+	ja	e801_more_than_16mb
+	shlw	$6, %ax				/* multiply by 64 */
+	subw	$0x400, %ax			/* 1st meg does not count */
+ 	
+gs	movw	%ax, OFFS_AX(%bp)   		/* return memory size between 1M and 16M in 1kb chunks in AX and CX */
 gs	movw	%ax, OFFS_CX(%bp)
-	xorw	%ax, %ax
-gs	movw	%ax, OFFS_BX(%bp)		/* set BX and DX to 0*/
-gs	movw	%ax, OFFS_DX(%bp)	
+gs	movw	$0, OFFS_BX(%bp)		/* set BX and DX to 0*/
+gs	movw	$0, OFFS_DX(%bp)	
 gs	movw	OFFS_FLAGS(%bp), %ax
 	andw	$0xfffe, %ax			/* clear carry -- function succeeded */
 gs	movw	%ax, OFFS_FLAGS(%bp)
 	xorw	%ax, %ax
 	ret
 	
-Lmore_than_16mb:
+e801_more_than_16mb:
 	subw	$0x100, %ax			/* subtract 16MB */	
 	
-gs	movw	$0x3c00, OFFS_AX(%bp)		/* return 0x3c00 (16MB-384k) in AX and CX */
+gs	movw	$0x3c00, OFFS_AX(%bp)		/* return 0x3c00 (16MB-1MB) in AX and CX */
 gs	movw	$0x3c00, OFFS_CX(%bp)
-gs	movw	%ax, OFFS_BX(%bp)		/* set BX and DX to number of 64kb chunks - 256 */
+gs	movw	%ax, OFFS_BX(%bp)		/* set BX and DX to number of 64kb chunks above 16MB */
 gs	movw	%ax, OFFS_DX(%bp)	
 
 gs	movw	OFFS_FLAGS(%bp), %ax
@@ -402,11 +403,15 @@
 	ret
 
 Lfunc_88h:
-	movw	ram_in_64kb_chunks, %ax
-	subw	$16, %ax
+cs	movw	ram_in_64kb_chunks, %ax
+	cmpw	$0x100, %ax
+	jna	b88_not_more_than16
+	movw	$0x100, %ax
+b88_not_more_than16:
 	shlw	$6, %ax
-	
-gs	movw	%ax, OFFS_AX(%bp)		/* return number of kilobytes in ax */
+	subw	$0x400, %ax			/* 1st meg does not count */
+		
+gs	movw	%ax, OFFS_AX(%bp)		/* return number of kilobytes between 16MB and 16MB in ax */
 
 gs	movw	OFFS_FLAGS(%bp), %ax
 	andw	$0xfffe, %ax			/* clear carry -- function succeeded */
@@ -432,6 +437,22 @@
 	xorw	%ax, %ax			/* do nothing -- function not supported */
 	ret
 
+/*
+ ************************************************************
+ * BIOS interrupt 1ah -- PCI bios
+ ************************************************************
+ */
+bios_1ah:
+gs	movw	OFFS_AX(%bp), %ax
+	cmpb	$0xb1, %ah
+	je	Lfunc_b1h
+	movw	$0xffff, %ax
+	ret
+Lfunc_b1h:
+	call	realmode_pci_bios
+	xorw	%ax, %ax			/* do nothing -- function not supported */
+	ret
+
 
 .globl ram_in_64kb_chunks
 ram_in_64kb_chunks:
diff --git a/lib_i386/bios.h b/lib_i386/bios.h
new file mode 100644
index 0000000..876fe31
--- /dev/null
+++ b/lib_i386/bios.h
@@ -0,0 +1,94 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
+ * 
+ * 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 _BIOS_H_
+#define _BIOS_H_
+
+#define OFFS_ES      0     /* 16bit */
+#define OFFS_GS      2     /* 16bit */
+#define OFFS_DS      4     /* 16bit */
+#define OFFS_EDI     6     /* 32bit */
+#define OFFS_DI      6     /* low 16 bits of EDI */   
+#define OFFS_ESI     10    /* 32bit */
+#define OFFS_SI      10    /* low 16 bits of ESI */   
+#define OFFS_EBP     14    /* 32bit */
+#define OFFS_BP      14    /* low 16 bits of EBP */
+#define OFFS_ESP     18    /* 32bit */
+#define OFFS_SP      18    /* low 16 bits of ESP */
+#define OFFS_EBX     22    /* 32bit */
+#define OFFS_BX      22    /* low 16 bits of EBX */
+#define OFFS_BL      22    /* low  8 bits of BX */
+#define OFFS_BH      23    /* high 8 bits of BX */
+#define OFFS_EDX     26    /* 32bit */
+#define OFFS_DX      26    /* low 16 bits of EBX */
+#define OFFS_DL      26    /* low  8 bits of BX */
+#define OFFS_DH      27    /* high 8 bits of BX */
+#define OFFS_ECX     30    /* 32bit */
+#define OFFS_CX      30    /* low 16 bits of EBX */
+#define OFFS_CL      30    /* low  8 bits of BX */
+#define OFFS_CH      31    /* high 8 bits of BX */
+#define OFFS_EAX     34    /* 32bit */
+#define OFFS_AX      34    /* low 16 bits of EBX */
+#define OFFS_AL      34    /* low  8 bits of BX */
+#define OFFS_AH      35    /* high 8 bits of BX */
+#define OFFS_VECTOR  38    /* 16bit */
+#define OFFS_IP      40    /* 16bit */
+#define OFFS_CS      42    /* 16bit */
+#define OFFS_FLAGS   44    /* 16bit */   
+
+#define SEGMENT      0x40
+#define STACK	     0x800  			/* stack at 0x40:0x800 -> 0x800 */
+
+/* save general registers */
+/* save some segments     */
+/* save callers stack segment .. */
+/* ... in gs */
+	/* setup my segments */ 
+	/* setup BIOS stackpointer */ 
+	
+#define MAKE_BIOS_STACK \
+	pushal		; \
+	pushw	%ds	; \
+	pushw	%gs	; \
+	pushw	%es	; \
+	pushw	%ss	; \
+	popw	%gs	; \
+	movw	$SEGMENT,%ax ; \
+	movw	%ax,%ds	; \
+	movw	%ax,%es	; \
+	movw	%ax,%ss	; \
+	movw	%sp,%bp	; \
+	movw	$STACK,%sp
+
+#define RESTORE_CALLERS_STACK \
+	pushw	%gs     ;			/* restore callers stack segment */ \
+	popw	%ss     ; \
+	movw	%bp,%sp	;			/* restore stackpointer */ \
+		\
+	popw	%es	;			/* restore segment selectors */ \
+	popw	%gs     ; \
+	popw	%ds     ; \
+		\
+	popal					/* restore GP registers */ 
+
+#endif
diff --git a/lib_i386/bios_pci.S b/lib_i386/bios_pci.S
new file mode 100644
index 0000000..e53791a
--- /dev/null
+++ b/lib_i386/bios_pci.S
@@ -0,0 +1,411 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
+ * 
+ * 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
+ */
+
+/*
+ * x86 realmode assembly implementation of a PCI BIOS
+ * for platforms that use one PCI hose and configuration 
+ * access type 1. (The common case for low-end PC's)
+ */
+ 
+#include "bios.h"
+
+#define PCI_BIOS_DEBUG
+
+.section .bios, "ax"
+.code16
+.globl realmode_pci_bios_call_entry
+realmode_pci_bios_call_entry:
+	MAKE_BIOS_STACK
+	call realmode_pci_bios
+	RESTORE_CALLERS_STACK
+	ret
+	
+	
+.globl realmode_pci_bios
+realmode_pci_bios:
+gs	movw	OFFS_AX(%bp), %ax
+	cmpb	$1, %al
+	je	pci_bios_present
+	cmpb	$2, %al
+	je	pci_bios_find_device
+	cmpb	$3, %al
+	je	pci_bios_find_class
+	cmpb	$6, %al
+	je	pci_bios_generate_special_cycle
+	cmpb	$8, %al
+	je	pci_bios_read_cfg_byte
+	cmpb	$9, %al
+	je	pci_bios_read_cfg_word
+	cmpb	$10, %al
+	je	pci_bios_read_cfg_dword
+	cmpb	$11, %al
+	je	pci_bios_write_cfg_byte
+	cmpb	$12, %al
+	je	pci_bios_write_cfg_word
+	cmpb	$13, %al
+	je	pci_bios_write_cfg_dword
+	cmpb	$14, %al
+	je	pci_bios_get_irq_routing
+	cmpb	$15, %al
+	je	pci_bios_set_irq
+	jmp	unknown_function
+	
+/*****************************************************************************/
+
+pci_bios_present:
+#ifdef PCI_BIOS_DEBUG
+cs	incl	num_pci_bios_present
+#endif
+	movl	$0x20494350, %eax
+gs	movl	%eax, OFFS_EDX(%bp)	
+	movb	$0x01, %al
+gs	movb	%al, OFFS_AL(%bp)	/* We support cfg type 1 */ 
+	movw	$0x0210, %ax            /* version 2.10 */	
+gs	movw	%ax, OFFS_BX(%bp)	
+cs	movb	pci_last_bus, %al       /* last bus number */
+gs	movb	%al, OFFS_CL(%bp)	
+	jmp 	clear_carry
+
+/*****************************************************************************/
+
+/* device 0-31, function 0-7 */
+pci_bios_find_device:	
+#ifdef PCI_BIOS_DEBUG
+cs	incl 	num_pci_bios_find_device
+#endif
+gs	movw	OFFS_CX(%bp), %di 
+	shll	$16, %edi
+gs	movw	OFFS_DX(%bp), %di       /* edi now holds device in upper 16 
+                                         * bits and vendor in lower 16 bits */
+gs	movw	OFFS_SI(%bp), %si 	
+	xorw	%bx, %bx                /* start at bus 0 dev 0 function 0 */
+pfd_loop:	
+	xorw	%ax, %ax		/* dword 0 is vendor/device */	
+	call	__pci_bios_select_register		
+	movw	$0xcfc, %dx
+	inl	%dx, %eax
+	cmpl	%edi, %eax		/* our device ? */
+	je	pfd_found_one
+pfd_next_dev:
+	/* check for multi function devices */
+	movw	%bx, %ax
+	andw	$3, %ax
+	jnz	pfd_function_not_zero
+	movw	$0x000c, %ax	
+	call	__pci_bios_select_register		
+	movw	$0xcfe, %dx
+	inb	%dx, %al
+	andb	$0x80, %al
+	jz	pfd_not_multi_function
+pfd_function_not_zero:
+	incw	%bx			/* next function, overflows in to
+					 * device number, then bus number */
+	jmp	pfd_check_bus
+	
+pfd_not_multi_function:
+	andw	$0xfff8, %bx            /* remove function bits */
+	addw	$0x0008, %bx            /* next device, overflows in to bus number */
+pfd_check_bus:	
+cs	movb	pci_last_bus, %ah
+	cmpb	%ah, %bh
+	ja	pfd_not_found
+	jmp	pfd_loop
+pfd_found_one:
+	decw	%si
+	js	pfd_done
+	jmp	pfd_next_dev
+
+pfd_done:
+gs	movw	%bx, OFFS_BX(%bp) 
+	jmp	clear_carry
+
+pfd_not_found:
+	movb	$0x86, %ah              /* device not found */
+	jmp	set_carry
+
+/*****************************************************************************/
+
+pci_bios_find_class:
+#ifdef PCI_BIOS_DEBUG
+cs	incl	num_pci_bios_find_class
+#endif
+gs	movl	OFFS_ECX(%bp), %edi 
+	andl	$0x00ffffff, %edi       /* edi now holds class-code in lower 24 bits */ 
+gs	movw	OFFS_SI(%bp), %si 	
+	xorw	%bx, %bx                /* start at bus 0 dev 0 function 0 */
+pfc_loop:	
+	movw	$8, %ax			/* dword 8 is class-code high 24bits */	
+	call	__pci_bios_select_register		
+	movw	$0xcfc, %dx
+	inl	%dx, %eax
+	shrl	$8, %eax
+	andl	$0x00ffffff, %eax
+	cmpl	%edi, %eax		/* our device ? */
+	je	pfc_found_one
+pfc_next_dev:
+	/* check for multi function devices */
+	andw	$3, %bx
+	jnz	pfc_function_not_zero
+	movw	$0x000c, %ax	
+	call	__pci_bios_select_register		
+	movw	$0xcfe, %dx
+	inb	%dx, %al
+	andb	$0x80, %al
+	jz	pfc_not_multi_function
+pfc_function_not_zero:
+	incw	%bx			/* next function, overflows in to
+					 * device number, then bus number */
+	jmp	pfc_check_bus
+	
+pfc_not_multi_function:
+	andw	$0xfff8, %bx            /* remove function bits */
+	addw	$0x0008, %bx            /* next device, overflows in to bus number */
+pfc_check_bus:	
+cs	movb	pci_last_bus, %ah
+	cmpb	%ah, %bh
+	ja	pfc_not_found
+	jmp	pfc_loop
+pfc_found_one:
+	decw	%si
+	js	pfc_done
+	jmp	pfc_next_dev
+
+pfc_done:
+gs	movw	%bx, OFFS_BX(%bp) 
+	jmp	clear_carry
+
+pfc_not_found:
+	movb	$0x86, %ah              /* device not found */
+	jmp	set_carry
+
+/*****************************************************************************/
+
+pci_bios_generate_special_cycle:
+#ifdef PCI_BIOS_DEBUG
+cs	incl	num_pci_bios_generate_special_cycle
+#endif
+	movb	$0x81, %ah              /* function not supported */
+	jmp	set_carry
+	
+/*****************************************************************************/
+
+pci_bios_read_cfg_byte: 
+#ifdef PCI_BIOS_DEBUG
+cs	incl	num_pci_bios_read_cfg_byte
+#endif
+	call	pci_bios_select_register	
+gs	movw 	OFFS_DI(%bp), %dx
+	andw	$3, %dx
+	addw	$0xcfc, %dx
+	inb	%dx, %al
+gs	movb	%al, OFFS_CL(%bp)	   
+	jmp 	clear_carry
+
+/*****************************************************************************/
+
+pci_bios_read_cfg_word: 
+#ifdef PCI_BIOS_DEBUG
+cs	incl	num_pci_bios_read_cfg_word
+#endif
+	call	pci_bios_select_register
+gs	movw 	OFFS_DI(%bp), %dx
+	andw	$2, %dx
+	addw	$0xcfc, %dx
+	inw	%dx, %ax
+gs	movw	%ax, OFFS_CX(%bp)	   
+	jmp 	clear_carry
+
+
+/*****************************************************************************/
+
+pci_bios_read_cfg_dword: 
+#ifdef PCI_BIOS_DEBUG
+cs	incl	num_pci_bios_read_cfg_dword
+#endif
+	call	pci_bios_select_register
+	movw	$0xcfc, %dx
+	inl	%dx, %eax
+gs	movl	%eax, OFFS_ECX(%bp)	    
+	jmp 	clear_carry
+
+/*****************************************************************************/
+
+pci_bios_write_cfg_byte:
+#ifdef PCI_BIOS_DEBUG
+cs	incl	num_pci_bios_write_cfg_byte
+#endif
+	call	pci_bios_select_register	
+gs	movw 	OFFS_DI(%bp), %dx
+gs	movb	OFFS_CL(%bp), %al
+	andw	$3, %dx
+	addw	$0xcfc, %dx
+	outb	%al, %dx
+	jmp 	clear_carry
+	
+/*****************************************************************************/
+
+pci_bios_write_cfg_word:
+#ifdef PCI_BIOS_DEBUG
+cs	incl	num_pci_bios_write_cfg_word
+#endif
+	call	pci_bios_select_register	
+gs	movw 	OFFS_DI(%bp), %dx
+gs	movw	OFFS_CX(%bp), %ax
+	andw	$2, %dx
+	addw	$0xcfc, %dx
+	outw	%ax, %dx
+	jmp 	clear_carry
+	
+/*****************************************************************************/
+
+pci_bios_write_cfg_dword:
+#ifdef PCI_BIOS_DEBUG
+cs	incl	num_pci_bios_write_cfg_dword
+#endif
+	call	pci_bios_select_register	
+gs	movl	OFFS_ECX(%bp), %eax
+	movw	$0xcfc, %dx
+	outl	%eax, %dx
+	jmp 	clear_carry
+
+/*****************************************************************************/
+
+pci_bios_get_irq_routing:
+#ifdef PCI_BIOS_DEBUG
+cs	incl	num_pci_bios_get_irq_routing
+#endif
+	movb	$0x81, %ah              /* function not supported */
+	jmp	set_carry
+	
+/*****************************************************************************/
+
+pci_bios_set_irq:
+#ifdef PCI_BIOS_DEBUG
+cs	incl	num_pci_bios_set_irq
+#endif
+	movb	$0x81, %ah              /* function not supported */
+	jmp	set_carry
+
+/*****************************************************************************/
+
+unknown_function:
+#ifdef PCI_BIOS_DEBUG
+cs	incl	num_pci_bios_unknown_function
+#endif
+	movb	$0x81, %ah              /* function not supported */
+	jmp	set_carry
+
+/*****************************************************************************/
+		
+pci_bios_select_register:
+gs	movw 	OFFS_BX(%bp), %bx
+gs	movw 	OFFS_DI(%bp), %ax
+/* destroys eax, dx */
+__pci_bios_select_register:               /* BX holds device id, AX holds register index */
+	pushl	%ebx
+	andl	$0xfc, %eax
+	andl	$0xffff, %ebx
+	shll	$8, %ebx
+	orl	%ebx, %eax
+	orl	$0x80000000, %eax
+	movw	$0xcf8, %dx
+	outl	%eax, %dx
+	popl	%ebx
+	ret
+
+
+clear_carry:
+gs	movw	OFFS_FLAGS(%bp), %ax
+	andw	$0xfffe, %ax			/* clear carry -- function succeeded */
+gs	movw	%ax, OFFS_FLAGS(%bp)
+	xorw	%ax, %ax
+gs	movb	%ah, OFFS_AH(%bp)	
+	ret
+
+set_carry:
+gs	movb	%ah, OFFS_AH(%bp)	
+gs	movw	OFFS_FLAGS(%bp), %ax
+	orw	$1, %ax				/* return carry -- function not supported */
+gs	movw	%ax, OFFS_FLAGS(%bp)
+	movw	$-1, %ax
+	ret
+
+/*****************************************************************************/
+
+.globl pci_last_bus
+pci_last_bus:
+	.byte 	0
+
+#ifdef PCI_BIOS_DEBUG
+.globl num_pci_bios_present
+num_pci_bios_present:
+	.long 	0
+	
+.globl num_pci_bios_find_device
+num_pci_bios_find_device:
+	.long 	0
+
+.globl num_pci_bios_find_class
+num_pci_bios_find_class:
+	.long 	0
+
+.globl num_pci_bios_generate_special_cycle
+num_pci_bios_generate_special_cycle: 
+	.long 0
+	
+.globl num_pci_bios_read_cfg_byte
+num_pci_bios_read_cfg_byte:
+	.long 	0
+
+.globl num_pci_bios_read_cfg_word
+num_pci_bios_read_cfg_word:
+	.long 	0
+
+.globl num_pci_bios_read_cfg_dword
+num_pci_bios_read_cfg_dword:
+	.long 	0
+
+.globl num_pci_bios_write_cfg_byte
+num_pci_bios_write_cfg_byte:
+	.long 	0
+
+.globl num_pci_bios_write_cfg_word
+num_pci_bios_write_cfg_word:
+	.long 	0
+
+.globl num_pci_bios_write_cfg_dword
+num_pci_bios_write_cfg_dword:
+	.long 	0
+
+.globl num_pci_bios_get_irq_routing
+num_pci_bios_get_irq_routing:
+	.long 	0
+
+.globl num_pci_bios_set_irq
+num_pci_bios_set_irq:
+	.long 	0
+
+.globl num_pci_bios_unknown_function
+num_pci_bios_unknown_function:
+	.long 	0
+#endif
diff --git a/lib_i386/bios_setup.c b/lib_i386/bios_setup.c
index 94319af..3da7858 100644
--- a/lib_i386/bios_setup.c
+++ b/lib_i386/bios_setup.c
@@ -32,6 +32,7 @@
  */
 
 #include <common.h>
+#include <pci.h>
 #include <asm/realmode.h>
 #include <asm/io.h>
 
@@ -42,8 +43,13 @@
 #define BIOS_BASE        ((char*)0xf0000)
 #define BIOS_CS          0xf000
 
+/* these are defined in a 16bit segment and needs
+ * to be accessed with the RELOC_16_xxxx() macros below
+ */
 extern u16 ram_in_64kb_chunks;
 extern u16 bios_equipment;
+extern u8  pci_last_bus;
+
 extern void *rm_int00;
 extern void *rm_int01;
 extern void *rm_int02;
@@ -78,6 +84,34 @@
 extern void *rm_int1f;
 extern void *rm_def_int;
 
+extern void *realmode_reset;
+extern void *realmode_pci_bios_call_entry;
+
+static int set_jmp_vector(int entry_point, void *target) 
+{
+	if (entry_point & ~0xffff) {
+		return -1;
+	}
+	
+	if (((u32)target-0xf0000) & ~0xffff) {
+		return -1;
+	}
+	printf("set_jmp_vector: 0xf000:%04x -> %p\n",
+	       entry_point, target);
+	
+	/* jmp opcode */
+	writeb(0xea, 0xf0000 + entry_point);
+	
+	/* offset */
+	writew(((u32)target-0xf0000), 0xf0000 + entry_point + 1);
+	
+	/* segment */
+	writew(0xf000, 0xf0000 + entry_point + 3);
+	
+	return 0;
+}
+
+
 /*
  ************************************************************
  * Install an interrupt vector
@@ -96,11 +130,16 @@
 #endif	
 }
 
+#define RELOC_16_LONG(seg, off) *(u32*)(seg << 4 | (u32)&off) 
+#define RELOC_16_WORD(seg, off) *(u16*)(seg << 4 | (u32)&off) 
+#define RELOC_16_BYTE(seg, off) *(u8*)(seg << 4 | (u32)&off) 
+
 int bios_setup(void)
 {
 	DECLARE_GLOBAL_DATA_PTR;
 	static int done=0;	
 	int vector;
+	struct pci_controller *pri_hose;
 	
 	if (done) {
 		return 0;
@@ -169,9 +208,26 @@
 	setvector(0x1e, BIOS_CS, &rm_int1e);
 	setvector(0x1f, BIOS_CS, &rm_int1f);
 
+	set_jmp_vector(0xfff0, &realmode_reset);
+	set_jmp_vector(0xfe6e, &realmode_pci_bios_call_entry);
+	
 	/* fill in data area */
-	ram_in_64kb_chunks = gd->ram_size >> 16;
-	bios_equipment = 0; /* FixMe */
+	RELOC_16_WORD(0xf000, ram_in_64kb_chunks) = gd->ram_size >> 16;
+	RELOC_16_WORD(0xf000, bios_equipment) = 0; /* FixMe */
+	
+	/* If we assume only one PCI hose, this PCI hose
+	 * will own PCI bus #0, and the last PCI bus of 
+	 * that PCI hose will be the last PCI bus in the 
+	 * system. 
+	 * (This, ofcause break on multi hose systems,
+	 *  but our PCI BIOS only support one hose anyway) 
+	 */
+	pri_hose = pci_bus_to_hose(0);
+	if (NULL != pri_hose) {
+		/* fill in last pci bus number for use by the realmode 
+		 * PCI BIOS */
+		RELOC_16_BYTE(0xf000, pci_last_bus) = pri_hose->last_busno;
+	}
 	
 	return 0;
 }
diff --git a/lib_i386/board.c b/lib_i386/board.c
index 193860a..85d7d7f 100644
--- a/lib_i386/board.c
+++ b/lib_i386/board.c
@@ -37,6 +37,7 @@
 #include <syscall.h>
 #include <net.h>
 #include <ide.h>
+#include <asm/u-boot-i386.h>
 
 extern long _i386boot_start;	    
 extern long _i386boot_end;	    
@@ -82,21 +83,14 @@
 {
 	DECLARE_GLOBAL_DATA_PTR;
         
-#if 1	
 	/* start malloc area right after the stack */
 	mem_malloc_start = i386boot_bss_start + 
 		i386boot_bss_size + CFG_STACK_SIZE;
 	mem_malloc_start = (mem_malloc_start+3)&~3;
-#else
-	mem_malloc_start = 0x400000;
-#endif	
-#if 1
+	
 	/* Use all available RAM for malloc() */
 	mem_malloc_end = gd->ram_size;
-#else	
-	/* Use only  CONFIG_MALLOC_SIZE bytes of RAM for malloc() */
-	mem_malloc_end = mem_malloc_start + CONFIG_MALLOC_SIZE;
-#endif	
+	
 	mem_malloc_brk = mem_malloc_start;
 
 	return 0;
@@ -149,10 +143,10 @@
 {
 	DECLARE_GLOBAL_DATA_PTR;
 
-	uchar tmp[64];	/* long enough for environment variables */
-	int i = getenv_r ("baudrate", tmp, sizeof (tmp));
+	char tmp[64];	/* long enough for environment variables */
+	int i = getenv_r("baudrate", tmp, 64);
 
-	gd->baudrate = (i > 0)
+	gd->baudrate = (i != 0)
 			? (int) simple_strtoul (tmp, NULL, 10)
 			: CONFIG_BAUDRATE;
 
@@ -237,6 +231,7 @@
 	mem_malloc_init,        /* dependant on dram_init */
 	interrupt_init,		/* set up exceptions */
 	timer_init,	
+	serial_init,
 	env_init,		/* initialize environment */
 	init_baudrate,		/* initialze baudrate settings */
 	serial_init,		/* serial communications setup */
@@ -267,6 +262,7 @@
 	memset (gd->bd, 0, sizeof (bd_t));
 	show_boot_progress(0x22);
 
+	gd->baudrate =  CONFIG_BAUDRATE;
 	
 	for (init_fnc_ptr = init_sequence, i=0; *init_fnc_ptr; ++init_fnc_ptr, i++) {
 		show_boot_progress(0xa130|i);
@@ -323,7 +319,8 @@
 
 	/* allocate syscalls table (console_init_r will fill it in */
 	syscall_tbl = (void **) malloc (NR_SYSCALLS * sizeof (void *));
-
+	memset(syscall_tbl, 0, NR_SYSCALLS * sizeof (void *));
+	
 	/* Initialize the console (after the relocation and devices init) */
 	console_init_r();
 	syscalls_init();
@@ -355,7 +352,7 @@
 #endif
 
 	/* enable exceptions */
-	enable_interrupts ();
+	enable_interrupts();
 	show_boot_progress(0x28);
 
 	/* Must happen after interrupts are initialized since
@@ -369,7 +366,7 @@
 	status_led_set (STATUS_LED_BOOT, STATUS_LED_BLINKING);
 #endif
 
-	udelay (20);
+	udelay(20);
 
 	set_timer (0);
 
@@ -399,7 +396,7 @@
 
 #if (CONFIG_COMMANDS & CFG_CMD_DOC)
 	WATCHDOG_RESET();
-	puts ("DOC:   ");
+	puts("DOC:   ");
 	doc_init();
 #endif
 
@@ -428,12 +425,13 @@
 		board_poweroff();
 	}
 #endif
-
+	
+	
 	show_boot_progress(0x29);
 	
 	/* main_loop() can return to retry autoboot, if so just run it again. */
 	for (;;) {
-		main_loop ();
+		main_loop();
 	}
 
 	/* NOTREACHED - no way out of command loop except booting */
diff --git a/lib_i386/ic/ali512x.c b/lib_i386/ic/ali512x.c
deleted file mode 100644
index 4537095..0000000
--- a/lib_i386/ic/ali512x.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * (C) Copyright 2002
- * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>.
- *
- * 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
- */
-
-/*
- * Based on sc520cdp.c from rolo 1.6:
- *----------------------------------------------------------------------
- * (C) Copyright 2000
- * Sysgo Real-Time Solutions GmbH
- * Klein-Winternheim, Germany
- *----------------------------------------------------------------------
- */
-
-#include <common.h>
-#include <asm/io.h>
-#include <asm/ic/ali512x.h>
-
-
-/* ALI M5123 Logical device numbers:
- * 0 FDC
- * 1 unused?
- * 2 unused?
- * 3 lpt
- * 4 UART1
- * 5 UART2
- * 6 RTC
- * 7 mouse/kbd
- * 8 CIO
- */
-
-/*
- ************************************************************
- *  Some access primitives for the ALi chip:                *
- ************************************************************
- */
-
-static void ali_write(u8 index, u8 value)
-{	
-	/* write an arbirary register */
-	outb(index, ALI_INDEX);
-	outb(value, ALI_DATA);
-}
-
-static int ali_read(u8 index)
-{
-	outb(index, ALI_INDEX);
-	return inb(ALI_DATA);
-}
-
-#define ALI_OPEN() \
-	outb(0x51, ALI_DATA); \
-	outb(0x23, ALI_DATA)	
-
-
-#define ALI_CLOSE() \
-	outb(0xbb, ALI_DATA)
-
-/* Select a logical device */
-#define ALI_SELDEV(dev)	\
-	ali_write(0x07, dev)	
-
-
-void ali512x_init(void)
-{
-	ALI_OPEN();
-
-	ali_write(0x02, 0x01);	/* soft reset */
-	ali_write(0x03, 0x03);	/* disable access to CIOs */
-	ali_write(0x22, 0x00);	/* disable direct powerdown */
-	ali_write(0x23, 0x00);	/* disable auto powerdown */
-	ali_write(0x24, 0x00);	/* IR 8 is active hi, pin26 is PDIR */
-
-	ALI_CLOSE();
-}
-
-void ali512x_set_fdc(int enabled, u16 io, u8 irq, u8 dma_channel)
-{
-	ALI_OPEN();
-	ALI_SELDEV(0);
-	
-	ali_write(0x30, enabled?1:0);
-	if (enabled) {
-		ali_write(0x60, io >> 8);
-		ali_write(0x61, io & 0xff);
-		ali_write(0x70, irq);
-		ali_write(0x74, dma_channel);
-		
-		/* AT mode, no drive swap */
-		ali_write(0xf0, 0x08);
-		ali_write(0xf1, 0x00);
-		ali_write(0xf2, 0xff);
-		ali_write(0xf4, 0x00);
-	}
-	ALI_CLOSE();
-}
-
-
-void ali512x_set_pp(int enabled, u16 io, u8 irq, u8 dma_channel)
-{
-	ALI_OPEN();
-	ALI_SELDEV(3);
-	
-	ali_write(0x30, enabled?1:0);
-	if (enabled) {
-		ali_write(0x60, io >> 8);
-		ali_write(0x61, io & 0xff);
-		ali_write(0x70, irq);
-		ali_write(0x74, dma_channel);
-		
-		/* mode: EPP 1.9, ECP FIFO threshold = 7, IRQ active low */
-		ali_write(0xf0, 0xbc);
-		/* 12 MHz, Burst DMA in ECP */
-		ali_write(0xf1, 0x05);
-	}
-	ALI_CLOSE();
-
-}
-
-void ali512x_set_uart(int enabled, int index, u16 io, u8 irq)
-{
-	ALI_OPEN();
-	ALI_SELDEV(index?5:4);
-	
-	ali_write(0x30, enabled?1:0);
-	if (enabled) {
-		ali_write(0x60, io >> 8);
-		ali_write(0x61, io & 0xff);
-		ali_write(0x70, irq);
-		
-		ali_write(0xf0, 0x00);
-		ali_write(0xf1, 0x00);
-		
-		/* huh? write 0xf2 twice - a typo in rolo
-		 * or some secret ali errata? Who knows? 
-		 */
-		if (index) {
-			ali_write(0xf2, 0x00);
-		}
-		ali_write(0xf2, 0x0c);
-	}
-	ALI_CLOSE();
-
-}
-
-void ali512x_set_uart2_irda(int enabled)
-{
-	ALI_OPEN();
-	ALI_SELDEV(5);
-	
-	ali_write(0xf1, enabled?0x48:0x00); /* fullduplex IrDa */
-	ALI_CLOSE();
-
-}
-
-void ali512x_set_rtc(int enabled, u16 io, u8 irq)
-{
-	ALI_OPEN();
-	ALI_SELDEV(6);
-	
-	ali_write(0x30, enabled?1:0);
-	if (enabled) {
-		ali_write(0x60, io >> 8);
-		ali_write(0x61, io & 0xff);
-		ali_write(0x70, irq);
-
-		ali_write(0xf0, 0x00);
-	}
-	ALI_CLOSE();
-}
-
-void ali512x_set_kbc(int enabled, u8 kbc_irq, u8 mouse_irq)
-{
-	ALI_OPEN();
-	ALI_SELDEV(7);
-	
-	ali_write(0x30, enabled?1:0);
-	if (enabled) {
-		ali_write(0x70, kbc_irq);
-		ali_write(0x72, mouse_irq);		
-		
-		ali_write(0xf0, 0x00);
-	}
-	ALI_CLOSE();
-}
-
-
-/* Common I/O
- * 
- * (This descripotsion is base on several incompete sources
- *  since I have not been able to obtain any datasheet for the device
- *  there may be some mis-understandings burried in here. 
- *  -- Daniel daniel@omicron.se)
- * 
- * There are 22 CIO pins numbered
- * 10-17
- * 20-25
- * 30-37
- * 
- * 20-24 are dedicated CIO pins, the other 17 are muliplexed with
- * other functions.
- * 
- *           Secondary 
- * CIO Pin   Function    Decription
- * =======================================================
- * CIO10     IRQIN1      Interrupt input 1?
- * CIO11     IRQIN2      Interrupt input 2?
- * CIO12     IRRX        IrDa Receive
- * CIO13     IRTX        IrDa Transmit
- * CIO14     P21         KBC P21 fucntion
- * CIO15     P20         KBC P21 fucntion
- * CIO16     I2C_CLK     I2C Clock
- * CIO17     I2C_DAT     I2C Data
- * 
- * CIO20     -
- * CIO21     -
- * CIO22     -
- * CIO23     -
- * CIO24     -
- * CIO25     LOCK        Keylock
- * 
- * CIO30     KBC_CLK     Keybaord Clock
- * CIO31     CS0J        General Chip Select decoder CS0J
- * CIO32     CS1J        General Chip Select decoder CS1J
- * CIO33     ALT_KCLK    Alternative Keyboard Clock
- * CIO34     ALT_KDAT    Alternative Keyboard Data
- * CIO35     ALT_MCLK    Alternative Mouse Clock
- * CIO36     ALT_MDAT    Alternative Mouse Data
- * CIO37     ALT_KBC     Alternative KBC select
- *
- * The CIO use a double indirect address scheme. 
- * 
- * Reigster 3 in the SIO is used to selectg where the CIO 
- * I/O registers show up under function 8. Note that these
- * registers clash with the CIO function select regsters,
- * below.
- * 
- * SIO reigster 3 (CIO Address Selection) bit definitions:
- * bit 7   CIO data register enabled
- * bit 1-0 CIO indirect registers select
- *     	 0  index = 0xE0 data = 0xE1
- *       1  index = 0xE2 data = 0xE3
- *       2  index = 0xE4 data = 0xE5
- *       3  index = 0xEA data = 0xEB
- * 
- * There are three CIO I/O register accessed via CIO index and CIO data
- * 0x01     CIO 10-17 data
- * 0x02     CIO 20-25 data (bits 7-6 unused)
- * 0x03     CIO 30-37 data
- * 
- * 
- * The pin function is accessed through normal 
- * SIO registers, each register have the same format:
- * 
- * Bit   Function                     Value
- * 0     Input/output                 1=input 
- * 1     Polarity of signal           1=inverted
- * 2     Unused                       ??
- * 3     Function (normal or special) 1=special
- * 7-4   Unused
- * 
- * SIO REG
- * 0xe0     CIO 10 Config
- * 0xe1     CIO 11 Config
- * 0xe2     CIO 12 Config
- * 0xe3     CIO 13 Config
- * 0xe4     CIO 14 Config
- * 0xe5     CIO 15 Config
- * 0xe6     CIO 16 Config
- * 0xe7     CIO 16 Config
- *
- * 0xe8     CIO 20 Config
- * 0xe9     CIO 21 Config
- * 0xea     CIO 22 Config
- * 0xeb     CIO 23 Config
- * 0xec     CIO 24 Config
- * 0xed     CIO 25 Config
- *
- * 0xf5     CIO 30 Config
- * 0xf6     CIO 31 Config
- * 0xf7     CIO 32 Config
- * 0xf8     CIO 33 Config
- * 0xf9     CIO 34 Config
- * 0xfa     CIO 35 Config
- * 0xfb     CIO 36 Config
- * 0xfc     CIO 37 Config
- * 
- */
-
-void ali512x_set_cio(int enabled)
-{
-	int i;
-	
-	ALI_OPEN();
-	ali_write(0x3, 3);    /* Disable CIO data register */
-	
-	ALI_SELDEV(8);
-	ali_write(0x30, enabled?1:0);
-	
-	/* set all pins to input to start with */
-	for (i=0xe0;i<0xee;i++) {
-		ali_write(i, 1);
-	}
-	for (i=0xf5;i<0xfe;i++) {
-		ali_write(i, 1);
-	}
-			
-	ALI_CLOSE();
-}
-
-void ali512x_cio_function(int pin, int special, int inv, int input)
-{
-	u8 data;
-	u8 addr;
-	
-	
-	/* valid pins are 10-17, 20-25 and 30-37 */
-	if (pin >= 10 && pin <= 17) { 
-		addr = 0xe0+(pin-10);
-	} else if (pin >= 20 && pin <= 25) {
-		addr = 0xe8+(pin-20);
-	} else if (pin >= 30 && pin <= 37) { 
-		addr = 0xf5+(pin-30);
-	} else {
-		return;
-	}
-	
-	ALI_OPEN();
-	ALI_SELDEV(8);
-	
-	ali_write(0x03, 0x03);    /* Disable CIO data register */
-	
-	data=0;
-	if (special) {
-		data |= 0x08;
-	} else {
-		if (inv) {
-			data |= 0x02;
-		}
-		if (input) {
-			data |= 0x01;
-		}
-	}
-	
-	ali_write(addr, data);
-	
-	ALI_CLOSE();
-}
-
-void ali512x_cio_out(int pin, int value) 
-{
-	u8 reg;
-	u8 data;
-	u8 bit;
-	
-	/* valid pins are 10-17, 20-25 and 30-37 */
-	if (pin >= 10 && pin <= 17) { 
-		reg = 1;
-		pin -= 10;
-	} else if (pin >= 20 && pin <= 25) {
-		reg = 2;
-		pin -= 20;
-	} else if (pin >= 30 && pin <= 37) { 
-		reg = 3;
-		pin -= 30;
-	} else {
-		return;
-	}
-	bit = 1 << pin;
-	
-	ALI_OPEN();
-	ALI_SELDEV(8);
-	
-	ali_write(0x03, 0x83);    /* Enable CIO data register, use data port at 0xea */
-	
-	ali_write(0xea, reg);     /* select I/O register */
-	data = ali_read(0xeb);
-	if (value) {
-		data |= bit;
-	} else {
-		data &= ~bit;
-	}
-	ali_write(0xeb, data);
-	ali_write(0xea, 0);       /* select register 0 */
-	ali_write(0x03, 0x03);    /* Disable CIO data register */
-	ALI_CLOSE();
-}
-
-int ali512x_cio_in(int pin)
-{
-	u8 reg;
-	u8 data;
-	u8 bit;
-	
-	/* valid pins are 10-17, 20-25 and 30-37 */
-	if (pin >= 10 && pin <= 17) { 
-		reg = 1;
-		pin -= 10;
-	} else if (pin >= 20 && pin <= 25) {
-		reg = 2;
-		pin -= 20;
-	} else if (pin >= 30 && pin <= 37) { 
-		reg = 3;
-		pin -= 30;
-	} else {
-		return -1; 
-	}
-	bit = 1 << pin;
-	
-	ALI_OPEN();
-	ALI_SELDEV(8);
-	
-	ali_write(0x03, 0x83);    /* Enable CIO data register, use data port at 0xea */
-	
-	ali_write(0xea, reg);     /* select I/O register */
-	data = ali_read(0xeb);
-	ali_write(0xea, 0);       /* select register 0 */
-	ali_write(0x03, 0x03);    /* Disable CIO data register */
-	ALI_CLOSE();
-	
-	return data & bit; 
-}
-
- 
diff --git a/lib_i386/ic/sc520.c b/lib_i386/ic/sc520.c
deleted file mode 100644
index d202625..0000000
--- a/lib_i386/ic/sc520.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * (C) Copyright 2002
- * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>.
- *
- * 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
- */
-
-/* stuff specific for the sc520,
- * but idependent of implementation */
-
-
-#include <common.h>
-#include <config.h>
-#include <pci.h>
-#include <asm/io.h>
-#include <asm/pci.h>
-#include <asm/ic/sc520.h>
-
-/* 
- * utility functions for boards based on the AMD sc520 
- * 
- * void write_mmcr_byte(u16 mmcr, u8 data)
- * void write_mmcr_word(u16 mmcr, u16 data)
- * void write_mmcr_long(u16 mmcr, u32 data)
- * 
- * u8   read_mmcr_byte(u16 mmcr)
- * u16  read_mmcr_word(u16 mmcr)
- * u32  read_mmcr_long(u16 mmcr)
- * 
- * void init_sc520(void)
- * unsigned long init_sc520_dram(void)
- * void pci_sc520_init(struct pci_controller *hose)
- * 
- * void reset_timer(void)
- * ulong get_timer(ulong base)
- * void set_timer(ulong t)
- * void udelay(unsigned long usec)
- * 
- */
-
-static u32 mmcr_base= 0xfffef000;
-
-void write_mmcr_byte(u16 mmcr, u8 data)
-{
-	writeb(data, mmcr+mmcr_base);
-}
-
-void write_mmcr_word(u16 mmcr, u16 data)
-{
-	writew(data, mmcr+mmcr_base);	
-}
-
-void write_mmcr_long(u16 mmcr, u32 data)
-{
-	writel(data, mmcr+mmcr_base);
-}
-
-u8 read_mmcr_byte(u16 mmcr)
-{
-	return readb(mmcr+mmcr_base);
-}
-
-u16 read_mmcr_word(u16 mmcr)
-{
-	return readw(mmcr+mmcr_base);	
-}
-
-u32 read_mmcr_long(u16 mmcr)
-{
-	return readl(mmcr+mmcr_base);
-}
-
-
-void init_sc520(void)
-{
-	DECLARE_GLOBAL_DATA_PTR;
-	
-	/* Set the UARTxCTL register at it's slower,
-	 * baud clock giving us a 1.8432 MHz reference 
-	 */
-	write_mmcr_byte(SC520_UART1CTL, 7);
-	write_mmcr_byte(SC520_UART2CTL, 7);
-	
-	/* first set the timer pin mapping */
-	write_mmcr_byte(SC520_CLKSEL, 0x72);	/* no clock frequency selected, use 1.1892MHz */
-	
-	/* enable PCI bus arbitrer */
-	write_mmcr_byte(SC520_SYSARBCTL,0x02);  /* enable concurrent mode */
-	
-	write_mmcr_word(SC520_SYSARBMENB,0x1f); /* enable external grants */
-	write_mmcr_word(SC520_HBCTL,0x04);      /* enable posted-writes */
-
-
-	if (CFG_SC520_HIGH_SPEED) {
-		write_mmcr_byte(SC520_CPUCTL, 0x2);	/* set it to 133 MHz and write back */
-		gd->cpu_clk = 133000000;
-		printf("## CPU Speed set to 133MHz\n");
-	} else {
-		write_mmcr_byte(SC520_CPUCTL, 1);	/* set CPU to 100 MHz and write back cache */
-		printf("## CPU Speed set to 100MHz\n");
-		gd->cpu_clk = 100000000;
-	}
-	
-
-	/* wait at least one millisecond */
-        asm("movl	$0x2000,%%ecx\n"
-	    "wait_loop:	pushl %%ecx\n"
-	    "popl	%%ecx\n"
-	    "loop wait_loop\n": : : "ecx");
-
-	/* turn on the SDRAM write buffer */
-	write_mmcr_byte(SC520_DBCTL, 0x11);
-
-	/* turn on the cache and disable write through */
-	asm("movl	%%cr0, %%eax\n"
-	    "andl	$0x9fffffff, %%eax\n"
-	    "movl	%%eax, %%cr0\n"  : : : "eax");
-}
-
-unsigned long init_sc520_dram(void)
-{
-	DECLARE_GLOBAL_DATA_PTR;
-	bd_t *bd = gd->bd;
-	
-	u32 dram_present=0;
-	u32 dram_ctrl;
-
-	int val;
-	
-	int cas_precharge_delay = CFG_SDRAM_PRECHARGE_DELAY;	
-	int refresh_rate        = CFG_SDRAM_REFRESH_RATE;	
-	int ras_cas_delay       = CFG_SDRAM_RAS_CAS_DELAY;
-	
-	/* set SDRAM speed here */
-	
-	refresh_rate/=78;	
-	if (refresh_rate<=1) {
-		val = 0;  /* 7.8us */
-	} else if (refresh_rate==2) {
-		val = 1;  /* 15.6us */
-	} else if (refresh_rate==3 || refresh_rate==4) {
-		val = 2;  /* 31.2us */
-	} else {
-		val = 3;  /* 62.4us */
-	}
-	write_mmcr_byte(SC520_DRCCTL, (read_mmcr_byte(SC520_DRCCTL) & 0xcf) | (val<<4));
-	
-	val = read_mmcr_byte(SC520_DRCTMCTL);
-	val &= 0xf0;
-	
-	if (cas_precharge_delay==3) {		
-		val |= 0x04;   /* 3T */
-	} else if (cas_precharge_delay==4) {		
-		val |= 0x08;   /* 4T */
-	} else if (cas_precharge_delay>4) {		
-		val |= 0x0c;
-	} 
-	
-	if (ras_cas_delay > 3) {
-		val |= 2; 
-	} else {
-		val |= 1; 
-	}
-	write_mmcr_byte(SC520_DRCTMCTL, val);
-
-
-	/* We read-back the configuration of the dram
-	 * controller that the assembly code wrote */
-	dram_ctrl = read_mmcr_long(SC520_DRCBENDADR);
-	
-
-	bd->bi_dram[0].start = 0;
-	if (dram_ctrl & 0x80) {
-		/* bank 0 enabled */
-		dram_present = bd->bi_dram[1].start = (dram_ctrl & 0x7f) << 22;
-		bd->bi_dram[0].size = bd->bi_dram[1].start; 
-
-	} else {
-		bd->bi_dram[0].size = 0;
-		bd->bi_dram[1].start = bd->bi_dram[0].start;
-	}
-	
-	if (dram_ctrl & 0x8000) {
-		/* bank 1 enabled */
-		dram_present = bd->bi_dram[2].start = (dram_ctrl & 0x7f00) << 14;
-		bd->bi_dram[1].size = bd->bi_dram[2].start -  bd->bi_dram[1].start; 
-	} else {
-		bd->bi_dram[1].size = 0;
-		bd->bi_dram[2].start = bd->bi_dram[1].start;
-	}
-	
-	if (dram_ctrl & 0x800000) {
-		/* bank 2 enabled */
-		dram_present = bd->bi_dram[3].start = (dram_ctrl & 0x7f0000) << 6;
-		bd->bi_dram[2].size = bd->bi_dram[3].start -  bd->bi_dram[2].start; 
-	} else {
-		bd->bi_dram[2].size = 0;
-		bd->bi_dram[3].start = bd->bi_dram[2].start;
-	} 
-	
-	if (dram_ctrl & 0x80000000) {
-		/* bank 3 enabled */
-		dram_present  = (dram_ctrl & 0x7f000000) >> 2;
-		bd->bi_dram[3].size = dram_present -  bd->bi_dram[3].start;
-	} else {
-		bd->bi_dram[3].size = 0;
-	}
-
-	
-#if 0	
-	printf("Configured %d bytes of dram\n", dram_present);
-#endif	
-	gd->ram_size = dram_present;
-	
-	return dram_present;
-}
-
-
-#ifdef CONFIG_PCI
-
-
-
-void pci_sc520_init(struct pci_controller *hose)
-{
-	hose->first_busno = 0;
-	hose->last_busno = 0xff;
-
-	/* System memory space */
-	pci_set_region(hose->regions + 0, 
-		       SC520_PCI_MEMORY_BUS,
-		       SC520_PCI_MEMORY_PHYS,
-		       SC520_PCI_MEMORY_SIZE,
-		       PCI_REGION_MEM | PCI_REGION_MEMORY);
-
-	/* PCI memory space */
-	pci_set_region(hose->regions + 1, 
-		       SC520_PCI_MEM_BUS,
-		       SC520_PCI_MEM_PHYS,
-		       SC520_PCI_MEM_SIZE,
-		       PCI_REGION_MEM);
-
-	/* ISA/PCI memory space */
-	pci_set_region(hose->regions + 2, 
-		       SC520_ISA_MEM_BUS,
-		       SC520_ISA_MEM_PHYS,
-		       SC520_ISA_MEM_SIZE,
-		       PCI_REGION_MEM);
-
-	/* PCI I/O space */
-	pci_set_region(hose->regions + 3, 
-		       SC520_PCI_IO_BUS,
-		       SC520_PCI_IO_PHYS,
-		       SC520_PCI_IO_SIZE,
-		       PCI_REGION_IO);
-
-	/* ISA/PCI I/O space */
-	pci_set_region(hose->regions + 4, 
-		       SC520_ISA_IO_BUS,
-		       SC520_ISA_IO_PHYS,
-		       SC520_ISA_IO_SIZE,
-		       PCI_REGION_IO);
-
-	hose->region_count = 5;
-
-	pci_setup_type1(hose,
-			SC520_REG_ADDR,
-			SC520_REG_DATA);
-
-	pci_register_hose(hose);
-
-	hose->last_busno = pci_hose_scan(hose);
-	
-	/* enable target memory acceses on host brige */
-	pci_write_config_word(0, PCI_COMMAND, 
-			      PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
-
-}
-
-
-#endif
-
-#ifdef CFG_TIMER_SC520
-
-
-void reset_timer(void)
-{
-	write_mmcr_word(SC520_GPTMR0CNT, 0);
-	write_mmcr_word(SC520_GPTMR0CTL, 0x6001);
-	
-}
-
-ulong get_timer(ulong base)
-{
-	/* fixme: 30 or 33 */
-	return 	read_mmcr_word(SC520_GPTMR0CNT) / 33;
-}
-
-void set_timer(ulong t)
-{
-	/* FixMe: use two cascade coupled timers */
-	write_mmcr_word(SC520_GPTMR0CTL, 0x4001);
-	write_mmcr_word(SC520_GPTMR0CNT, t*33);
-	write_mmcr_word(SC520_GPTMR0CTL, 0x6001);
-}
-
-
-void udelay(unsigned long usec)
-{
-	int m=0;
-	long u;
-	
-	read_mmcr_word(SC520_SWTMRMILLI);
-	read_mmcr_word(SC520_SWTMRMICRO);
-	     
-#if 0
-	/* do not enable this line, udelay is used in the serial driver -> recursion */
-	printf("udelay: %ld m.u %d.%d  tm.tu %d.%d\n", usec, m, u, tm, tu);
-#endif	
-	while (1) {
-		
-		m += read_mmcr_word(SC520_SWTMRMILLI);
-		u = read_mmcr_word(SC520_SWTMRMICRO) + (m * 1000);
-		
-		if (usec <= u) {
-			break;
-		}
-	}
-}
-
-#endif
-
-
diff --git a/lib_i386/ic/sc520_asm.S b/lib_i386/ic/sc520_asm.S
deleted file mode 100644
index 72110c4..0000000
--- a/lib_i386/ic/sc520_asm.S
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * (C) Copyright 2002
- * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>.
- *
- * 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
- */
-
-/* This file is largely based on code obtned from AMD. AMD's original
- * copyright is included below 
- */
-
-/*
- *  =============================================================================
- *                                                                              
- *   Copyright 1999 Advanced Micro Devices, Inc.                                
- *                                                                              
- *  This software is the property of Advanced Micro Devices, Inc  (AMD)  which 
- *  specifically grants the user the right to modify, use and distribute this 
- *  software provided this COPYRIGHT NOTICE is not removed or altered.  All 
- *  other rights are reserved by AMD.                                                       
- *                                                                             
- *  THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY 
- *  OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT OF 
- *  THIRD-PARTY INTELLECTUAL PROPERTY, OR FITNESS FOR ANY PARTICULAR PURPOSE.
- *  IN NO EVENT SHALL AMD OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER
- *  (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS
- *  INTERRUPTION, LOSS OF INFORMAITON) ARISING OUT OF THE USE OF OR INABILITY
- *  TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE POSSIBILITY OF
- *  SUCH DAMAGES.  BECAUSE SOME JURSIDICTIONS PROHIBIT THE EXCLUSION OR
- *  LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE
- *  LIMITATION MAY NOT APPLY TO YOU.
- * 
- *  AMD does not assume any responsibility for any errors that may appear in
- *  the Materials nor any responsibility to support or update the Materials.
- *  AMD retains the right to make changes to its test specifications at any
- *  time, without notice.
- * 
- *  So that all may benefit from your experience, please report  any  problems 
- *  or suggestions about this software back to AMD.  Please include your name, 
- *  company,  telephone number,  AMD product requiring support and question or 
- *  problem encountered.                                                       
- *                                                                             
- *  Advanced Micro Devices, Inc.         Worldwide support and contact           
- *  Embedded Processor Division            information available at:               
- *  Systems Engineering                       epd.support@amd.com
- *  5204 E. Ben White Blvd.                          -or-
- *  Austin, TX 78741                http://www.amd.com/html/support/techsup.html
- *  ============================================================================
- */
-
-
-/*******************************************************************************
- *	 AUTHOR      : Buddy Fey - Original. 
- *******************************************************************************
- */
-
-
-/*******************************************************************************
- *       FUNCTIONAL DESCRIPTION:
- * This routine is called to autodetect the geometry of the DRAM.
- *
- * This routine is called to determine the number of column bits for the DRAM
- * devices in this external bank. This routine assumes that the external bank
- * has been configured for an 11-bit column and for 4 internal banks. This gives
- * us the maximum address reach in memory. By writing a test value to the max
- * address and locating where it aliases to, we can determine the number of valid
- * column bits.
- *
- * This routine is called to determine the number of internal banks each DRAM
- * device has. The external bank (under test) is configured for maximum reach
- * with 11-bit columns and 4 internal banks. This routine will write to a max
- * address (BA1 and BA0 = 1) and then read from an address with BA1=0 to see if
- * that column is a "don't care". If BA1 does not affect write/read of data,
- * then this device has only 2 internal banks.
- *
- * This routine is called to determine the ending address for this external
- * bank of SDRAM. We write to a max address with a data value and then disable
- * row address bits looking for "don't care" locations. Each "don't care" bit
- * represents a dividing of the maximum density (128M) by 2. By dividing the
- * maximum of 32 4M chunks in an external bank down by all the "don't care" bits
- * determined during sizing, we set the proper density.
- *
- * WARNINGS.
- * bp must be preserved because it is used for return linkage.
- *
- * EXIT
- * nothing returned - but the memory subsystem is enabled
- *******************************************************************************
- */
-
-.section .text
-.equ            DRCCTL,     0x0fffef010   /* DRAM control register */
-.equ            DRCTMCTL,   0x0fffef012   /* DRAM timing control register */
-.equ            DRCCFG,     0x0fffef014   /* DRAM bank configuration register */
-.equ            DRCBENDADR, 0x0fffef018   /* DRAM bank ending address register */
-.equ            ECCCTL,     0x0fffef020   /* DRAM ECC control register */
-.equ            DBCTL,      0x0fffef040   /* DRAM buffer control register */
-
-.equ            CACHELINESZ, 0x00000010   /* size of our cache line (read buffer) */
-.equ            COL11_ADR,  0x0e001e00    /* 11 col addrs */
-.equ            COL10_ADR,  0x0e000e00    /* 10 col addrs */
-.equ            COL09_ADR,  0x0e000600    /*  9 col addrs */
-.equ            COL08_ADR,  0x0e000200    /*  8 col addrs */
-.equ            ROW14_ADR,  0x0f000000    /* 14 row addrs */
-.equ            ROW13_ADR,  0x07000000    /* 13 row addrs */
-.equ            ROW12_ADR,  0x03000000    /* 12 row addrs */
-.equ            ROW11_ADR,  0x01000000    /* 11 row addrs/also bank switch */
-.equ            ROW10_ADR,  0x00000000    /* 10 row addrs/also bank switch */
-.equ            COL11_DATA, 0x0b0b0b0b    /* 11 col addrs */
-.equ            COL10_DATA, 0x0a0a0a0a    /* 10 col data */
-.equ            COL09_DATA, 0x09090909    /*  9 col data */
-.equ            COL08_DATA, 0x08080808    /*  8 col data */
-.equ            ROW14_DATA, 0x3f3f3f3f    /* 14 row data (MASK) */
-.equ            ROW13_DATA, 0x1f1f1f1f    /* 13 row data (MASK) */
-.equ            ROW12_DATA, 0x0f0f0f0f    /* 12 row data (MASK) */
-.equ            ROW11_DATA, 0x07070707    /* 11 row data/also bank switch (MASK) */
-.equ            ROW10_DATA, 0xaaaaaaaa    /* 10 row data/also bank switch (MASK) */
-
-
- /*
-  * initialize dram controller registers
-  */
-.globl mem_init
-mem_init: 
-        xorw    %ax,%ax
-        movl    $DBCTL, %edi             
-fs	movb     %al, (%edi)             /* disable write buffer */
-
-        movl    $ECCCTL, %edi            
-fs	movb     %al, (%edi)             /* disable ECC */
-
-        movl    $DRCTMCTL, %edi           
-        movb    $0x1E,%al                /* Set SDRAM timing for slowest */
-fs	movb     %al, (%edi)
-
- /*
-  * setup loop to do 4 external banks starting with bank 3
-  */
-        movl    $0xff000000,%eax         /* enable last bank and setup */
-        movl    $DRCBENDADR, %edi        /* ending address register */
-fs	movl     %eax, (%edi)
-
-        movl    $DRCCFG, %edi            /* setup */
-        movw    $0xbbbb,%ax              /* dram config register for  */
-fs	movw    %ax, (%edi)
-
- /*
-  * issue a NOP to all DRAMs
-  */
-        movl    $DRCCTL, %edi            /* setup DRAM control register with */
-        movb    $0x1,%al                 /* Disable refresh,disable write buffer */ 
-fs	movb     %al, (%edi)
-        movl    $CACHELINESZ, %esi       /* just a dummy address to write for */ 
-fs	movw     %ax, (%esi)
- /*
-  * delay for 100 usec? 200?
-  * ******this is a cludge for now *************
-  */
-        movw    $100,%cx
-sizdelay: 
-        loop    sizdelay                 /* we need 100 usec here */
- /***********************************************/
-
- /*
-  * issue all banks precharge
-  */
-        movb    $0x2,%al                 /* All banks precharge */
-fs	movb     %al, (%edi)
-fs	movw     %ax, (%esi)
-
- /*
-  * issue 2 auto refreshes to all banks 
-  */
-        movb    $0x4,%al                 /* Auto refresh cmd */
-fs	movb     %al, (%edi)
-        movw    $2,%cx
-refresh1: 
-fs	movw     %ax, (%esi)
-        loop    refresh1
-
- /*
-  * issue LOAD MODE REGISTER command
-  */
-        movb    $0x3,%al                 /* Load mode register cmd */
-fs	movb     %al, (%edi)
-fs	movw     %ax, (%esi)
-
- /*
-  * issue 8 more auto refreshes to all banks 
-  */ 
-        movb    $0x4,%al                 /* Auto refresh cmd */
-fs	movb     %al, (%edi)
-        movw    $8,%cx
-refresh2: 
-fs	movw     %ax, (%esi)
-        loop    refresh2
-
- /*
-  * set control register to NORMAL mode 
-  */
-        movb    $0x0,%al                 /* Normal mode value */
-fs	movb     %al, (%edi)
-
- /*
-  * size dram starting with external bank 3 moving to external bank 0
-  */
-        movl    $0x3,%ecx                /* start with external bank 3 */
-
-nextbank: 
-
- /*
-  * write col 11 wrap adr
-  */
-        movl    $COL11_ADR, %esi         /* set address to max col (11) wrap addr */
-        movl    $COL11_DATA, %eax        /* pattern for max supported columns(11) */
-fs      movl    %eax, (%esi)             /* write max col pattern at max col adr */
-fs      movl    (%esi), %ebx             /* optional read */
-        cmpl    %ebx,%eax                /* to verify write */
-        jnz     bad_ram                  /* this ram is bad */
- /*
-  * write col 10 wrap adr
-  */
-
-        movl    $COL10_ADR, %esi         /* set address to 10 col wrap address */
-        movl    $COL10_DATA, %eax        /* pattern for 10 col wrap */
-fs      movl    %eax, (%esi)             /* write 10 col pattern @ 10 col wrap adr */
-fs      movl    (%esi), %ebx             /* optional read */
-        cmpl    %ebx,%eax                /* to verify write */
-        jnz     bad_ram                  /* this ram is bad */
- /*
-  * write col 9 wrap adr
-  */
-        movl    $COL09_ADR, %esi         /* set address to 9 col wrap address */
-        movl    $COL09_DATA, %eax        /* pattern for 9 col wrap */
-fs      movl    %eax, (%esi)             /* write 9 col pattern @ 9 col wrap adr */
-fs      movl    (%esi), %ebx             /* optional read */
-        cmpl    %ebx,%eax                /* to verify write */
-        jnz     bad_ram                  /* this ram is bad */
- /*
-  * write col 8 wrap adr
-  */
-        movl    $COL08_ADR, %esi         /* set address to min(8) col wrap address */
-        movl    $COL08_DATA, %eax        /* pattern for min (8) col wrap */
-fs      movl    %eax, (%esi)             /* write min col pattern @ min col adr */
-fs      movl    (%esi), %ebx             /* optional read */
-        cmpl    %ebx,%eax                /* to verify write */
-        jnz     bad_ram                  /* this ram is bad */
- /*
-  * write row 14 wrap adr
-  */
-        movl    $ROW14_ADR, %esi         /* set address to max row (14) wrap addr */
-        movl    $ROW14_DATA, %eax        /* pattern for max supported rows(14) */
-fs      movl    %eax, (%esi)             /* write max row pattern at max row adr */
-fs      movl    (%esi), %ebx             /* optional read */
-        cmpl    %ebx,%eax                /* to verify write */
-        jnz     bad_ram                  /* this ram is bad */
- /*
-  * write row 13 wrap adr
-  */
-        movl    $ROW13_ADR, %esi         /* set address to 13 row wrap address */
-        movl    $ROW13_DATA, %eax        /* pattern for 13 row wrap */
-fs      movl    %eax, (%esi)             /* write 13 row pattern @ 13 row wrap adr */
-fs      movl    (%esi), %ebx             /* optional read */
-        cmpl    %ebx,%eax                /* to verify write */
-        jnz     bad_ram                  /* this ram is bad */
- /*
-  * write row 12 wrap adr
-  */
-        movl    $ROW12_ADR, %esi         /* set address to 12 row wrap address */
-        movl    $ROW12_DATA, %eax        /* pattern for 12 row wrap */
-fs      movl    %eax, (%esi)             /* write 12 row pattern @ 12 row wrap adr */
-fs      movl    (%esi), %ebx             /* optional read */
-        cmpl    %ebx,%eax                /* to verify write */
-        jnz     bad_ram                  /* this ram is bad */
- /*
-  * write row 11 wrap adr
-  */
-        movl    $ROW11_ADR, %edi         /* set address to 11 row wrap address */
-        movl    $ROW11_DATA, %eax        /* pattern for 11 row wrap */
-fs      movl    %eax, (%edi)             /* write 11 row pattern @ 11 row wrap adr */
-fs      movl    (%edi), %ebx             /* optional read */
-        cmpl    %ebx,%eax                /* to verify write */
-        jnz     bad_ram                  /* this ram is bad */
- /*
-  * write row 10 wrap adr --- this write is really to determine number of banks
-  */
-        movl    $ROW10_ADR, %edi         /* set address to 10 row wrap address */
-        movl    $ROW10_DATA, %eax        /* pattern for 10 row wrap (AA) */
-fs      movl    %eax, (%edi)             /* write 10 row pattern @ 10 row wrap adr */
-fs      movl    (%edi), %ebx             /* optional read */
-        cmpl    %ebx,%eax                /* to verify write */
-        jnz     bad_ram                  /* this ram is bad */
- /*
-  * read data @ row 12 wrap adr to determine  * banks, 
-  * and read data @ row 14 wrap adr to determine  * rows.
-  * if data @ row 12 wrap adr is not AA, 11 or 12 we have bad RAM.
-  * if data @ row 12 wrap == AA, we only have 2 banks, NOT 4 
-  * if data @ row 12 wrap == 11 or 12, we have 4 banks,
-  */
-        xorw    %di,%di                  /* value for 2 banks in DI */
-fs      movl    (%esi), %ebx             /* read from 12 row wrap to check banks 
-                                          * (esi is setup from the write to row 12 wrap) */
-        cmpl    %ebx,%eax                /* check for AA pattern  (eax holds the aa pattern) */
-        jz      only2                    /* if pattern == AA, we only have 2 banks */
-
-	/* 4 banks */
-	
-        movw    $8,%di                   /* value for 4 banks in DI (BNK_CNT bit) */
-        cmpl    $ROW11_DATA, %ebx        /* only other legitimate values are 11 */
-        jz      only2
-        cmpl    $ROW12_DATA, %ebx        /* and 12 */
-        jnz     bad_ram                  /* its bad if not 11 or 12! */
-	
-	/* fall through */
-only2: 
- /*
-  * validate row mask
-  */
-        movl    $ROW14_ADR, %esi         /* set address back to max row wrap addr */
-fs      movl    (%esi), %eax             /* read actual number of rows @ row14 adr */
-
-        cmpl    $ROW11_DATA, %eax        /* row must be greater than 11 pattern */
-        jb      bad_ram
-
-        cmpl    $ROW14_DATA, %eax        /* and row must be less than 14 pattern */
-        ja      bad_ram
-
-        cmpb    %ah,%al                  /* verify all 4 bytes of dword same */
-        jnz     bad_ram
-        movl    %eax,%ebx
-        shrl    $16,%ebx
-        cmpw    %bx,%ax
-        jnz     bad_ram
- /*
-  * read col 11 wrap adr for real column data value
-  */
-        movl    $COL11_ADR, %esi         /* set address to max col (11) wrap addr */
-fs      movl    (%esi), %eax             /* read real col number at max col adr */
- /*
-  * validate column data
-  */
-        cmpl    $COL08_DATA, %eax        /* col must be greater than 8 pattern */
-        jb      bad_ram
-
-        cmpl    $COL11_DATA, %eax        /* and row must be less than 11 pattern */
-        ja      bad_ram
-
-        subl    $COL08_DATA, %eax        /* normalize column data to zero */
-        jc      bad_ram
-        cmpb    %ah,%al                  /* verify all 4 bytes of dword equal */
-        jnz     bad_ram
-        movl    %eax,%edx
-        shrl    $16,%edx
-        cmpw    %dx,%ax
-        jnz     bad_ram
- /*
-  * merge bank and col data together
-  */
-        addw    %di,%dx                  /* merge of bank and col info in dl */
- /*
-  * fix ending addr mask based upon col info
-  */
-        movb    $3,%al
-        subb    %dh,%al                  /* dh contains the overflow from the bank/col merge  */
-        movb    %bl,%dh                  /* bl contains the row mask (aa, 07, 0f, 1f or 3f) */
-        xchgw   %cx,%ax                  /* cx = ax = 3 or 2 depending on 2 or 4 bank device */
-        shrb    %cl,%dh	                 /*  */
-        incb    %dh                      /* ending addr is 1 greater than real end */
-        xchgw   %cx,%ax                  /* cx is bank number again */
- /*
-  * issue all banks precharge
-  */
-bad_reint: 
-        movl    $DRCCTL, %esi            /* setup DRAM control register with */
-        movb    $0x2,%al                 /* All banks precharge */
-fs	movb     %al, (%esi)
-        movl    $CACHELINESZ, %esi       /* address to init read buffer */
-fs	movw     %ax, (%esi)
-
- /*
-  * update ENDING ADDRESS REGISTER
-  */
-        movl    $DRCBENDADR, %edi        /* DRAM ending address register */
-        movl    %ecx,%ebx
-	addl	%ebx, %edi
-fs	movb    %dh, (%edi)
- /*
-  * update CONFIG REGISTER
-  */
-        xorb    %dh,%dh
-        movw    $0x00f,%bx
-        movw    %cx,%ax
-        shlw    $2,%ax
-        xchgw   %cx,%ax
-        shlw    %cl,%dx
-        shlw    %cl,%bx
-        notw    %bx
-        xchgw   %cx,%ax
-        movl    $DRCCFG, %edi
-fs	mov     (%edi), %ax
-        andw    %bx,%ax
-        orw     %dx,%ax
-fs      movw    %ax, (%edi)
-        jcxz    cleanup
-
-        decw    %cx
-        movl    %ecx,%ebx
-        movl    $DRCBENDADR, %edi        /* DRAM ending address register */
-        movb    $0xff,%al
-	addl	%ebx, %edi
-fs	movb    %al, (%edi)
- /*
-  * set control register to NORMAL mode 
-  */
-        movl    $DRCCTL, %esi            /* setup DRAM control register with */
-        movb    $0x0,%al                 /* Normal mode value */
-fs	movb    %al, (%esi)
-        movl    $CACHELINESZ, %esi       /* address to init read buffer */
-fs	movw    %ax, (%esi)
-        jmp     nextbank
-
-cleanup: 
-        movl    $DRCBENDADR, %edi        /* DRAM ending address register  */
-        movw    $4,%cx
-        xorw    %ax,%ax
-cleanuplp: 
-fs	movb   (%edi), %al
-        orb     %al,%al
-        jz      emptybank
-
-        addb    %ah,%al
-        jns     nottoomuch
-
-        movb    $0x7f,%al
-nottoomuch: 
-        movb    %al,%ah
-        orb     $0x80,%al
-fs	movb    %al, (%edi)
-emptybank: 
-        incl    %edi
-        loop    cleanuplp
-
-#if defined(CFG_SDRAM_CAS_LATENCY_2T) || defined(CFG_SDRAM_CAS_LATENCY_3T)
-	/* set the CAS latency now since it is hard to do
-	 * when we run from the RAM */
-	movl    $DRCTMCTL, %edi          /* DRAM timing register */
-	movb    (%edi), %al	
-#ifdef CFG_SDRAM_CAS_LATENCY_2T
-	andb    $0xef, %al
-#endif
-#ifdef CFG_SDRAM_CAS_LATENCY_3T
-	orb     $0x10, %al
-#endif	 
-	movb    %al, (%edi)
-#endif
-        movl    $DRCCTL, %edi            /* DRAM Control register */
-        movb    $0x3,%al                 /* Load mode register cmd */
-fs	movb     %al, (%edi)
-fs	movw     %ax, (%esi)
-
-
-        movl    $DRCCTL, %edi            /* DRAM Control register */
-        movb    $0x18,%al                /*  Enable refresh and NORMAL mode */
-fs	movb    %al, (%edi)
-
-        jmp     dram_done
-
-bad_ram: 
-        xorl    %edx,%edx
-        xorl    %edi,%edi
-        jmp     bad_reint
-
-dram_done: 
-	
-	/* readback DRCBENDADR and return the number
-	 * of available ram bytes in %eax */ 
-
-        movl    $DRCBENDADR, %edi        /* DRAM ending address register  */
-	
-	movl	(%edi), %eax
-	movl	%eax, %ecx
-	andl	$0x80000000, %ecx
-	jz	bank2
-	andl	$0x7f000000, %eax
-	shrl	$2, %eax 
-	movl	%eax, %ebx
-
-bank2: 	movl	(%edi), %eax
-	movl	%eax, %ecx
-	andl	$0x00800000, %ecx
-	jz	bank1
-	andl	$0x007f0000, %eax
-	shll	$6, %eax 
-	movl	%eax, %ebx
-
-bank1: 	movl	(%edi), %eax
-	movl	%eax, %ecx
-	andl	$0x00008000, %ecx
-	jz	bank0
-	andl	$0x00007f00, %eax
-	shll	$14, %eax 
-	movl	%eax, %ebx
-
-bank0: 	movl	(%edi), %eax
-	movl	%eax, %ecx
-	andl	$0x00000080, %ecx
-	jz	done
-	andl	$0x0000007f, %eax
-	shll	$22, %eax 
-	movl	%eax, %ebx
-
-done:	movl	%ebx, %eax
-
-	jmp	*%ebp
diff --git a/lib_i386/pci.c b/lib_i386/pci.c
new file mode 100644
index 0000000..acd1d25
--- /dev/null
+++ b/lib_i386/pci.c
@@ -0,0 +1,156 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
+ *
+ * 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/io.h> 
+#include <asm/pci.h> 
+
+#ifdef CONFIG_PCI
+#undef PCI_ROM_SCAN_VERBOSE
+
+int pci_shadow_rom(pci_dev_t dev, unsigned char *dest) 
+{
+	struct pci_controller *hose;
+	int res = -1;
+	int i;
+	
+	u32 rom_addr;
+	u32 addr_reg;
+	u32 size;
+	
+	u16 vendor;
+	u16 device;
+	u32 class_code;
+
+	hose = pci_bus_to_hose(PCI_BUS(dev));
+#if 0
+	printf("pci_shadow_rom() asked to shadow device %x to %x\n",
+	       dev, (u32)dest);
+#endif	
+	pci_read_config_word(dev, PCI_VENDOR_ID, &vendor);
+	pci_read_config_word(dev, PCI_DEVICE_ID, &device);
+	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_code);
+	
+ 	class_code &= 0xffffff00;
+	class_code >>= 8;
+
+#if 0	
+	printf("PCI Header Vendor %04x device %04x class %06x\n",
+	       vendor, device, class_code);
+#endif	
+	/* Enable the rom addess decoder */
+	pci_write_config_dword(dev, PCI_ROM_ADDRESS, PCI_ROM_ADDRESS_MASK);
+	pci_read_config_dword(dev, PCI_ROM_ADDRESS, &addr_reg);
+
+	if (!addr_reg) {
+		/* register unimplemented */
+		printf("pci_chadow_rom: device do not seem to have a rom\n");
+		return -1;
+	}
+	
+	size = (~(addr_reg&PCI_ROM_ADDRESS_MASK))+1;  
+	
+#if 0	
+	printf("ROM is %d bytes\n", size);
+#endif	
+	rom_addr = pci_get_rom_window(hose, size);
+#if 0	
+	printf("ROM mapped at %x \n", rom_addr);
+#endif	
+	pci_write_config_dword(dev, PCI_ROM_ADDRESS, 
+			       pci_phys_to_mem(dev, rom_addr)
+			       |PCI_ROM_ADDRESS_ENABLE);
+
+
+	
+	for (i=rom_addr;i<rom_addr+size; i+=512) {
+		
+		
+		if (readw(i) == 0xaa55) {
+			u32 pci_data;
+#ifdef PCI_ROM_SCAN_VERBOSE
+			printf("ROM signature found\n");
+#endif			
+			pci_data = readw(0x18+i);
+			pci_data += i;
+			
+			if (0==memcmp((void*)pci_data, "PCIR", 4)) {
+#ifdef PCI_ROM_SCAN_VERBOSE				
+				printf("Fount PCI rom image at offset %d\n", i-rom_addr);
+				printf("Vendor %04x device %04x class %06x\n",
+				       readw(pci_data+4), readw(pci_data+6),
+				       readl(pci_data+0x0d)&0xffffff);
+				printf("%s\n", 
+				       (readw(pci_data+0x15) &0x80)?
+				       "Last image":"More images follow");
+				switch 	(readb(pci_data+0x14)) {
+				case 0:
+					printf("X86 code\n");
+					break;
+				case 1:
+					printf("Openfirmware code\n");
+					break;
+				case 2:
+					printf("PARISC code\n");
+					break;
+				}
+				printf("Image size %d\n", readw(pci_data+0x10) * 512);
+#endif				
+				/* FixMe: I think we should compare the class code
+				 * bytes as well but I have no reference on the
+				 * exact order of these bytes in the PCI ROM header */
+				if (readw(pci_data+4) == vendor && 
+				    readw(pci_data+6) == device &&
+				    /* (readl(pci_data+0x0d)&0xffffff) == class_code && */
+				    readb(pci_data+0x14) == 0 /* x86 code image */ ) {
+#ifdef PCI_ROM_SCAN_VERBOSE					
+					printf("Suitable ROM image found, copying\n");
+#endif					
+					memmove(dest, (void*)rom_addr, readw(pci_data+0x10) * 512);
+					res = 0;
+					break;
+					
+				}
+				if (readw(pci_data+0x15) &0x80) {
+					break;
+				}
+			}
+		}
+		
+	}
+	
+#ifdef PCI_ROM_SCAN_VERBOSE
+	if (res) {
+		printf("No suitable image found\n");
+	}
+#endif	
+	/* disable PAR register and PCI device ROM address devocer */
+	pci_remove_rom_window(hose, rom_addr);
+	  	
+	pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
+
+	return res;
+}
+
+#endif
diff --git a/lib_i386/realmode.c b/lib_i386/realmode.c
index 27d4693..d7bb81c 100644
--- a/lib_i386/realmode.c
+++ b/lib_i386/realmode.c
@@ -33,25 +33,33 @@
 
 extern char realmode_enter;
 
-
-int enter_realmode(u16 seg, u16 off, struct pt_regs *in, struct pt_regs *out)
+int realmode_setup(void)
 {
-	
-	/* setup out thin bios emulation */
-	if (bios_setup()) {
-		return -1;
-	}
-		
 	/* copy the realmode switch code */
 	if (i386boot_realmode_size > (REALMODE_MAILBOX-REALMODE_BASE)) {
 		printf("realmode switch too large (%ld bytes, max is %d)\n", 
-		       i386boot_realmode_size, (int)(REALMODE_MAILBOX-REALMODE_BASE));
+		       i386boot_realmode_size, (REALMODE_MAILBOX-REALMODE_BASE));
 		return -1;
 	}
 	
 	memcpy(REALMODE_BASE, (void*)i386boot_realmode, i386boot_realmode_size);
+	asm("wbinvd\n");
+	
+	return 0;
+}
 		
+int enter_realmode(u16 seg, u16 off, struct pt_regs *in, struct pt_regs *out)
+{
 	
+	/* setup out thin bios emulation */
+	if (bios_setup()) {
+		return -1;
+	}
+	
+	if (realmode_setup()) {
+		return -1;
+	}
+		       	
 	in->eip = off;
 	in->xcs = seg;
 	if (3>(in->esp & 0xffff)) {
@@ -59,12 +67,30 @@
 	}
 	
 	memcpy(REALMODE_MAILBOX, in, sizeof(struct pt_regs));
+	asm("wbinvd\n");
 	
 	__asm__ volatile ( 
 		 "lcall $0x20,%0\n"  : :  "i" (&realmode_enter) );
 
+	asm("wbinvd\n");
 	memcpy(out, REALMODE_MAILBOX, sizeof(struct pt_regs));
 
 	return out->eax;
 }
 
+
+/* This code is supposed to access a realmode interrupt
+ * it does currently not work for me */
+int enter_realmode_int(u8 lvl, struct pt_regs *in, struct pt_regs *out)
+{
+	/* place two instructions at 0x700 */
+	writeb(0xcd, 0x700);  /* int $lvl */
+	writeb(lvl, 0x701);
+	writeb(0xcb, 0x702);  /* lret */
+	asm("wbinvd\n");
+      
+	enter_realmode(0x00, 0x700, in, out);	
+	
+	return out->eflags&1;
+}
+
diff --git a/lib_i386/realmode_switch.S b/lib_i386/realmode_switch.S
index 9f212c2..17adcbd 100644
--- a/lib_i386/realmode_switch.S
+++ b/lib_i386/realmode_switch.S
@@ -50,7 +50,6 @@
 
 .section .realmode, "ax"
 .code16
-
 						/* 16bit protected mode code here */
 .globl realmode_enter
 realmode_enter:
diff --git a/lib_i386/video.c b/lib_i386/video.c
new file mode 100644
index 0000000..776022e
--- /dev/null
+++ b/lib_i386/video.c
@@ -0,0 +1,238 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
+ *
+ * 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 <devices.h>
+#include <i8042.h>
+#include <asm/ptrace.h> 
+#include <asm/realmode.h> 
+#include <asm/io.h> 
+#include <asm/pci.h> 
+
+
+/* basic textmode I/O from linux kernel */
+static char *vidmem = (char *)0xb8000;
+static int vidport;
+static int lines, cols;
+static int orig_x, orig_y;
+
+static void beep(int dur)
+{
+	int i;
+	
+	outb_p(3, 0x61);
+	for (i=0;i<10*dur;i++) {
+		udelay(1000);
+	}
+	outb_p(0, 0x61);
+}
+
+static void scroll(void)
+{
+	int i;
+
+	memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
+	for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
+		vidmem[i] = ' ';
+}
+
+static void __video_putc(const char c, int *x, int *y)
+{
+	if (c == '\n') {
+ 		(*x) = 0;
+		if ( ++(*y) >= lines ) {
+			scroll();
+			(*y)--;
+		}
+	} else if (c == '\b') { 
+		if ((*x) != 0) {
+			--(*x);
+			vidmem [ ( (*x) + cols * (*y) ) * 2 ] = ' '; 
+		}
+ 	} else if (c == '\r') { 
+		(*x) = 0;
+		
+	} else if (c == '\a') { 
+		beep(3);
+		
+	} else if (c == '\t') { 
+		__video_putc(' ', x, y);
+		__video_putc(' ', x, y);
+		__video_putc(' ', x, y);
+		__video_putc(' ', x, y);
+		__video_putc(' ', x, y);
+		__video_putc(' ', x, y);
+		__video_putc(' ', x, y);
+		__video_putc(' ', x, y);
+	} else if (c == '\v') { 
+		switch ((*x) % 8) {
+		case 0:
+			__video_putc(' ', x, y);
+		case 7:
+			__video_putc(' ', x, y);
+		case 6:
+			__video_putc(' ', x, y);
+		case 5:
+			__video_putc(' ', x, y);
+		case 4:
+			__video_putc(' ', x, y);
+		case 3:
+			__video_putc(' ', x, y);
+		case 2:
+			__video_putc(' ', x, y);
+		case 1:
+			__video_putc(' ', x, y);
+		}
+	} else if (c == '\f') { 
+		int i;
+		for (i=0;i<lines*cols*2;i+=2) {
+			vidmem[i] = 0;
+		}
+		(*x) = 0;
+		(*y) = 0;
+	} else {
+		vidmem [ ( (*x) + cols * (*y) ) * 2 ] = c; 
+		if ( ++(*x) >= cols ) {
+			(*x) = 0;
+			if ( ++(*y) >= lines ) {
+				scroll();
+				(*y)--;
+			}
+		}
+	}
+}
+
+static void video_putc(const char c)
+{
+	int x,y,pos;
+	
+	x = orig_x;
+	y = orig_y;
+	
+	__video_putc(c, &x, &y);
+
+	orig_x = x;
+	orig_y = y;
+	
+	pos = (x + cols * y) * 2;	/* Update cursor position */
+	outb_p(14, vidport);
+	outb_p(0xff & (pos >> 9), vidport+1);
+	outb_p(15, vidport);
+	outb_p(0xff & (pos >> 1), vidport+1);
+}
+
+static void video_puts(const char *s)
+{
+	int x,y,pos;
+	char c;
+
+	x = orig_x;
+	y = orig_y;
+
+	while ( ( c = *s++ ) != '\0' ) {
+		__video_putc(c, &x, &y);
+	}
+
+	orig_x = x;
+	orig_y = y;
+
+	pos = (x + cols * y) * 2;	/* Update cursor position */
+	outb_p(14, vidport);
+	outb_p(0xff & (pos >> 9), vidport+1);
+	outb_p(15, vidport);
+	outb_p(0xff & (pos >> 1), vidport+1);
+}
+
+int video_init(void)
+{
+	u16 pos;
+	
+	static device_t vga_dev;
+	static device_t kbd_dev;
+	
+	vidmem = (char *) 0xb8000;
+	vidport = 0x3d4;
+
+	lines = 25;
+	cols = 80;
+	
+	outb_p(14, vidport);
+	pos = inb_p(vidport+1);
+	pos <<= 8;
+	outb_p(15, vidport);
+	pos |= inb_p(vidport+1);
+	
+	orig_x = pos%cols;
+	orig_y = pos/cols;
+
+#if 0	
+	printf("pos %x %d %d\n", pos, orig_x, orig_y);
+#endif	
+	if (orig_y > lines) {
+		orig_x = orig_y =0;
+	}
+	
+	
+	memset(&vga_dev, 0, sizeof(vga_dev));
+        strcpy(vga_dev.name, "vga");
+        vga_dev.ext   = 0; 
+        vga_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM;
+        vga_dev.putc  = video_putc;        /* 'putc' function */
+        vga_dev.puts  = video_puts;        /* 'puts' function */
+        vga_dev.tstc  = NULL;              /* 'tstc' function */
+        vga_dev.getc  = NULL;              /* 'getc' function */
+
+        if (device_register(&vga_dev) == 0) {
+            return 1;
+	}
+	
+	if (i8042_kbd_init()) {
+		return 1;
+	}
+	
+	memset(&kbd_dev, 0, sizeof(kbd_dev));
+        strcpy(kbd_dev.name, "kbd");
+        kbd_dev.ext   = 0; 
+        kbd_dev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+        kbd_dev.putc  = NULL;        /* 'putc' function */
+        kbd_dev.puts  = NULL;        /* 'puts' function */
+        kbd_dev.tstc  = i8042_tstc;  /* 'tstc' function */
+        kbd_dev.getc  = i8042_getc;  /* 'getc' function */
+
+        if (device_register(&kbd_dev) == 0) {
+            return 1;
+	}
+	return 0;
+}
+
+
+int drv_video_init(void) 
+{
+	if (video_bios_init()) {
+		return 1;
+	}
+	
+	return video_init();	
+}
+      
diff --git a/lib_i386/video_bios.c b/lib_i386/video_bios.c
new file mode 100644
index 0000000..d9709b9
--- /dev/null
+++ b/lib_i386/video_bios.c
@@ -0,0 +1,221 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
+ *
+ * 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 <malloc.h> 
+#include <asm/ptrace.h> 
+#include <asm/realmode.h> 
+#include <asm/io.h> 
+#include <asm/pci.h> 
+
+#undef PCI_BIOS_DEBUG
+#undef VGA_BIOS_DEBUG
+
+#ifdef	VGA_BIOS_DEBUG
+#define	PRINTF(fmt,args...)	printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#ifdef CONFIG_PCI
+
+#ifdef PCI_BIOS_DEBUG
+#define RELOC_16(seg, off) *(u32*)(seg << 4 | (u32)&off) 
+extern u32 num_pci_bios_present;
+extern u32 num_pci_bios_find_device;
+extern u32 num_pci_bios_find_class;
+extern u32 num_pci_bios_generate_special_cycle;
+extern u32 num_pci_bios_read_cfg_byte;
+extern u32 num_pci_bios_read_cfg_word;
+extern u32 num_pci_bios_read_cfg_dword;
+extern u32 num_pci_bios_write_cfg_byte;
+extern u32 num_pci_bios_write_cfg_word;
+extern u32 num_pci_bios_write_cfg_dword;
+extern u32 num_pci_bios_get_irq_routing;
+extern u32 num_pci_bios_set_irq;
+extern u32 num_pci_bios_unknown_function;
+
+void print_bios_bios_stat(void)
+{
+	printf("16 bit functions:\n");
+	printf("pci_bios_present:                %d\n", RELOC_16(0xf000, num_pci_bios_present));
+	printf("pci_bios_find_device:            %d\n", RELOC_16(0xf000, num_pci_bios_find_device));
+	printf("pci_bios_find_class:             %d\n", RELOC_16(0xf000, num_pci_bios_find_class));
+	printf("pci_bios_generate_special_cycle: %d\n", RELOC_16(0xf000, num_pci_bios_generate_special_cycle));	
+	printf("pci_bios_read_cfg_byte:          %d\n", RELOC_16(0xf000, num_pci_bios_read_cfg_byte));
+	printf("pci_bios_read_cfg_word:          %d\n", RELOC_16(0xf000, num_pci_bios_read_cfg_word));
+	printf("pci_bios_read_cfg_dword:         %d\n", RELOC_16(0xf000, num_pci_bios_read_cfg_dword));
+	printf("pci_bios_write_cfg_byte:         %d\n", RELOC_16(0xf000, num_pci_bios_write_cfg_byte));
+	printf("pci_bios_write_cfg_word:         %d\n", RELOC_16(0xf000, num_pci_bios_write_cfg_word));
+	printf("pci_bios_write_cfg_dword:        %d\n", RELOC_16(0xf000, num_pci_bios_write_cfg_dword));
+	printf("pci_bios_get_irq_routing:        %d\n", RELOC_16(0xf000, num_pci_bios_get_irq_routing));
+	printf("pci_bios_set_irq:                %d\n", RELOC_16(0xf000, num_pci_bios_set_irq));
+	printf("pci_bios_unknown_function:       %d\n", RELOC_16(0xf000, num_pci_bios_unknown_function));
+
+}
+#endif
+
+#define PCI_CLASS_VIDEO             3
+#define PCI_CLASS_VIDEO_STD         0
+#define PCI_CLASS_VIDEO_PROG_IF_VGA 0
+
+
+static u32 probe_pci_video(void)
+{
+	pci_dev_t devbusfn;
+	
+	if ((devbusfn = pci_find_class(PCI_CLASS_VIDEO, 
+				       PCI_CLASS_VIDEO_STD, 
+				       PCI_CLASS_VIDEO_PROG_IF_VGA, 0)) != -1) {
+		u32 old;
+		u32 addr;
+		
+		/* PCI video device detected */
+		printf("Found PCI VGA device at %02x.%02x.%x\n", 
+		       PCI_BUS(devbusfn), PCI_DEV(devbusfn), PCI_FUNC(devbusfn));
+		
+		/* Enable I/O decoding as well, PCI viudeo boards
+		 * support I/O accesses, but they provide no
+		 * bar register for this since the ports are fixed.
+		 */
+		pci_write_config_word(devbusfn, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_IO | PCI_COMMAND_MASTER);
+		
+		/* Test the ROM decoder, do the device support a rom? */
+		pci_read_config_dword(devbusfn, PCI_ROM_ADDRESS, &old);		
+		pci_write_config_dword(devbusfn, PCI_ROM_ADDRESS, PCI_ROM_ADDRESS_MASK);
+		pci_read_config_dword(devbusfn, PCI_ROM_ADDRESS, &addr);
+		pci_write_config_dword(devbusfn, PCI_ROM_ADDRESS, old);
+				
+		if (!addr) {
+			printf("PCI VGA have no ROM?\n");
+			return 0;
+		}
+		
+		/* device have a rom */
+		if (pci_shadow_rom(devbusfn, (void*)0xc0000)) { 
+			printf("Shadowing of PCI VGA BIOS failed\n");
+			return 0;
+		}
+		
+		/* Now enable lagacy VGA port access */
+		if (pci_enable_legacy_video_ports(pci_bus_to_hose(PCI_BUS(devbusfn)))) {
+			printf("PCI VGA enable failed\n");
+			return 0;
+		}
+				
+	
+		/* return the pci device info, that we'll need later */
+		return PCI_BUS(devbusfn) << 8 | 
+			PCI_DEV(devbusfn) << 3 | (PCI_FUNC(devbusfn)&7);
+	}
+	
+	return 0;
+}
+
+
+#endif
+
+static int probe_isa_video(void)
+{
+	u32 ptr;
+	char *buf;	
+	
+	if (0 == (ptr = isa_map_rom(0xc0000, 0x8000))) {
+		return -1;
+	}
+	if (NULL == (buf=malloc(0x8000))) {
+		isa_unmap_rom(ptr);
+		return -1;
+	}
+	if (readw(ptr) != 0xaa55) {
+		free(buf);
+		isa_unmap_rom(ptr);
+		return -1;
+	}
+	
+	/* shadow the rom */
+	memcpy(buf, (void*)ptr, 0x8000);
+	isa_unmap_rom(ptr);
+	memcpy((void*)0xc0000, buf, 0x8000);
+	
+	free(buf);
+	
+	return 0;
+}
+
+int video_bios_init(void)
+{
+	struct pt_regs regs;
+
+	/* clear the video bios area in case we warmbooted */
+	memset((void*)0xc0000, 0, 0x8000);	
+	memset(&regs, 0, sizeof(struct pt_regs));
+	
+	if (probe_isa_video()) {
+		/* No ISA board found, try the PCI bus */
+		regs.eax = probe_pci_video();
+	}
+	
+	/* Did we succeed in mapping any video bios */
+	if (readw(0xc0000) == 0xaa55) {
+	        int size;
+		int i;
+		u8 sum;
+		
+		PRINTF("Found video bios signature\n");
+		size = 512*readb(0xc0002);
+		PRINTF("size %d\n", size);
+		sum=0;
+		for (i=0;i<size;i++) {
+			sum += readb(0xc0000 + i);
+		}
+		PRINTF("Checksum is %sOK\n",sum?"NOT ":"");
+		if (sum) {
+			return 1;
+		}
+		
+		/* some video bioses (ATI Mach64) seem to think that
+		 * the original int 10 handler is always at
+		 * 0xf000:0xf065 , place an iret instruction there
+		 */
+		writeb(0xcf, 0xff065);
+		
+		regs.esp = 0x8000;
+		regs.xss = 0x2000;
+		enter_realmode(0xc000, 3, &regs, &regs);
+		PRINTF("INT 0x10 vector after:  %04x:%04x\n",
+		       readw(0x42), readw(0x40)); 
+		PRINTF("BIOS returned %scarry\n", regs.eflags & 1?"":"NOT ");
+#ifdef PCI_BIOS_DEBUG		
+		print_bios_bios_stat();
+#endif		
+		return (regs.eflags & 1);
+		
+	}
+	
+	return 1;
+	
+}
+
+
diff --git a/lib_i386/zimage.c b/lib_i386/zimage.c
index 190d46e..9d33b2d 100644
--- a/lib_i386/zimage.c
+++ b/lib_i386/zimage.c
@@ -220,8 +220,8 @@
 	
 	memset(&regs, 0, sizeof(struct pt_regs));
 	regs.xds = (u32)setup_base >> 4;
-	regs.xss = 0x8e00;
-	regs.esp = 0x200;
+	regs.xss = 0x9000;
+	regs.esp = 0x9000;
 	regs.eflags = 0;
 	enter_realmode(((u32)setup_base+SETUP_START_OFFSET)>>4, 0, &regs, &regs);
 }