diff -Nur linux-2.6.26.orig/arch/mips/Kconfig linux-2.6.26.2f/arch/mips/Kconfig
--- linux-2.6.26.orig/arch/mips/Kconfig	2008-07-14 05:51:29.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/Kconfig	2008-08-28 14:41:41.462406188 +0800
@@ -169,6 +169,7 @@
 	select I8259
 	select ISA
 	select IRQ_CPU
+	select I8253
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -181,6 +182,32 @@
 	  Lemote Fulong mini-PC board based on the Chinese Loongson-2E CPU and
 	  an FPGA northbridge
 
+config LEMOTE_FULONG2F
+	bool "Lemote LOONGSON2F Fulong mini-PC"
+	select ARCH_SPARSEMEM_ENABLE
+	select CEVT_R4K
+	select CSRC_R4K
+	select SYS_HAS_CPU_LOONGSON2
+	select DMA_NONCOHERENT
+	select BOOT_ELF32
+	select BOARD_SCACHE
+	select HAVE_STD_PC_SERIAL_PORT
+	select HW_HAS_PCI
+	select I8259
+	select ISA
+	select IRQ_CPU
+	select I8253
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_64BIT_KERNEL
+	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_SUPPORTS_HIGHMEM
+	select SYS_HAS_EARLY_PRINTK
+	select GENERIC_HARDIRQS_NO__DO_IRQ
+	select GENERIC_ISA_DMA_SUPPORT_BROKEN
+	select CPU_HAS_WB
+	help
+	  Lemote Fulong mini-PC board based on the Chinese Loongson-2F CPU
+
 config MIPS_ATLAS
 	bool "MIPS Atlas board"
 	select BOOT_ELF32
diff -Nur linux-2.6.26.orig/arch/mips/Makefile linux-2.6.26.2f/arch/mips/Makefile
--- linux-2.6.26.orig/arch/mips/Makefile	2008-07-14 05:51:29.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/Makefile	2008-08-28 14:41:21.057763182 +0800
@@ -305,6 +305,13 @@
 cflags-$(CONFIG_LEMOTE_FULONG) += -Iinclude/asm-mips/mach-lemote
 
 #
+# lemote loongson2f fulong mini-PC board
+#
+core-$(CONFIG_LEMOTE_FULONG2F) +=arch/mips/lemote/lm2f/
+load-$(CONFIG_LEMOTE_FULONG2F) +=0xffffffff80200000
+cflags-$(CONFIG_LEMOTE_FULONG2F) += -Iinclude/asm-mips/mach-lemote
+
+#
 # For all MIPS, Inc. eval boards
 #
 core-$(CONFIG_MIPS_BOARDS_GEN)	+= arch/mips/mips-boards/generic/
diff -Nur linux-2.6.26.orig/arch/mips/kernel/8250-platform.c linux-2.6.26.2f/arch/mips/kernel/8250-platform.c
--- linux-2.6.26.orig/arch/mips/kernel/8250-platform.c	2008-07-14 05:51:29.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/kernel/8250-platform.c	2008-08-29 13:02:58.759058058 +0800
@@ -20,10 +20,24 @@
 }
 
 static struct plat_serial8250_port uart8250_data[] = {
+#ifdef CONFIG_LEMOTE_FULONG2F
+#if 1 //for fl
+	PORT(0x2F8, 3),
+#else
+	{.membase = (void*)(0xffffffffbff003f8),
+	.irq = 19,
+	.uartclk = 3686400,
+	.iotype = UPIO_MEM,
+	.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST ,
+	.regshift = 0,
+	},
+#endif
+#else
 	PORT(0x3F8, 4),
 	PORT(0x2F8, 3),
 	PORT(0x3E8, 4),
 	PORT(0x2E8, 3),
+#endif
 	{ },
 };
 
diff -Nur linux-2.6.26.orig/arch/mips/kernel/Makefile linux-2.6.26.2f/arch/mips/kernel/Makefile
--- linux-2.6.26.orig/arch/mips/kernel/Makefile	2008-07-14 05:51:29.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/kernel/Makefile	2008-08-28 14:41:34.157716973 +0800
@@ -6,7 +6,7 @@
 
 obj-y		+= cpu-probe.o branch.o entry.o genex.o irq.o process.o \
 		   ptrace.o reset.o setup.o signal.o syscall.o \
-		   time.o topology.o traps.o unaligned.o
+		   time.o topology.o traps.o unaligned.o rtc.o
 
 obj-$(CONFIG_CEVT_BCM1480)	+= cevt-bcm1480.o
 obj-$(CONFIG_CEVT_R4K)		+= cevt-r4k.o
diff -Nur linux-2.6.26.orig/arch/mips/kernel/i8259.c linux-2.6.26.2f/arch/mips/kernel/i8259.c
--- linux-2.6.26.orig/arch/mips/kernel/i8259.c	2008-07-14 05:51:29.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/kernel/i8259.c	2008-08-28 14:41:35.037061832 +0800
@@ -53,7 +53,7 @@
 /*
  * This contains the irq mask for both 8259A irq controllers,
  */
-static unsigned int cached_irq_mask = 0xffff;
+unsigned int cached_irq_mask = 0xffff;
 
 #define cached_master_mask	(cached_irq_mask)
 #define cached_slave_mask	(cached_irq_mask >> 8)
@@ -175,11 +175,15 @@
 	if (irq & 8) {
 		inb(PIC_SLAVE_IMR);	/* DUMMY - (do we need this?) */
 		outb(cached_slave_mask, PIC_SLAVE_IMR);
+		inb(PIC_SLAVE_IMR);	
 		outb(0x60+(irq&7), PIC_SLAVE_CMD);/* 'Specific EOI' to slave */
+		inb(PIC_SLAVE_CMD);
 		outb(0x60+PIC_CASCADE_IR, PIC_MASTER_CMD); /* 'Specific EOI' to master-IRQ2 */
+		inb(PIC_MASTER_CMD);
 	} else {
 		inb(PIC_MASTER_IMR);	/* DUMMY - (do we need this?) */
 		outb(cached_master_mask, PIC_MASTER_IMR);
+		inb(PIC_MASTER_IMR);
 		outb(0x60+irq, PIC_MASTER_CMD);	/* 'Specific EOI to master */
 	}
 	smtc_im_ack_irq(irq);
@@ -203,8 +207,8 @@
 		 * At this point we can be sure the IRQ is spurious,
 		 * lets ACK and report it. [once per IRQ]
 		 */
-		if (!(spurious_irq_mask & irqmask)) {
-			printk(KERN_DEBUG "spurious 8259A interrupt: IRQ%d.\n", irq);
+		if (!(spurious_irq_mask & irqmask) || 1) {
+			printk("spurious 8259A interrupt: IRQ%d.\n", irq);
 			spurious_irq_mask |= irqmask;
 		}
 		atomic_inc(&irq_err_count);
diff -Nur linux-2.6.26.orig/arch/mips/kernel/rtc.c linux-2.6.26.2f/arch/mips/kernel/rtc.c
--- linux-2.6.26.orig/arch/mips/kernel/rtc.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/kernel/rtc.c	2008-08-28 14:41:36.673704517 +0800
@@ -0,0 +1,232 @@
+/*
+ * RTC related functions
+ */
+#include <linux/acpi.h>
+#include <linux/bcd.h>
+#include <linux/mc146818rtc.h>
+#include <linux/platform_device.h>
+#include <linux/pnp.h>
+
+#include <asm/time.h>
+
+#ifdef CONFIG_X86_32
+/*
+ * This is a special lock that is owned by the CPU and holds the index
+ * register we are working with.  It is required for NMI access to the
+ * CMOS/RTC registers.  See include/asm-i386/mc146818rtc.h for details.
+ */
+volatile unsigned long cmos_lock = 0;
+EXPORT_SYMBOL(cmos_lock);
+#endif
+
+/* For two digit years assume time is always after that */
+#define CMOS_YEARS_OFFS 2000
+
+#if 0
+DEFINE_SPINLOCK(rtc_lock);
+EXPORT_SYMBOL(rtc_lock);
+#else
+extern spinlock_t rtc_lock;
+#endif
+
+/*
+ * In order to set the CMOS clock precisely, set_rtc_mmss has to be
+ * called 500 ms after the second nowtime has started, because when
+ * nowtime is written into the registers of the CMOS clock, it will
+ * jump to the next second precisely 500 ms later. Check the Motorola
+ * MC146818A or Dallas DS12887 data sheet for details.
+ *
+ * BUG: This routine does not handle hour overflow properly; it just
+ *      sets the minutes. Usually you'll only notice that after reboot!
+ */
+int mach_set_rtc_mmss(unsigned long nowtime)
+{
+	int retval = 0;
+	int real_seconds, real_minutes, cmos_minutes;
+	unsigned char save_control, save_freq_select;
+
+	 /* tell the clock it's being set */
+	save_control = CMOS_READ(RTC_CONTROL);
+	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
+
+	/* stop and reset prescaler */
+	save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
+	CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+
+	cmos_minutes = CMOS_READ(RTC_MINUTES);
+	if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
+		BCD_TO_BIN(cmos_minutes);
+
+	/*
+	 * since we're only adjusting minutes and seconds,
+	 * don't interfere with hour overflow. This avoids
+	 * messing with unknown time zones but requires your
+	 * RTC not to be off by more than 15 minutes
+	 */
+	real_seconds = nowtime % 60;
+	real_minutes = nowtime / 60;
+	/* correct for half hour time zone */
+	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
+		real_minutes += 30;
+	real_minutes %= 60;
+
+	if (abs(real_minutes - cmos_minutes) < 30) {
+		if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+			BIN_TO_BCD(real_seconds);
+			BIN_TO_BCD(real_minutes);
+		}
+		CMOS_WRITE(real_seconds,RTC_SECONDS);
+		CMOS_WRITE(real_minutes,RTC_MINUTES);
+	} else {
+		printk(KERN_WARNING
+		       "set_rtc_mmss: can't update from %d to %d\n",
+		       cmos_minutes, real_minutes);
+		retval = -1;
+	}
+
+	/* The following flags have to be released exactly in this order,
+	 * otherwise the DS12887 (popular MC146818A clone with integrated
+	 * battery and quartz) will not reset the oscillator and will not
+	 * update precisely 500 ms later. You won't find this mentioned in
+	 * the Dallas Semiconductor data sheets, but who believes data
+	 * sheets anyway ...                           -- Markus Kuhn
+	 */
+	CMOS_WRITE(save_control, RTC_CONTROL);
+	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+
+	return retval;
+}
+
+unsigned long mach_get_cmos_time(void)
+{
+	unsigned int status, year, mon, day, hour, min, sec, century = 0;
+
+	/*
+	 * If UIP is clear, then we have >= 244 microseconds before
+	 * RTC registers will be updated.  Spec sheet says that this
+	 * is the reliable way to read RTC - registers. If UIP is set
+	 * then the register access might be invalid.
+	 */
+	while ((CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
+		cpu_relax();
+
+	sec = CMOS_READ(RTC_SECONDS);
+	min = CMOS_READ(RTC_MINUTES);
+	hour = CMOS_READ(RTC_HOURS);
+	day = CMOS_READ(RTC_DAY_OF_MONTH);
+	mon = CMOS_READ(RTC_MONTH);
+	year = CMOS_READ(RTC_YEAR);
+
+#ifdef CONFIG_ACPI
+	if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
+	    acpi_gbl_FADT.century)
+		century = CMOS_READ(acpi_gbl_FADT.century);
+#endif
+
+	status = CMOS_READ(RTC_CONTROL);
+	WARN_ON_ONCE(RTC_ALWAYS_BCD && (status & RTC_DM_BINARY));
+
+	if (RTC_ALWAYS_BCD || !(status & RTC_DM_BINARY)) {
+		BCD_TO_BIN(sec);
+		BCD_TO_BIN(min);
+		BCD_TO_BIN(hour);
+		BCD_TO_BIN(day);
+		BCD_TO_BIN(mon);
+		BCD_TO_BIN(year);
+	}
+
+	if (century) {
+		BCD_TO_BIN(century);
+		year += century * 100;
+		printk(KERN_INFO "Extended CMOS year: %d\n", century * 100);
+	} else
+		year += CMOS_YEARS_OFFS;
+
+	return mktime(year, mon, day, hour, min, sec);
+}
+
+/* Routines for accessing the CMOS RAM/RTC. */
+unsigned char rtc_cmos_read(unsigned char addr)
+{
+	unsigned char val;
+
+	lock_cmos_prefix(addr);
+	outb(addr, RTC_PORT(0));
+	val = inb(RTC_PORT(1));
+	lock_cmos_suffix(addr);
+	return val;
+}
+EXPORT_SYMBOL(rtc_cmos_read);
+
+void rtc_cmos_write(unsigned char val, unsigned char addr)
+{
+	lock_cmos_prefix(addr);
+	outb(addr, RTC_PORT(0));
+	outb(val, RTC_PORT(1));
+	lock_cmos_suffix(addr);
+}
+EXPORT_SYMBOL(rtc_cmos_write);
+
+static int set_rtc_mmss(unsigned long nowtime)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&rtc_lock, flags);
+	retval = set_wallclock(nowtime);
+	spin_unlock_irqrestore(&rtc_lock, flags);
+
+	return retval;
+}
+
+/* not static: needed by APM */
+#if 0
+unsigned long read_persistent_clock(void)
+{
+	unsigned long retval, flags;
+
+	spin_lock_irqsave(&rtc_lock, flags);
+	retval = get_wallclock();
+	spin_unlock_irqrestore(&rtc_lock, flags);
+
+	return retval;
+}
+#endif
+
+int update_persistent_clock(struct timespec now)
+{
+	return set_rtc_mmss(now.tv_sec);
+}
+
+
+static struct resource rtc_resources[] = {
+	[0] = {
+		.start	= RTC_PORT(0),
+		.end	= RTC_PORT(1),
+		.flags	= IORESOURCE_IO,
+	},
+	[1] = {
+		.start	= RTC_IRQ,
+		.end	= RTC_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device rtc_device = {
+	.name		= "rtc_cmos",
+	.id		= -1,
+	.resource	= rtc_resources,
+	.num_resources	= ARRAY_SIZE(rtc_resources),
+};
+
+static __init int add_rtc_cmos(void)
+{
+#ifdef CONFIG_PNP
+	if (!pnp_platform_devices)
+		platform_device_register(&rtc_device);
+#else
+	platform_device_register(&rtc_device);
+#endif /* CONFIG_PNP */
+	return 0;
+}
+device_initcall(add_rtc_cmos);
diff -Nur linux-2.6.26.orig/arch/mips/kernel/time.c linux-2.6.26.2f/arch/mips/kernel/time.c
--- linux-2.6.26.orig/arch/mips/kernel/time.c	2008-07-14 05:51:29.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/kernel/time.c	2008-08-28 14:41:34.485061991 +0800
@@ -44,7 +44,7 @@
 	return rtc_mips_set_time(nowtime);
 }
 
-int update_persistent_clock(struct timespec now)
+int __weak update_persistent_clock(struct timespec now)
 {
 	return rtc_mips_set_mmss(now.tv_sec);
 }
diff -Nur linux-2.6.26.orig/arch/mips/lemote/lm2e/Makefile linux-2.6.26.2f/arch/mips/lemote/lm2e/Makefile
--- linux-2.6.26.orig/arch/mips/lemote/lm2e/Makefile	2008-07-14 05:51:29.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/lemote/lm2e/Makefile	2008-08-28 14:41:20.305062348 +0800
@@ -2,6 +2,6 @@
 # Makefile for Lemote Fulong mini-PC board.
 #
 
-obj-y += setup.o prom.o reset.o irq.o pci.o bonito-irq.o dbg_io.o mem.o
+obj-y += setup.o prom.o reset.o irq.o pci.o bonito-irq.o dbg_io.o mem.o mipsdha.o
 
 EXTRA_CFLAGS += -Werror
diff -Nur linux-2.6.26.orig/arch/mips/lemote/lm2e/mipsdha.c linux-2.6.26.2f/arch/mips/lemote/lm2e/mipsdha.c
--- linux-2.6.26.orig/arch/mips/lemote/lm2e/mipsdha.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/lemote/lm2e/mipsdha.c	2008-08-28 14:41:20.269062168 +0800
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+static ssize_t mipsdha_proc_read(struct file *file, char *buf, size_t len, loff_t *ppos);
+
+static ssize_t mipsdha_proc_write(struct file *file, const char *buf, size_t len, loff_t *ppos);
+
+
+static struct proc_dir_entry *mipsdha_proc_entry;
+
+#define INFO_SIZE 4096
+static char info_buf[INFO_SIZE];
+
+static struct file_operations mipsdha_fops =
+{
+    owner:	THIS_MODULE,
+    read:	mipsdha_proc_read,
+    write:	mipsdha_proc_write,
+};
+
+static enum {CMD_ERR, CMD_GIB, CMD_GPI} cmd;
+
+typedef struct pciinfo_s
+{
+  int		bus,card,func;
+  unsigned short command;
+  unsigned short vendor,device;
+  unsigned	base0,base1,base2,baserom;
+} pciinfo_t;
+
+
+extern struct proc_dir_entry proc_root;
+
+static int __init mipsdha_proc_init(void)
+{
+	mipsdha_proc_entry = create_proc_entry("mipsdha", S_IWUSR | S_IRUGO, &proc_root);
+	if (mipsdha_proc_entry == NULL) {
+		printk("MIPSDHA: register /proc/mipsdha failed!\n");
+		return 0;
+	}
+	
+	mipsdha_proc_entry->owner = THIS_MODULE;
+	mipsdha_proc_entry->proc_fops = &mipsdha_fops;
+
+	cmd=CMD_ERR;
+	return 0;
+}
+
+static ssize_t mipsdha_proc_write (struct file *file, const char *buf, size_t len, loff_t *ppos)
+{
+	char cmd_gib[]="GET IO BASE";
+	char cmd_gpi[]="GET PCI INFO";
+
+	if (len >= INFO_SIZE) return -ENOMEM;
+
+	if (copy_from_user(info_buf, buf, len)) return -EFAULT;
+	info_buf[len] = '\0';
+
+	if (strncmp(info_buf, cmd_gib, sizeof(cmd_gib)-1)==0) {
+		cmd = CMD_GIB;
+		return len;
+	} else if (strncmp(info_buf, cmd_gpi, sizeof(cmd_gpi)-1)==0) {
+		cmd = CMD_GPI;
+		return len;
+	} else {
+		return -EINVAL;
+	}
+}
+
+static ssize_t mipsdha_proc_read (struct file *file, char *buf, size_t len, loff_t *ppos)
+{
+	int info_cnt;
+	pciinfo_t *pciinfo;
+	struct pci_dev *dev = NULL;
+
+	switch (cmd) {
+		default:
+			printk("MIPSDHA: BUG found in function %s!(cmd=%d)\n", 
+					__FUNCTION__, cmd);
+			return -EINVAL;
+
+
+		case CMD_ERR:
+			return -EINVAL;
+
+
+		case CMD_GIB:
+			*(unsigned long *)info_buf = 
+				virt_to_phys((void *) mips_io_port_base);
+			info_cnt=sizeof(unsigned long);
+			break;
+
+
+		case CMD_GPI:
+			pciinfo = (pciinfo_t *) info_buf;
+			info_cnt = 0;
+			for_each_pci_dev(dev) {
+
+				if (info_cnt+sizeof(pciinfo_t)>INFO_SIZE) return -ENOMEM;
+
+				pciinfo->bus = dev->bus->number;
+				pciinfo->card = PCI_SLOT(dev->devfn);
+				pciinfo->func = PCI_FUNC(dev->devfn);
+
+				if (pci_read_config_word(dev, PCI_COMMAND, &pciinfo->command)
+						!= PCIBIOS_SUCCESSFUL) {
+					printk("MIPSDHA: BUG found in function %s!\n", 
+							__FUNCTION__);
+					pciinfo->command=0;
+				}
+
+				pciinfo->vendor = dev->vendor;
+				pciinfo->device = dev->device;
+
+				pciinfo->base0 = (dev->resource[0]).start;
+				pciinfo->base1 = (dev->resource[1]).start;
+				pciinfo->base2 = (dev->resource[2]).start;
+				pciinfo->baserom = (dev->resource[PCI_ROM_RESOURCE]).start;
+
+				pciinfo++;
+				info_cnt += sizeof(pciinfo_t);
+			}
+			break;
+	}
+
+	if (len < info_cnt) return -ENOMEM;
+	if (copy_to_user(buf, info_buf, info_cnt)) return -EFAULT;
+
+	return info_cnt;
+}
+
+__initcall(mipsdha_proc_init);
diff -Nur linux-2.6.26.orig/arch/mips/lemote/lm2f/Makefile linux-2.6.26.2f/arch/mips/lemote/lm2f/Makefile
--- linux-2.6.26.orig/arch/mips/lemote/lm2f/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/lemote/lm2f/Makefile	2008-08-28 14:41:19.701061867 +0800
@@ -0,0 +1,7 @@
+#
+# Makefile for ICT CAS godsonev2e board.
+#
+
+obj-y	+= setup.o prom.o reset.o irq.o pci.o bonito-irq.o mipsdha.o dbg_io.o mem.o cs5536_vsm.o mipsdha.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff -Nur linux-2.6.26.orig/arch/mips/lemote/lm2f/bonito-irq.c linux-2.6.26.2f/arch/mips/lemote/lm2f/bonito-irq.c
--- linux-2.6.26.orig/arch/mips/lemote/lm2f/bonito-irq.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/lemote/lm2f/bonito-irq.c	2008-08-28 14:41:19.905061667 +0800
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/io.h>
+
+#include <asm/mips-boards/bonito64.h>
+
+#define	bonito_irq_shutdown	bonito_irq_disable
+
+
+static inline void bonito_irq_enable(unsigned int irq)
+{
+	BONITO_INTENSET = (1 << (irq - BONITO_IRQ_BASE));
+	(void)BONITO_INTENSET;
+	mmiowb();
+}
+
+static unsigned int bonito_irq_startup(unsigned int irq) 
+{
+	bonito_irq_enable(irq);
+	return 0;
+}
+
+static inline void bonito_irq_ack(unsigned int irq) 
+{
+	BONITO_INTENCLR = (1 << (irq - BONITO_IRQ_BASE));
+	(void)BONITO_INTENCLR;
+	mmiowb();
+}
+
+static inline void bonito_irq_end(unsigned int irq) 
+{
+	BONITO_INTENSET = (1 << (irq - BONITO_IRQ_BASE ));
+	mmiowb();
+}
+
+static inline void bonito_irq_disable(unsigned int irq)
+{
+	BONITO_INTENCLR = (1 << (irq - BONITO_IRQ_BASE));
+	(void)BONITO_INTENCLR; 
+	mmiowb();
+}
+
+static struct irq_chip bonito_irq_type = {
+	.name	= "bonito_irq",
+	.startup = bonito_irq_startup,
+	.shutdown = bonito_irq_shutdown,
+	.enable = bonito_irq_enable,
+	.disable = bonito_irq_disable,
+	.ack	= bonito_irq_ack,
+	.end    = bonito_irq_end,
+	.mask	= bonito_irq_disable,
+	.mask_ack = bonito_irq_disable,
+	.unmask	= bonito_irq_enable,
+};
+
+/* There is no need to handle the DMA IO problem on godson2f any more. */
+/*
+static struct irqaction dma_timeout_irqaction = {
+	.handler	= no_action,
+	.name		= "dma_timeout",
+};
+*/
+
+void bonito_irq_init(void)
+{
+	u32 i;
+
+	for (i = BONITO_IRQ_BASE; i < BONITO_IRQ_BASE + 32; i++) {
+		set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq);
+	}
+
+	/* setup_irq(BONITO_IRQ_BASE + 10, &dma_timeout_irqaction); */
+}
diff -Nur linux-2.6.26.orig/arch/mips/lemote/lm2f/cs5536.h linux-2.6.26.2f/arch/mips/lemote/lm2f/cs5536.h
--- linux-2.6.26.orig/arch/mips/lemote/lm2f/cs5536.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/lemote/lm2f/cs5536.h	2008-08-28 14:41:19.377080671 +0800
@@ -0,0 +1,578 @@
+/*
+ * cs5536.h
+ * 
+ * The include file of cs5536 sourthbridge define which is used in the pmon only.
+ * you can modify it or change it, please set the modify time and steps.
+ *
+ * Author : jlliu <liujl@lemote.com>
+ * Data : 07-6-27
+ */
+
+#ifndef	_CS5536_H
+#define	_CS5536_H
+
+/*************************************************************************/
+
+/*
+ * basic define
+ */
+#define	PCI_IO_BASE		0x1fd00000	//( < 0x1fe00000)
+#define	PCI_IO_BASE_VA		0xbfd00000
+#define	PCI_MEM_BASE		0x10000000	//( < 0x1c000000 )
+#define	PCI_MEM_BASE_VA		0xb0000000
+
+/*
+ * MSR module base
+ */ 
+#define	CS5536_SB_MSR_BASE		(0x00000000)
+#define	CS5536_GLIU_MSR_BASE		(0x10000000)
+#define	CS5536_ILLEGAL_MSR_BASE		(0x20000000)
+#define	CS5536_USB_MSR_BASE		(0x40000000)
+#define	CS5536_IDE_MSR_BASE		(0x60000000)
+#define	CS5536_DIVIL_MSR_BASE		(0x80000000)
+#define	CS5536_ACC_MSR_BASE		(0xa0000000)
+#define	CS5536_UNUSED_MSR_BASE		(0xc0000000)
+#define	CS5536_GLCP_MSR_BASE		(0xe0000000)
+
+#define	SB_MSR_REG(offset)	(CS5536_SB_MSR_BASE	| offset)
+#define	GLIU_MSR_REG(offset)	(CS5536_GLIU_MSR_BASE	| offset)
+#define	ILLEGAL_MSR_REG(offset)	(CS5536_ILLEGAL_MSR_BASE| offset)
+#define	USB_MSR_REG(offset)	(CS5536_USB_MSR_BASE	| offset)
+#define	IDE_MSR_REG(offset)	(CS5536_IDE_MSR_BASE	| offset)
+#define	DIVIL_MSR_REG(offset)	(CS5536_DIVIL_MSR_BASE	| offset)
+#define	ACC_MSR_REG(offset)	(CS5536_ACC_MSR_BASE	| offset)
+#define	UNUSED_MSR_REG(offset)	(CS5536_UNUSED_MSR_BASE	| offset)
+#define	GLCP_MSR_REG(offset)	(CS5536_GLCP_MSR_BASE	| offset)
+
+/*
+ * BAR SPACE OF VIRTUAL PCI : range for pci probe use, length is the actual size. 
+ */
+// IO space for all DIVIL modules
+#define	CS5536_IRQ_RANGE		0xffffffe0	// USERD FOR PCI PROBE
+#define	CS5536_IRQ_LENGTH		0x20		// THE REGS ACTUAL LENGTH
+#define	CS5536_SMB_RANGE		0xfffffff8
+#define	CS5536_SMB_LENGTH		0x08
+#define	CS5536_GPIO_RANGE		0xffffff00
+#define	CS5536_GPIO_LENGTH		0x100
+#define	CS5536_MFGPT_RANGE		0xffffffc0
+#define	CS5536_MFGPT_LENGTH		0x40
+#define	CS5536_ACPI_RANGE		0xffffffe0
+#define	CS5536_ACPI_LENGTH		0x20
+#define	CS5536_PMS_RANGE		0xffffff80
+#define	CS5536_PMS_LENGTH		0x80
+// MEM space for 4KB nand flash; IO space for 16B nor flash.
+#ifdef	CS5536_USE_NOR_FLASH
+#define	CS5536_FLSH0_RANGE	0xfffffff0
+#define	CS5536_FLSH0_LENGTH	0x10
+#define	CS5536_FLSH1_RANGE	0xfffffff0
+#define	CS5536_FLSH1_LENGTH	0x10
+#define	CS5536_FLSH2_RANGE	0xfffffff0
+#define	CS5536_FLSH2_LENGTH	0x10
+#define	CS5536_FLSH3_RANGE	0xfffffff0
+#define	CS5536_FLSH3_LENGTH	0x10
+#else
+#define	CS5536_FLSH0_RANGE	0xfffff000
+#define	CS5536_FLSH0_LENGTH	0x1000
+#define	CS5536_FLSH1_RANGE	0xfffff000
+#define	CS5536_FLSH1_LENGTH	0x1000
+#define	CS5536_FLSH2_RANGE	0xfffff000
+#define	CS5536_FLSH2_LENGTH	0x1000
+#define	CS5536_FLSH3_RANGE	0xfffff000
+#define	CS5536_FLSH3_LENGTH	0x1000
+#endif
+// IO space for IDE
+#define	CS5536_IDE_RANGE	0xfffffff0
+#define	CS5536_IDE_LENGTH	0x10
+// IO space for ACC
+#define	CS5536_ACC_RANGE	0xffffff80
+#define	CS5536_ACC_LENGTH	0x80
+// MEM space for ALL USB modules
+//#define	CS5536_OHCI_RANGE	0xfffffff0
+#define	CS5536_OHCI_RANGE	0xfffff000
+#define	CS5536_OHCI_LENGTH	0x1000
+//#define	CS5536_EHCI_RANGE	0xfffffff0
+#define	CS5536_EHCI_RANGE	0xfffff000
+#define	CS5536_EHCI_LENGTH	0x1000
+#define	CS5536_UDC_RANGE	0xffffe000
+#define	CS5536_UDC_LENGTH	0x2000
+#define	CS5536_OTG_RANGE	0xfffff000
+#define	CS5536_OTG_LENGTH	0x1000
+
+/*
+ * PCI MSR ACCESS
+ */
+#define	PCI_MSR_CTRL		0xF0
+#define	PCI_MSR_ADDR		0xF4
+#define	PCI_MSR_DATA_LO		0xF8
+#define	PCI_MSR_DATA_HI		0xFC
+
+/******************************* MSR *********************************************/
+
+/*
+ * GLIU STANDARD MSR
+ */
+#define	GLIU_CAP		0x00
+#define	GLIU_CONFIG		0x01
+#define	GLIU_SMI		0x02
+#define	GLIU_ERROR		0x03
+#define	GLIU_PM			0x04
+#define	GLIU_DIAG		0x05
+
+/*
+ * GLIU SPEC. MSR
+ */
+#define	GLIU_P2D_BM0		0x20 
+#define	GLIU_P2D_BM1		0x21 
+#define	GLIU_P2D_BM2		0x22 
+#define	GLIU_P2D_BMK0		0x23
+#define	GLIU_P2D_BMK1		0x24
+#define	GLIU_P2D_BM3		0x25 
+#define	GLIU_P2D_BM4		0x26 
+#define	GLIU_COH		0x80
+#define	GLIU_PAE		0x81	
+#define	GLIU_ARB		0x82
+#define	GLIU_ASMI		0x83
+#define	GLIU_AERR		0x84
+#define	GLIU_DEBUG		0x85
+#define	GLIU_PHY_CAP		0x86
+#define	GLIU_NOUT_RESP		0x87
+#define	GLIU_NOUT_WDATA		0x88
+#define	GLIU_WHOAMI		0x8B
+#define	GLIU_SLV_DIS		0x8C
+#define	GLIU_IOD_BM0		0xE0
+#define	GLIU_IOD_BM1		0xE1
+#define	GLIU_IOD_BM2		0xE2
+#define	GLIU_IOD_BM3		0xE3
+#define	GLIU_IOD_BM4		0xE4
+#define	GLIU_IOD_BM5		0xE5
+#define	GLIU_IOD_BM6		0xE6
+#define	GLIU_IOD_BM7		0xE7
+#define	GLIU_IOD_BM8		0xE8
+#define	GLIU_IOD_BM9		0xE9
+#define	GLIU_IOD_SC0		0xEA
+#define	GLIU_IOD_SC1		0xEB
+#define	GLIU_IOD_SC2		0xEC
+#define	GLIU_IOD_SC3		0xED
+#define	GLIU_IOD_SC4		0xEE
+#define	GLIU_IOD_SC5		0xEF
+#define	GLIU_IOD_SC6		0xF0
+#define	GLIU_IOD_SC7		0xF1
+
+/*
+ * SB STANDARD
+ */
+#define	SB_CAP		0x00
+#define	SB_CONFIG	0x01
+#define	SB_SMI		0x02
+#define	SB_ERROR	0x03
+#define	SB_MAR_ERR_EN		0x00000001
+#define	SB_TAR_ERR_EN		0x00000002
+#define	SB_RSVD_BIT1		0x00000004
+#define	SB_EXCEP_ERR_EN		0x00000008
+#define	SB_SYSE_ERR_EN		0x00000010
+#define	SB_PARE_ERR_EN		0x00000020
+#define	SB_TAS_ERR_EN		0x00000040
+#define	SB_MAR_ERR_FLAG		0x00010000
+#define	SB_TAR_ERR_FLAG		0x00020000
+#define	SB_RSVD_BIT2		0x00040000
+#define	SB_EXCEP_ERR_FLAG	0x00080000
+#define	SB_SYSE_ERR_FLAG	0x00100000
+#define	SB_PARE_ERR_FLAG	0x00200000
+#define	SB_TAS_ERR_FLAG		0x00400000
+#define	SB_PM		0x04
+#define	SB_DIAG		0x05
+
+/*
+ * SB SPEC.
+ */
+#define	SB_CTRL		0x10
+#define	SB_R0		0x20
+#define	SB_R1		0x21
+#define	SB_R2		0x22
+#define	SB_R3		0x23
+#define	SB_R4		0x24
+#define	SB_R5		0x25
+#define	SB_R6		0x26
+#define	SB_R7		0x27
+#define	SB_R8		0x28
+#define	SB_R9		0x29
+#define	SB_R10		0x2A
+#define	SB_R11		0x2B
+#define	SB_R12		0x2C
+#define	SB_R13		0x2D
+#define	SB_R14		0x2E
+#define	SB_R15		0x2F
+
+/*
+ * GLCP STANDARD
+ */
+#define	GLCP_CAP		0x00
+#define	GLCP_CONFIG		0x01
+#define	GLCP_SMI		0x02
+#define	GLCP_ERROR		0x03
+#define	GLCP_PM			0x04
+#define	GLCP_DIAG		0x05
+
+/*
+ * GLCP SPEC. 
+ */
+#define	GLCP_CLK_DIS_DELAY	0x08
+#define	GLCP_PM_CLK_DISABLE	0x09
+#define	GLCP_GLB_PM		0x0B
+#define	GLCP_DBG_OUT		0x0C
+#define	GLCP_RSVD1		0x0D
+#define	GLCP_SOFT_COM		0x0E
+#define	SOFT_BAR_SMB_FLAG		0x00000001
+#define	SOFT_BAR_GPIO_FLAG		0x00000002
+#define	SOFT_BAR_MFGPT_FLAG		0x00000004
+#define	SOFT_BAR_IRQ_FLAG		0x00000008
+#define	SOFT_BAR_PMS_FLAG		0x00000010
+#define	SOFT_BAR_ACPI_FLAG		0x00000020
+#define	SOFT_BAR_FLSH0_FLAG		0x00000040
+#define	SOFT_BAR_FLSH1_FLAG		0x00000080
+#define	SOFT_BAR_FLSH2_FLAG		0x00000100
+#define	SOFT_BAR_FLSH3_FLAG		0x00000200
+#define	SOFT_BAR_IDE_FLAG		0x00000400
+#define	SOFT_BAR_ACC_FLAG		0x00000800
+#define	SOFT_BAR_OHCI_FLAG		0x00001000
+#define	SOFT_BAR_EHCI_FLAG		0x00002000
+#define	SOFT_BAR_UDC_FLAG		0x00004000
+#define	SOFT_BAR_OTG_FLAG		0x00008000
+#define	GLCP_RSVD2		0x0F
+#define	GLCP_CLK_OFF		0x10
+#define	GLCP_CLK_ACTIVE		0x11
+#define	GLCP_CLK_DISABLE	0x12
+#define	GLCP_CLK4ACK		0x13
+#define	GLCP_SYS_RST		0x14
+#define	GLCP_RSVD3		0x15
+#define	GLCP_DBG_CLK_CTRL	0x16
+#define	GLCP_CHIP_REV_ID	0x17
+
+/*
+ * DIVIL STANDARD
+ */
+#define	DIVIL_CAP		0x00
+#define	DIVIL_CONFIG		0x01
+#define	DIVIL_SMI		0x02
+#define	DIVIL_ERROR		0x03
+#define	DIVIL_PM		0x04
+#define	DIVIL_DIAG		0x05
+
+/*
+ * DIVIL SPEC. 
+ */
+#define	DIVIL_LBAR_IRQ		0x08
+#define	DIVIL_LBAR_KEL		0x09
+#define	DIVIL_LBAR_SMB		0x0B
+#define	DIVIL_LBAR_GPIO		0x0C
+#define	DIVIL_LBAR_MFGPT	0x0D
+#define	DIVIL_LBAR_ACPI		0x0E
+#define	DIVIL_LBAR_PMS		0x0F
+#define	DIVIL_LBAR_FLSH0	0x10
+#define	DIVIL_LBAR_FLSH1	0x11
+#define	DIVIL_LBAR_FLSH2	0x12
+#define	DIVIL_LBAR_FLSH3	0x13
+#define	DIVIL_LEG_IO		0x14
+#define	DIVIL_BALL_OPTS		0x15
+#define	DIVIL_SOFT_IRQ		0x16
+#define	DIVIL_SOFT_RESET	0x17
+// NOR FLASH
+#define	NORF_CTRL		0x18
+#define	NORF_T01		0x19
+#define	NORF_T23		0x1A
+// NAND FLASH
+#define	NANDF_DATA		0x1B
+#define	NANDF_CTRL		0x1C
+#define	NANDF_RSVD		0x1D
+// KEL Keyboard Emulation Logic
+#define	KEL_CTRL		0x1F
+// PIC
+#define	PIC_YSEL_LOW		0x20
+#define	PIC_YSEL_LOW_USB_SHIFT		8
+#define	PIC_YSEL_LOW_ACC_SHIFT		16
+#define	PIC_YSEL_LOW_FLASH_SHIFT	24
+#define	PIC_YSEL_HIGH		0x21
+#define	PIC_ZSEL_LOW		0x22
+#define	PIC_ZSEL_HIGH		0x23
+#define	PIC_IRQM_PRIM		0x24
+#define	PIC_IRQM_LPC		0x25
+#define	PIC_XIRR_STS_LOW	0x26
+#define	PIC_XIRR_STS_HIGH	0x27
+#define	PCI_SHDW		0x34
+// MFGPT
+#define	MFGPT_IRQ		0x28
+#define	MFGPT_NR		0x29
+#define	MFGPT_RSVD		0x2A
+#define	MFGPT_SETUP		0x2B
+// FLOPPY
+#define	FLPY_3F2_SHDW		0x30
+#define	FLPY_3F7_SHDW		0x31
+#define	FLPY_372_SHDW		0x32
+#define	FLPY_377_SHDW		0x33
+// PIT
+#define	PIT_SHDW		0x36
+#define	PIT_CNTRL		0x37
+// UART
+#define	UART1_MOD		0x38
+#define	UART1_DONG		0x39
+#define	UART1_CONF		0x3A
+#define	UART1_RSVD		0x3B
+#define	UART2_MOD		0x3C
+#define	UART2_DONG		0x3D
+#define	UART2_CONF		0x3E
+#define	UART2_RSVD		0x3F
+// DMA
+#define	DIVIL_AC_DMA		0x1E
+#define	DMA_MAP			0x40
+#define	DMA_SHDW_CH0		0x41
+#define	DMA_SHDW_CH1		0x42
+#define	DMA_SHDW_CH2		0x43
+#define	DMA_SHDW_CH3		0x44
+#define	DMA_SHDW_CH4		0x45
+#define	DMA_SHDW_CH5		0x46
+#define	DMA_SHDW_CH6		0x47
+#define	DMA_SHDW_CH7		0x48
+#define	DMA_MSK_SHDW		0x49
+// LPC
+#define	LPC_EADDR		0x4C
+#define	LPC_ESTAT		0x4D
+#define	LPC_SIRQ		0x4E
+#define	LPC_RSVD		0x4F
+// PMC
+#define	PMC_LTMR		0x50
+#define	PMC_RSVD		0x51
+// RTC
+#define	RTC_RAM_LOCK		0x54
+#define	RTC_DOMA_OFFSET		0x55
+#define	RTC_MONA_OFFSET		0x56
+#define	RTC_CEN_OFFSET		0x57
+
+/*
+ * IDE STANDARD 
+ */
+#define	IDE_CAP		0x00
+#define	IDE_CONFIG	0x01
+#define	IDE_SMI		0x02
+#define	IDE_ERROR	0x03
+#define	IDE_PM		0x04
+#define	IDE_DIAG	0x05
+
+/*
+ * IDE SPEC. 
+ */
+#define	IDE_IO_BAR	0x08
+#define	IDE_CFG		0x10
+#define	IDE_DTC		0x12
+#define	IDE_CAST	0x13
+#define	IDE_ETC		0x14
+#define	IDE_INTERNAL_PM	0x15
+
+/*
+ * ACC STANDARD
+ */
+#define	ACC_CAP		0x00
+#define	ACC_CONFIG	0x01
+#define	ACC_SMI		0x02
+#define	ACC_ERROR	0x03
+#define	ACC_PM		0x04
+#define	ACC_DIAG	0x05
+
+/*
+ * USB STANDARD
+ */
+#define	USB_CAP		0x00
+#define	USB_CONFIG	0x01
+#define	USB_SMI		0x02
+#define	USB_ERROR	0x03
+#define	USB_PM		0x04
+#define	USB_DIAG	0x05
+
+/*
+ * USB SPEC.
+ */
+#define	USB_OHCI	0x08
+#define	USB_EHCI	0x09
+#define	USB_UDC		0x0A
+#define	USB_OTG		0x0B
+
+/********************************** NATIVE ****************************************/
+// IDE NATIVE registers
+#define	IDE_BM_CMD	0x00
+#define	IDE_BM_STS	0x02
+#define	IDE_BM_PRD	0x04
+
+// OHCI native registers
+#define	OHCI_REVISION		0x00
+#define	OHCI_CONTROL		0x04
+#define	OHCI_COMMAND_STATUS	0x08
+#define	OHCI_INT_STATUS		0x0C
+#define	OHCI_INT_ENABLE		0x10
+#define	OHCI_INT_DISABLE	0x14
+#define	OHCI_HCCA		0x18
+#define	OHCI_PERI_CUR_ED	0x1C
+#define	OHCI_CTRL_HEAD_ED	0x20
+#define	OHCI_CTRL_CUR_ED	0x24
+#define	OHCI_BULK_HEAD_ED	0x28
+#define	OHCI_BULK_CUR_ED	0x2C
+#define	OHCI_DONE_HEAD		0x30
+#define	OHCI_FM_INTERVAL	0x34
+#define	OHCI_FM_REMAINING	0x38
+#define	OHCI_FM_NUMBER		0x3C
+#define	OHCI_PERI_START		0x40
+#define	OHCI_LS_THRESHOLD	0x44
+#define	OHCI_RH_DESCRIPTORA	0x48
+#define	OHCI_RH_DESCRIPTORB	0x4C
+#define	OHCI_RH_STATUS		0x50
+#define	OHCI_RH_PORT_STATUS1	0x54
+#define	OHCI_RH_PORT_STATUS2	0x58
+#define	OHCI_RH_PORT_STATUS3	0x5C
+#define	OHCI_RH_PORT_STATUS4	0x60
+
+// KEL : MEM SPACE; REG :32BITS WIDTH
+#define	KEL_HCE_CTRL	0x100
+#define	KEL_HCE_IN	0x104
+#define	KEL_HCE_OUT	0x108
+#define	KEL_HCE_STS	0x10C
+#define	KEL_PORTA	0x92	//8bits
+// PIC : I/O SPACE; REG : 8BITS
+#define	PIC_ICW1_MASTER	0x20
+#define	PIC_ICW1_SLAVE	0xA0
+#define	PIC_ICW2_MASTER	0x21
+#define	PIC_ICW2_SLAVE	0xA1
+#define	PIC_ICW3_MASTER	0x21
+#define	PIC_ICW3_SLAVE	0xA1
+#define	PIC_ICW4_MASTER	0x21
+#define	PIC_ICW4_SLAVE	0xA1
+#define	PIC_OCW1_MASTER	0x21
+#define	PIC_OCW1_SLAVE	0xA1
+#define	PIC_OCW2_MASTER	0x20
+#define	PIC_OCW2_SLAVE	0xA0
+#define	PIC_OCW3_MASTER	0x20
+#define	PIC_OCW3_SLAVE	0xA0
+#define	PIC_IRR_MASTER	0x20
+#define	PIC_IRR_SLAVE	0xA0
+#define	PIC_ISR_MASTER	0x20
+#define	PIC_ISR_SLAVE	0xA0
+#define	PIC_INT_SEL1	0x4D0
+#define	PIC_INT_SEL2	0x4D1
+// GPIO : I/O SPACE; REG : 32BITS
+#define	GPIOL_OUT_VAL		0x00
+#define	GPIOL_OUT_EN		0x04
+#define	GPIOL_OUT_OD_EN		0x08
+#define	GPIOL_OUT_INVRT_EN	0x0c
+#define	GPIOL_OUT_AUX1_SEL	0x10
+#define	GPIOL_OUT_AUX2_SEL	0x14
+#define	GPIOL_PU_EN		0x18
+#define	GPIOL_PD_EN		0x1c
+#define	GPIOL_IN_EN		0x20
+#define	GPIOL_IN_INVRT_EN	0x24
+#define	GPIOL_IN_FLTR_EN	0x28
+#define	GPIOL_IN_EVNTCNT_EN	0x2c
+#define	GPIOL_IN_READBACK	0x30
+#define	GPIOL_IN_AUX1_SEL	0x34
+#define	GPIOL_EVNT_EN		0x38
+#define	GPIOL_LOCK_EN		0x3c
+#define	GPIOL_IN_POSEDGE_EN	0x40
+#define	GPIOL_IN_NEGEDGE_EN	0x44
+#define	GPIOL_IN_POSEDGE_STS	0x48
+#define	GPIOL_IN_NEGEDGE_STS	0x4c
+#define	GPIOH_OUT_VAL		0x80
+#define	GPIOH_OUT_EN		0x84
+#define	GPIOH_OUT_OD_EN		0x88
+#define	GPIOH_OUT_INVRT_EN	0x8c
+#define	GPIOH_OUT_AUX1_SEL	0x90
+#define	GPIOH_OUT_AUX2_SEL	0x94
+#define	GPIOH_PU_EN		0x98
+#define	GPIOH_PD_EN		0x9c
+#define	GPIOH_IN_EN		0xA0
+#define	GPIOH_IN_INVRT_EN	0xA4
+#define	GPIOH_IN_FLTR_EN	0xA8
+#define	GPIOH_IN_EVNTCNT_EN	0xAc
+#define	GPIOH_IN_READBACK	0xB0
+#define	GPIOH_IN_AUX1_SEL	0xB4
+#define	GPIOH_EVNT_EN		0xB8
+#define	GPIOH_LOCK_EN		0xBc
+#define	GPIOH_IN_POSEDGE_EN	0xC0
+#define	GPIOH_IN_NEGEDGE_EN	0xC4
+#define	GPIOH_IN_POSEDGE_STS	0xC8
+#define	GPIOH_IN_NEGEDGE_STS	0xCC
+// SMB : I/O SPACE, REG : 8BITS WIDTH
+#define	SMB_SDA				0x00
+#define	SMB_STS				0x01
+#define	SMB_STS_SLVSTP		(1 << 7)
+#define	SMB_STS_SDAST		(1 << 6)
+#define	SMB_STS_BER		(1 << 5)
+#define	SMB_STS_NEGACK		(1 << 4)
+#define	SMB_STS_STASTR		(1 << 3)
+#define	SMB_STS_NMATCH		(1 << 2)
+#define	SMB_STS_MASTER		(1 << 1)
+#define	SMB_STS_XMIT		(1 << 0)
+#define	SMB_CTRL_STS			0x02
+#define	SMB_CSTS_TGSTL		(1 << 5)
+#define	SMB_CSTS_TSDA		(1 << 4)
+#define	SMB_CSTS_GCMTCH		(1 << 3)
+#define	SMB_CSTS_MATCH		(1 << 2)
+#define	SMB_CSTS_BB		(1 << 1)
+#define	SMB_CSTS_BUSY		(1 << 0)
+#define	SMB_CTRL1			0x03
+#define	SMB_CTRL1_STASTRE	(1 << 7)
+#define	SMB_CTRL1_NMINTE	(1 << 6)
+#define	SMB_CTRL1_GCMEN		(1 << 5)
+#define	SMB_CTRL1_ACK		(1 << 4)
+#define	SMB_CTRL1_RSVD		(1 << 3)
+#define	SMB_CTRL1_INTEN		(1 << 2)
+#define	SMB_CTRL1_STOP		(1 << 1)
+#define	SMB_CTRL1_START		(1 << 0)
+#define	SMB_ADDR			0x04
+#define	SMB_ADDR_SAEN		(1 << 7)
+#define	SMB_CONTROLLER_ADDR	(0xef << 0)
+#define	SMB_CTRL2			0x05
+#define	SMB_FREQ		(0x20 << 1)	//(0x7f << 1)
+#define	SMB_ENABLE		(0x01 << 0)
+#define	SMB_CTRL3			0x06
+
+/*********************************** LEGACY I/O *******************************/
+
+/*
+ * LEGACY I/O SPACE BASE
+ */
+#define	CS5536_LEGACY_BASE_ADDR		(PCI_IO_BASE_VA | 0x0000)
+
+/*
+ * IDE LEGACY REG : legacy IO address is 0x170~0x177 and 0x376 (0x1f0~0x1f7 and 0x3f6)
+ * all registers are 16bits except the IDE_LEGACY_DATA reg
+ * some registers are read only and the 
+ */
+#define	PRI_IDE_LEGACY_REG(offset) 	(CS5536_LEGACY_BASE_ADDR | 0x1f0 | offset)
+#define	SEC_IDE_LEGACY_REG(offset)	(CS5536_LEGACY_BASE_ADDR | 0x170 | offset)
+
+#define	IDE_LEGACY_DATA		0x00 // RW
+#define	IDE_LEGACY_ERROR	0x01 // RO
+#define	IDE_LEGACY_FEATURE	0x01 // WO
+#define	IDE_LEGACY_SECTOR_COUNT	0x02 // RW
+#define	IDE_LEGACY_SECTOR_NUM	0x03 // RW
+#define	IDE_LEGACY_CYL_LO	0x04 // RW
+#define	IDE_LEGACY_CYL_HI	0x05 // RW
+#define	IDE_LEGACY_HEAD		0x06 // RW
+#define	IDE_LEGACY_HEAD_DRV		(1 << 4)
+#define	IDE_LEGACY_HEAD_LBA		(1 << 6)
+#define	IDE_LEGACY_HEAD_IBM		(1 << 7 | 1 << 5)
+#define	IDE_LEGACY_STATUS	0x07 // RO
+#define IDE_LEGACY_STATUS_ERR		(1 << 0)
+#define	IDE_LEGACY_STATUS_IDX		(1 << 1)
+#define IDE_LEGACY_STATUS_CORR		(1 << 2)
+#define	IDE_LEGACY_STATUS_DRQ		(1 << 3)
+#define	IDE_LEGACY_STATUS_DSC 		(1 << 4)
+#define	IDE_LEGACY_STATUS_DWF		(1 << 5)
+#define	IDE_LEGACY_STATUS_DRDY		(1 << 6)
+#define	IDE_LEGACY_STATUS_BUSY		(1 << 7)
+#define	IDE_LEGACY_COMMAND	0x07 // WO
+#define	IDE_LEGACY_ASTATUS	0x206 // RO
+#define	IDE_LEGACY_CTRL		0x206 // WO
+#define	IDE_LEGACY_CTRL_IDS	0x02
+#define	IDE_LEGACY_CTRL_RST	0x04
+#define	IDE_LEGACY_CTRL_4BIT	0x08
+
+/**********************************************************************************/
+
+#endif	/* _CS5536_H */
diff -Nur linux-2.6.26.orig/arch/mips/lemote/lm2f/cs5536_pci.h linux-2.6.26.2f/arch/mips/lemote/lm2f/cs5536_pci.h
--- linux-2.6.26.orig/arch/mips/lemote/lm2f/cs5536_pci.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/lemote/lm2f/cs5536_pci.h	2008-08-28 14:41:20.137777465 +0800
@@ -0,0 +1,181 @@
+/*
+ * cs5536_vsm.h
+ * the definition file of cs5536 Virtual Support Module(VSM).
+ * pci configuration space can be accessed through the VSM, so
+ * there is no need the MSR read/write now, except the spec. MSR
+ * registers which are not implemented yet.
+ *
+ * Author : jlliu <liujl@lemote.com>
+ * Date : 07-07-04
+ *
+ */
+
+#ifndef	_CS5536_PCI_H
+#define	_CS5536_PCI_H
+
+/**********************************************************************/
+
+//#define	TEST_CS5536_USE_FLASH
+//#ifdef	TEST_CS5536_USE_FLASH
+//#define	TEST_CS5536_USE_NOR_FLASH
+//#endif
+#define		TEST_CS5536_USE_EHCI
+#define	TEST_CS5536_USE_UDC
+#define	TEST_CS5536_USE_OTG
+
+/**********************************************************************/
+
+#define	PCI_SPECIAL_SHUTDOWN	1
+#define	CS5536_FLASH_INTR	6
+#define	CS5536_ACC_INTR		9
+#define	CS5536_IDE_INTR		14
+#define	CS5536_USB_INTR		11
+#define	CS5536_UART1_INTR	4
+#define	CS5536_UART2_INTR	3
+
+/************************* PCI BUS DEVICE FUNCTION ********************/
+
+/*
+ * PCI bus device function
+ */
+#define	PCI_BUS_CS5536		0
+#define	PCI_IDSEL_CS5536	14
+#define	PCI_CFG_BASE		0x02000000
+
+#define	CS5536_ISA_FUNC		0
+#define	CS5536_FLASH_FUNC	1
+#define	CS5536_IDE_FUNC		2
+#define	CS5536_ACC_FUNC		3
+#define	CS5536_OHCI_FUNC	4
+#define	CS5536_EHCI_FUNC	5
+#define	CS5536_UDC_FUNC		6
+#define	CS5536_OTG_FUNC		7
+#define	CS5536_FUNC_START	0
+#define	CS5536_FUNC_END		7
+#define	CS5536_FUNC_COUNT	(CS5536_FUNC_END - CS5536_FUNC_START + 1)
+
+/***************************** STANDARD PCI-2.2 EXPANSION ***********************/
+
+/*
+ * PCI configuration space
+ * we have to virtualize the PCI configure space head, so we should
+ * define the necessary IDs and some others.
+ */
+/* VENDOR ID */ 
+#define	CS5536_VENDOR_ID	0x1022
+
+/* DEVICE ID */
+#define	CS5536_ISA_DEVICE_ID		0x2090
+#define	CS5536_FLASH_DEVICE_ID		0x2091
+#define	CS5536_IDE_DEVICE_ID		0x209a
+#define	CS5536_ACC_DEVICE_ID		0x2093
+#define	CS5536_OHCI_DEVICE_ID		0x2094
+#define	CS5536_EHCI_DEVICE_ID		0x2095
+#define	CS5536_UDC_DEVICE_ID		0x2096
+#define	CS5536_OTG_DEVICE_ID		0x2097
+
+/* CLASS CODE : CLASS SUB-CLASS INTERFACE */
+#define	CS5536_ISA_CLASS_CODE		0x060100
+#define	CS5536_FLASH_CLASS_CODE		0x050100
+#define CS5536_IDE_CLASS_CODE		0x010180
+#define	CS5536_ACC_CLASS_CODE		0x040100
+#define	CS5536_OHCI_CLASS_CODE		0x0C0310
+#define	CS5536_EHCI_CLASS_CODE		0x0C0320
+#define	CS5536_UDC_CLASS_CODE		0x0C03FE
+#define	CS5536_OTG_CLASS_CODE		0x0C0380
+
+/* BHLC : BIST HEADER-TYPE LATENCY-TIMER CACHE-LINE-SIZE */
+#define	PCI_NONE_BIST			0x00	//RO not implemented yet.
+#define	PCI_BRIDGE_HEADER_TYPE		0x80	//RO
+#define	PCI_NORMAL_HEADER_TYPE		0x00
+#define	PCI_NORMAL_LATENCY_TIMER	0x00
+#define	PCI_NORMAL_CACHE_LINE_SIZE	0x08	//RW
+
+/* BAR */
+#define	PCI_BAR0_REG			0x10
+#define	PCI_BAR1_REG			0x14
+#define	PCI_BAR2_REG			0x18
+#define	PCI_BAR3_REG			0x1c
+#define	PCI_BAR4_REG			0x20
+#define	PCI_BAR5_REG			0x24
+#define	PCI_BAR_COUNT			6
+#define	PCI_BAR_RANGE_MASK		0xFFFFFFFF
+
+/* CARDBUS CIS POINTER */
+#define	PCI_CARDBUS_CIS_POINTER		0x00000000
+
+/* SUBSYSTEM VENDOR ID  */
+#define	CS5536_SUB_VENDOR_ID		CS5536_VENDOR_ID
+
+/* SUBSYSTEM ID */
+#define	CS5536_ISA_SUB_ID		CS5536_ISA_DEVICE_ID
+#define	CS5536_FLASH_SUB_ID		CS5536_FLASH_DEVICE_ID
+#define	CS5536_IDE_SUB_ID		CS5536_IDE_DEVICE_ID
+#define	CS5536_ACC_SUB_ID		CS5536_ACC_DEVICE_ID
+#define	CS5536_OHCI_SUB_ID		CS5536_OHCI_DEVICE_ID
+#define	CS5536_EHCI_SUB_ID		CS5536_EHCI_DEVICE_ID
+#define	CS5536_UDC_SUB_ID		CS5536_UDC_DEVICE_ID
+#define	CS5536_OTG_SUB_ID		CS5536_OTG_DEVICE_ID
+
+/* EXPANSION ROM BAR */
+#define	PCI_EXPANSION_ROM_BAR		0x00000000
+
+/* CAPABILITIES POINTER */
+#define	PCI_CAPLIST_POINTER		0x00000000
+#define PCI_CAPLIST_USB_POINTER		0x40
+/* INTERRUPT */
+#define	PCI_MAX_LATENCY			0x40
+#define	PCI_MIN_GRANT			0x00
+#define	PCI_DEFAULT_PIN			0x01
+
+/**************************** EXPANSION PCI REG **************************************/
+
+/*
+ * ISA EXPANSION
+ */
+#define	PCI_UART1_INT_REG 	0x50
+#define PCI_UART2_INT_REG	0x54
+#define	PCI_ISA_FIXUP_REG	0x58
+
+/*
+ * FLASH EXPANSION
+ */
+#define	PCI_FLASH_INT_REG		0x50
+#define	PCI_NOR_FLASH_CTRL_REG		0x40
+#define	PCI_NOR_FLASH_T01_REG		0x44
+#define	PCI_NOR_FLASH_T23_REG		0x48
+#define	PCI_NAND_FLASH_TDATA_REG	0x60
+#define	PCI_NAND_FLASH_TCTRL_REG	0x64
+#define	PCI_NAND_FLASH_RSVD_REG		0x68
+#define	PCI_FLASH_SELECT_REG		0x70
+
+/*
+ * IDE EXPANSION
+ */ 
+#define	PCI_IDE_CFG_REG		0x40
+#define	CS5536_IDE_FLASH_SIGNATURE	0xDEADBEEF
+#define	PCI_IDE_DTC_REG		0x48
+#define	PCI_IDE_CAST_REG	0x4C
+#define	PCI_IDE_ETC_REG		0x50
+#define	PCI_IDE_PM_REG		0x54
+#define	PCI_IDE_INT_REG		0x60
+
+/*
+ * ACC EXPANSION
+ */
+#define	PCI_ACC_INT_REG		0x50
+
+/*
+ * OHCI EXPANSION : INTTERUPT IS IMPLEMENTED BY THE OHCI
+ */
+#define	PCI_OHCI_PM_REG		0x40
+#define	PCI_OHCI_INT_REG	0x50
+
+/*
+ * EHCI EXPANSION
+ */
+#define	PCI_EHCI_LEGSMIEN_REG	0x50
+#define	PCI_EHCI_LEGSMISTS_REG	0x54
+#define	PCI_EHCI_FLADJ_REG	0x60
+
+#endif /* _CS5536_PCI_H_ */
diff -Nur linux-2.6.26.orig/arch/mips/lemote/lm2f/cs5536_vsm.c linux-2.6.26.2f/arch/mips/lemote/lm2f/cs5536_vsm.c
--- linux-2.6.26.orig/arch/mips/lemote/lm2f/cs5536_vsm.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/lemote/lm2f/cs5536_vsm.c	2008-08-28 14:41:19.809061891 +0800
@@ -0,0 +1,2294 @@
+/*
+ * pci_machdep_cs5536.c  
+ * 	the Virtual Support Module(VSM) for virtulize the PCI configure  
+ * 	space. so user can access the PCI configure space directly as
+ *	a normal multi-function PCI device which following the PCI-2.2 spec.
+ *
+ * Author : jlliu <liujl@lemote.com>
+ * Date : 07-07-05
+ *
+ */
+#include <linux/types.h>
+
+#include "cs5536.h"
+#include "cs5536_pci.h"
+#include "pcireg.h"
+
+extern void _wrmsr(u32 reg, u32 hi, u32 lo);
+extern void _rdmsr(u32 reg, u32 *hi, u32 *lo);
+
+/******************************INTERNAL USED FUNCTIONS***********************************/
+
+/*
+ * divil_lbar_enable_disable : enable/disable the divil module bar space.
+ * For all the DIVIL module LBAR, you should control the DIVIL LBAR reg
+ * and the RCONFx(0~5) reg to use the modules.
+ */
+static void divil_lbar_enable_disable(int enable)
+{
+	u32 hi, lo;
+	
+	/* 
+	 * The DIVIL IRQ is not used yet. and make the RCONF0 reserved.
+	 */
+	
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo);
+	if(enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo);
+
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
+	if(enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), hi, lo);
+
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &hi, &lo);
+	if(enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), hi, lo);
+
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_PMS), &hi, &lo);
+	if(enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_PMS), hi, lo);
+
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_ACPI), &hi, &lo);
+	if(enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_ACPI), hi, lo);
+	
+	/*
+	 * RCONF0 is reserved to the DIVIL IRQ mdoule
+	 */
+#if	0	
+	_rdmsr(SB_MSR_REG(SB_R1), &hi, &lo);
+	if(enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R1), hi, lo);
+	
+	_rdmsr(SB_MSR_REG(SB_R2), &hi, &lo);
+	if(enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R2), hi, lo);
+
+	_rdmsr(SB_MSR_REG(SB_R3), &hi, &lo);
+	if(enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R3), hi, lo);
+	
+	_rdmsr(SB_MSR_REG(SB_R4), &hi, &lo);
+	if(enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R4), hi, lo);
+
+	_rdmsr(SB_MSR_REG(SB_R5), &hi, &lo);
+	if(enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R5), hi, lo);
+#endif	
+	return;
+}
+
+#ifdef	TEST_CS5536_USE_FLASH
+/*
+ * flash_lbar_enable_disable : enable or disable the region of flashs(NOR or NAND)
+ * the same as the DIVIL other modules above, two groups of regs should be modified
+ * here to control the region. DIVIL flash LBAR and the RCONFx(6~9 reserved).
+ */
+static void flash_lbar_enable_disable(int enable)
+{
+	u32 hi, lo;
+	
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo);
+	if(enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), hi, lo);
+
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), &hi, &lo);
+	if(enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), hi, lo);
+
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), &hi, &lo);
+	if(enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), hi, lo);
+
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), &hi, &lo);
+	if(enable)
+		hi |= 0x01;
+	else
+		hi &= ~0x01;
+	_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), hi, lo);
+
+	_rdmsr(SB_MSR_REG(SB_R6), &hi, &lo);
+	if(enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R6), hi, lo);
+	
+	_rdmsr(SB_MSR_REG(SB_R7), &hi, &lo);
+	if(enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R7), hi, lo);
+	
+	_rdmsr(SB_MSR_REG(SB_R8), &hi, &lo);
+	if(enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R8), hi, lo);
+
+	_rdmsr(SB_MSR_REG(SB_R9), &hi, &lo);
+	if(enable)
+		lo |= 0x01;
+	else
+		lo &= ~0x01;
+	_wrmsr(SB_MSR_REG(SB_R9), hi, lo);
+	
+	return;
+}
+#endif
+
+
+/**********************************MODULES*********************************************/
+
+/*
+ * isa_write : isa write transfering.
+ * WE assume that the ISA is not the BUS MASTER.!!!
+ */
+/* FAST BACK TO BACK '1' for BUS MASTER '0' for BUS SALVE */
+/* COMMAND :
+ * 	bit0 : IO SPACE ENABLE
+ *	bit1 : MEMORY SPACE ENABLE(ignore)
+ *	bit2 : BUS MASTER ENABLE(ignore)
+ *	bit3 : SPECIAL CYCLE(ignore)? default is ignored.
+ *	bit4 : MEMORY WRITE and INVALIDATE(ignore)
+ *	bit5 : VGA PALETTE(ignore)
+ *	bit6 : PARITY ERROR(ignore)? : default is ignored.
+ *	bit7 : WAIT CYCLE CONTROL(ignore)
+ *	bit8 : SYSTEM ERROR(ignore)
+ *	bit9 : FAST BACK TO BACK(ignore)
+ *	bit10-bit15 : RESERVED
+ * STATUS :
+ *	bit0-bit3 : RESERVED
+ *	bit4 : CAPABILITY LIST(ignore)
+ *	bit5 : 66MHZ CAPABLE
+ *	bit6 : RESERVED
+ *	bit7 : FAST BACK TO BACK(ignore)
+ *	bit8 : DATA PARITY ERROR DETECED(ignore)
+ *	bit9-bit10 : DEVSEL TIMING(ALL MEDIUM)
+ *	bit11: SIGNALED TARGET ABORT
+ *	bit12: RECEIVED TARGET ABORT
+ *	bit13: RECEIVED MASTER ABORT
+ *	bit14: SIGNALED SYSTEM ERROR
+ *	bit15: DETECTED PARITY ERROR
+ */
+static void pci_isa_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+	u32 temp;
+
+	switch(reg){
+		case PCI_COMMAND_STATUS_REG :
+			// command
+			if( value & PCI_COMMAND_IO_ENABLE ){
+				divil_lbar_enable_disable(1);
+			}else{
+				divil_lbar_enable_disable(0);
+			}
+#if	0
+			/* PER response enable or disable. */
+			if( value & PCI_COMMAND_PARITY_ENABLE ){
+				_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+				lo |= SB_PARE_ERR_EN;
+				_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);			
+			}else{
+				_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+				lo &= ~SB_PARE_ERR_EN;
+				_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);			
+			}
+#endif
+			// status
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			temp = lo & 0x0000ffff;
+			if( (value & PCI_STATUS_TARGET_TARGET_ABORT) && 
+				(lo & SB_TAS_ERR_EN) ){
+				temp |= SB_TAS_ERR_FLAG;
+			}
+			if( (value & PCI_STATUS_MASTER_TARGET_ABORT) &&
+				(lo & SB_TAR_ERR_EN) ){
+				temp |= SB_TAR_ERR_FLAG;
+			}
+			if( (value & PCI_STATUS_MASTER_ABORT) &&
+				(lo & SB_MAR_ERR_EN) ){
+				temp |= SB_MAR_ERR_FLAG;
+			}
+			if( (value & PCI_STATUS_PARITY_DETECT) &&
+				(lo & SB_PARE_ERR_EN) ){
+				temp |= SB_PARE_ERR_FLAG; 
+			}
+			lo = temp;
+			_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+			break;
+		case PCI_BHLC_REG :
+			value &= 0x0000ff00;
+			_rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
+			hi &= 0xffffff00;
+			hi |= (value >> 8);
+			_wrmsr(SB_MSR_REG(SB_CTRL), hi, lo);
+			break;
+		case PCI_BAR0_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_SMB_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if(value & 0x01){
+				// SMB NATIVE IO space has 8bytes
+				hi = 0x0000f001;
+				lo = value & 0x0000fff8;
+				_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo);
+				
+				// RCONFx is 4bytes in units for IO space.
+				hi = ((value & 0x000ffffc) << 12) | ((CS5536_SMB_LENGTH - 4) << 12) | 0x01;
+				lo = ((value & 0x000ffffc) << 12) | 0x01;
+				_wrmsr(SB_MSR_REG(SB_R0), hi, lo);
+			}
+			break;
+		case PCI_BAR1_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_GPIO_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if(value & 0x01){
+				// GPIO NATIVE reg is 256bytes
+				hi = 0x0000f001;
+				lo = value & 0x0000ff00;
+				_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), hi, lo);
+
+				// RCONFx is 4bytes in units for IO space
+				hi = ((value & 0x000ffffc) << 12) | ((CS5536_GPIO_LENGTH - 4) << 12) | 0x01;
+				lo = ((value & 0x000ffffc) << 12) | 0x01;
+				_wrmsr(SB_MSR_REG(SB_R1), hi, lo);
+			}
+			break;
+		case PCI_BAR2_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_MFGPT_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if(value & 0x01){
+				// MFGPT NATIVE reg is 64bytes
+				hi = 0x0000f001;
+				lo = value & 0x0000ffc0;
+				_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), hi, lo);
+
+				// RCONFx is 4bytes in units for IO space
+				hi = ((value & 0x000ffffc) << 12) | ((CS5536_MFGPT_LENGTH - 4) << 12) | 0x01;
+				lo = ((value & 0x000ffffc) << 12) | 0x01;
+				_wrmsr(SB_MSR_REG(SB_R2), hi, lo);
+			}
+			break;
+		case PCI_BAR3_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_IRQ_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if(value & 0x01){
+				// IRQ NATIVE reg is 32bytes
+				hi = 0x0000f001;
+				lo = value & 0x0000ffc0;
+				_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_IRQ), hi, lo);
+
+				// RCONFx is 4bytes in units for IO space
+				hi = ((value & 0x000ffffc) << 12) | ((CS5536_IRQ_LENGTH - 4) << 12) | 0x01;
+				lo = ((value & 0x000ffffc) << 12) | 0x01;
+				_wrmsr(SB_MSR_REG(SB_R3), hi, lo);
+			}
+			break;
+		case PCI_BAR4_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_PMS_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if(value & 0x01){
+				// PMS NATIVE reg is 128bytes
+				hi = 0x0000f001;
+				lo = value & 0x0000ff80;
+				_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_PMS), hi, lo);
+
+				// RCONFx is 4bytes in units for IO space.
+				hi = ((value & 0x000ffffc) << 12) | ((CS5536_PMS_LENGTH - 4) << 12) | 0x01;
+				lo = ((value & 0x000ffffc) << 12) | 0x01;
+				_wrmsr(SB_MSR_REG(SB_R4), hi, lo);
+			}
+			break;
+		case PCI_BAR5_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_ACPI_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if(value & 0x01){
+				// ACPI NATIVE reg is 32bytes
+				hi = 0x0000f001;
+				lo = value & 0x0000ffe0;
+				_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_ACPI), hi, lo);
+				
+				// RCONFx is 4bytes in units for IO space.
+				hi = ((value & 0x000ffffc) << 12) | ((CS5536_ACPI_LENGTH - 4) << 12) | 0x01;
+				lo = ((value & 0x000ffffc) << 12) | 0x01;
+				_wrmsr(SB_MSR_REG(SB_R5), hi, lo);
+			}
+			break;
+		case PCI_UART1_INT_REG :
+			if(value){
+			/* enable uart1 interrupt in PIC */	
+				_rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo);
+				lo &= ~(0xf << 24);
+				lo |= (CS5536_UART1_INTR << 24);
+				_wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo);
+			}else{
+			/* disable uart1 interrupt in PIC */
+				_rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo);
+				lo &= ~(0xf << 24);
+				_wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo);
+			}
+			break;
+		case PCI_UART2_INT_REG :
+			if(value){
+			/* enable uart2 interrupt in PIC */	
+				_rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo);
+				lo &= ~(0xf << 28);
+				lo |= (CS5536_UART2_INTR << 28);
+				_wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo);
+			}else{
+			/* disable uart2 interrupt in PIC */
+				_rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo);
+				lo &= ~(0xf << 28);
+				_wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo);
+			}
+			break;
+		case PCI_ISA_FIXUP_REG :
+			if(value){
+				/* enable the TARGET ABORT/MASTER ABORT etc. */
+				_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+				lo |= 0x00000063;
+				_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+			}
+
+		default :
+			/* ALL OTHER PCI CONFIG SPACE HEADER IS NOT IMPLEMENTED. */
+			break;			
+	}
+	
+	return;
+}
+
+/*
+ * isa_read : isa read transfering.
+ * we assume that the ISA is not the BUS MASTER. 
+ */
+ 
+ /* COMMAND :
+ * 	bit0 : IO SPACE ENABLE
+ *	bit1 : MEMORY SPACE ENABLE(ignore)
+ *	bit2 : BUS MASTER ENABLE(ignore)
+ *	bit3 : SPECIAL CYCLE(ignore)? default is ignored.
+ *	bit4 : MEMORY WRITE and INVALIDATE(ignore)
+ *	bit5 : VGA PALETTE(ignore)
+ *	bit6 : PARITY ERROR(ignore)? : default is ignored.
+ *	bit7 : WAIT CYCLE CONTROL(ignore)
+ *	bit8 : SYSTEM ERROR(ignore)
+ *	bit9 : FAST BACK TO BACK(ignore)
+ *	bit10-bit15 : RESERVED
+ * STATUS :
+ *	bit0-bit3 : RESERVED
+ *	bit4 : CAPABILITY LIST(ignore)
+ *	bit5 : 66MHZ CAPABLE
+ *	bit6 : RESERVED
+ *	bit7 : FAST BACK TO BACK(ignore)
+ *	bit8 : DATA PARITY ERROR DETECED(ignore)?
+ *	bit9-bit10 : DEVSEL TIMING(ALL MEDIUM)
+ *	bit11: SIGNALED TARGET ABORT
+ *	bit12: RECEIVED TARGET ABORT
+ *	bit13: RECEIVED MASTER ABORT
+ *	bit14: SIGNALED SYSTEM ERROR
+ *	bit15: DETECTED PARITY ERROR(?)
+ */
+
+static u32 pci_isa_read_reg(int reg)
+{
+	u32 conf_data;
+	u32 hi, lo;
+	
+	switch(reg){
+		case PCI_ID_REG :
+			conf_data = (CS5536_ISA_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+			break;
+		case PCI_COMMAND_STATUS_REG :
+			conf_data = 0;
+			// COMMAND
+			// we just check the first LBAR for the IO enable bit,
+			// maybe we should changed later.
+			_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo);
+			if(hi & 0x01){
+				conf_data |= PCI_COMMAND_IO_ENABLE;
+			}
+			//conf_data |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE;
+#if	0
+			conf_data |= PCI_COMMAND_SPECIAL_ENABLE;
+#endif
+#if	0
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if(lo & SB_PARE_ERR_EN){
+				conf_data |= PCI_COMMAND_PARITY_ENABLE;
+			}else{
+				conf_data &= ~PCI_COMMAND_PARITY_ENABLE;
+			}
+#endif
+			// STATUS	
+			conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+			conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+#if	1
+			conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+#endif
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if(lo & SB_TAS_ERR_FLAG)
+				conf_data |= PCI_STATUS_TARGET_TARGET_ABORT;
+			if(lo & SB_TAR_ERR_FLAG)
+				conf_data |= PCI_STATUS_MASTER_TARGET_ABORT;
+			if(lo & SB_MAR_ERR_FLAG)
+				conf_data |= PCI_STATUS_MASTER_ABORT;
+			if(lo & SB_PARE_ERR_FLAG)
+				conf_data |= PCI_STATUS_PARITY_DETECT;
+			break;
+		case PCI_CLASS_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_CHIP_REV_ID), &hi, &lo);
+			conf_data = lo & 0x000000ff;
+			conf_data |= (CS5536_ISA_CLASS_CODE << 8);
+			break;
+		case PCI_BHLC_REG :
+			_rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
+			hi &= 0x000000f8;
+			conf_data = (PCI_NONE_BIST << 24) | (PCI_BRIDGE_HEADER_TYPE << 16) |
+				(hi << 8) | PCI_NORMAL_CACHE_LINE_SIZE;
+			break;
+		/*
+		 * we only use the LBAR of DIVIL, no RCONF used. 
+		 * all of them are IO space.
+		 */
+		case PCI_BAR0_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_SMB_FLAG){
+				conf_data = CS5536_SMB_RANGE | PCI_MAPREG_TYPE_IO;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_SMB_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo);
+				conf_data = lo & 0x0000fff8;
+				conf_data |= 0x01;
+				conf_data &= ~0x02;
+			}
+			break;
+		case PCI_BAR1_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_GPIO_FLAG){
+				conf_data = CS5536_GPIO_RANGE | PCI_MAPREG_TYPE_IO;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_GPIO_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
+				conf_data = lo & 0x0000ff00;
+				conf_data |= 0x01;
+				conf_data &= ~0x02;
+			}
+			break;
+		case PCI_BAR2_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_MFGPT_FLAG){
+				conf_data = CS5536_MFGPT_RANGE | PCI_MAPREG_TYPE_IO;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_MFGPT_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &hi, &lo);
+				conf_data = lo & 0x0000ffc0;
+				conf_data |= 0x01;
+				conf_data &= ~0x02;
+			}
+			break;
+#if	1
+		case PCI_BAR3_REG :
+			conf_data = 0;
+			break;
+#else
+		case PCI_BAR3_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_IRQ_FLAG){
+				conf_data = CS5536_IRQ_RANGE | PCI_MAPREG_TYPE_IO;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_IRQ_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_IRQ), &hi, &lo);
+				conf_data = lo & 0x0000ffc0;
+				conf_data |= 0x01;
+				conf_data &= ~0x02;
+			}
+			break;
+#endif
+		case PCI_BAR4_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_PMS_FLAG){
+				conf_data = CS5536_PMS_RANGE | PCI_MAPREG_TYPE_IO;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_PMS_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_PMS), &hi, &lo);
+				conf_data = lo & 0x0000ff80;
+				conf_data |= 0x01;
+				conf_data &= ~0x02;
+			}
+			break;
+		case PCI_BAR5_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_ACPI_FLAG){
+				conf_data = CS5536_ACPI_RANGE | PCI_MAPREG_TYPE_IO;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_ACPI_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_ACPI), &hi, &lo);
+				conf_data = lo & 0x0000ffe0;
+				conf_data |= 0x01;
+				conf_data &= ~0x02;
+			}
+			break;
+		case PCI_CARDBUS_CIS_REG :
+			conf_data = PCI_CARDBUS_CIS_POINTER;
+			break;
+		case PCI_SUBSYS_ID_REG :
+			conf_data = (CS5536_ISA_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+			break;
+		case PCI_MAPREG_ROM :
+			conf_data = PCI_EXPANSION_ROM_BAR;
+			break;
+		case PCI_CAPLISTPTR_REG :
+			conf_data = PCI_CAPLIST_POINTER;
+			break;
+		case PCI_INTERRUPT_REG :
+			conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | 
+				(0x00 << 8) | 0x00;
+			break;
+		default :
+			conf_data = 0;
+			break;
+	}
+	
+	return conf_data;
+}
+
+#ifdef	TEST_CS5536_USE_FLASH
+
+#ifndef	TEST_CS5536_USE_NOR_FLASH	/* for nand flash */
+static void pci_flash_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+
+	switch(reg){
+		case PCI_COMMAND_STATUS_REG :
+			// command
+			if( value & PCI_COMMAND_MEM_ENABLE ){
+				flash_lbar_enable_disable(1);
+			}else{
+				flash_lbar_enable_disable(0);
+			}
+			// STATUS
+			if(value & PCI_STATUS_PARITY_ERROR){
+				_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+				if(lo & SB_PARE_ERR_FLAG){
+					lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+					_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+				}				
+			}
+			break;
+		case PCI_BAR0_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				// make the flag for reading the bar length.
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_FLSH0_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if( (value & 0x01) == 0x00 ){
+				// mem space nand flash native reg base addr
+				hi = 0xfffff007;
+				lo = value & 0xfffff000;
+				_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), hi, lo);
+	
+				// RCONFx is 4KB in units for mem space.
+				hi = ((value & 0xfffff000) << 12) | ( (CS5536_FLSH0_LENGTH & 0xfffff000) - (1 << 12) ) | 0x00;
+				lo = ((value & 0xfffff000) << 12) | 0x01;
+				_wrmsr(SB_MSR_REG(SB_R6), hi, lo);			
+			}
+			break;
+		case PCI_BAR1_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_FLSH1_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if( (value & 0x01) == 0x00 ){
+				// mem space nand flash native reg base addr
+				hi = 0xfffff007;
+				lo = value & 0xfffff000;
+				_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), hi, lo);
+	
+				// RCONFx is 4KB in units for mem space.
+				hi = ((value & 0xfffff000) << 12) | ( (CS5536_FLSH1_LENGTH & 0xfffff000) - (1 << 12) ) | 0x00;
+				lo = ((value & 0xfffff000) << 12) | 0x01;
+				_wrmsr(SB_MSR_REG(SB_R7), hi, lo);
+			}
+			break;
+		case PCI_BAR2_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_FLSH2_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if( (value & 0x01) == 0x00 ){
+				// mem space nand flash native reg base addr
+				hi = 0xfffff007;
+				lo = value & 0xfffff000;
+				_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), hi, lo);
+	
+				// RCONFx is 4KB in units for mem space.
+				hi = ((value & 0xfffff000) << 12) | ( (CS5536_FLSH2_LENGTH & 0xfffff000) - (1 << 12) ) | 0x00;
+				lo = ((value & 0xfffff000) << 12) | 0x01;
+				_wrmsr(SB_MSR_REG(SB_R8), hi, lo);
+			}
+			break;		
+		case PCI_BAR3_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_FLSH3_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if( (value & 0x01) == 0x00 ){
+				// mem space nand flash native reg base addr
+				hi = 0xfffff007;
+				lo = value & 0xfffff000;
+				_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), hi, lo);
+	
+				// RCONFx is 4KB in units for mem space.
+				hi = ((value & 0xfffff000) << 12) | ( (CS5536_FLSH3_LENGTH & 0xfffff000)- (1 << 12) ) | 0x00;
+				lo = ((value & 0xfffff000) << 12) | 0x01;
+				_wrmsr(SB_MSR_REG(SB_R9), hi, lo);
+			}
+			break;
+		case PCI_FLASH_INT_REG :
+			if(value){
+			/* enable all the flash interrupt in PIC */	
+				_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+				lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT);
+				lo |= (CS5536_FLASH_INTR << PIC_YSEL_LOW_FLASH_SHIFT);
+				_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+			}else{
+			/* disable all the flash interrupt in PIC */
+				_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+				lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT);
+				_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+			}
+			break;
+		case PCI_NAND_FLASH_TDATA_REG :
+			hi = 0;
+			lo = value;
+			_wrmsr(DIVIL_MSR_REG(NANDF_DATA), hi, lo);
+			break;
+		case PCI_NAND_FLASH_TCTRL_REG :
+			hi = 0;
+			lo = value & 0x00000fff;
+			_wrmsr(DIVIL_MSR_REG(NANDF_CTRL), hi, lo);
+			break;
+		case PCI_NAND_FLASH_RSVD_REG :
+			hi = 0;
+			lo = value;
+			_wrmsr(DIVIL_MSR_REG(NANDF_RSVD), hi, lo);
+			break;
+		case PCI_FLASH_SELECT_REG :
+			if(value == CS5536_IDE_FLASH_SIGNATURE){
+				_rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo);
+				lo &= ~0x01;
+				_wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo);
+			}
+			break;
+		default :
+			break;
+	}
+	
+	return;
+}
+
+static u32 pci_flash_read_reg(int reg)
+{
+	u32 conf_data;
+	u32 hi, lo;
+	
+	switch(reg){
+		case PCI_ID_REG :
+			conf_data = (CS5536_FLASH_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+			break;
+		case PCI_COMMAND_STATUS_REG :
+			conf_data = 0;
+			// COMMAND
+			// we just read one lbar for returning.
+			_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo);
+			if(hi & 0x01)
+				conf_data |= PCI_COMMAND_MEM_ENABLE;
+			//STATUS
+			conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+			conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if(lo & SB_PARE_ERR_FLAG)
+				conf_data |= PCI_STATUS_PARITY_ERROR;
+			conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+			break;
+		case PCI_CLASS_REG :
+			_rdmsr(DIVIL_MSR_REG(DIVIL_CAP), &hi, &lo);
+			conf_data = lo & 0x000000ff;
+			conf_data |= (CS5536_FLASH_CLASS_CODE << 8);
+			break;
+		case PCI_BHLC_REG :
+			conf_data = (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) |
+				(PCI_NORMAL_LATENCY_TIMER << 8) | PCI_NORMAL_CACHE_LINE_SIZE;
+			break;
+		case PCI_BAR0_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_FLSH0_FLAG){
+				conf_data = CS5536_FLSH0_RANGE | PCI_MAPREG_TYPE_MEM;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_FLSH0_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo);
+				conf_data = lo;
+				conf_data &= ~0x0f;
+			}
+			break;
+		case PCI_BAR1_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_FLSH1_FLAG){
+				conf_data = CS5536_FLSH1_RANGE | PCI_MAPREG_TYPE_MEM;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_FLSH1_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), &hi, &lo);
+				conf_data = lo;
+				conf_data &= ~0x0f;
+			}
+			break;
+		case PCI_BAR2_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_FLSH2_FLAG){
+				conf_data = CS5536_FLSH2_RANGE | PCI_MAPREG_TYPE_MEM;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_FLSH2_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), &hi, &lo);
+				conf_data = lo;
+				conf_data &= ~0x0f;
+			}
+			break;
+		case PCI_BAR3_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_FLSH3_FLAG){
+				conf_data = CS5536_FLSH3_RANGE | PCI_MAPREG_TYPE_MEM;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_FLSH3_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), &hi, &lo);
+				conf_data = lo;
+				conf_data &= ~0x0f;
+			}
+			break;	
+		case PCI_CARDBUS_CIS_REG :
+			conf_data = PCI_CARDBUS_CIS_POINTER;
+			break;
+		case PCI_SUBSYS_ID_REG :
+			conf_data = (CS5536_FLASH_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+			break;
+		case PCI_MAPREG_ROM :
+			conf_data = PCI_EXPANSION_ROM_BAR;
+			break;
+		case PCI_CAPLISTPTR_REG :
+			conf_data = PCI_CAPLIST_POINTER;
+			break;
+		case PCI_INTERRUPT_REG :
+			conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | 
+				(PCI_DEFAULT_PIN << 8) | (CS5536_FLASH_INTR);
+			break;
+		case PCI_NAND_FLASH_TDATA_REG :
+			_rdmsr(DIVIL_MSR_REG(NANDF_DATA), &hi, &lo);
+			conf_data = lo;
+			break;
+		case PCI_NAND_FLASH_TCTRL_REG :
+			_rdmsr(DIVIL_MSR_REG(NANDF_CTRL), &hi, &lo);
+			conf_data = lo & 0x00000fff;
+			break;
+		case PCI_NAND_FLASH_RSVD_REG :
+			_rdmsr(DIVIL_MSR_REG(NANDF_RSVD), &hi, &lo);
+			conf_data = lo;
+			break;
+		case PCI_FLASH_SELECT_REG :
+			_rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo);
+			conf_data = lo & 0x01;
+			break;
+
+		}
+	return 0;
+}
+
+#else /* nor flash */
+
+static void pci_flash_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+
+	switch(reg){
+		case PCI_COMMAND_STATUS_REG :
+			// command
+			if( value & PCI_COMMAND_IO_ENABLE ){
+				flash_lbar_enable_disable(1);
+			}else{
+				flash_lbar_enable_disable(0);
+			}
+			// STATUS
+			if(value & PCI_STATUS_PARITY_ERROR){
+				_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+				if(lo & SB_PARE_ERR_FLAG){
+					lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+					_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+				}				
+			}
+			break;
+		case PCI_BAR0_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_FLSH0_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if(value & 0x01){
+				// IO space of 16bytes nor flash
+				hi = 0x0000fff1;
+				lo = value & 0x0000fff0;
+				_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), hi, lo);
+	
+				// RCONFx used for 16bytes reserved.
+				hi = ((value & 0x000ffffc) << 12) | ((CS5536_FLSH0_LENGTH - 4) << 12) | 0x01;
+				lo = ((value & 0x000ffffc) << 12) | 0x01;
+				_wrmsr(SB_MSR_REG(SB_R6), hi, lo);
+			}
+			break;
+		case PCI_BAR1_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_FLSH1_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if(value & 0x01){
+				// IO space of 16bytes nor flash
+				hi = 0x0000fff1;
+				lo = value & 0x0000fff0;
+				_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), hi, lo);
+	
+				// RCONFx used for 16bytes reserved.
+				hi = ((value & 0x000ffffc) << 12) | ((CS5536_FLSH1_LENGTH - 4) << 12) | 0x01;
+				lo = ((value & 0x000ffffc) << 12) | 0x01;
+				_wrmsr(SB_MSR_REG(SB_R7), hi, lo);			
+			}
+			break;
+		case PCI_BAR2_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_FLSH2_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if(value & 0x01){
+				hi = 0x0000fff1;
+				lo = value & 0x0000fff0;
+				_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), hi, lo);
+	
+				hi = ((value & 0x000ffffc) << 12) | ((CS5536_FLSH2_LENGTH - 4) << 12) | 0x01;
+				lo = ((value & 0x000ffffc) << 12) | 0x01;
+				_wrmsr(SB_MSR_REG(SB_R8), hi, lo);				
+			}
+			break;		
+		case PCI_BAR3_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_FLSH3_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if(value & 0x01){
+				// 16bytes for nor flash
+				hi = 0x0000fff1;
+				lo = value & 0x0000fff0;
+				_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), hi, lo);
+	
+				// 16bytes of IO space of RCONFx region.
+				hi = ((value & 0x000ffffc) << 12) | ((CS5536_FLSH3_LENGTH - 4) << 12) | 0x01;
+				lo = ((value & 0x000ffffc) << 12) | 0x01;
+				_wrmsr(SB_MSR_REG(SB_R9), hi, lo);	
+			}
+			break;
+			
+		case PCI_INTERRUPT_REG :
+			conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | 
+				(PCI_DEFAULT_PIN << 8) | (CS5536_FLASH_INTR);
+			break;
+		case PCI_FLASH_INT_REG :
+			if(value){
+			/* enable all the flash interrupt in PIC */	
+				_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+				lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT);
+				lo |= (CS5536_FLASH_INTR << PIC_YSEL_LOW_FLASH_SHIFT);
+				_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+			}else{
+			/* disable all the flash interrupt in PIC */
+				_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+				lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT);
+				_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+			}
+			break;
+		case PCI_NOR_FLASH_CTRL_REG :
+			hi = 0;
+			lo = value & 0x000000ff;
+			_wrmsr(DIVIL_MSR_REG(NORF_CTRL), hi, lo);
+			break;
+		case PCI_NOR_FLASH_T01_REG :
+			hi = 0;
+			lo = value;
+			_wrmsr(DIVIL_MSR_REG(NORF_T01), hi, lo);
+			break;
+		case PCI_NOR_FLASH_T23_REG :
+			hi = 0;
+			lo = value;
+			_wrmsr(DIVIL_MSR_REG(NORF_T23), hi, lo);
+			break;
+		case PCI_FLASH_SELECT_REG :
+			if(value == CS5536_IDE_FLASH_SIGNATURE){
+				_rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo);
+				lo &= ~0x01;
+				_wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo);
+			}
+			break;
+
+		default :
+			break;			
+	}
+	
+	return;
+}
+
+static u32 pci_flash_read_reg(int reg)
+{
+	u32 conf_data;
+	u32 hi, lo;
+	
+	switch(reg){
+		case PCI_ID_REG :
+			conf_data = (CS5536_FLASH_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+			break;
+		case PCI_COMMAND_STATUS_REG :
+			conf_data = 0;
+			// COMMAND
+			// we just check one flash bar for returning.
+			_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo);
+			if(hi & 0x01)
+				conf_data |= PCI_COMMAND_IO_ENABLE;
+			//STATUS
+			conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+			conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if(lo & SB_PARE_ERR_FLAG)
+				conf_data |= PCI_STATUS_PARITY_ERROR;
+			conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+			break;
+		case PCI_CLASS_REG :
+			_rdmsr(DIVIL_MSR_REG(DIVIL_CAP), &hi, &lo);
+			conf_data = lo & 0x000000ff;
+			conf_data |= (CS5536_FLASH_CLASS_CODE << 8);
+			break;
+		case PCI_BHLC_REG :
+			conf_data = (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) |
+				(PCI_NORMAL_LATENCY_TIMER << 8) | PCI_NORMAL_CACHE_LINE_SIZE;
+			break;
+		case PCI_BAR0_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_FLSH0_FLAG){
+				conf_data = CS5536_FLSH0_RANGE | PCI_MAPREG_TYPE_IO;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_FLSH0_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo);
+				conf_data = lo & 0x0000ffff;
+				conf_data |= 0x01;
+				conf_data &= ~0x02;
+			}
+			break;
+		case PCI_BAR1_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_FLSH1_FLAG){
+				conf_data = CS5536_FLSH1_RANGE | PCI_MAPREG_TYPE_IO;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_FLSH1_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), &hi, &lo);
+				conf_data = lo & 0x0000ffff;
+				conf_data |= 0x01;
+				conf_data &= ~0x02;
+			}
+			break;
+		case PCI_BAR2_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_FLSH2_FLAG){
+				conf_data = CS5536_FLSH2_RANGE | PCI_MAPREG_TYPE_IO;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_FLSH2_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), &hi, &lo);
+				conf_data = lo & 0x0000ffff;
+				conf_data |= 0x01;
+				conf_data &= ~0x02;
+			}
+			break;
+		case PCI_BAR3_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_FLSH3_FLAG){
+				conf_data = CS5536_FLSH3_RANGE | PCI_MAPREG_TYPE_IO;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_FLSH3_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), &hi, &lo);
+				conf_data = lo & 0x0000ffff;
+				conf_data |= 0x01;
+				conf_data &= ~0x02;
+			}
+			break;	
+		case PCI_CARDBUS_CIS_REG :
+			conf_data = PCI_CARDBUS_CIS_POINTER;
+			break;
+		case PCI_SUBSYS_ID_REG :
+			conf_data = (CS5536_FLASH_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+			break;
+		case PCI_MAPREG_ROM :
+			conf_data = PCI_EXPANSION_ROM_BAR;
+			break;
+		case PCI_CAPLISTPTR_REG :
+			conf_data = PCI_CAPLIST_POINTER;
+			break;
+		case PCI_INTERRUPT_REG :
+			conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | 
+				(PCI_DEFAULT_PIN << 8) | (CS5536_FLASH_INTR);
+			break;
+		case PCI_NOR_FLASH_CTRL_REG :
+			_rdmsr(DIVIL_MSR_REG(NORF_CTRL), &hi, &lo);
+			conf_data = lo & 0x000000ff;
+			break;
+		case PCI_NOR_FLASH_T01_REG :
+			_rdmsr(DIVIL_MSR_REG(NORF_T01), &hi, &lo);
+			conf_data = lo;
+			break;
+		case PCI_NOR_FLASH_T23_REG :
+			_rdmsr(DIVIL_MSR_REG(NORF_T23), &hi, &lo);
+			conf_data = lo;
+			break;
+		default :
+			conf_data = 0;
+			break;
+	}
+	return conf_data;
+}
+#endif  /* TEST_CS5536_USE_NOR_FLASH */
+
+#else	/* TEST_CS5536_USE_FLASH */
+
+static void pci_flash_write_reg(int reg, u32 value)
+{
+	return;
+}
+
+static u32 pci_flash_read_reg(int reg)
+{
+	return 0xffffffff;
+}
+
+#endif	/* TEST_CS5536_USE_FLASH */
+
+/*
+ * ide_write : ide write transfering
+ */
+static void pci_ide_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+	
+	switch(reg){
+		case PCI_COMMAND_STATUS_REG :
+			// COMMAND
+			if(value & PCI_COMMAND_MASTER_ENABLE){
+				_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+				lo |= (0x03 << 4);
+				_wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo);			
+			}else{
+				_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+				lo &= ~(0x03 << 4);
+				_wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo);	
+			}
+			// STATUS
+			if(value & PCI_STATUS_PARITY_ERROR){
+				_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+				if(lo & SB_PARE_ERR_FLAG){
+					lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+					_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+				}				
+			}
+			break;
+		case PCI_BHLC_REG :
+			value &= 0x0000ff00;
+			_rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
+			hi &= 0xffffff00;
+			hi |= (value >> 8);
+			_wrmsr(SB_MSR_REG(SB_CTRL), hi, lo);
+			break;
+		case PCI_BAR4_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_IDE_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if(value & 0x01){
+				hi = 0x00000000;
+				//lo = ((value & 0x0fffffff) << 4) | 0x001;
+				lo = (value & 0xfffffff0) | 0x1;
+				_wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo);
+
+				value &= 0xfffffffc;
+				hi = 0x60000000 | ((value & 0x000ff000) >> 12);
+				lo = 0x000ffff0 | ((value & 0x00000fff) << 20);
+				_wrmsr(GLIU_MSR_REG(GLIU_IOD_BM2), hi, lo);
+	   		}
+			break;
+		case PCI_IDE_CFG_REG :
+			if(value == CS5536_IDE_FLASH_SIGNATURE){
+				_rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo);
+				lo |= 0x01;
+				_wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo);
+			}else{
+				hi = 0;
+				lo = value;
+				_wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo);			
+			}
+			break;
+		case PCI_IDE_DTC_REG :
+			hi = 0;
+			lo = value;
+			_wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo);
+			break;
+		case PCI_IDE_CAST_REG :
+			hi = 0;
+			lo = value;
+			_wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo);
+			break;
+		case PCI_IDE_ETC_REG :
+			hi = 0;
+			lo = value;
+			_wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo);
+			break;
+		case PCI_IDE_PM_REG :
+			hi = 0;
+			lo = value;
+			_wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo);
+			break;
+		default :
+			break;			
+	}
+	
+	return;
+}
+
+/*
+ * ide_read : ide read tranfering.
+ */
+static u32 pci_ide_read_reg(int reg)
+{
+	u32 conf_data;
+	u32 hi, lo;
+	
+	switch(reg){
+		case PCI_ID_REG :
+			conf_data = (CS5536_IDE_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+			break;
+		case PCI_COMMAND_STATUS_REG :
+			conf_data = 0;
+			// COMMAND
+			_rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
+			if(lo & 0xfffffff0)
+				conf_data |= PCI_COMMAND_IO_ENABLE;
+			_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+			if( (lo & 0x30) == 0x30 )
+				conf_data |= PCI_COMMAND_MASTER_ENABLE;
+			/* conf_data |= PCI_COMMAND_BACKTOBACK_ENABLE??? HOW TO GET..*/
+			//STATUS
+			conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+			conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if(lo & SB_PARE_ERR_FLAG)
+				conf_data |= PCI_STATUS_PARITY_ERROR;
+			conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+			break;
+		case PCI_CLASS_REG :
+			_rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo);
+			conf_data = lo & 0x000000ff;
+			conf_data |= (CS5536_IDE_CLASS_CODE << 8);
+			break;
+		case PCI_BHLC_REG :
+			_rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
+			hi &= 0x000000f8;
+			conf_data = (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) |
+				(hi << 8) | PCI_NORMAL_CACHE_LINE_SIZE;
+			break;
+		case PCI_BAR0_REG :
+			conf_data = 0x00000000;
+			break;
+		case PCI_BAR1_REG :
+			conf_data = 0x00000000;
+			break;
+		case PCI_BAR2_REG :
+			conf_data = 0x00000000;
+			break;
+		case PCI_BAR3_REG :
+			conf_data = 0x00000000;
+			break;
+		case PCI_BAR4_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_IDE_FLAG){
+				conf_data = CS5536_IDE_RANGE | PCI_MAPREG_TYPE_IO;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_IDE_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
+				//conf_data = lo >> 4;
+				conf_data = lo & 0xfffffff0;
+				conf_data |= 0x01;
+				conf_data &= ~0x02;
+			}
+			break;
+		case PCI_BAR5_REG :
+			conf_data = 0x00000000;
+			break;
+		case PCI_CARDBUS_CIS_REG :
+			conf_data = PCI_CARDBUS_CIS_POINTER;
+			break;
+		case PCI_SUBSYS_ID_REG :
+			conf_data = (CS5536_IDE_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+			break;
+		case PCI_MAPREG_ROM :
+			conf_data = PCI_EXPANSION_ROM_BAR;
+			break;
+		case PCI_CAPLISTPTR_REG :
+			conf_data = PCI_CAPLIST_POINTER;
+			break;
+		case PCI_INTERRUPT_REG :
+			conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | 
+				(PCI_DEFAULT_PIN << 8) | (CS5536_IDE_INTR);
+			break;
+		case PCI_IDE_CFG_REG :
+			_rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);
+			conf_data = lo;
+			break;
+		case PCI_IDE_DTC_REG :
+			_rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);
+			conf_data = lo;
+			break;
+		case PCI_IDE_CAST_REG :
+			_rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);
+			conf_data = lo;
+			break;
+		case PCI_IDE_ETC_REG :
+			_rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
+			conf_data = lo;
+		case PCI_IDE_PM_REG :
+			_rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
+			conf_data = lo;
+			break;
+			
+		default :
+			conf_data = 0;
+			break;
+	}
+
+	return conf_data;
+}
+
+static void pci_acc_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+
+	switch(reg){
+		case PCI_COMMAND_STATUS_REG :
+			// COMMAND
+			if(value & PCI_COMMAND_MASTER_ENABLE){
+				_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+				lo |= (0x03 << 8);
+				_wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo);			
+			}else{
+				_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+				lo &= ~(0x03 << 8);
+				_wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo);	
+			}
+			// STATUS
+			if(value & PCI_STATUS_PARITY_ERROR){
+				_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+				if(lo & SB_PARE_ERR_FLAG){
+					lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+					_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+				}				
+			}
+			break;
+		case PCI_BAR0_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_ACC_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if( value & 0x01 ){
+				value &= 0xfffffffc;
+				hi = 0xA0000000 | ((value & 0x000ff000) >> 12);
+				lo = 0x000fff80 | ((value & 0x00000fff) << 20);
+				_wrmsr(GLIU_MSR_REG(GLIU_IOD_BM1), hi, lo);
+			}
+			break;
+		case PCI_ACC_INT_REG :
+			if(value){
+			/* enable all the acc interrupt in PIC */	
+				_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+				lo &= ~(0xf << PIC_YSEL_LOW_ACC_SHIFT);
+				lo |= (CS5536_ACC_INTR << PIC_YSEL_LOW_ACC_SHIFT);
+				_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+			}else{
+			/* disable all the usb interrupt in PIC */
+				_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+				lo &= ~(0xf << PIC_YSEL_LOW_ACC_SHIFT);
+				_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+			}
+			break;
+		default :
+			break;			
+	}
+
+	return;
+}
+
+static u32 pci_acc_read_reg(int reg)
+{
+	u32 hi, lo;
+	u32 conf_data;
+
+	switch(reg){
+		case PCI_ID_REG :
+			conf_data = (CS5536_ACC_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+			break;
+		case PCI_COMMAND_STATUS_REG :
+			
+			conf_data = 0;
+			// COMMAND
+			_rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);
+			if( ( (lo & 0xfff00000) || (hi & 0x000000ff) ) 
+					&& ((hi & 0xf0000000) == 0xa0000000) )
+				conf_data |= PCI_COMMAND_IO_ENABLE;
+			_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+			if( (lo & 0x300) == 0x300 )
+				conf_data |= PCI_COMMAND_MASTER_ENABLE;
+			/* conf_data |= PCI_COMMAND_BACKTOBACK_ENABLE??? HOW TO GET..*/
+			//STATUS
+			conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+			conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if(lo & SB_PARE_ERR_FLAG)
+				conf_data |= PCI_STATUS_PARITY_ERROR;
+			conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+			break;
+		case PCI_CLASS_REG :
+			_rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo);
+			conf_data = lo & 0x000000ff;
+			conf_data |= (CS5536_ACC_CLASS_CODE << 8);
+			break;
+		case PCI_BHLC_REG :
+			conf_data = (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) |
+				(PCI_NORMAL_LATENCY_TIMER << 8) | PCI_NORMAL_CACHE_LINE_SIZE;
+			break;
+		case PCI_BAR0_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_ACC_FLAG){
+				conf_data = CS5536_ACC_RANGE | PCI_MAPREG_TYPE_IO;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_ACC_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);
+				conf_data = (hi & 0x000000ff) << 12;
+				conf_data |= (lo & 0xfff00000) >> 20; 
+				conf_data |= 0x01;
+				conf_data &= ~0x02;
+			}
+			break;
+		case PCI_BAR1_REG :
+			conf_data = 0x000000;
+			break;		
+		case PCI_BAR2_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_BAR3_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_BAR4_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_BAR5_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_CARDBUS_CIS_REG :
+			conf_data = PCI_CARDBUS_CIS_POINTER;
+			break;
+		case PCI_SUBSYS_ID_REG :
+			conf_data = (CS5536_ACC_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+			break;
+		case PCI_MAPREG_ROM :
+			conf_data = PCI_EXPANSION_ROM_BAR;
+			break;
+		case PCI_CAPLISTPTR_REG :
+			conf_data = PCI_CAPLIST_USB_POINTER;
+			break;
+		case PCI_INTERRUPT_REG :
+			conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | 
+				(PCI_DEFAULT_PIN << 8) | (CS5536_ACC_INTR);
+			break;
+		default :
+			conf_data = 0;
+			break;
+	}
+
+	return conf_data;
+}
+
+
+/*
+ * ohci_write : ohci write tranfering.
+ */
+static void pci_ohci_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+	
+	switch(reg){
+		case PCI_COMMAND_STATUS_REG :
+			// COMMAND
+			if(value & PCI_COMMAND_MASTER_ENABLE){
+				_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+				hi |= (1 << 2);
+				_wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
+			}else{
+				_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+				hi &= ~(1 << 2);
+				_wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
+			}
+			if(value & PCI_COMMAND_MEM_ENABLE){
+				_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+				hi |= (1 << 1);
+				_wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
+			}else{
+				_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+				hi &= ~(1 << 1);
+				_wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);				
+			}
+			// STATUS
+			if(value & PCI_STATUS_PARITY_ERROR){
+				_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+				if(lo & SB_PARE_ERR_FLAG){
+					lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+					_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+				}				
+			}
+			break;
+		case PCI_BAR0_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_OHCI_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if( (value & 0x01) == 0x00 ){
+				_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+				//lo = (value & 0xffffff00) << 8;
+				lo = value;
+				_wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
+				
+				value &= 0xfffffff0;
+				hi = 0x40000000 | ((value & 0xff000000) >> 24);
+				lo = 0x000fffff | ((value & 0x00fff000) << 8);
+				_wrmsr(GLIU_MSR_REG(GLIU_P2D_BM3), hi, lo);
+			}
+			break;
+		case PCI_INTERRUPT_REG :
+			value &= 0x000000ff;
+			break;
+		case PCI_OHCI_PM_REG :
+			break;
+		case PCI_OHCI_INT_REG :
+			if(value){
+			/* enable all the usb interrupt in PIC */	
+				_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+				lo &= ~(0xf << 8);
+				lo |= (CS5536_USB_INTR << 8);
+				_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+			}else{
+			/* disable all the usb interrupt in PIC */
+				_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+				lo &= ~(0xf << 8);
+				_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+			}
+			break;
+		default :
+			break;			
+	}
+	
+	return;
+}
+
+/*
+ * ohci_read : ohci read transfering.
+ */
+static u32 pci_ohci_read_reg(int reg)
+{
+	u32 conf_data;
+	u32 hi, lo;
+	
+	switch(reg){
+		case PCI_ID_REG :
+			conf_data = (CS5536_OHCI_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+			break;
+		case PCI_COMMAND_STATUS_REG :
+			conf_data = 0;
+			// COMMAND
+			_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+			if(hi & 0x04)
+				conf_data |= PCI_COMMAND_MASTER_ENABLE;
+			if(hi & 0x02)
+				conf_data |= PCI_COMMAND_MEM_ENABLE;
+			// STATUS
+			conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+			conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if(lo & SB_PARE_ERR_FLAG)
+				conf_data |= PCI_STATUS_PARITY_ERROR;
+			conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+			break;
+		case PCI_CLASS_REG :
+			_rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
+			conf_data = lo & 0x000000ff;
+			conf_data |= (CS5536_OHCI_CLASS_CODE << 8);
+			break;
+		case PCI_BHLC_REG :
+			conf_data = (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) |
+				(0x00 << 8) | PCI_NORMAL_CACHE_LINE_SIZE;
+			break;
+		case PCI_BAR0_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_OHCI_FLAG){
+				conf_data = CS5536_OHCI_RANGE | PCI_MAPREG_TYPE_MEM;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_OHCI_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+				//conf_data = lo >> 8;
+				conf_data = lo & 0xffffff00;
+				conf_data &= ~0x0000000f; // 32bit mem
+			}
+			break;
+		case PCI_BAR1_REG :
+			conf_data = 0x000000;
+			break;		
+		case PCI_BAR2_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_BAR3_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_BAR4_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_BAR5_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_CARDBUS_CIS_REG :
+			conf_data = PCI_CARDBUS_CIS_POINTER;
+			break;
+		case PCI_SUBSYS_ID_REG :
+			conf_data = (CS5536_OHCI_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+			break;
+		case PCI_MAPREG_ROM :
+			conf_data = PCI_EXPANSION_ROM_BAR;
+			break;
+		case PCI_CAPLISTPTR_REG :
+			conf_data = PCI_CAPLIST_USB_POINTER;
+			break;
+		case PCI_INTERRUPT_REG :
+			conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | 
+				(PCI_DEFAULT_PIN << 8) | (CS5536_USB_INTR);
+			break;
+		case PCI_OHCI_PM_REG :
+			conf_data = 0;
+			break;
+		case PCI_OHCI_INT_REG :
+			_rdmsr(DIVIL_MSR_REG(0x20), &hi, &lo);
+			if((lo & 0x00000f00) == 11)
+				conf_data = 1;
+			else
+				conf_data = 0;
+			break;
+		default :
+			conf_data = 0;
+			break;
+	}
+
+	return conf_data;
+}
+
+#ifdef	TEST_CS5536_USE_EHCI
+static void pci_ehci_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+	
+	switch(reg){
+		case PCI_COMMAND_STATUS_REG :
+			// COMMAND
+			if(value & PCI_COMMAND_MASTER_ENABLE){
+				_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+				hi |= (1 << 2);
+				_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+			}else{
+				_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+				hi &= ~(1 << 2);
+				_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+			}
+			if(value & PCI_COMMAND_MEM_ENABLE){
+				_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+				hi |= (1 << 1);
+				_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+			}else{
+				_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+				hi &= ~(1 << 1);
+				_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);				
+			}
+			// STATUS
+			if(value & PCI_STATUS_PARITY_ERROR){
+				_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+				if(lo & SB_PARE_ERR_FLAG){
+					lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+					_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+				}				
+			}
+			break;
+		case PCI_BAR0_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_EHCI_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if( (value & 0x01) == 0x00 ){
+				_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+				lo = value;
+				_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+				
+				value &= 0xfffffff0;
+				hi = 0x40000000 | ((value & 0xff000000) >> 24);
+				lo = 0x000fffff | ((value & 0x00fff000) << 8);
+				_wrmsr(GLIU_MSR_REG(GLIU_P2D_BM4), hi, lo);
+			}
+			break;
+		case PCI_EHCI_LEGSMIEN_REG :
+			_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+			hi &= 0x003f0000;
+			hi |= (value & 0x3f) << 16;
+			_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+			break;
+		case PCI_EHCI_FLADJ_REG :
+			_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+			hi &= ~0x00003f00;
+			hi |= value & 0x00003f00;
+			_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+			break;
+		default :
+			break;			
+	}
+	
+	return;
+}
+
+static u32 pci_ehci_read_reg(int reg)
+{
+	u32 conf_data;
+	u32 hi, lo;
+	
+	switch(reg){
+		case PCI_ID_REG :
+			conf_data = (CS5536_EHCI_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+			break;
+		case PCI_COMMAND_STATUS_REG :
+			conf_data = 0;
+			// COMMAND
+			_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+			if(hi & 0x04)
+				conf_data |= PCI_COMMAND_MASTER_ENABLE;
+			if(hi & 0x02)
+				conf_data |= PCI_COMMAND_MEM_ENABLE;
+			// STATUS
+			conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+			conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if(lo & SB_PARE_ERR_FLAG)
+				conf_data |= PCI_STATUS_PARITY_ERROR;
+			conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+			break;
+		case PCI_CLASS_REG :
+			_rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
+			conf_data = lo & 0x000000ff;
+			conf_data |= (CS5536_EHCI_CLASS_CODE << 8);
+			break;
+		case PCI_BHLC_REG :
+			conf_data = (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) |
+				(PCI_NORMAL_LATENCY_TIMER << 8) | PCI_NORMAL_CACHE_LINE_SIZE;
+			break;
+		case PCI_BAR0_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_EHCI_FLAG){
+				conf_data = CS5536_EHCI_RANGE | PCI_MAPREG_TYPE_MEM;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_EHCI_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+				conf_data = lo & 0xfffff000;
+			}
+			break;
+		case PCI_BAR1_REG :
+			conf_data = 0x000000;
+			break;		
+		case PCI_BAR2_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_BAR3_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_BAR4_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_BAR5_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_CARDBUS_CIS_REG :
+			conf_data = PCI_CARDBUS_CIS_POINTER;
+			break;
+		case PCI_SUBSYS_ID_REG :
+			conf_data = (CS5536_EHCI_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+			break;
+		case PCI_MAPREG_ROM :
+			conf_data = PCI_EXPANSION_ROM_BAR;
+			break;
+		case PCI_CAPLISTPTR_REG :
+			conf_data = PCI_CAPLIST_USB_POINTER;
+			break;
+		case PCI_INTERRUPT_REG :
+			conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | 
+				(PCI_DEFAULT_PIN << 8) | (CS5536_USB_INTR);
+			break;
+		case PCI_EHCI_LEGSMIEN_REG :
+			_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+			conf_data = (hi & 0x003f0000) >> 16;
+			break;
+		case PCI_EHCI_LEGSMISTS_REG :
+			_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+			conf_data = (hi & 0x3f000000) >> 24;
+			break;
+		case PCI_EHCI_FLADJ_REG :
+			_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+			conf_data = hi & 0x00003f00;
+			break;
+		default :
+			conf_data = 0;
+			break;
+	}
+
+	return conf_data;
+}
+#else
+static void pci_ehci_write_reg(int reg, u32 value)
+{
+	return;
+}
+
+static u32 pci_ehci_read_reg(int reg)
+{
+	return  0xffffffff;
+}
+
+
+#endif
+
+#ifdef	TEST_CS5536_USE_UDC
+static void pci_udc_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+	
+	switch(reg){
+		case PCI_COMMAND_STATUS_REG :
+			// COMMAND
+			if(value & PCI_COMMAND_MASTER_ENABLE){
+				_rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo);
+				hi |= (1 << 2);
+				_wrmsr(USB_MSR_REG(USB_UDC), hi, lo);
+			}else{
+				_rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo);
+				hi &= ~(1 << 2);
+				_wrmsr(USB_MSR_REG(USB_UDC), hi, lo);
+			}
+			if(value & PCI_COMMAND_MEM_ENABLE){
+				_rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo);
+				hi |= (1 << 1);
+				_wrmsr(USB_MSR_REG(USB_UDC), hi, lo);
+			}else{
+				_rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo);
+				hi &= ~(1 << 1);
+				_wrmsr(USB_MSR_REG(USB_UDC), hi, lo);				
+			}
+			// STATUS
+			if(value & PCI_STATUS_PARITY_ERROR){
+				_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+				if(lo & SB_PARE_ERR_FLAG){
+					lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+					_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+				}				
+			}
+			break;
+		case PCI_BAR0_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_UDC_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if( (value & 0x01) == 0x00 ){
+				_rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo);
+				lo = value;
+				_wrmsr(USB_MSR_REG(USB_UDC), hi, lo);
+				
+				value &= 0xfffffff0;
+				hi = 0x40000000 | ((value & 0xff000000) >> 24);
+				lo = 0x000fffff | ((value & 0x00fff000) << 8);
+				_wrmsr(GLIU_MSR_REG(GLIU_P2D_BM0), hi, lo);
+			}
+			break;
+		default :
+			break;			
+	}
+	
+	return;
+}
+
+static u32 pci_udc_read_reg(int reg)
+{
+	u32 conf_data;
+	u32 hi, lo;
+	
+	switch(reg){
+		case PCI_ID_REG :
+			conf_data = (CS5536_UDC_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+			break;
+		case PCI_COMMAND_STATUS_REG :
+			conf_data = 0;
+			// COMMAND
+			_rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo);
+			if(hi & 0x04)
+				conf_data |= PCI_COMMAND_MASTER_ENABLE;
+			if(hi & 0x02)
+				conf_data |= PCI_COMMAND_MEM_ENABLE;
+			// STATUS
+			conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+			conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if(lo & SB_PARE_ERR_FLAG)
+				conf_data |= PCI_STATUS_PARITY_ERROR;
+			conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+			break;
+		case PCI_CLASS_REG :
+			_rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
+			conf_data = lo & 0x000000ff;
+			conf_data |= (CS5536_UDC_CLASS_CODE << 8);
+			break;
+		case PCI_BHLC_REG :
+			conf_data = (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) |
+				(0x00 << 8) | PCI_NORMAL_CACHE_LINE_SIZE;
+			break;
+		case PCI_BAR0_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_UDC_FLAG){
+				conf_data = CS5536_UDC_RANGE | PCI_MAPREG_TYPE_MEM;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_UDC_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo);
+				conf_data = lo & 0xfffff000;
+				conf_data &= ~0x0000000f; // 32bit mem
+			}
+			break;
+		case PCI_BAR1_REG :
+			conf_data = 0x000000;
+			break;		
+		case PCI_BAR2_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_BAR3_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_BAR4_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_BAR5_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_CARDBUS_CIS_REG :
+			conf_data = PCI_CARDBUS_CIS_POINTER;
+			break;
+		case PCI_SUBSYS_ID_REG :
+			conf_data = (CS5536_UDC_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+			break;
+		case PCI_MAPREG_ROM :
+			conf_data = PCI_EXPANSION_ROM_BAR;
+			break;
+		case PCI_CAPLISTPTR_REG :
+			conf_data = PCI_CAPLIST_USB_POINTER;
+			break;
+		case PCI_INTERRUPT_REG :
+			conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | 
+				(PCI_DEFAULT_PIN << 8) | (CS5536_USB_INTR);
+			break;
+		default :
+			conf_data = 0;
+			break;
+	}
+
+	return conf_data;
+}
+
+#else	/* TEST_CS5536_USE_UDC */
+
+static void pci_udc_write_reg(int reg, u32 value)
+{
+	return;
+}
+
+static u32 pci_udc_read_reg(int reg)
+{
+	return  0xffffffff;
+}
+
+#endif	/* TEST_CS5536_USE_UDC */
+
+
+#ifdef	TEST_CS5536_USE_OTG
+static void pci_otg_write_reg(int reg, u32 value)
+{
+	u32 hi, lo;
+	
+	switch(reg){
+		case PCI_COMMAND_STATUS_REG :
+			// COMMAND
+			if(value & PCI_COMMAND_MEM_ENABLE){
+				_rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo);
+				hi |= (1 << 1);
+				_wrmsr(USB_MSR_REG(USB_OTG), hi, lo);
+			}else{
+				_rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo);
+				hi &= ~(1 << 1);
+				_wrmsr(USB_MSR_REG(USB_OTG), hi, lo);				
+			}
+			// STATUS
+			if(value & PCI_STATUS_PARITY_ERROR){
+				_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+				if(lo & SB_PARE_ERR_FLAG){
+					lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+					_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+				}				
+			}
+			break;
+		case PCI_BAR0_REG :
+			if(value == PCI_BAR_RANGE_MASK){
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo |= SOFT_BAR_OTG_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else if( (value & 0x01) == 0x00 ){
+				_rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo);
+				lo = value & 0xffffff00;
+				_wrmsr(USB_MSR_REG(USB_OTG), hi, lo);
+				
+				value &= 0xfffffff0;
+				hi = 0x40000000 | ((value & 0xff000000) >> 24);
+				lo = 0x000fffff | ((value & 0x00fff000) << 8);
+				_wrmsr(GLIU_MSR_REG(GLIU_P2D_BM1), hi, lo);
+			}
+			break;
+		default :
+			break;			
+	}
+	
+	return;
+}
+
+static u32 pci_otg_read_reg(int reg)
+{
+	u32 conf_data;
+	u32 hi, lo;
+	
+	switch(reg){
+		case PCI_ID_REG :
+			conf_data = (CS5536_OTG_DEVICE_ID << 16 | CS5536_VENDOR_ID);
+			break;
+		case PCI_COMMAND_STATUS_REG :
+			conf_data = 0;
+			// COMMAND
+			_rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo);
+			if(hi & 0x02)
+				conf_data |= PCI_COMMAND_MEM_ENABLE;
+			// STATUS
+			conf_data |= PCI_STATUS_66MHZ_SUPPORT;
+			conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT;
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if(lo & SB_PARE_ERR_FLAG)
+				conf_data |= PCI_STATUS_PARITY_ERROR;
+			conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+			break;
+		case PCI_CLASS_REG :
+			_rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
+			conf_data = lo & 0x000000ff;
+			conf_data |= (CS5536_OTG_CLASS_CODE << 8);
+			break;
+		case PCI_BHLC_REG :
+			conf_data = (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) |
+				(0x00 << 8) | PCI_NORMAL_CACHE_LINE_SIZE;
+			break;
+		case PCI_BAR0_REG :
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			if(lo & SOFT_BAR_OTG_FLAG){
+				conf_data = CS5536_OTG_RANGE | PCI_MAPREG_TYPE_MEM;
+				_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+				lo &= ~SOFT_BAR_OTG_FLAG;
+				_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+			}else{
+				_rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo);
+				conf_data = lo & 0xffffff00;
+				conf_data &= ~0x0000000f;
+			}
+			break;
+		case PCI_BAR1_REG :
+			conf_data = 0x000000;
+			break;		
+		case PCI_BAR2_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_BAR3_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_BAR4_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_BAR5_REG :
+			conf_data = 0x000000;
+			break;
+		case PCI_CARDBUS_CIS_REG :
+			conf_data = PCI_CARDBUS_CIS_POINTER;
+			break;
+		case PCI_SUBSYS_ID_REG :
+			conf_data = (CS5536_OTG_SUB_ID << 16) | CS5536_SUB_VENDOR_ID;
+			break;
+		case PCI_MAPREG_ROM :
+			conf_data = PCI_EXPANSION_ROM_BAR;
+			break;
+		case PCI_CAPLISTPTR_REG :
+			conf_data = PCI_CAPLIST_USB_POINTER;
+			break;
+		case PCI_INTERRUPT_REG :
+			conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | 
+				(PCI_DEFAULT_PIN << 8) | (CS5536_USB_INTR);
+			break;
+		default :
+			conf_data = 0;
+			break;
+	}
+
+	return conf_data;
+}
+
+#else	/* TEST_CS5536_USE_OTG */
+
+static void pci_otg_write_reg(int reg, u32 value)
+{
+	return;
+}
+
+static u32 pci_otg_read_reg(int reg)
+{
+	return 0xffffffff;
+}
+
+#endif	/* TEST_CS5536_USE_OTG */
+
+/*******************************************************************************/
+
+/*
+ * writen : write to PCI config space and transfer it to MSR write.
+ */
+void cs5536_pci_conf_write4(int function, int reg, u32 value)
+{
+	/* some basic checking. */
+	if( (function < CS5536_FUNC_START) || (function > CS5536_FUNC_END) ){
+		return;
+	}
+	if( (reg < 0) || (reg > 0x100) || ((reg & 0x03) != 0) ){
+		return;
+	}
+	
+	switch(function){
+		case CS5536_ISA_FUNC :
+			pci_isa_write_reg(reg, value);		
+			break;
+
+		case CS5536_FLASH_FUNC :
+			pci_flash_write_reg(reg, value);
+			break;
+		
+		case CS5536_IDE_FUNC :
+			pci_ide_write_reg(reg, value);
+			break;
+
+		case CS5536_ACC_FUNC :
+			pci_acc_write_reg(reg, value);
+			break;
+
+		case CS5536_OHCI_FUNC :
+			pci_ohci_write_reg(reg, value);
+			break;
+
+		case CS5536_EHCI_FUNC :
+			pci_ehci_write_reg(reg, value);
+			break;
+
+		case CS5536_UDC_FUNC :
+			pci_udc_write_reg(reg, value);
+			break;
+
+		case CS5536_OTG_FUNC :
+			pci_otg_write_reg(reg, value);
+			break;
+		
+		default :
+			break;
+	}
+	
+	return;
+}
+
+/*
+ * readn : read PCI config space and transfer it to MSR access.
+ */
+u32 cs5536_pci_conf_read4(int function, int reg)
+{
+	u32 data = 0;
+
+	/* some basic checking. */
+	if( (function < CS5536_FUNC_START) || (function > CS5536_FUNC_END) ){
+		return 0;
+	}
+	if( (reg < 0) || ((reg & 0x03) != 0) ){
+		return 0;
+	}
+	if( reg > 0x100 )
+		return 0xffffffff;
+	
+	switch(function){
+		case CS5536_ISA_FUNC :
+			data = pci_isa_read_reg(reg);
+			break;
+
+		case CS5536_FLASH_FUNC :
+			data = pci_flash_read_reg(reg);
+			break;
+		
+		case CS5536_IDE_FUNC :
+			data = pci_ide_read_reg(reg);
+			break;
+
+		case CS5536_ACC_FUNC :
+			data = pci_acc_read_reg(reg);
+			break;
+
+		case CS5536_OHCI_FUNC :
+			data = pci_ohci_read_reg(reg);
+			break;
+
+		case CS5536_EHCI_FUNC :
+			data = pci_ehci_read_reg(reg);
+			break;
+
+		case CS5536_UDC_FUNC :
+			data = pci_udc_read_reg(reg);
+			break;
+
+		case CS5536_OTG_FUNC :
+			data = pci_otg_read_reg(reg);
+			break;
+		
+		default :
+			break;
+	
+	}
+	
+	return data;
+}
+
+/**************************************************************************/
+
diff -Nur linux-2.6.26.orig/arch/mips/lemote/lm2f/dbg_io.c linux-2.6.26.2f/arch/mips/lemote/lm2f/dbg_io.c
--- linux-2.6.26.orig/arch/mips/lemote/lm2f/dbg_io.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/lemote/lm2f/dbg_io.c	2008-08-29 13:45:15.715803859 +0800
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/io.h>
+#include <asm/types.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <asm/serial.h>		/* For the serial port location and base baud */
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+/* ----------------------------------------------------- */
+
+//#define	USE_LOONGSON2F_UART
+#ifdef	USE_LOONGSON2F_UART
+
+/* === CONFIG === */
+#ifdef CONFIG_64BIT
+#define         BASE                    (0xffffffffbff003f8)
+#else
+#define         BASE                    (0xbff003f8)
+#endif
+
+#else	/* USE_CS5536_UART1/2 */
+
+#ifdef CONFIG_64BIT
+#define         BASE                    0xffffffffbfd002f8
+#else
+#define         BASE                    0xbfd002f8
+#endif
+
+#endif	/* end of USE_LOONGSON2F_UART */
+
+#define         MAX_BAUD                BASE_BAUD
+/* === END OF CONFIG === */
+
+#define         REG_OFFSET              1
+
+/* register offset */
+#define         OFS_RCV_BUFFER          0
+#define         OFS_TRANS_HOLD          0
+#define         OFS_SEND_BUFFER         0
+#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
+#define         OFS_INTR_ID             (2*REG_OFFSET)
+#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
+#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
+#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
+#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
+#define         OFS_LINE_STATUS         (5*REG_OFFSET)
+#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
+#define         OFS_RS232_INPUT         (6*REG_OFFSET)
+#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
+
+#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
+#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
+
+/* memory-mapped read/write of the port */
+#define         UART16550_READ(y)    (*((volatile u8*)(BASE + y)))
+#define         UART16550_WRITE(y, z)  ((*((volatile u8*)(BASE + y))) = z)
+
+void debugInit(u32 baud, u8 data, u8 parity, u8 stop)
+{
+	/* disable interrupts */
+	UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+	/* set up buad rate */
+	{
+		u32 divisor;
+
+		/* set DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+		/* set divisor */
+		divisor = MAX_BAUD / baud;
+		UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+		UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+		/* clear DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+	}
+
+	/* set data format */
+	UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+static int remoteDebugInitialized = 0;
+
+u8 getDebugChar(void)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_115200,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0) ;
+	return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+int putDebugChar(u8 byte)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		/*
+		   debugInit(UART16550_BAUD_115200,
+		   UART16550_DATA_8BIT,
+		   UART16550_PARITY_NONE, UART16550_STOP_1BIT); */
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0) ;
+	UART16550_WRITE(OFS_SEND_BUFFER, byte);
+	return 1;
+}
+
+extern void prom_putchar(char c);
+
+void prom_printf(char *fmt, ...)
+{
+	va_list args;
+	char ppbuf[1024];
+	char *bptr;
+
+	va_start(args, fmt);
+	vsprintf(ppbuf, fmt, args);
+
+	bptr = ppbuf;
+
+	while (*bptr != 0) {
+		if (*bptr == '\n')
+			prom_putchar('\r');
+
+		prom_putchar(*bptr++);
+	}
+	va_end(args);
+}
diff -Nur linux-2.6.26.orig/arch/mips/lemote/lm2f/irq.c linux-2.6.26.2f/arch/mips/lemote/lm2f/irq.c
--- linux-2.6.26.orig/arch/mips/lemote/lm2f/irq.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/lemote/lm2f/irq.c	2008-08-28 14:41:19.853390845 +0800
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/irq_cpu.h>
+#include <asm/i8259.h>
+#include <asm/mipsregs.h>
+#include <asm/delay.h>
+#include <asm/mips-boards/bonito64.h>
+
+#define	BONITO_INT_BIT_GPIO0		(1 << 0)
+#define	BONITO_INT_BIT_GPIO1		(1 << 1)
+#define	BONITO_INT_BIT_GPIO2		(1 << 2)
+#define	BONITO_INT_BIT_GPIO3		(1 << 3)
+#define	BONITO_INT_BIT_PCI_INTA		(1 << 4)
+#define	BONITO_INT_BIT_PCI_INTB		(1 << 5)
+#define	BONITO_INT_BIT_PCI_INTC		(1 << 6)
+#define	BONITO_INT_BIT_PCI_INTD		(1 << 7)
+#define	BONITO_INT_BIT_PCI_PERR		(1 << 8)
+#define	BONITO_INT_BIT_PCI_SERR		(1 << 9)
+#define	BONITO_INT_BIT_DDR		(1 << 10)
+#define	BONITO_INT_BIT_INT0		(1 << 11)
+#define	BONITO_INT_BIT_INT1		(1 << 12)
+#define	BONITO_INT_BIT_INT2		(1 << 13)
+#define	BONITO_INT_BIT_INT3		(1 << 14)
+
+#define	BONITO_INT_TIMER_OFF		7
+#define	BONITO_INT_BONITO_OFF		6
+#define	BONITO_INT_UART_OFF			3
+#define	BONITO_INT_I8259_OFF		2
+
+/****************************************************************/
+
+static void godson2f_timer_dispatch(void)
+{
+	/* place the godson2f timer interrupt on 23 */
+	do_IRQ(MIPS_CPU_IRQ_BASE + BONITO_INT_TIMER_OFF);
+	return;
+}
+
+static void godson2f_bonito_dispatch(void)
+{
+	int int_status;
+	int i = 0;
+
+	/* place the other interrupt on bit6 for bonito, inclding PCI and so on */
+	int_status = BONITO_INTISR & BONITO_INTEN;
+	
+	for(i = 0; (i < 10) && int_status; i++){
+		if(int_status & (1 << i)){
+			if(i == 10)
+				printk("ddr int.\n");
+			if(int_status & 0x000000f0)
+				do_IRQ(BONITO_IRQ_BASE + i);
+			int_status &= ~(1 << i);
+		}
+	}
+	
+	return;
+}
+
+static void godson2f_int3_dispatch(void)
+{
+	int int_status;
+	
+	int_status = BONITO_INTISR & BONITO_INTEN;
+	if(int_status & BONITO_INT_BIT_INT3){
+	//	printk("bonito int3 occurred. check your mother board.\n");
+	}
+	
+	return;
+}
+
+static void godson2f_int2_dispatch(void)
+{
+	int int_status;
+	
+	int_status = BONITO_INTISR & BONITO_INTEN;
+	if(int_status & BONITO_INT_BIT_INT2){
+	//	printk("bonito int2 occurred. check your mother board.\n");
+	}
+	
+	return;
+}
+
+static void godson2f_int1_dispatch(void)
+{
+	/* place the godson2f uart interrupt on int1 */
+	do_IRQ(MIPS_CPU_IRQ_BASE + BONITO_INT_UART_OFF);
+}
+
+static void i8259_irqdispatch(void)
+{
+	int irq, isr;
+	extern unsigned int cached_irq_mask;
+
+	if((BONITO_INTISR & BONITO_INTEN) & BONITO_INT_BIT_INT0) {
+
+		isr = inb(0x20) | (inb(0xa0) << 8);
+		isr &= ~0x4; // irq2 for cascade
+		isr &= ~cached_irq_mask;
+		irq = ffs(isr) - 1;
+
+		if(irq >= 0) {
+			do_IRQ(irq);
+		} else {
+			spurious_interrupt();
+		}
+	}
+}
+
+static void godson2f_steer1_dispatch(void)
+{
+	printk(KERN_INFO "godson2f steer1 is not used yet.\n");
+	return;
+}
+
+static void godson2f_steer0_dispatch(void)
+{
+	printk(KERN_INFO "godson2f steer0 is not used yet.\n");
+	return;
+}
+
+
+asmlinkage void plat_irq_dispatch(void)
+{
+	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+
+	if(pending & CAUSEF_IP7){
+		godson2f_timer_dispatch();
+	}else if(pending & CAUSEF_IP6){ /*nb*/
+		godson2f_bonito_dispatch();
+	}else if(pending & CAUSEF_IP5){
+		godson2f_int3_dispatch();
+	}else if(pending & CAUSEF_IP4){
+		godson2f_int2_dispatch();
+	}else if(pending & CAUSEF_IP3){ /*cpu uart*/
+		godson2f_int1_dispatch();
+	}else if(pending & CAUSEF_IP2){ /*sb*/
+		i8259_irqdispatch();
+	}else if(pending & CAUSEF_IP1){
+		godson2f_steer1_dispatch();
+	}else if(pending & CAUSEF_IP0){
+		godson2f_steer0_dispatch();
+	}else{
+		spurious_interrupt();
+	}
+	return;
+}
+
+static struct irqaction cascade_irqaction = {
+	.handler = no_action,
+	.mask = CPU_MASK_NONE,
+	.name = "cascade",
+};
+
+void __init arch_init_irq(void)
+{
+	extern void bonito_irq_init(void);
+
+	/*
+	 * Clear all of the interrupts while we change the able around a bit.
+	 * int-handler is not on bootstrap
+	 */
+	clear_c0_status(ST0_IM | ST0_BEV);
+	local_irq_disable();
+	
+#if	0
+	/* most bonito irq should be level triggered */
+	BONITO_INTEDGE = BONITO_ICU_SYSTEMERR | BONITO_ICU_MASTERERR
+	    | BONITO_ICU_RETRYERR | BONITO_ICU_MBOXES;
+#endif
+
+	/* setup cs5536 as high level */
+	BONITO_INTPOL  = (1 << 11 | 1 << 12);
+	BONITO_INTEDGE &= ~(1 << 11 | 1 << 12);
+
+	/* no steer */
+	BONITO_INTSTEER = 0;
+
+	/*
+	 * Mask out all interrupt by writing "1" to all bit position in
+	 * the interrupt reset reg.
+	 */
+	BONITO_INTENCLR = ~0;
+
+	/* init all controller
+	 *   0-15         ------> i8259 interrupt
+	 *   16-23        ------> mips cpu interrupt
+	 *   32-63        ------> bonito irq
+	 */
+	
+	/* Sets the first-level interrupt dispatcher. */
+	mips_cpu_irq_init();
+
+	init_i8259_irqs();
+	bonito_irq_init();
+	
+	/* setup bonito interrupt */
+	setup_irq(MIPS_CPU_IRQ_BASE + BONITO_INT_BONITO_OFF, &cascade_irqaction);
+	/* 8259 irq at IP2 */
+	setup_irq(MIPS_CPU_IRQ_BASE + BONITO_INT_I8259_OFF, &cascade_irqaction);
+
+}
diff -Nur linux-2.6.26.orig/arch/mips/lemote/lm2f/mem.c linux-2.6.26.2f/arch/mips/lemote/lm2f/mem.c
--- linux-2.6.26.orig/arch/mips/lemote/lm2f/mem.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/lemote/lm2f/mem.c	2008-08-28 14:41:19.501549374 +0800
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+#include <linux/fs.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+
+/* override of arch/mips/mm/cache.c: __uncached_access */
+int __uncached_access(struct file *file, unsigned long addr)
+{
+	if (file->f_flags & O_SYNC)
+		return 1;
+
+	/*
+	 * On the Lemote Loongson 2e system, the peripheral registers
+	 * reside between 0x1000:0000 and 0x2000:0000.
+	 */
+	return addr >= __pa(high_memory) ||
+		((addr >= 0x10000000) && (addr < 0x80000000));
+}
diff -Nur linux-2.6.26.orig/arch/mips/lemote/lm2f/mipsdha.c linux-2.6.26.2f/arch/mips/lemote/lm2f/mipsdha.c
--- linux-2.6.26.orig/arch/mips/lemote/lm2f/mipsdha.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/lemote/lm2f/mipsdha.c	2008-08-28 14:41:19.625094781 +0800
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+static ssize_t mipsdha_proc_read(struct file *file, char *buf, size_t len, loff_t *ppos);
+
+static ssize_t mipsdha_proc_write(struct file *file, const char *buf, size_t len, loff_t *ppos);
+
+
+static struct proc_dir_entry *mipsdha_proc_entry;
+
+#define INFO_SIZE 4096
+static char info_buf[INFO_SIZE];
+
+static struct file_operations mipsdha_fops =
+{
+    owner:	THIS_MODULE,
+    read:	mipsdha_proc_read,
+    write:	mipsdha_proc_write,
+};
+
+static enum {CMD_ERR, CMD_GIB, CMD_GPI} cmd;
+
+typedef struct pciinfo_s
+{
+  int		bus,card,func;
+  unsigned short command;
+  unsigned short vendor,device;
+  unsigned	base0,base1,base2,baserom;
+} pciinfo_t;
+
+
+extern struct proc_dir_entry proc_root;
+
+static int __init mipsdha_proc_init(void)
+{
+	mipsdha_proc_entry = create_proc_entry("mipsdha", S_IWUSR | S_IRUGO, &proc_root);
+	if (mipsdha_proc_entry == NULL) {
+		printk("MIPSDHA: register /proc/mipsdha failed!\n");
+		return 0;
+	}
+	
+	mipsdha_proc_entry->owner = THIS_MODULE;
+	mipsdha_proc_entry->proc_fops = &mipsdha_fops;
+
+	cmd=CMD_ERR;
+	return 0;
+}
+
+static ssize_t mipsdha_proc_write (struct file *file, const char *buf, size_t len, loff_t *ppos)
+{
+	char cmd_gib[]="GET IO BASE";
+	char cmd_gpi[]="GET PCI INFO";
+
+	if (len >= INFO_SIZE) return -ENOMEM;
+
+	if (copy_from_user(info_buf, buf, len)) return -EFAULT;
+	info_buf[len] = '\0';
+
+	if (strncmp(info_buf, cmd_gib, sizeof(cmd_gib)-1)==0) {
+		cmd = CMD_GIB;
+		return len;
+	} else if (strncmp(info_buf, cmd_gpi, sizeof(cmd_gpi)-1)==0) {
+		cmd = CMD_GPI;
+		return len;
+	} else {
+		return -EINVAL;
+	}
+}
+
+static ssize_t mipsdha_proc_read (struct file *file, char *buf, size_t len, loff_t *ppos)
+{
+	int info_cnt;
+	pciinfo_t *pciinfo;
+	struct pci_dev *dev = NULL;
+
+	switch (cmd) {
+		default:
+			printk("MIPSDHA: BUG found in function %s!(cmd=%d)\n", 
+					__FUNCTION__, cmd);
+			return -EINVAL;
+
+
+		case CMD_ERR:
+			return -EINVAL;
+
+
+		case CMD_GIB:
+			*(unsigned long *)info_buf = 
+				virt_to_phys((void *) mips_io_port_base);
+			info_cnt=sizeof(unsigned long);
+			break;
+
+
+		case CMD_GPI:
+			pciinfo = (pciinfo_t *) info_buf;
+			info_cnt = 0;
+			for_each_pci_dev(dev) {
+
+				if (info_cnt+sizeof(pciinfo_t)>INFO_SIZE) return -ENOMEM;
+
+				pciinfo->bus = dev->bus->number;
+				pciinfo->card = PCI_SLOT(dev->devfn);
+				pciinfo->func = PCI_FUNC(dev->devfn);
+
+				if (pci_read_config_word(dev, PCI_COMMAND, &pciinfo->command)
+						!= PCIBIOS_SUCCESSFUL) {
+					printk("MIPSDHA: BUG found in function %s!\n", 
+							__FUNCTION__);
+					pciinfo->command=0;
+				}
+
+				pciinfo->vendor = dev->vendor;
+				pciinfo->device = dev->device;
+
+				pciinfo->base0 = (dev->resource[0]).start;
+				pciinfo->base1 = (dev->resource[1]).start;
+				pciinfo->base2 = (dev->resource[2]).start;
+				pciinfo->baserom = (dev->resource[PCI_ROM_RESOURCE]).start;
+
+				pciinfo++;
+				info_cnt += sizeof(pciinfo_t);
+			}
+			break;
+	}
+
+	if (len < info_cnt) return -ENOMEM;
+	if (copy_to_user(buf, info_buf, info_cnt)) return -EFAULT;
+
+	return info_cnt;
+}
+
+__initcall(mipsdha_proc_init);
diff -Nur linux-2.6.26.orig/arch/mips/lemote/lm2f/pci.c linux-2.6.26.2f/arch/mips/lemote/lm2f/pci.c
--- linux-2.6.26.orig/arch/mips/lemote/lm2f/pci.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/lemote/lm2f/pci.c	2008-08-28 14:41:19.319101733 +0800
@@ -0,0 +1,88 @@
+/*
+ * pci.c
+ *
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+extern struct pci_ops loongson2f_pci_pci_ops;
+/* if you want to expand the pci memory space, you should config 64bits kernel too. */
+
+static struct resource loongson2f_pci_mem_resource = {
+	.name   = "LOONGSON2E PCI MEM",
+	.start  = 0x14000000UL,
+	.end    = 0x1fffffffUL,
+	.flags  = IORESOURCE_MEM,
+};
+
+static struct resource loongson2f_pci_io_resource = {
+	.name   = "LOONGSON2E PCI IO MEM",
+	.start  = 0x00004000UL,
+	.end    = 0x0000ffffUL,
+	.flags  = IORESOURCE_IO,
+};
+
+
+static struct pci_controller  loongson2f_pci_controller = {
+	.pci_ops        = &loongson2f_pci_pci_ops,
+	.io_resource    = &loongson2f_pci_io_resource,
+	.mem_resource   = &loongson2f_pci_mem_resource,
+	.mem_offset     = 0x00000000UL,
+	.io_offset      = 0x00000000UL,
+};
+
+static int __init pcibios_init(void)
+{
+	extern int pci_probe_only;
+	pci_probe_only = 0;
+
+#ifdef CONFIG_TRACE_BOOT
+	printk(KERN_INFO"arch_initcall:pcibios_init\n");
+	printk(KERN_INFO"register_pci_controller : %x\n",&loongson2f_pci_controller);
+#endif
+	
+#ifdef	CONFIG_64BIT
+	loongson2f_pci_mem_resource.start	= 0x50000000UL; 
+	loongson2f_pci_mem_resource.end		= 0x7fffffffUL;
+	__asm__(".set mips3\n"
+	            "dli $2,0x900000003ff00000\n"
+				"li $3,0x40000000\n"
+				"sd $3,0x18($2)\n"
+				"or $3,1\n"
+				"sd $3,0x58($2)\n"
+				"dli $3,0xffffffffc0000000\n"
+				"sd $3,0x38($2)\n"
+				".set mips0\n"
+				:::"$2","$3","memory"
+			   );
+#endif
+	register_pci_controller(&loongson2f_pci_controller);
+	return 0;
+}
+
+arch_initcall(pcibios_init);
diff -Nur linux-2.6.26.orig/arch/mips/lemote/lm2f/pcireg.h linux-2.6.26.2f/arch/mips/lemote/lm2f/pcireg.h
--- linux-2.6.26.orig/arch/mips/lemote/lm2f/pcireg.h	1970-01-01 08:00:00.000000000 +0800
+++ linux-2.6.26.2f/arch/mips/lemote/lm2f/pcireg.h	2008-08-28 14:41:20.005364342 +0800
@@ -0,0 +1,503 @@
+/*	$OpenBSD: pcireg.h,v 1.17 2001/05/08 19:47:43 mickey Exp $	*/
+/*	$NetBSD: pcireg.h,v 1.26 2000/05/10 16:58:42 thorpej Exp $	*/
+
+/*
+ * Copyright (c) 1995, 1996 Christopher G. Demetriou.  All rights reserved.
+ * Copyright (c) 1994, 1996 Charles Hannum.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Charles Hannum.
+ * 4. The name of the author may not be used to 