summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
authorWolfgang Denk <wd@denx.de>2009-12-15 23:38:34 +0100
committerWolfgang Denk <wd@denx.de>2009-12-15 23:38:34 +0100
commitbb3bcfa2426cc6a0aecec7270e3ee67ca843a125 (patch)
tree0314e3d8e8d9e4d568a496fca27db33d66e68bb4 /cpu
parenta200a7c04d89853d2a1395b96d8ca5e3dd754551 (diff)
parent4b142febff71eabdb7ddbb125c7b583b24ddc434 (diff)
downloadu-boot-imx-bb3bcfa2426cc6a0aecec7270e3ee67ca843a125.zip
u-boot-imx-bb3bcfa2426cc6a0aecec7270e3ee67ca843a125.tar.gz
u-boot-imx-bb3bcfa2426cc6a0aecec7270e3ee67ca843a125.tar.bz2
Merge branch 'next' of ../next
Diffstat (limited to 'cpu')
-rw-r--r--cpu/arm1136/mx31/timer.c2
-rw-r--r--cpu/arm1136/omap24xx/timer.c2
-rw-r--r--cpu/arm1176/cpu.c2
-rw-r--r--cpu/arm1176/s3c64xx/cpu_init.S2
-rw-r--r--cpu/arm1176/s3c64xx/reset.S2
-rw-r--r--cpu/arm1176/s3c64xx/speed.c2
-rw-r--r--cpu/arm1176/s3c64xx/timer.c4
-rw-r--r--cpu/arm1176/start.S9
-rw-r--r--cpu/arm720t/interrupts.c4
-rw-r--r--cpu/arm920t/a320/Makefile47
-rw-r--r--cpu/arm920t/a320/ftsmc020.c51
-rw-r--r--cpu/arm920t/a320/reset.S22
-rw-r--r--cpu/arm920t/a320/timer.c193
-rw-r--r--cpu/arm920t/at91rm9200/timer.c2
-rw-r--r--cpu/arm920t/imx/timer.c2
-rw-r--r--cpu/arm920t/ks8695/timer.c2
-rw-r--r--cpu/arm920t/s3c24x0/interrupts.c6
-rw-r--r--cpu/arm920t/s3c24x0/speed.c13
-rw-r--r--cpu/arm920t/s3c24x0/timer.c17
-rw-r--r--cpu/arm920t/s3c24x0/usb.c17
-rw-r--r--cpu/arm920t/s3c24x0/usb_ohci.c11
-rw-r--r--cpu/arm920t/start.S4
-rw-r--r--cpu/arm925t/timer.c2
-rw-r--r--cpu/arm926ejs/at91/timer.c2
-rw-r--r--cpu/arm926ejs/davinci/cpu.c50
-rw-r--r--cpu/arm926ejs/davinci/psc.c43
-rw-r--r--cpu/arm926ejs/davinci/timer.c30
-rw-r--r--cpu/arm926ejs/kirkwood/timer.c2
-rw-r--r--cpu/arm926ejs/mx27/timer.c2
-rw-r--r--cpu/arm926ejs/nomadik/timer.c2
-rw-r--r--cpu/arm926ejs/omap/timer.c2
-rwxr-xr-xcpu/arm926ejs/versatile/timer.c2
-rw-r--r--cpu/arm_cortexa8/omap3/mem.c5
-rw-r--r--cpu/arm_cortexa8/omap3/sys_info.c2
-rw-r--r--cpu/arm_cortexa8/omap3/timer.c2
-rw-r--r--cpu/arm_cortexa8/s5pc1xx/timer.c2
-rw-r--r--cpu/at32ap/Makefile2
-rw-r--r--cpu/at32ap/hsdramc.c3
-rw-r--r--cpu/at32ap/interrupts.c2
-rw-r--r--cpu/blackfin/interrupts.c2
-rw-r--r--cpu/i386/Makefile2
-rw-r--r--cpu/i386/cpu.c11
-rw-r--r--cpu/i386/exceptions.c229
-rw-r--r--cpu/i386/interrupts.c439
-rw-r--r--cpu/i386/sc520/sc520_timer.c13
-rw-r--r--cpu/i386/start.S132
-rw-r--r--cpu/ixp/start.S4
-rw-r--r--cpu/ixp/timer.c2
-rw-r--r--cpu/lh7a40x/timer.c2
-rw-r--r--cpu/mcf547x_8x/slicetimer.c2
-rw-r--r--cpu/mpc512x/cpu.c1
-rw-r--r--cpu/mpc5xxx/cpu.c1
-rw-r--r--cpu/mpc85xx/mp.c4
-rw-r--r--cpu/mpc85xx/u-boot-nand.lds1
-rw-r--r--cpu/ppc4xx/4xx_pci.c253
-rw-r--r--cpu/ppc4xx/4xx_pcie.c119
-rw-r--r--cpu/ppc4xx/cmd_chip_config.c6
-rw-r--r--cpu/ppc4xx/config.mk3
-rw-r--r--cpu/ppc4xx/cpu.c2
-rw-r--r--cpu/ppc4xx/i2c.c199
-rw-r--r--cpu/ppc4xx/u-boot.lds169
-rw-r--r--cpu/pxa/timer.c2
-rw-r--r--cpu/s3c44b0/timer.c2
-rw-r--r--cpu/sa1100/timer.c2
64 files changed, 1560 insertions, 613 deletions
diff --git a/cpu/arm1136/mx31/timer.c b/cpu/arm1136/mx31/timer.c
index 29b484e..7972ba0 100644
--- a/cpu/arm1136/mx31/timer.c
+++ b/cpu/arm1136/mx31/timer.c
@@ -152,7 +152,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND perserve advance timstamp value */
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
unsigned long long tmp;
ulong tmo;
diff --git a/cpu/arm1136/omap24xx/timer.c b/cpu/arm1136/omap24xx/timer.c
index 8dd8d7b..6754749 100644
--- a/cpu/arm1136/omap24xx/timer.c
+++ b/cpu/arm1136/omap24xx/timer.c
@@ -74,7 +74,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND perserve advance timstamp value */
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
ulong tmo, tmp;
diff --git a/cpu/arm1176/cpu.c b/cpu/arm1176/cpu.c
index d1a3327..2c0014f 100644
--- a/cpu/arm1176/cpu.c
+++ b/cpu/arm1176/cpu.c
@@ -33,7 +33,7 @@
#include <common.h>
#include <command.h>
-#include <s3c6400.h>
+#include <asm/arch/s3c6400.h>
#include <asm/system.h>
static void cache_flush (void);
diff --git a/cpu/arm1176/s3c64xx/cpu_init.S b/cpu/arm1176/s3c64xx/cpu_init.S
index 32bb467..df88cba 100644
--- a/cpu/arm1176/s3c64xx/cpu_init.S
+++ b/cpu/arm1176/s3c64xx/cpu_init.S
@@ -24,7 +24,7 @@
*/
#include <config.h>
-#include <s3c6400.h>
+#include <asm/arch/s3c6400.h>
.globl mem_ctrl_asm_init
mem_ctrl_asm_init:
diff --git a/cpu/arm1176/s3c64xx/reset.S b/cpu/arm1176/s3c64xx/reset.S
index 315b13f..eae572e 100644
--- a/cpu/arm1176/s3c64xx/reset.S
+++ b/cpu/arm1176/s3c64xx/reset.S
@@ -21,7 +21,7 @@
* MA 02111-1307 USA
*/
-#include <s3c6400.h>
+#include <asm/arch/s3c6400.h>
.globl reset_cpu
reset_cpu:
diff --git a/cpu/arm1176/s3c64xx/speed.c b/cpu/arm1176/s3c64xx/speed.c
index 5c335a5..11962ac 100644
--- a/cpu/arm1176/s3c64xx/speed.c
+++ b/cpu/arm1176/s3c64xx/speed.c
@@ -31,7 +31,7 @@
*/
#include <common.h>
-#include <s3c6400.h>
+#include <asm/arch/s3c6400.h>
#define APLL 0
#define MPLL 1
diff --git a/cpu/arm1176/s3c64xx/timer.c b/cpu/arm1176/s3c64xx/timer.c
index 22a5b77..9768319 100644
--- a/cpu/arm1176/s3c64xx/timer.c
+++ b/cpu/arm1176/s3c64xx/timer.c
@@ -40,7 +40,7 @@
#include <common.h>
#include <asm/proc-armv/ptrace.h>
-#include <s3c6400.h>
+#include <asm/arch/s3c6400.h>
#include <div64.h>
static ulong timer_load_val;
@@ -164,7 +164,7 @@ void set_timer(ulong t)
timestamp = t * (timer_load_val / (100 * CONFIG_SYS_HZ));
}
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
unsigned long long tmp;
ulong tmo;
diff --git a/cpu/arm1176/start.S b/cpu/arm1176/start.S
index cb891df..68a356d 100644
--- a/cpu/arm1176/start.S
+++ b/cpu/arm1176/start.S
@@ -35,7 +35,7 @@
#ifdef CONFIG_ENABLE_MMU
#include <asm/proc/domain.h>
#endif
-#include <s3c6400.h>
+#include <asm/arch/s3c6400.h>
#if !defined(CONFIG_ENABLE_MMU) && !defined(CONFIG_SYS_PHY_UBOOT_BASE)
#define CONFIG_SYS_PHY_UBOOT_BASE CONFIG_SYS_UBOOT_BASE
@@ -241,16 +241,11 @@ mmu_enable:
skip_hw_init:
/* Set up the stack */
stack_setup:
-#ifdef CONFIG_MEMORY_UPPER_CODE
- ldr sp, =(CONFIG_SYS_UBOOT_BASE + CONFIG_SYS_UBOOT_SIZE - 0xc)
-#else
- ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
+ ldr r0, =CONFIG_SYS_UBOOT_BASE /* base of copy in DRAM */
sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */
sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */
sub sp, r0, #12 /* leave 3 words for abort-stack */
-#endif
-
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
diff --git a/cpu/arm720t/interrupts.c b/cpu/arm720t/interrupts.c
index 91d552c..eb8d425 100644
--- a/cpu/arm720t/interrupts.c
+++ b/cpu/arm720t/interrupts.c
@@ -224,7 +224,7 @@ void set_timer (ulong t)
timestamp = t;
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
ulong tmo;
@@ -296,7 +296,7 @@ ulong get_timer (ulong base)
return timestamp - base;
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
u32 ticks;
diff --git a/cpu/arm920t/a320/Makefile b/cpu/arm920t/a320/Makefile
new file mode 100644
index 0000000..f030c53
--- /dev/null
+++ b/cpu/arm920t/a320/Makefile
@@ -0,0 +1,47 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(SOC).a
+
+SOBJS += reset.o
+COBJS += timer.o
+COBJS += ftsmc020.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm920t/a320/ftsmc020.c b/cpu/arm920t/a320/ftsmc020.c
new file mode 100644
index 0000000..7646537
--- /dev/null
+++ b/cpu/arm920t/a320/ftsmc020.c
@@ -0,0 +1,51 @@
+/*
+ * (C) Copyright 2009 Faraday Technology
+ * Po-Yu Chuang <ratbert@faraday-tech.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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/ftsmc020.h>
+
+struct ftsmc020_config {
+ unsigned int config;
+ unsigned int timing;
+};
+
+static struct ftsmc020_config config[] = CONFIG_SYS_FTSMC020_CONFIGS;
+
+static struct ftsmc020 *smc = (struct ftsmc020 *)CONFIG_FTSMC020_BASE;
+
+static void ftsmc020_setup_bank(unsigned int bank, struct ftsmc020_config *cfg)
+{
+ if (bank > 3) {
+ printf("bank # %u invalid\n", bank);
+ return;
+ }
+
+ writel(cfg->config, &smc->bank[bank].cr);
+ writel(cfg->timing, &smc->bank[bank].tpr);
+}
+
+void ftsmc020_init(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(config); i++)
+ ftsmc020_setup_bank(i, &config[i]);
+}
diff --git a/cpu/arm920t/a320/reset.S b/cpu/arm920t/a320/reset.S
new file mode 100644
index 0000000..12ca527
--- /dev/null
+++ b/cpu/arm920t/a320/reset.S
@@ -0,0 +1,22 @@
+/*
+ * (C) Copyright 2009 Faraday Technology
+ * Po-Yu Chuang <ratbert@faraday-tech.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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+.global reset_cpu
+reset_cpu:
+ b reset_cpu
diff --git a/cpu/arm920t/a320/timer.c b/cpu/arm920t/a320/timer.c
new file mode 100644
index 0000000..bb65593
--- /dev/null
+++ b/cpu/arm920t/a320/timer.c
@@ -0,0 +1,193 @@
+/*
+ * (C) Copyright 2009 Faraday Technology
+ * Po-Yu Chuang <ratbert@faraday-tech.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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/ftpmu010.h>
+#include <asm/arch/fttmr010.h>
+
+static ulong timestamp;
+static ulong lastdec;
+
+static struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE;
+static struct ftpmu010 *pmu = (struct ftpmu010 *)CONFIG_FTPMU010_BASE;
+
+#define TIMER_CLOCK 32768
+#define TIMER_LOAD_VAL 0xffffffff
+
+int timer_init(void)
+{
+ unsigned int oscc;
+ unsigned int cr;
+
+ debug("%s()\n", __func__);
+
+ /* disable timers */
+ writel(0, &tmr->cr);
+
+ /*
+ * use 32768Hz oscillator for RTC, WDT, TIMER
+ */
+
+ /* enable the 32768Hz oscillator */
+ oscc = readl(&pmu->OSCC);
+ oscc &= ~(FTPMU010_OSCC_OSCL_OFF | FTPMU010_OSCC_OSCL_TRI);
+ writel(oscc, &pmu->OSCC);
+
+ /* wait until ready */
+ while (!(readl(&pmu->OSCC) & FTPMU010_OSCC_OSCL_STABLE))
+ ;
+
+ /* select 32768Hz oscillator */
+ oscc = readl(&pmu->OSCC);
+ oscc |= FTPMU010_OSCC_OSCL_RTCLSEL;
+ writel(oscc, &pmu->OSCC);
+
+ /* setup timer */
+ writel(TIMER_LOAD_VAL, &tmr->timer3_load);
+ writel(TIMER_LOAD_VAL, &tmr->timer3_counter);
+ writel(0, &tmr->timer3_match1);
+ writel(0, &tmr->timer3_match2);
+
+ /* we don't want timer to issue interrupts */
+ writel(FTTMR010_TM3_MATCH1 |
+ FTTMR010_TM3_MATCH2 |
+ FTTMR010_TM3_OVERFLOW,
+ &tmr->interrupt_mask);
+
+ cr = readl(&tmr->cr);
+ cr |= FTTMR010_TM3_CLOCK; /* use external clock */
+ cr |= FTTMR010_TM3_ENABLE;
+ writel(cr, &tmr->cr);
+
+ /* init the timestamp and lastdec value */
+ reset_timer_masked();
+
+ return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+
+/*
+ * reset time
+ */
+void reset_timer_masked(void)
+{
+ /* capure current decrementer value time */
+ lastdec = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ);
+ timestamp = 0; /* start "advancing" time stamp from 0 */
+
+ debug("%s(): lastdec = %lx\n", __func__, lastdec);
+}
+
+void reset_timer(void)
+{
+ debug("%s()\n", __func__);
+ reset_timer_masked();
+}
+
+/*
+ * return timer ticks
+ */
+ulong get_timer_masked(void)
+{
+ /* current tick value */
+ ulong now = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ);
+
+ debug("%s(): now = %lx, lastdec = %lx\n", __func__, now, lastdec);
+
+ if (lastdec >= now) {
+ /*
+ * normal mode (non roll)
+ * move stamp fordward with absoulte diff ticks
+ */
+ timestamp += lastdec - now;
+ } else {
+ /*
+ * we have overflow of the count down timer
+ *
+ * nts = ts + ld + (TLV - now)
+ * ts=old stamp, ld=time that passed before passing through -1
+ * (TLV-now) amount of time after passing though -1
+ * nts = new "advancing time stamp"...it could also roll and
+ * cause problems.
+ */
+ timestamp += lastdec + TIMER_LOAD_VAL - now;
+ }
+
+ lastdec = now;
+
+ debug("%s() returns %lx\n", __func__, timestamp);
+
+ return timestamp;
+}
+
+/*
+ * return difference between timer ticks and base
+ */
+ulong get_timer(ulong base)
+{
+ debug("%s(%lx)\n", __func__, base);
+ return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+ debug("%s(%lx)\n", __func__, t);
+ timestamp = t;
+}
+
+/* delay x useconds AND perserve advance timstamp value */
+void udelay(unsigned long usec)
+{
+ long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
+ unsigned long now, last = readl(&tmr->timer3_counter);
+
+ debug("%s(%lu)\n", __func__, usec);
+ while (tmo > 0) {
+ now = readl(&tmr->timer3_counter);
+ if (now > last) /* count down timer overflow */
+ tmo -= TIMER_LOAD_VAL + last - now;
+ else
+ tmo -= last - now;
+ last = now;
+ }
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ debug("%s()\n", __func__);
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ debug("%s()\n", __func__);
+ return CONFIG_SYS_HZ;
+}
diff --git a/cpu/arm920t/at91rm9200/timer.c b/cpu/arm920t/at91rm9200/timer.c
index 235d107..9c54bbe 100644
--- a/cpu/arm920t/at91rm9200/timer.c
+++ b/cpu/arm920t/at91rm9200/timer.c
@@ -87,7 +87,7 @@ void set_timer (ulong t)
timestamp = t;
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
udelay_masked(usec);
}
diff --git a/cpu/arm920t/imx/timer.c b/cpu/arm920t/imx/timer.c
index 31ec588..b06b518 100644
--- a/cpu/arm920t/imx/timer.c
+++ b/cpu/arm920t/imx/timer.c
@@ -89,7 +89,7 @@ void udelay_masked (unsigned long usec)
} while (diff >= 0);
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
udelay_masked(usec);
}
diff --git a/cpu/arm920t/ks8695/timer.c b/cpu/arm920t/ks8695/timer.c
index 22987bc..886e370 100644
--- a/cpu/arm920t/ks8695/timer.c
+++ b/cpu/arm920t/ks8695/timer.c
@@ -81,7 +81,7 @@ void set_timer(ulong t)
timer_ticks = t;
}
-void udelay(ulong usec)
+void __udelay(ulong usec)
{
ulong start = get_timer_masked();
ulong end;
diff --git a/cpu/arm920t/s3c24x0/interrupts.c b/cpu/arm920t/s3c24x0/interrupts.c
index 9148946..879fda6 100644
--- a/cpu/arm920t/s3c24x0/interrupts.c
+++ b/cpu/arm920t/s3c24x0/interrupts.c
@@ -31,11 +31,7 @@
#include <common.h>
-#if defined(CONFIG_S3C2400)
-#include <s3c2400.h>
-#elif defined(CONFIG_S3C2410)
-#include <s3c2410.h>
-#endif
+#include <asm/arch/s3c24x0_cpu.h>
#include <asm/proc-armv/ptrace.h>
void do_irq (struct pt_regs *pt_regs)
diff --git a/cpu/arm920t/s3c24x0/speed.c b/cpu/arm920t/s3c24x0/speed.c
index 136c779..b13283a 100644
--- a/cpu/arm920t/s3c24x0/speed.c
+++ b/cpu/arm920t/s3c24x0/speed.c
@@ -30,15 +30,10 @@
*/
#include <common.h>
-#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB)
+#ifdef CONFIG_S3C24X0
#include <asm/io.h>
-
-#if defined(CONFIG_S3C2400)
-#include <s3c2400.h>
-#elif defined(CONFIG_S3C2410)
-#include <s3c2410.h>
-#endif
+#include <asm/arch/s3c24x0_cpu.h>
#define MPLL 0
#define UPLL 1
@@ -100,6 +95,4 @@ ulong get_UCLK(void)
return get_PLLCLK(UPLL);
}
-#endif /* defined(CONFIG_S3C2400) ||
- defined (CONFIG_S3C2410) ||
- defined (CONFIG_TRAB) */
+#endif /* CONFIG_S3C24X0 */
diff --git a/cpu/arm920t/s3c24x0/timer.c b/cpu/arm920t/s3c24x0/timer.c
index a27f0e2..7d47354 100644
--- a/cpu/arm920t/s3c24x0/timer.c
+++ b/cpu/arm920t/s3c24x0/timer.c
@@ -30,17 +30,10 @@
*/
#include <common.h>
-#if defined(CONFIG_S3C2400) || \
- defined(CONFIG_S3C2410) || \
- defined(CONFIG_TRAB)
+#ifdef CONFIG_S3C24X0
#include <asm/io.h>
-
-#if defined(CONFIG_S3C2400)
-#include <s3c2400.h>
-#elif defined(CONFIG_S3C2410)
-#include <s3c2410.h>
-#endif
+#include <asm/arch/s3c24x0_cpu.h>
int timer_load_val = 0;
static ulong timer_clk;
@@ -106,7 +99,7 @@ void set_timer(ulong t)
timestamp = t;
}
-void udelay(unsigned long usec)
+void __udelay (unsigned long usec)
{
ulong tmo;
ulong start = get_ticks();
@@ -227,6 +220,4 @@ void reset_cpu(ulong ignored)
/*NOTREACHED*/
}
-#endif /* defined(CONFIG_S3C2400) ||
- defined (CONFIG_S3C2410) ||
- defined (CONFIG_TRAB) */
+#endif /* CONFIG_S3C24X0 */
diff --git a/cpu/arm920t/s3c24x0/usb.c b/cpu/arm920t/s3c24x0/usb.c
index b5ba8c4..e468ed0 100644
--- a/cpu/arm920t/s3c24x0/usb.c
+++ b/cpu/arm920t/s3c24x0/usb.c
@@ -23,15 +23,11 @@
#include <common.h>
-#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT)
-# if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
-
-#if defined(CONFIG_S3C2400)
-# include <s3c2400.h>
-#elif defined(CONFIG_S3C2410)
-# include <s3c2410.h>
-#endif
+#if defined(CONFIG_USB_OHCI_NEW) && \
+ defined(CONFIG_SYS_USB_OHCI_CPU_INIT) && \
+ defined(CONFIG_S3C24X0)
+#include <asm/arch/s3c24x0_cpu.h>
#include <asm/io.h>
int usb_cpu_init(void)
@@ -70,5 +66,6 @@ int usb_cpu_init_fail(void)
return 0;
}
-# endif /* defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) */
-#endif /* defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) */
+#endif /* defined(CONFIG_USB_OHCI_NEW) && \
+ defined(CONFIG_SYS_USB_OHCI_CPU_INIT) && \
+ defined(CONFIG_S3C24X0) */
diff --git a/cpu/arm920t/s3c24x0/usb_ohci.c b/cpu/arm920t/s3c24x0/usb_ohci.c
index 7672e4c..5aa8d64 100644
--- a/cpu/arm920t/s3c24x0/usb_ohci.c
+++ b/cpu/arm920t/s3c24x0/usb_ohci.c
@@ -36,14 +36,9 @@
#include <common.h>
/* #include <pci.h> no PCI on the S3C24X0 */
-#ifdef CONFIG_USB_OHCI
-
-#if defined(CONFIG_S3C2400)
-#include <s3c2400.h>
-#elif defined(CONFIG_S3C2410)
-#include <s3c2410.h>
-#endif
+#if defined(CONFIG_USB_OHCI) && defined(CONFIG_S3C24X0)
+#include <asm/arch/s3c24x0_cpu.h>
#include <asm/io.h>
#include <malloc.h>
#include <usb.h>
@@ -1757,4 +1752,4 @@ int usb_lowlevel_stop(void)
return 0;
}
-#endif /* CONFIG_USB_OHCI */
+#endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_S3C24X0) */
diff --git a/cpu/arm920t/start.S b/cpu/arm920t/start.S
index 114427a..779f192 100644
--- a/cpu/arm920t/start.S
+++ b/cpu/arm920t/start.S
@@ -131,7 +131,7 @@ copyex:
bne copyex
#endif
-#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
+#ifdef CONFIG_S3C24X0
/* turn off the watchdog */
# if defined(CONFIG_S3C2400)
@@ -166,7 +166,7 @@ copyex:
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
-#endif /* CONFIG_S3C2400 || CONFIG_S3C2410 */
+#endif /* CONFIG_S3C24X0 */
/*
* we do sys-critical inits only at reboot,
diff --git a/cpu/arm925t/timer.c b/cpu/arm925t/timer.c
index c16ef25..7dfe2b5 100644
--- a/cpu/arm925t/timer.c
+++ b/cpu/arm925t/timer.c
@@ -81,7 +81,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND preserve advance timestamp value */
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
int32_t tmo = usec * (TIMER_CLOCK / 1000) / 1000;
uint32_t now, last = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM);
diff --git a/cpu/arm926ejs/at91/timer.c b/cpu/arm926ejs/at91/timer.c
index 811bb3c..7352b5c 100644
--- a/cpu/arm926ejs/at91/timer.c
+++ b/cpu/arm926ejs/at91/timer.c
@@ -105,7 +105,7 @@ ulong get_timer_masked(void)
return tick_to_time(get_ticks());
}
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
unsigned long long tmp;
ulong tmo;
diff --git a/cpu/arm926ejs/davinci/cpu.c b/cpu/arm926ejs/davinci/cpu.c
index 390cab8..fc3551c 100644
--- a/cpu/arm926ejs/davinci/cpu.c
+++ b/cpu/arm926ejs/davinci/cpu.c
@@ -23,7 +23,7 @@
#include <common.h>
#include <netdev.h>
#include <asm/arch/hardware.h>
-
+#include <asm/io.h>
/* offsets from PLL controller base */
#define PLLC_PLLCTL 0x100
@@ -60,6 +60,54 @@
#define DDR_PLLDIV PLLC_PLLDIV1
#endif
+#ifdef CONFIG_SOC_DA8XX
+const dv_reg * const sysdiv[7] = {
+ &davinci_pllc_regs->plldiv1, &davinci_pllc_regs->plldiv2,
+ &davinci_pllc_regs->plldiv3, &davinci_pllc_regs->plldiv4,
+ &davinci_pllc_regs->plldiv5, &davinci_pllc_regs->plldiv6,
+ &davinci_pllc_regs->plldiv7
+};
+
+int clk_get(enum davinci_clk_ids id)
+{
+ int pre_div;
+ int pllm;
+ int post_div;
+ int pll_out;
+
+ pll_out = CONFIG_SYS_OSCIN_FREQ;
+
+ if (id == DAVINCI_AUXCLK_CLKID)
+ goto out;
+
+ /*
+ * Lets keep this simple. Combining operations can result in
+ * unexpected approximations
+ */
+ pre_div = (readl(&davinci_pllc_regs->prediv) &
+ DAVINCI_PLLC_DIV_MASK) + 1;
+ pllm = readl(&davinci_pllc_regs->pllm) + 1;
+
+ pll_out /= pre_div;
+ pll_out *= pllm;
+
+ if (id == DAVINCI_PLLM_CLKID)
+ goto out;
+
+ post_div = (readl(&davinci_pllc_regs->postdiv) &
+ DAVINCI_PLLC_DIV_MASK) + 1;
+
+ pll_out /= post_div;
+
+ if (id == DAVINCI_PLLC_CLKID)
+ goto out;
+
+ pll_out /= (readl(sysdiv[id - 1]) & DAVINCI_PLLC_DIV_MASK) + 1;
+
+out:
+ return pll_out;
+}
+#endif /* CONFIG_SOC_DA8XX */
#ifdef CONFIG_DISPLAY_CPUINFO
diff --git a/cpu/arm926ejs/davinci/psc.c b/cpu/arm926ejs/davinci/psc.c
index 5bb972f..8273a7f 100644
--- a/cpu/arm926ejs/davinci/psc.c
+++ b/cpu/arm926ejs/davinci/psc.c
@@ -25,6 +25,7 @@
#include <common.h>
#include <asm/arch/hardware.h>
+#include <asm/io.h>
/*
* The PSC manages three inputs to a "module" which may be a peripheral or
@@ -47,21 +48,45 @@
/* Works on Always On power domain only (no PD argument) */
void lpsc_on(unsigned int id)
{
- dv_reg_p mdstat, mdctl;
+ dv_reg_p mdstat, mdctl, ptstat, ptcmd;
+#ifdef CONFIG_SOC_DA8XX
+ struct davinci_psc_regs *psc_regs;
+#endif
+#ifndef CONFIG_SOC_DA8XX
if (id >= DAVINCI_LPSC_GEM)
return; /* Don't work on DSP Power Domain */
mdstat = REG_P(PSC_MDSTAT_BASE + (id * 4));
mdctl = REG_P(PSC_MDCTL_BASE + (id * 4));
+ ptstat = REG_P(PSC_PTSTAT);
+ ptcmd = REG_P(PSC_PTCMD);
+#else
+ if (id < DAVINCI_LPSC_PSC1_BASE) {
+ if (id >= PSC_PSC0_MODULE_ID_CNT)
+ return;
+ psc_regs = davinci_psc0_regs;
+ mdstat = &psc_regs->psc0.mdstat[id];
+ mdctl = &psc_regs->psc0.mdctl[id];
+ } else {
+ id -= DAVINCI_LPSC_PSC1_BASE;
+ if (id >= PSC_PSC1_MODULE_ID_CNT)
+ return;
+ psc_regs = davinci_psc1_regs;
+ mdstat = &psc_regs->psc1.mdstat[id];
+ mdctl = &psc_regs->psc1.mdctl[id];
+ }
+ ptstat = &psc_regs->ptstat;
+ ptcmd = &psc_regs->ptcmd;
+#endif
- while (REG(PSC_PTSTAT) & 0x01)
+ while (readl(ptstat) & 0x01)
continue;
- if ((*mdstat & 0x1f) == 0x03)
- return; /* Already on and enabled */
+ if ((readl(mdstat) & 0x1f) == 0x03)
+ return; /* Already on and enabled */
- *mdctl |= 0x03;
+ writel(readl(mdctl) | 0x03, mdctl);
switch (id) {
#ifdef CONFIG_SOC_DM644X
@@ -80,16 +105,16 @@ void lpsc_on(unsigned int id)
case DAVINCI_LPSC_MEMSTICK:
case DAVINCI_LPSC_McBSP:
case DAVINCI_LPSC_GPIO:
- *mdctl |= 0x200;
+ writel(readl(mdctl) | 0x200, mdctl);
break;
#endif
}
- REG(PSC_PTCMD) = 0x01;
+ writel(0x01, ptcmd);
- while (REG(PSC_PTSTAT) & 0x03)
+ while (readl(ptstat) & 0x01)
continue;
- while ((*mdstat & 0x1f) != 0x03) /* Probably an overkill... */
+ while ((readl(mdstat) & 0x1f) != 0x03)
continue;
}
diff --git a/cpu/arm926ejs/davinci/timer.c b/cpu/arm926ejs/davinci/timer.c
index 80751ad..9da7443 100644
--- a/cpu/arm926ejs/davinci/timer.c
+++ b/cpu/arm926ejs/davinci/timer.c
@@ -38,8 +38,9 @@
*/
#include <common.h>
+#include <asm/io.h>
-typedef volatile struct {
+struct davinci_timer {
u_int32_t pid12;
u_int32_t emumgt;
u_int32_t na1;
@@ -51,9 +52,10 @@ typedef volatile struct {
u_int32_t tcr;
u_int32_t tgcr;
u_int32_t wdtcr;
-} davinci_timer;
+};
-davinci_timer *timer = (davinci_timer *)CONFIG_SYS_TIMERBASE;
+static struct davinci_timer * const timer =
+ (struct davinci_timer *)CONFIG_SYS_TIMERBASE;
#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ)
#define TIM_CLK_DIV 16
@@ -64,30 +66,30 @@ static ulong lastinc;
int timer_init(void)
{
/* We are using timer34 in unchained 32-bit mode, full speed */
- timer->tcr = 0x0;
- timer->tgcr = 0x0;
- timer->tgcr = 0x06 | ((TIM_CLK_DIV - 1) << 8);
- timer->tim34 = 0x0;
- timer->prd34 = TIMER_LOAD_VAL;
+ writel(0x0, &timer->tcr);
+ writel(0x0, &timer->tgcr);
+ writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &timer->tgcr);
+ writel(0x0, &timer->tim34);
+ writel(TIMER_LOAD_VAL, &timer->prd34);
lastinc = 0;
timestamp = 0;
- timer->tcr = 2 << 22;
+ writel(2 << 22, &timer->tcr);
return(0);
}
void reset_timer(void)
{
- timer->tcr = 0x0;
- timer->tim34 = 0;
+ writel(0x0, &timer->tcr);
+ writel(0x0, &timer->tim34);
lastinc = 0;
timestamp = 0;
- timer->tcr = 2 << 22;
+ writel(2 << 22, &timer->tcr);
}
static ulong get_timer_raw(void)
{
- ulong now = timer->tim34;
+ ulong now = readl(&timer->tim34);
if (now >= lastinc) {
/* normal mode */
@@ -110,7 +112,7 @@ void set_timer(ulong t)
timestamp = t;
}
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
ulong tmo;
ulong endtime;
diff --git a/cpu/arm926ejs/kirkwood/timer.c b/cpu/arm926ejs/kirkwood/timer.c
index 817ff42..2ec6a93 100644
--- a/cpu/arm926ejs/kirkwood/timer.c
+++ b/cpu/arm926ejs/kirkwood/timer.c
@@ -125,7 +125,7 @@ void set_timer(ulong t)
timestamp = t;
}
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
uint current;
ulong delayticks;
diff --git a/cpu/arm926ejs/mx27/timer.c b/cpu/arm926ejs/mx27/timer.c
index 9011058..8f1d47b 100644
--- a/cpu/arm926ejs/mx27/timer.c
+++ b/cpu/arm926ejs/mx27/timer.c
@@ -177,7 +177,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND preserve advance timstamp value */
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
unsigned long long tmp;
ulong tmo;
diff --git a/cpu/arm926ejs/nomadik/timer.c b/cpu/arm926ejs/nomadik/timer.c
index 16067c9..047b9e3 100644
--- a/cpu/arm926ejs/nomadik/timer.c
+++ b/cpu/arm926ejs/nomadik/timer.c
@@ -59,7 +59,7 @@ ulong get_timer(ulong base)
}
/* Delay x useconds */
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
ulong ini, end;
diff --git a/cpu/arm926ejs/omap/timer.c b/cpu/arm926ejs/omap/timer.c
index 392b158..2ac38c4 100644
--- a/cpu/arm926ejs/omap/timer.c
+++ b/cpu/arm926ejs/omap/timer.c
@@ -80,7 +80,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND perserve advance timstamp value */
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
ulong tmo, tmp;
diff --git a/cpu/arm926ejs/versatile/timer.c b/cpu/arm926ejs/versatile/timer.c
index 50c1335..563db36 100755
--- a/cpu/arm926ejs/versatile/timer.c
+++ b/cpu/arm926ejs/versatile/timer.c
@@ -109,7 +109,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND perserve advance timstamp value */
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
ulong tmo, tmp;
diff --git a/cpu/arm_cortexa8/omap3/mem.c b/cpu/arm_cortexa8/omap3/mem.c
index 8b8cd6d..dfb7e4c 100644
--- a/cpu/arm_cortexa8/omap3/mem.c
+++ b/cpu/arm_cortexa8/omap3/mem.c
@@ -161,10 +161,11 @@ void do_sdrc_init(u32 cs, u32 early)
writel(0, &sdrc_base->sysconfig);
/* setup sdrc to ball mux */
- writel(SDP_SDRC_SHARING, &sdrc_base->sharing);
+ writel(SDRC_SHARING, &sdrc_base->sharing);
/* Disable Power Down of CKE cuz of 1 CKE on combo part */
- writel(SRFRONRESET | PAGEPOLICY_HIGH, &sdrc_base->power);
+ writel(WAKEUPPROC | PWDNEN | SRFRONRESET | PAGEPOLICY_HIGH,
+ &sdrc_base->power);
writel(ENADLL | DLLPHASE_90, &sdrc_base->dlla_ctrl);
sdelay(0x20000);
diff --git a/cpu/arm_cortexa8/omap3/sys_info.c b/cpu/arm_cortexa8/omap3/sys_info.c
index 31b2003..08fb32e 100644
--- a/cpu/arm_cortexa8/omap3/sys_info.c
+++ b/cpu/arm_cortexa8/omap3/sys_info.c
@@ -109,7 +109,7 @@ u32 get_cpu_rev(void)
****************************************************/
u32 is_mem_sdr(void)
{
- if (readl(&sdrc_base->cs[CS0].mr) == SDP_SDRC_MR_0_SDR)
+ if (readl(&sdrc_base->cs[CS0].mr) == SDRC_MR_0_SDR)
return 1;
return 0;
}
diff --git a/cpu/arm_cortexa8/omap3/timer.c b/cpu/arm_cortexa8/omap3/timer.c
index 12a16b3..401bfe6 100644
--- a/cpu/arm_cortexa8/omap3/timer.c
+++ b/cpu/arm_cortexa8/omap3/timer.c
@@ -82,7 +82,7 @@ void set_timer(ulong t)
}
/* delay x useconds */
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
unsigned long now, last = readl(&timer_base->tcrr);
diff --git a/cpu/arm_cortexa8/s5pc1xx/timer.c b/cpu/arm_cortexa8/s5pc1xx/timer.c
index cdba5d9..c5df5c5 100644
--- a/cpu/arm_cortexa8/s5pc1xx/timer.c
+++ b/cpu/arm_cortexa8/s5pc1xx/timer.c
@@ -115,7 +115,7 @@ void set_timer(unsigned long t)
}
/* delay x useconds */
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
unsigned long tmo, tmp;
diff --git a/cpu/at32ap/Makefile b/cpu/at32ap/Makefile
index e08f273..60899c7 100644
--- a/cpu/at32ap/Makefile
+++ b/cpu/at32ap/Makefile
@@ -30,7 +30,7 @@ LIB := $(obj)lib$(CPU).a
START-y += start.o
COBJS-y += cpu.o
-COBJS-y += hsdramc.o
+COBJS-$(CONFIG_SYS_HSDRAMC) += hsdramc.o
COBJS-y += exception.o
COBJS-y += cache.o
COBJS-y += interrupts.o
diff --git a/cpu/at32ap/hsdramc.c b/cpu/at32ap/hsdramc.c
index f74121c..b6eae66 100644
--- a/cpu/at32ap/hsdramc.c
+++ b/cpu/at32ap/hsdramc.c
@@ -21,7 +21,6 @@
*/
#include <common.h>
-#ifdef CONFIG_SYS_HSDRAMC
#include <asm/io.h>
#include <asm/sdram.h>
@@ -116,5 +115,3 @@ unsigned long sdram_init(void *sdram_base, const struct sdram_config *config)
return sdram_size;
}
-
-#endif /* CONFIG_SYS_HSDRAMC */
diff --git a/cpu/at32ap/interrupts.c b/cpu/at32ap/interrupts.c
index 75cc39e..c6d8d16 100644
--- a/cpu/at32ap/interrupts.c
+++ b/cpu/at32ap/interrupts.c
@@ -96,7 +96,7 @@ void set_timer(unsigned long t)
/*
* For short delays only. It will overflow after a few seconds.
*/
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
unsigned long cycles;
unsigned long base;
diff --git a/cpu/blackfin/interrupts.c b/cpu/blackfin/interrupts.c
index 19456e5..921bfe0 100644
--- a/cpu/blackfin/interrupts.c
+++ b/cpu/blackfin/interrupts.c
@@ -64,7 +64,7 @@ int disable_interrupts(void)
return 1;
}
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
unsigned long delay, start, stop;
unsigned long cclk;
diff --git a/cpu/i386/Makefile b/cpu/i386/Makefile
index e98bd3d..c658c6e 100644
--- a/cpu/i386/Makefile
+++ b/cpu/i386/Makefile
@@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
START = start.o start16.o resetvec.o
-COBJS = serial.o interrupts.o exceptions.o cpu.o
+COBJS = serial.o interrupts.o cpu.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/cpu/i386/cpu.c b/cpu/i386/cpu.c
index d91e33b..3010519 100644
--- a/cpu/i386/cpu.c
+++ b/cpu/i386/cpu.c
@@ -37,7 +37,7 @@
#include <command.h>
#include <asm/interrupt.h>
-int cpu_init(void)
+int cpu_init_f(void)
{
/* initialize FPU, reset EM, set MP and NE */
asm ("fninit\n" \
@@ -46,10 +46,13 @@ int cpu_init(void)
"orl $0x22, %eax\n" \
"movl %eax, %cr0\n" );
+ return 0;
+}
+
+int cpu_init_r(void)
+{
/* Initialize core interrupt and exception functionality of CPU */
cpu_init_interrupts ();
- cpu_init_exceptions ();
-
return 0;
}
@@ -74,6 +77,8 @@ void __attribute__ ((regparm(0))) generate_gpf(void);
/* segment 0x70 is an arbitrary segment which does not exist */
asm(".globl generate_gpf\n"
+ ".hidden generate_gpf\n"
+ ".type generate_gpf, @function\n"
"generate_gpf:\n"
"ljmp $0x70, $0x47114711\n");
diff --git a/cpu/i386/exceptions.c b/cpu/i386/exceptions.c
deleted file mode 100644
index bc3d434..0000000
--- a/cpu/i386/exceptions.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * (C) Copyright 2002
- * Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <asm/interrupt.h>
-
-asm (".globl exp_return\n"
- "exp_return:\n"
- " addl $12, %esp\n"
- " pop %esp\n"
- " popa\n"
- " iret\n");
-
-char exception_stack[4096];
-
-/*
- * For detailed description of each exception, refer to:
- * Intel® 64 and IA-32 Architectures Software Developer's Manual
- * Volume 1: Basic Architecture
- * Order Number: 253665-029US, November 2008
- * Table 6-1. Exceptions and Interrupts
- */
-DECLARE_EXCEPTION(0, divide_error_entry);
-DECLARE_EXCEPTION(1, debug_entry);
-DECLARE_EXCEPTION(2, nmi_interrupt_entry);
-DECLARE_EXCEPTION(3, breakpoint_entry);
-DECLARE_EXCEPTION(4, overflow_entry);
-DECLARE_EXCEPTION(5, bound_range_exceeded_entry);
-DECLARE_EXCEPTION(6, invalid_opcode_entry);
-DECLARE_EXCEPTION(7, device_not_available_entry);
-DECLARE_EXCEPTION(8, double_fault_entry);
-DECLARE_EXCEPTION(9, coprocessor_segment_overrun_entry);
-DECLARE_EXCEPTION(10, invalid_tss_entry);
-DECLARE_EXCEPTION(11, segment_not_present_entry);
-DECLARE_EXCEPTION(12, stack_segment_fault_entry);
-DECLARE_EXCEPTION(13, general_protection_entry);
-DECLARE_EXCEPTION(14, page_fault_entry);
-DECLARE_EXCEPTION(15, reserved_exception_entry);
-DECLARE_EXCEPTION(16, floating_point_error_entry);
-DECLARE_EXCEPTION(17, alignment_check_entry);
-DECLARE_EXCEPTION(18, machine_check_entry);
-DECLARE_EXCEPTION(19, simd_floating_point_exception_entry);
-DECLARE_EXCEPTION(20, reserved_exception_entry);
-DECLARE_EXCEPTION(21, reserved_exception_entry);
-DECLARE_EXCEPTION(22, reserved_exception_entry);
-DECLARE_EXCEPTION(23, reserved_exception_entry);
-DECLARE_EXCEPTION(24, reserved_exception_entry);
-DECLARE_EXCEPTION(25, reserved_exception_entry);
-DECLARE_EXCEPTION(26, reserved_exception_entry);
-DECLARE_EXCEPTION(27, reserved_exception_entry);
-DECLARE_EXCEPTION(28, reserved_exception_entry);
-DECLARE_EXCEPTION(29, reserved_exception_entry);
-DECLARE_EXCEPTION(30, reserved_exception_entry);
-DECLARE_EXCEPTION(31, reserved_exception_entry);
-
-__isr__ reserved_exception_entry(int cause, int ip, int seg)
-{
- printf("Reserved Exception %d at %04x:%08x\n", cause, seg, ip);
-}
-
-__isr__ divide_error_entry(int cause, int ip, int seg)
-{
- printf("Divide Error (Division by zero) at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ debug_entry(int cause, int ip, int seg)
-{
- printf("Debug Interrupt (Single step) at %04x:%08x\n", seg, ip);
-}
-
-__isr__ nmi_interrupt_entry(int cause, int ip, int seg)
-{
- printf("NMI Interrupt at %04x:%08x\n", seg, ip);
-}
-
-__isr__ breakpoint_entry(int cause, int ip, int seg)
-{
- printf("Breakpoint at %04x:%08x\n", seg, ip);
-}
-
-__isr__ overflow_entry(int cause, int ip, int seg)
-{
- printf("Overflow at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ bound_range_exceeded_entry(int cause, int ip, int seg)
-{
- printf("BOUND Range Exceeded at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ invalid_opcode_entry(int cause, int ip, int seg)
-{
- printf("Invalid Opcode (UnDefined Opcode) at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ device_not_available_entry(int cause, int ip, int seg)
-{
- printf("Device Not Available (No Math Coprocessor) at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ double_fault_entry(int cause, int ip, int seg)
-{
- printf("Double fault at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ coprocessor_segment_overrun_entry(int cause, int ip, int seg)
-{
- printf("Co-processor segment overrun at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ invalid_tss_entry(int cause, int ip, int seg)
-{
- printf("Invalid TSS at %04x:%08x\n", seg, ip);
-}
-
-__isr__ segment_not_present_entry(int cause, int ip, int seg)
-{
- printf("Segment Not Present at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ stack_segment_fault_entry(int cause, int ip, int seg)
-{
- printf("Stack Segment Fault at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ general_protection_entry(int cause, int ip, int seg)
-{
- printf("General Protection at %04x:%08x\n", seg, ip);
-}
-
-__isr__ page_fault_entry(int cause, int ip, int seg)
-{
- printf("Page fault at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ floating_point_error_entry(int cause, int ip, int seg)
-{
- printf("Floating-Point Error (Math Fault) at %04x:%08x\n", seg, ip);
-}
-
-__isr__ alignment_check_entry(int cause, int ip, int seg)
-{
- printf("Alignment check at %04x:%08x\n", seg, ip);
-}
-
-__isr__ machine_check_entry(int cause, int ip, int seg)
-{
- printf("Machine Check at %04x:%08x\n", seg, ip);
-}
-
-__isr__ simd_floating_point_exception_entry(int cause, int ip, int seg)
-{
- printf("SIMD Floating-Point Exception at %04x:%08x\n", seg, ip);
-}
-
-int cpu_init_exceptions(void)
-{
- /* Just in case... */
- disable_interrupts();
-
- /* Setup exceptions */
- set_vector(0x00, exp_0);
- set_vector(0x01, exp_1);
- set_vector(0x02, exp_2);
- set_vector(0x03, exp_3);
- set_vector(0x04, exp_4);
- set_vector(0x05, exp_5);
- set_vector(0x06, exp_6);
- set_vector(0x07, exp_7);
- set_vector(0x08, exp_8);
- set_vector(0x09, exp_9);
- set_vector(0x0a, exp_10);
- set_vector(0x0b, exp_11);
- set_vector(0x0c, exp_12);
- set_vector(0x0d, exp_13);
- set_vector(0x0e, exp_14);
- set_vector(0x0f, exp_15);
- set_vector(0x10, exp_16);
- set_vector(0x11, exp_17);
- set_vector(0x12, exp_18);
- set_vector(0x13, exp_19);
- set_vector(0x14, exp_20);
- set_vector(0x15, exp_21);
- set_vector(0x16, exp_22);
- set_vector(0x17, exp_23);
- set_vector(0x18, exp_24);
- set_vector(0x19, exp_25);
- set_vector(0x1a, exp_26);
- set_vector(0x1b, exp_27);
- set_vector(0x1c, exp_28);
- set_vector(0x1d, exp_29);
- set_vector(0x1e, exp_30);
- set_vector(0x1f, exp_31);
-
- /* It is now safe to enable interrupts */
- enable_interrupts();
-
- return 0;
-}
diff --git a/cpu/i386/interrupts.c b/cpu/i386/interrupts.c
index 063ea42..4b57437 100644
--- a/cpu/i386/interrupts.c
+++ b/cpu/i386/interrupts.c
@@ -1,4 +1,7 @@
/*
+ * (C) Copyright 2008
+ * Graeme Russ, graeme.russ@gmail.com.
+ *
* (C) Copyright 2002
* Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
*
@@ -24,6 +27,16 @@
#include <common.h>
#include <asm/interrupt.h>
+#define DECLARE_INTERRUPT(x) \
+ ".globl irq_"#x"\n" \
+ ".hidden irq_"#x"\n" \
+ ".type irq_"#x", @function\n" \
+ "irq_"#x":\n" \
+ "pushl %ebp\n" \
+ "movl %esp,%ebp\n" \
+ "pusha\n" \
+ "pushl $"#x"\n" \
+ "jmp irq_common_entry\n"
struct idt_entry {
u16 base_low;
@@ -33,35 +46,37 @@ struct idt_entry {
u16 base_high;
} __attribute__ ((packed));
+struct desc_ptr {
+ unsigned short size;
+ unsigned long address;
+ unsigned short segment;
+} __attribute__((packed));
struct idt_entry idt[256];
+struct desc_ptr idt_ptr;
-asm (".globl irq_return\n"
- "irq_return:\n"
- " addl $4, %esp\n"
- " popa\n"
- " iret\n");
-
-void __attribute__ ((regparm(0))) default_isr(void);
-asm ("default_isr: iret\n");
-
-asm ("idt_ptr:\n"
- ".word 0x800\n" /* size of the table 8*256 bytes */
- ".long idt\n" /* offset */
- ".word 0x18\n");/* data segment */
+static inline void load_idt(const struct desc_ptr *dtr)
+{
+ asm volatile("cs lidt %0"::"m" (*dtr));
+}
void set_vector(u8 intnum, void *routine)
{
- idt[intnum].base_high = (u16)((u32)(routine + gd->reloc_off) >> 16);
- idt[intnum].base_low = (u16)((u32)(routine + gd->reloc_off) & 0xffff);
+ idt[intnum].base_high = (u16)((u32)(routine) >> 16);
+ idt[intnum].base_low = (u16)((u32)(routine) & 0xffff);
}
+void irq_0(void);
+void irq_1(void);
int cpu_init_interrupts(void)
{
int i;
+ int irq_entry_size = irq_1 - irq_0;
+ void *irq_entry = (void *)irq_0;
+
/* Just in case... */
disable_interrupts();
@@ -70,10 +85,15 @@ int cpu_init_interrupts(void)
idt[i].access = 0x8e;
idt[i].res = 0;
idt[i].selector = 0x10;
- set_vector(i, default_isr);
+ set_vector(i, irq_entry);
+ irq_entry += irq_entry_size;
}
- asm ("cs lidt idt_ptr\n");
+ idt_ptr.size = 256 * 8;
+ idt_ptr.address = (unsigned long) idt;
+ idt_ptr.segment = 0x18;
+
+ load_idt(&idt_ptr);
/* It is now safe to enable interrupts */
enable_interrupts();
@@ -81,6 +101,12 @@ int cpu_init_interrupts(void)
return 0;
}
+void __do_irq(int irq)
+{
+ printf("Unhandled IRQ : %d\n", irq);
+}
+void do_irq(int irq) __attribute__((weak, alias("__do_irq")));
+
void enable_interrupts(void)
{
asm("sti\n");
@@ -94,3 +120,382 @@ int disable_interrupts(void)
return (flags&0x200); /* IE flags is bit 9 */
}
+
+/* IRQ Low-Level Service Routine */
+__isr__ irq_llsr(int ip, int seg, int irq)
+{
+ /*
+ * For detailed description of each exception, refer to:
+ * Intel® 64 and IA-32 Architectures Software Developer's Manual
+ * Volume 1: Basic Architecture
+ * Order Number: 253665-029US, November 2008
+ * Table 6-1. Exceptions and Interrupts
+ */
+ switch (irq) {
+ case 0x00:
+ printf("Divide Error (Division by zero) at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x01:
+ printf("Debug Interrupt (Single step) at %04x:%08x\n", seg, ip);
+ break;
+ case 0x02:
+ printf("NMI Interrupt at %04x:%08x\n", seg, ip);
+ break;
+ case 0x03:
+ printf("Breakpoint at %04x:%08x\n", seg, ip);
+ break;
+ case 0x04:
+ printf("Overflow at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x05:
+ printf("BOUND Range Exceeded at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x06:
+ printf("Invalid Opcode (UnDefined Opcode) at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x07:
+ printf("Device Not Available (No Math Coprocessor) at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x08:
+ printf("Double fault at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x09:
+ printf("Co-processor segment overrun at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x0a:
+ printf("Invalid TSS at %04x:%08x\n", seg, ip);
+ break;
+ case 0x0b:
+ printf("Segment Not Present at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x0c:
+ printf("Stack Segment Fault at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x0d:
+ printf("General Protection at %04x:%08x\n", seg, ip);
+ break;
+ case 0x0e:
+ printf("Page fault at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x0f:
+ printf("Floating-Point Error (Math Fault) at %04x:%08x\n", seg, ip);
+ break;
+ case 0x10:
+ printf("Alignment check at %04x:%08x\n", seg, ip);
+ break;
+ case 0x11:
+ printf("Machine Check at %04x:%08x\n", seg, ip);
+ break;
+ case 0x12:
+ printf("SIMD Floating-Point Exception at %04x:%08x\n", seg, ip);
+ break;
+ case 0x13:
+ case 0x14:
+ case 0x15:
+ case 0x16:
+ case 0x17:
+ case 0x18:
+ case 0x19:
+ case 0x1a:
+ case 0x1b:
+ case 0x1c:
+ case 0x1d:
+ case 0x1e:
+ case 0x1f:
+ printf("Reserved Exception %d at %04x:%08x\n", irq, seg, ip);
+ break;
+
+ default:
+ /* Hardware or User IRQ */
+ do_irq(irq);
+ }
+}
+
+/*
+ * OK - This looks really horrible, but it serves a purpose - It helps create
+ * fully relocatable code.
+ * - The call to irq_llsr will be a relative jump
+ * - The IRQ entries will be guaranteed to be in order
+ * It's a bit annoying that we need to waste 3 bytes per interrupt entry
+ * (total of 768 code bytes), but we MUST create a Stack Frame and this is
+ * the easiest way I could do it. Maybe it can be made better later.
+ */
+asm(".globl irq_common_entry\n" \
+ ".hidden irq_common_entry\n" \
+ ".type irq_common_entry, @function\n" \
+ "irq_common_entry:\n" \
+ "pushl $0\n" \
+ "pushl $0\n" \
+ "call irq_llsr\n" \
+ "popl %eax\n" \
+ "popl %eax\n" \
+ "popl %eax\n" \
+ "popa\n" \
+ "leave\n"\
+ "iret\n" \
+ DECLARE_INTERRUPT(0) \
+ DECLARE_INTERRUPT(1) \
+ DECLARE_INTERRUPT(2) \
+ DECLARE_INTERRUPT(3) \
+ DECLARE_INTERRUPT(4) \
+ DECLARE_INTERRUPT(5) \
+ DECLARE_INTERRUPT(6) \
+ DECLARE_INTERRUPT(7) \
+ DECLARE_INTERRUPT(8) \
+ DECLARE_INTERRUPT(9) \
+ DECLARE_INTERRUPT(10) \
+ DECLARE_INTERRUPT(11) \
+ DECLARE_INTERRUPT(12) \
+ DECLARE_INTERRUPT(13) \
+ DECLARE_INTERRUPT(14) \
+ DECLARE_INTERRUPT(15) \
+ DECLARE_INTERRUPT(16) \
+ DECLARE_INTERRUPT(17) \
+ DECLARE_INTERRUPT(18) \
+ DECLARE_INTERRUPT(19) \
+ DECLARE_INTERRUPT(20) \
+ DECLARE_INTERRUPT(21) \
+ DECLARE_INTERRUPT(22) \
+ DECLARE_INTERRUPT(23) \
+ DECLARE_INTERRUPT(24) \
+ DECLARE_INTERRUPT(25) \
+ DECLARE_INTERRUPT(26) \
+ DECLARE_INTERRUPT(27) \
+ DECLARE_INTERRUPT(28) \
+ DECLARE_INTERRUPT(29) \
+ DECLARE_INTERRUPT(30) \
+ DECLARE_INTERRUPT(31) \
+ DECLARE_INTERRUPT(32) \
+ DECLARE_INTERRUPT(33) \
+ DECLARE_INTERRUPT(34) \
+ DECLARE_INTERRUPT(35) \
+ DECLARE_INTERRUPT(36) \
+ DECLARE_INTERRUPT(37) \
+ DECLARE_INTERRUPT(38) \
+ DECLARE_INTERRUPT(39) \
+ DECLARE_INTERRUPT(40) \
+ DECLARE_INTERRUPT(41) \
+ DECLARE_INTERRUPT(42) \
+ DECLARE_INTERRUPT(43) \
+ DECLARE_INTERRUPT(44) \
+ DECLARE_INTERRUPT(45) \
+ DECLARE_INTERRUPT(46) \
+ DECLARE_INTERRUPT(47) \
+ DECLARE_INTERRUPT(48) \
+ DECLARE_INTERRUPT(49) \
+ DECLARE_INTERRUPT(50) \
+ DECLARE_INTERRUPT(51) \
+ DECLARE_INTERRUPT(52) \
+ DECLARE_INTERRUPT(53) \
+ DECLARE_INTERRUPT(54) \
+ DECLARE_INTERRUPT(55) \
+ DECLARE_INTERRUPT(56) \
+ DECLARE_INTERRUPT(57) \
+ DECLARE_INTERRUPT(58) \
+ DECLARE_INTERRUPT(59) \
+ DECLARE_INTERRUPT(60) \
+ DECLARE_INTERRUPT(61) \
+ DECLARE_INTERRUPT(62) \
+ DECLARE_INTERRUPT(63) \
+ DECLARE_INTERRUPT(64) \
+ DECLARE_INTERRUPT(65) \
+ DECLARE_INTERRUPT(66) \
+ DECLARE_INTERRUPT(67) \
+ DECLARE_INTERRUPT(68) \
+ DECLARE_INTERRUPT(69) \
+ DECLARE_INTERRUPT(70) \
+ DECLARE_INTERRUPT(71) \
+ DECLARE_INTERRUPT(72) \
+ DECLARE_INTERRUPT(73) \
+ DECLARE_INTERRUPT(74) \
+ DECLARE_INTERRUPT(75) \
+ DECLARE_INTERRUPT(76) \
+ DECLARE_INTERRUPT(77) \
+ DECLARE_INTERRUPT(78) \
+ DECLARE_INTERRUPT(79) \
+ DECLARE_INTERRUPT(80) \
+ DECLARE_INTERRUPT(81) \
+ DECLARE_INTERRUPT(82) \
+ DECLARE_INTERRUPT(83) \
+ DECLARE_INTERRUPT(84) \
+ DECLARE_INTERRUPT(85) \
+ DECLARE_INTERRUPT(86) \
+ DECLARE_INTERRUPT(87) \
+ DECLARE_INTERRUPT(88) \
+ DECLARE_INTERRUPT(89) \
+ DECLARE_INTERRUPT(90) \
+ DECLARE_INTERRUPT(91) \
+ DECLARE_INTERRUPT(92) \
+ DECLARE_INTERRUPT(93) \
+ DECLARE_INTERRUPT(94) \
+ DECLARE_INTERRUPT(95) \
+ DECLARE_INTERRUPT(97) \
+ DECLARE_INTERRUPT(96) \
+ DECLARE_INTERRUPT(98) \
+ DECLARE_INTERRUPT(99) \
+ DECLARE_INTERRUPT(100) \
+ DECLARE_INTERRUPT(101) \
+ DECLARE_INTERRUPT(102) \
+ DECLARE_INTERRUPT(103) \
+ DECLARE_INTERRUPT(104) \
+ DECLARE_INTERRUPT(105) \
+ DECLARE_INTERRUPT(106) \
+ DECLARE_INTERRUPT(107) \
+ DECLARE_INTERRUPT(108) \
+ DECLARE_INTERRUPT(109) \
+ DECLARE_INTERRUPT(110) \
+ DECLARE_INTERRUPT(111) \
+ DECLARE_INTERRUPT(112) \
+ DECLARE_INTERRUPT(113) \
+ DECLARE_INTERRUPT(114) \
+ DECLARE_INTERRUPT(115) \
+ DECLARE_INTERRUPT(116) \
+ DECLARE_INTERRUPT(117) \
+ DECLARE_INTERRUPT(118) \
+ DECLARE_INTERRUPT(119) \
+ DECLARE_INTERRUPT(120) \
+ DECLARE_INTERRUPT(121) \
+ DECLARE_INTERRUPT(122) \
+ DECLARE_INTERRUPT(123) \
+ DECLARE_INTERRUPT(124) \
+ DECLARE_INTERRUPT(125) \
+ DECLARE_INTERRUPT(126) \
+ DECLARE_INTERRUPT(127) \
+ DECLARE_INTERRUPT(128) \
+ DECLARE_INTERRUPT(129) \
+ DECLARE_INTERRUPT(130) \
+ DECLARE_INTERRUPT(131) \
+ DECLARE_INTERRUPT(132) \
+ DECLARE_INTERRUPT(133) \
+ DECLARE_INTERRUPT(134) \
+ DECLARE_INTERRUPT(135) \
+ DECLARE_INTERRUPT(136) \
+ DECLARE_INTERRUPT(137) \
+ DECLARE_INTERRUPT(138) \
+ DECLARE_INTERRUPT(139) \
+ DECLARE_INTERRUPT(140) \
+ DECLARE_INTERRUPT(141) \
+ DECLARE_INTERRUPT(142) \
+ DECLARE_INTERRUPT(143) \
+ DECLARE_INTERRUPT(144) \
+ DECLARE_INTERRUPT(145) \
+ DECLARE_INTERRUPT(146) \
+ DECLARE_INTERRUPT(147) \
+ DECLARE_INTERRUPT(148) \
+ DECLARE_INTERRUPT(149) \
+ DECLARE_INTERRUPT(150) \
+ DECLARE_INTERRUPT(151) \
+ DECLARE_INTERRUPT(152) \
+ DECLARE_INTERRUPT(153) \
+ DECLARE_INTERRUPT(154) \
+ DECLARE_INTERRUPT(155) \
+ DECLARE_INTERRUPT(156) \
+ DECLARE_INTERRUPT(157) \
+ DECLARE_INTERRUPT(158) \
+ DECLARE_INTERRUPT(159) \
+ DECLARE_INTERRUPT(160) \
+ DECLARE_INTERRUPT(161) \
+ DECLARE_INTERRUPT(162) \
+ DECLARE_INTERRUPT(163) \
+ DECLARE_INTERRUPT(164) \
+ DECLARE_INTERRUPT(165) \
+ DECLARE_INTERRUPT(166) \
+ DECLARE_INTERRUPT(167) \
+ DECLARE_INTERRUPT(168) \
+ DECLARE_INTERRUPT(169) \
+ DECLARE_INTERRUPT(170) \
+ DECLARE_INTERRUPT(171) \
+ DECLARE_INTERRUPT(172) \
+ DECLARE_INTERRUPT(173) \
+ DECLARE_INTERRUPT(174) \
+ DECLARE_INTERRUPT(175) \
+ DECLARE_INTERRUPT(176) \
+ DECLARE_INTERRUPT(177) \
+ DECLARE_INTERRUPT(178) \
+ DECLARE_INTERRUPT(179) \
+ DECLARE_INTERRUPT(180) \
+ DECLARE_INTERRUPT(181) \
+ DECLARE_INTERRUPT(182) \
+ DECLARE_INTERRUPT(183) \
+ DECLARE_INTERRUPT(184) \
+ DECLARE_INTERRUPT(185) \
+ DECLARE_INTERRUPT(186) \
+ DECLARE_INTERRUPT(187) \
+ DECLARE_INTERRUPT(188) \
+ DECLARE_INTERRUPT(189) \
+ DECLARE_INTERRUPT(190) \
+ DECLARE_INTERRUPT(191) \
+ DECLARE_INTERRUPT(192) \
+ DECLARE_INTERRUPT(193) \
+ DECLARE_INTERRUPT(194) \
+ DECLARE_INTERRUPT(195) \
+ DECLARE_INTERRUPT(196) \
+ DECLARE_INTERRUPT(197) \
+ DECLARE_INTERRUPT(198) \
+ DECLARE_INTERRUPT(199) \
+ DECLARE_INTERRUPT(200) \
+ DECLARE_INTERRUPT(201) \
+ DECLARE_INTERRUPT(202) \
+ DECLARE_INTERRUPT(203) \
+ DECLARE_INTERRUPT(204) \
+ DECLARE_INTERRUPT(205) \
+ DECLARE_INTERRUPT(206) \
+ DECLARE_INTERRUPT(207) \
+ DECLARE_INTERRUPT(208) \
+ DECLARE_INTERRUPT(209) \
+ DECLARE_INTERRUPT(210) \
+ DECLARE_INTERRUPT(211) \
+ DECLARE_INTERRUPT(212) \
+ DECLARE_INTERRUPT(213) \
+ DECLARE_INTERRUPT(214) \
+ DECLARE_INTERRUPT(215) \
+ DECLARE_INTERRUPT(216) \
+ DECLARE_INTERRUPT(217) \
+ DECLARE_INTERRUPT(218) \
+ DECLARE_INTERRUPT(219) \
+ DECLARE_INTERRUPT(220) \
+ DECLARE_INTERRUPT(221) \
+ DECLARE_INTERRUPT(222) \
+ DECLARE_INTERRUPT(223) \
+ DECLARE_INTERRUPT(224) \
+ DECLARE_INTERRUPT(225) \
+ DECLARE_INTERRUPT(226) \
+ DECLARE_INTERRUPT(227) \
+ DECLARE_INTERRUPT(228) \
+ DECLARE_INTERRUPT(229) \
+ DECLARE_INTERRUPT(230) \
+ DECLARE_INTERRUPT(231) \
+ DECLARE_INTERRUPT(232) \
+ DECLARE_INTERRUPT(233) \
+ DECLARE_INTERRUPT(234) \
+ DECLARE_INTERRUPT(235) \
+ DECLARE_INTERRUPT(236) \
+ DECLARE_INTERRUPT(237) \
+ DECLARE_INTERRUPT(238) \
+ DECLARE_INTERRUPT(239) \
+ DECLARE_INTERRUPT(240) \
+ DECLARE_INTERRUPT(241) \
+ DECLARE_INTERRUPT(242) \
+ DECLARE_INTERRUPT(243) \
+ DECLARE_INTERRUPT(244) \
+ DECLARE_INTERRUPT(245) \
+ DECLARE_INTERRUPT(246) \
+ DECLARE_INTERRUPT(247) \
+ DECLARE_INTERRUPT(248) \
+ DECLARE_INTERRUPT(249) \
+ DECLARE_INTERRUPT(250) \
+ DECLARE_INTERRUPT(251) \
+ DECLARE_INTERRUPT(252) \
+ DECLARE_INTERRUPT(253) \
+ DECLARE_INTERRUPT(254) \
+ DECLARE_INTERRUPT(255));
diff --git a/cpu/i386/sc520/sc520_timer.c b/cpu/i386/sc520/sc520_timer.c
index 23de14b..93b5b55 100644
--- a/cpu/i386/sc520/sc520_timer.c
+++ b/cpu/i386/sc520/sc520_timer.c
@@ -35,6 +35,12 @@ void sc520_timer_isr(void)
int timer_init(void)
{
+ /* Register the SC520 specific timer interrupt handler */
+ register_timer_isr (sc520_timer_isr);
+
+ /* Install interrupt handler for GP Timer 1 */
+ irq_install_handler (0, timer_isr, NULL);
+
/* Map GP Timer 1 to Master PIC IR0 */
sc520_mmcr->gp_tmr_int_map[1] = 0x01;
@@ -54,11 +60,6 @@ int timer_init(void)
sc520_mmcr->gptmr1maxcmpa = 100;
sc520_mmcr->gptmr1ctl = 0xe009;
- /* Register the SC520 specific timer interrupt handler */
- register_timer_isr (sc520_timer_isr);
-
- /* Install interrupt handler for GP Timer 1 */
- irq_install_handler (0, timer_isr, NULL);
unmask_irq (0);
/* Clear the GP Timer 1 status register to get the show rolling*/
@@ -67,7 +68,7 @@ int timer_init(void)
return 0;
}
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
int m = 0;
long u;
diff --git a/cpu/i386/start.S b/cpu/i386/start.S
index 59089ef..25d32e6 100644
--- a/cpu/i386/start.S
+++ b/cpu/i386/start.S
@@ -63,11 +63,8 @@ early_board_init_ret:
jmp mem_init
mem_init_ret:
- /* check ammount of configured memory
- * (we need atleast bss start+bss size+stack size) */
- movl $_i386boot_bss_start, %ecx /* BSS start */
- addl $_i386boot_bss_size, %ecx /* BSS size */
- addl $CONFIG_SYS_STACK_SIZE, %ecx
+ /* Check we have enough memory for stack */
+ movl $CONFIG_SYS_STACK_SIZE, %ecx
cmpl %ecx, %eax
jae mem_ok
@@ -78,6 +75,8 @@ mem_init_ret:
.progress0a:
jmp die
mem_ok:
+ /* Set stack pointer to upper memory limit*/
+ movl %eax, %esp
/* indicate progress */
movw $0x02, %ax
@@ -85,12 +84,7 @@ mem_ok:
jmp show_boot_progress_asm
.progress1:
- /* create a stack after the bss */
- movl $_i386boot_bss_start, %eax
- addl $_i386boot_bss_size, %eax
- addl $CONFIG_SYS_STACK_SIZE, %eax
- movl %eax, %esp
-
+ /* Test the stack */
pushl $0
popl %eax
cmpl $0, %eax
@@ -116,115 +110,19 @@ stack_ok:
jmp show_boot_progress_asm
.progress2:
- /* copy data section to ram, size must be 4-byte aligned */
- movl $_i386boot_romdata_dest, %edi /* destination address */
- movl $_i386boot_romdata_start, %esi /* source address */
- movl $_i386boot_romdata_size, %ecx /* number of bytes to copy */
- movl %ecx, %eax
- andl $3, %eax
- jnz data_fail
-
- shrl $2, %ecx /* copy 4 byte each time */
- cld
- cmpl $0, %ecx
- je data_ok
-data_segment:
- movsl
- loop data_segment
- jmp data_ok
-data_fail:
- /* indicate (lack of) progress */
- movw $0x83, %ax
- movl $.progress2a, %ebp
- jmp show_boot_progress_asm
-.progress2a:
- jmp die
-
-data_ok:
-
- /* indicate progress */
- movw $0x04, %ax
- movl $.progress3, %ebp
- jmp show_boot_progress_asm
-.progress3:
-
- /* clear bss section in ram, size must be 4-byte aligned */
- movl $_i386boot_bss_start, %edi /* MK_CHG BSS start */
- movl $_i386boot_bss_size, %ecx /* BSS size */
- movl %ecx, %eax
- andl $3, %eax
- jnz bss_fail
- shrl $2, %ecx /* clear 4 byte each time */
- cld
- cmpl $0, %ecx
- je bss_ok
-bss:
- movl $0, (%edi)
- add $4, %edi
- loop bss
- jmp bss_ok
-
-bss_fail:
- /* indicate (lack of) progress */
- movw $0x84, %ax
- movl $.progress3a, %ebp
- jmp show_boot_progress_asm
-.progress3a:
- jmp die
-
-bss_ok:
-#ifndef CONFIG_SKIP_RELOCATE_UBOOT
- /* indicate progress */
- movw $0x06, %ax
- movl $.progress6, %ebp
- jmp show_boot_progress_asm
-.progress6:
-
- /* copy text section to ram, size must be 4-byte aligned */
- movl $CONFIG_SYS_BL_START_RAM, %edi /* destination address */
- movl $TEXT_BASE, %esi /* source address */
- movl $_i386boot_text_size, %ecx /* number of bytes to copy */
- movl %ecx, %eax
- andl $3, %eax
- jz text_copy /* Already 4-byte aligned */
- subl $4, %eax /* Add extra bytes to size */
- addl %eax, %ecx
-text_copy:
- shrl $2, %ecx /* copy 4 byte each time */
- cld
- cmpl $0, %ecx
- je text_ok
-text_segment:
- movsl
- loop text_segment
- jmp text_ok
-text_fail:
- /* indicate (lack of) progress */
- movw $0x86, %ax
- movl $.progress5a, %ebp
- jmp show_boot_progress_asm
-.progress5a:
- jmp die
-
-text_ok:
-#endif
wbinvd
+ /* Get upper memory limit */
+ movl %esp, %ecx
+ subl $CONFIG_SYS_STACK_SIZE, %ecx
- /* indicate progress */
- movw $0x05, %ax
- movl $.progress4, %ebp
- jmp show_boot_progress_asm
-.progress4:
-
-#ifndef CONFIG_SKIP_RELOCATE_UBOOT
- /* Jump to the RAM copy of start_i386boot */
- movl $start_i386boot, %ebp
- addl $(CONFIG_SYS_BL_START_RAM - TEXT_BASE), %ebp
- call *%ebp /* Enter, U-boot! */
-#else
- call start_i386boot /* Enter, U-boot! */
-#endif
+ /* Create a Stack Frame */
+ pushl %ebp
+ movl %esp, %ebp
+
+ /* stack_limit parameter */
+ pushl %ecx
+ call board_init_f /* Enter, U-boot! */
/* indicate (lack of) progress */
movw $0x85, %ax
diff --git a/cpu/ixp/start.S b/cpu/ixp/start.S
index 196ba5d..5ebce53 100644
--- a/cpu/ixp/start.S
+++ b/cpu/ixp/start.S
@@ -505,8 +505,8 @@ reset_endless:
/*
* 0 <= r0 <= 2000
*/
-.globl udelay
-udelay:
+.globl __udelay
+__udelay:
mov r2, #0x6800
orr r2, r2, #0x00db
mul r0, r2, r0
diff --git a/cpu/ixp/timer.c b/cpu/ixp/timer.c
index 6856149..edf341f 100644
--- a/cpu/ixp/timer.c
+++ b/cpu/ixp/timer.c
@@ -99,7 +99,7 @@ void ixp425_udelay(unsigned long usec)
while (!(*IXP425_OSST & IXP425_OSST_TIMER_1_PEND));
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
while (usec--) ixp425_udelay(1);
}
diff --git a/cpu/lh7a40x/timer.c b/cpu/lh7a40x/timer.c
index f9b5be0..2691315 100644
--- a/cpu/lh7a40x/timer.c
+++ b/cpu/lh7a40x/timer.c
@@ -90,7 +90,7 @@ void set_timer (ulong t)
timestamp = t;
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
ulong tmo,tmp;
diff --git a/cpu/mcf547x_8x/slicetimer.c b/cpu/mcf547x_8x/slicetimer.c
index 67e8189..8dc010a 100644
--- a/cpu/mcf547x_8x/slicetimer.c
+++ b/cpu/mcf547x_8x/slicetimer.c
@@ -40,7 +40,7 @@ static ulong timestamp;
#endif
extern void dtimer_intr_setup(void);
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
volatile slt_t *timerp = (slt_t *) (CONFIG_SYS_UDELAY_BASE);
u32 now, freq;
diff --git a/cpu/mpc512x/cpu.c b/cpu/mpc512x/cpu.c
index 42ccd81..dac48db 100644
--- a/cpu/mpc512x/cpu.c
+++ b/cpu/mpc512x/cpu.c
@@ -197,6 +197,7 @@ void ft_cpu_setup(void *blob, bd_t *bd)
#ifdef CONFIG_HAS_ETH0
fdt_fixup_ethernet(blob);
#endif
+ fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
}
#endif
diff --git a/cpu/mpc5xxx/cpu.c b/cpu/mpc5xxx/cpu.c
index efa64c7..2a28df4 100644
--- a/cpu/mpc5xxx/cpu.c
+++ b/cpu/mpc5xxx/cpu.c
@@ -157,6 +157,7 @@ void ft_cpu_setup(void *blob, bd_t *bd)
}
#endif
+ fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
}
#endif
diff --git a/cpu/mpc85xx/mp.c b/cpu/mpc85xx/mp.c
index 00b6450..7626eb8 100644
--- a/cpu/mpc85xx/mp.c
+++ b/cpu/mpc85xx/mp.c
@@ -90,11 +90,7 @@ int cpu_release(int nr, int argc, char *argv[])
return 1;
}
-#ifdef CONFIG_SYS_64BIT_STRTOUL
boot_addr = simple_strtoull(argv[0], NULL, 16);
-#else
- boot_addr = simple_strtoul(argv[0], NULL, 16);
-#endif
/* handle pir, r3, r6 */
for (i = 1; i < 4; i++) {
diff --git a/cpu/mpc85xx/u-boot-nand.lds b/cpu/mpc85xx/u-boot-nand.lds
index a0fc8f1..b4c63e2 100644
--- a/cpu/mpc85xx/u-boot-nand.lds
+++ b/cpu/mpc85xx/u-boot-nand.lds
@@ -58,7 +58,6 @@ SECTIONS
.text :
{
*(.text)
- *(.fixup)
*(.got1)
} :text
_etext = .;
diff --git a/cpu/ppc4xx/4xx_pci.c b/cpu/ppc4xx/4xx_pci.c
index fa521f0..eed4534 100644
--- a/cpu/ppc4xx/4xx_pci.c
+++ b/cpu/ppc4xx/4xx_pci.c
@@ -73,23 +73,30 @@
#include <common.h>
#include <command.h>
-#if !defined(CONFIG_440)
#include <asm/4xx_pci.h>
-#endif
#include <asm/processor.h>
+#include <asm/io.h>
#include <pci.h>
#ifdef CONFIG_PCI
DECLARE_GLOBAL_DATA_PTR;
+#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
+
+#if defined(CONFIG_PMC405)
+ushort pmc405_pci_subsys_deviceid(void);
+#endif
+
+/*#define DEBUG*/
+
/*
* Board-specific pci initialization
* Platform code can reimplement pci_pre_init() if needed
*/
int __pci_pre_init(struct pci_controller *hose)
{
-#if defined (CONFIG_405EP)
+#if defined(CONFIG_405EP)
/*
* Enable the internal PCI arbiter by default.
*
@@ -105,15 +112,8 @@ int __pci_pre_init(struct pci_controller *hose)
return 1;
}
-int pci_pre_init(struct pci_controller *hose) __attribute__((weak, alias("__pci_pre_init")));
-
-#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
-
-#if defined(CONFIG_PMC405)
-ushort pmc405_pci_subsys_deviceid(void);
-#endif
-
-/*#define DEBUG*/
+int pci_pre_init(struct pci_controller *hose)
+ __attribute__((weak, alias("__pci_pre_init")));
int __is_pci_host(struct pci_controller *hose)
{
@@ -231,7 +231,7 @@ void pci_405gp_init(struct pci_controller *hose)
pciauto_region_init(hose->pci_fb);
/* Let board change/modify hose & do initial checks */
- if (pci_pre_init (hose) == 0) {
+ if (pci_pre_init(hose) == 0) {
printf("PCI: Board-specific initialization failed.\n");
printf("PCI: Configuration aborted.\n");
return;
@@ -478,6 +478,231 @@ void pci_init_board(void)
static struct pci_controller ppc440_hose = {0};
+/*
+ * This routine is called to determine if a pci scan should be
+ * performed. With various hardware environments (especially cPCI and
+ * PPMC) it's insufficient to depend on the state of the arbiter enable
+ * bit in the strap register, or generic host/adapter assumptions.
+ *
+ * Rather than hard-code a bad assumption in the general 440 code, the
+ * 440 pci code requires the board to decide at runtime.
+ *
+ * Return 0 for adapter mode, non-zero for host (monarch) mode.
+ *
+ * Weak default implementation: "Normal" boards implement the PCI
+ * host functionality. This can be overridden for PCI adapter boards.
+ */
+int __is_pci_host(struct pci_controller *hose)
+{
+ return 1;
+}
+int is_pci_host(struct pci_controller *hose)
+ __attribute__((weak, alias("__is_pci_host")));
+
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPX) || \
+ defined(CONFIG_440GR) || defined(CONFIG_440GRX)
+
+#if defined(CONFIG_SYS_PCI_TARGET_INIT)
+/*
+ * pci_target_init
+ *
+ * The bootstrap configuration provides default settings for the pci
+ * inbound map (PIM). But the bootstrap config choices are limited and
+ * may not be sufficient for a given board.
+ */
+void __pci_target_init(struct pci_controller *hose)
+{
+ /*
+ * Set up Direct MMIO registers
+ */
+
+ /*
+ * PowerPC440 EP PCI Master configuration.
+ * Map one 1Gig range of PLB/processor addresses to PCI memory space.
+ * PLB address 0xA0000000-0xDFFFFFFF ==> PCI address 0xA0000000-0xDFFFFFFF
+ * Use byte reversed out routines to handle endianess.
+ * Make this region non-prefetchable.
+ */
+ /* PMM0 Mask/Attribute - disabled b4 setting */
+ out_le32((void *)PCIL0_PMM0MA, 0x00000000);
+ /* PMM0 Local Address */
+ out_le32((void *)PCIL0_PMM0LA, CONFIG_SYS_PCI_MEMBASE);
+ /* PMM0 PCI Low Address */
+ out_le32((void *)PCIL0_PMM0PCILA, CONFIG_SYS_PCI_MEMBASE);
+ /* PMM0 PCI High Address */
+ out_le32((void *)PCIL0_PMM0PCIHA, 0x00000000);
+ /* 512M + No prefetching, and enable region */
+ out_le32((void *)PCIL0_PMM0MA, 0xE0000001);
+
+ /* PMM1 Mask/Attribute - disabled b4 setting */
+ out_le32((void *)PCIL0_PMM1MA, 0x00000000);
+ /* PMM1 Local Address */
+ out_le32((void *)PCIL0_PMM1LA, CONFIG_SYS_PCI_MEMBASE2);
+ /* PMM1 PCI Low Address */
+ out_le32((void *)PCIL0_PMM1PCILA, CONFIG_SYS_PCI_MEMBASE2);
+ /* PMM1 PCI High Address */
+ out_le32((void *)PCIL0_PMM1PCIHA, 0x00000000);
+ /* 512M + No prefetching, and enable region */
+ out_le32((void *)PCIL0_PMM1MA, 0xE0000001);
+
+ out_le32((void *)PCIL0_PTM1MS, 0x00000001); /* Memory Size/Attribute */
+ out_le32((void *)PCIL0_PTM1LA, 0); /* Local Addr. Reg */
+ out_le32((void *)PCIL0_PTM2MS, 0); /* Memory Size/Attribute */
+ out_le32((void *)PCIL0_PTM2LA, 0); /* Local Addr. Reg */
+
+ /*
+ * Set up Configuration registers
+ */
+
+ /* Program the board's subsystem id/vendor id */
+ pci_write_config_word(0, PCI_SUBSYSTEM_VENDOR_ID,
+ CONFIG_SYS_PCI_SUBSYS_VENDORID);
+ pci_write_config_word(0, PCI_SUBSYSTEM_ID, CONFIG_SYS_PCI_SUBSYS_ID);
+
+ /* Configure command register as bus master */
+ pci_write_config_word(0, PCI_COMMAND, PCI_COMMAND_MASTER);
+
+ /* 240nS PCI clock */
+ pci_write_config_word(0, PCI_LATENCY_TIMER, 1);
+
+ /* No error reporting */
+ pci_write_config_word(0, PCI_ERREN, 0);
+
+ pci_write_config_dword(0, PCI_BRDGOPT2, 0x00000101);
+}
+#endif /* CONFIG_SYS_PCI_TARGET_INIT */
+
+/*
+ * pci_pre_init
+ *
+ * This routine is called just prior to registering the hose and gives
+ * the board the opportunity to check things. Returning a value of zero
+ * indicates that things are bad & PCI initialization should be aborted.
+ *
+ * Different boards may wish to customize the pci controller structure
+ * (add regions, override default access routines, etc) or perform
+ * certain pre-initialization actions.
+ *
+ */
+int __pci_pre_init(struct pci_controller *hose)
+{
+ u32 reg;
+
+ /*
+ * Set priority for all PLB3 devices to 0.
+ * Set PLB3 arbiter to fair mode.
+ */
+ mfsdr(SD0_AMP1, reg);
+ mtsdr(SD0_AMP1, (reg & 0x000000FF) | 0x0000FF00);
+ reg = mfdcr(PLB3_ACR);
+ mtdcr(PLB3_ACR, reg | 0x80000000);
+
+ /*
+ * Set priority for all PLB4 devices to 0.
+ */
+ mfsdr(SD0_AMP0, reg);
+ mtsdr(SD0_AMP0, (reg & 0x000000FF) | 0x0000FF00);
+ reg = mfdcr(PLB4_ACR) | 0xa0000000;
+ mtdcr(PLB4_ACR, reg);
+
+ /*
+ * Set Nebula PLB4 arbiter to fair mode.
+ */
+ /* Segment0 */
+ reg = (mfdcr(PLB0_ACR) & ~PLB0_ACR_PPM_MASK) | PLB0_ACR_PPM_FAIR;
+ reg = (reg & ~PLB0_ACR_HBU_MASK) | PLB0_ACR_HBU_ENABLED;
+ reg = (reg & ~PLB0_ACR_RDP_MASK) | PLB0_ACR_RDP_4DEEP;
+ reg = (reg & ~PLB0_ACR_WRP_MASK) | PLB0_ACR_WRP_2DEEP;
+ mtdcr(PLB0_ACR, reg);
+
+ /* Segment1 */
+ reg = (mfdcr(PLB1_ACR) & ~PLB1_ACR_PPM_MASK) | PLB1_ACR_PPM_FAIR;
+ reg = (reg & ~PLB1_ACR_HBU_MASK) | PLB1_ACR_HBU_ENABLED;
+ reg = (reg & ~PLB1_ACR_RDP_MASK) | PLB1_ACR_RDP_4DEEP;
+ reg = (reg & ~PLB1_ACR_WRP_MASK) | PLB1_ACR_WRP_2DEEP;
+ mtdcr(PLB1_ACR, reg);
+
+#if defined(CONFIG_SYS_PCI_BOARD_FIXUP_IRQ)
+ hose->fixup_irq = board_pci_fixup_irq;
+#endif
+
+ return 1;
+}
+
+#else /* defined(CONFIG_440EP) ... */
+
+#if defined(CONFIG_SYS_PCI_TARGET_INIT)
+void __pci_target_init(struct pci_controller * hose)
+{
+ /*
+ * Disable everything
+ */
+ out_le32((void *)PCIL0_PIM0SA, 0); /* disable */
+ out_le32((void *)PCIL0_PIM1SA, 0); /* disable */
+ out_le32((void *)PCIL0_PIM2SA, 0); /* disable */
+ out_le32((void *)PCIL0_EROMBA, 0); /* disable expansion rom */
+
+ /*
+ * Map all of SDRAM to PCI address 0x0000_0000. Note that the 440
+ * strapping options do not support sizes such as 128/256 MB.
+ */
+ out_le32((void *)PCIL0_PIM0LAL, CONFIG_SYS_SDRAM_BASE);
+ out_le32((void *)PCIL0_PIM0LAH, 0);
+ out_le32((void *)PCIL0_PIM0SA, ~(gd->ram_size - 1) | 1);
+ out_le32((void *)PCIL0_BAR0, 0);
+
+ /*
+ * Program the board's subsystem id/vendor id
+ */
+ out_le16((void *)PCIL0_SBSYSVID, CONFIG_SYS_PCI_SUBSYS_VENDORID);
+ out_le16((void *)PCIL0_SBSYSID, CONFIG_SYS_PCI_SUBSYS_DEVICEID);
+
+ out_le16((void *)PCIL0_CMD, in_le16((void *)PCIL0_CMD) |
+ PCI_COMMAND_MEMORY);
+}
+#endif /* CONFIG_SYS_PCI_TARGET_INIT */
+
+int __pci_pre_init(struct pci_controller *hose)
+{
+ /*
+ * This board is always configured as the host & requires the
+ * PCI arbiter to be enabled.
+ */
+ if (!pci_arbiter_enabled()) {
+ printf("PCI: PCI Arbiter disabled!\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+#endif /* defined(CONFIG_440EP) ... */
+
+#if defined(CONFIG_SYS_PCI_TARGET_INIT)
+void pci_target_init(struct pci_controller * hose)
+ __attribute__((weak, alias("__pci_target_init")));
+#endif /* CONFIG_SYS_PCI_TARGET_INIT */
+
+int pci_pre_init(struct pci_controller *hose)
+ __attribute__((weak, alias("__pci_pre_init")));
+
+#if defined(CONFIG_SYS_PCI_MASTER_INIT)
+void __pci_master_init(struct pci_controller *hose)
+{
+ u16 reg;
+
+ /*
+ * Write the PowerPC440 EP PCI Configuration regs.
+ * Enable PowerPC440 EP to be a master on the PCI bus (PMM).
+ * Enable PowerPC440 EP to act as a PCI memory target (PTM).
+ */
+ pci_read_config_word(0, PCI_COMMAND, &reg);
+ pci_write_config_word(0, PCI_COMMAND, reg |
+ PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+}
+void pci_master_init(struct pci_controller *hose)
+ __attribute__((weak, alias("__pci_master_init")));
+#endif /* CONFIG_SYS_PCI_MASTER_INIT */
int pci_440_init (struct pci_controller *hose)
{
@@ -548,7 +773,7 @@ int pci_440_init (struct pci_controller *hose)
pci_setup_indirect(hose, PCIL0_CFGADR, PCIL0_CFGDATA);
/* Let board change/modify hose & do initial checks */
- if (pci_pre_init (hose) == 0) {
+ if (pci_pre_init(hose) == 0) {
printf("PCI: Board-specific initialization failed.\n");
printf("PCI: Configuration aborted.\n");
return -1;
diff --git a/cpu/ppc4xx/4xx_pcie.c b/cpu/ppc4xx/4xx_pcie.c
index 19d2c7d..d9605c3 100644
--- a/cpu/ppc4xx/4xx_pcie.c
+++ b/cpu/ppc4xx/4xx_pcie.c
@@ -48,6 +48,125 @@ enum {
LNKW_X8 = 0x8
};
+static struct pci_controller pcie_hose[CONFIG_SYS_PCIE_NR_PORTS];
+
+/*
+ * Per default, all cards are present, so we need to check if the
+ * link comes up.
+ */
+int __board_pcie_card_present(int port)
+{
+ return 1;
+}
+int board_pcie_card_present(int port)
+ __attribute__((weak, alias("__board_pcie_card_present")));
+
+/*
+ * Some boards have runtime detection of the first and last PCIe
+ * slot used, so let's provide weak default functions for the
+ * common version.
+ */
+int __board_pcie_first(void)
+{
+ return 0;
+}
+int board_pcie_first(void)
+ __attribute__((weak, alias("__board_pcie_first")));
+
+int __board_pcie_last(void)
+{
+ return CONFIG_SYS_PCIE_NR_PORTS - 1;
+}
+int board_pcie_last(void)
+ __attribute__((weak, alias("__board_pcie_last")));
+
+void __board_pcie_setup_port(int port, int rootpoint)
+{
+ /* noting in this weak default implementation */
+}
+void board_pcie_setup_port(int port, int rootpoint)
+ __attribute__((weak, alias("__board_pcie_setup_port")));
+
+void pcie_setup_hoses(int busno)
+{
+ struct pci_controller *hose;
+ int i, bus;
+ int ret = 0;
+ char *env;
+ unsigned int delay;
+ int first = board_pcie_first();
+ int last = board_pcie_last();
+
+ /*
+ * Assume we're called after the PCI(X) hose(s) are initialized,
+ * which takes bus ID 0... and therefore start numbering PCIe's
+ * from the next number.
+ */
+ bus = busno;
+
+ for (i = first; i <= last; i++) {
+ /*
+ * Some boards (e.g. Katmai) can detects via hardware
+ * if a PCIe card is plugged, so let's check this.
+ */
+ if (!board_pcie_card_present(i))
+ continue;
+
+ if (is_end_point(i)) {
+ board_pcie_setup_port(i, 0);
+ ret = ppc4xx_init_pcie_endport(i);
+ } else {
+ board_pcie_setup_port(i, 1);
+ ret = ppc4xx_init_pcie_rootport(i);
+ }
+ if (ret == -ENODEV)
+ continue;
+ if (ret) {
+ printf("PCIE%d: initialization as %s failed\n", i,
+ is_end_point(i) ? "endpoint" : "root-complex");
+ continue;
+ }
+
+ hose = &pcie_hose[i];
+ hose->first_busno = bus;
+ hose->last_busno = bus;
+ hose->current_busno = bus;
+
+ /* setup mem resource */
+ pci_set_region(hose->regions + 0,
+ CONFIG_SYS_PCIE_MEMBASE + i * CONFIG_SYS_PCIE_MEMSIZE,
+ CONFIG_SYS_PCIE_MEMBASE + i * CONFIG_SYS_PCIE_MEMSIZE,
+ CONFIG_SYS_PCIE_MEMSIZE,
+ PCI_REGION_MEM);
+ hose->region_count = 1;
+ pci_register_hose(hose);
+
+ if (is_end_point(i)) {
+ ppc4xx_setup_pcie_endpoint(hose, i);
+ /*
+ * Reson for no scanning is endpoint can not generate
+ * upstream configuration accesses.
+ */
+ } else {
+ ppc4xx_setup_pcie_rootpoint(hose, i);
+ env = getenv ("pciscandelay");
+ if (env != NULL) {
+ delay = simple_strtoul(env, NULL, 10);
+ if (delay > 5)
+ printf("Warning, expect noticable delay before "
+ "PCIe scan due to 'pciscandelay' value!\n");
+ mdelay(delay * 1000);
+ }
+
+ /*
+ * Config access can only go down stream
+ */
+ hose->last_busno = pci_hose_scan(hose);
+ bus = hose->last_busno + 1;
+ }
+ }
+}
+
static int validate_endpoint(struct pci_controller *hose)
{
if (hose->cfg_data == (u8 *)CONFIG_SYS_PCIE0_CFGBASE)
diff --git a/cpu/ppc4xx/cmd_chip_config.c b/cpu/ppc4xx/cmd_chip_config.c
index d360d5b..ba57211 100644
--- a/cpu/ppc4xx/cmd_chip_config.c
+++ b/cpu/ppc4xx/cmd_chip_config.c
@@ -52,6 +52,12 @@ static int do_chip_config(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int cur_config_nr = -1;
u8 cur_config[CONFIG_4xx_CONFIG_BLOCKSIZE];
+ /*
+ * First switch to correct I2C bus. This is I2C bus 0
+ * for all currently available 4xx derivats.
+ */
+ I2C_SET_BUS(0);
+
#ifdef CONFIG_CMD_EEPROM
ret = eeprom_read(CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR,
CONFIG_4xx_CONFIG_I2C_EEPROM_OFFSET,
diff --git a/cpu/ppc4xx/config.mk b/cpu/ppc4xx/config.mk
index 00ad39b..979004b 100644
--- a/cpu/ppc4xx/config.mk
+++ b/cpu/ppc4xx/config.mk
@@ -32,3 +32,6 @@ PLATFORM_CPPFLAGS += -Wa,-m440 -mcpu=440
else
PLATFORM_CPPFLAGS += -Wa,-m405 -mcpu=405
endif
+
+# Use default linker script. Board port can override in board/*/config.mk
+LDSCRIPT := $(SRCTREE)/cpu/ppc4xx/u-boot.lds
diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c
index e1b00a7..73d4d06 100644
--- a/cpu/ppc4xx/cpu.c
+++ b/cpu/ppc4xx/cpu.c
@@ -81,7 +81,7 @@ static int pci_async_enabled(void)
#if defined(CONFIG_PCI) && !defined(CONFIG_IOP480) && \
!defined(CONFIG_405) && !defined(CONFIG_405EX)
-static int pci_arbiter_enabled(void)
+int pci_arbiter_enabled(void)
{
#if defined(CONFIG_405GP)
return (mfdcr(CPC0_PSR) & PSR_PCI_ARBIT_EN);
diff --git a/cpu/ppc4xx/i2c.c b/cpu/ppc4xx/i2c.c
index e3e1bab..7976e75 100644
--- a/cpu/ppc4xx/i2c.c
+++ b/cpu/ppc4xx/i2c.c
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2007
+ * (C) Copyright 2007-2009
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* based on work by Anne Sophie Harnois <anne-sophie.harnois@nextream.fr>
@@ -37,7 +37,8 @@
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_I2C_MULTI_BUS)
-/* Initialize the bus pointer to whatever one the SPD EEPROM is on.
+/*
+ * Initialize the bus pointer to whatever one the SPD EEPROM is on.
* Default is bus 0. This is necessary because the DDR initialization
* runs from ROM, and we can't switch buses because we can't modify
* the global variables.
@@ -45,59 +46,63 @@ DECLARE_GLOBAL_DATA_PTR;
#ifndef CONFIG_SYS_SPD_BUS_NUM
#define CONFIG_SYS_SPD_BUS_NUM 0
#endif
-static unsigned int i2c_bus_num __attribute__ ((section (".data"))) = CONFIG_SYS_SPD_BUS_NUM;
+static unsigned int i2c_bus_num __attribute__ ((section (".data"))) =
+ CONFIG_SYS_SPD_BUS_NUM;
#endif /* CONFIG_I2C_MULTI_BUS */
static void _i2c_bus_reset(void)
{
+ struct ppc4xx_i2c *i2c = (struct ppc4xx_i2c *)I2C_BASE_ADDR;
int i;
u8 dc;
/* Reset status register */
/* write 1 in SCMP and IRQA to clear these fields */
- out_8((u8 *)IIC_STS, 0x0A);
+ out_8(&i2c->sts, 0x0A);
/* write 1 in IRQP IRQD LA ICT XFRA to clear these fields */
- out_8((u8 *)IIC_EXTSTS, 0x8F);
+ out_8(&i2c->extsts, 0x8F);
/* Place chip in the reset state */
- out_8((u8 *)IIC_XTCNTLSS, IIC_XTCNTLSS_SRST);
+ out_8(&i2c->xtcntlss, IIC_XTCNTLSS_SRST);
/* Check if bus is free */
- dc = in_8((u8 *)IIC_DIRECTCNTL);
+ dc = in_8(&i2c->directcntl);
if (!DIRCTNL_FREE(dc)){
/* Try to set bus free state */
- out_8((u8 *)IIC_DIRECTCNTL, IIC_DIRCNTL_SDAC | IIC_DIRCNTL_SCC);
+ out_8(&i2c->directcntl, IIC_DIRCNTL_SDAC | IIC_DIRCNTL_SCC);
/* Wait until we regain bus control */
for (i = 0; i < 100; ++i) {
- dc = in_8((u8 *)IIC_DIRECTCNTL);
+ dc = in_8(&i2c->directcntl);
if (DIRCTNL_FREE(dc))
break;
/* Toggle SCL line */
dc ^= IIC_DIRCNTL_SCC;
- out_8((u8 *)IIC_DIRECTCNTL, dc);
+ out_8(&i2c->directcntl, dc);
udelay(10);
dc ^= IIC_DIRCNTL_SCC;
- out_8((u8 *)IIC_DIRECTCNTL, dc);
+ out_8(&i2c->directcntl, dc);
}
}
/* Remove reset */
- out_8((u8 *)IIC_XTCNTLSS, 0);
+ out_8(&i2c->xtcntlss, 0);
}
-void i2c_init(int speed, int slaveadd)
+void i2c_init(int speed, int slaveaddr)
{
- unsigned long freqOPB;
+ struct ppc4xx_i2c *i2c = (struct ppc4xx_i2c *)I2C_BASE_ADDR;
int val, divisor;
int bus;
#ifdef CONFIG_SYS_I2C_INIT_BOARD
- /* call board specific i2c bus reset routine before accessing the */
- /* environment, which might be in a chip on that bus. For details */
- /* about this problem see doc/I2C_Edge_Conditions. */
+ /*
+ * Call board specific i2c bus reset routine before accessing the
+ * environment, which might be in a chip on that bus. For details
+ * about this problem see doc/I2C_Edge_Conditions.
+ */
i2c_init_board();
#endif
@@ -109,54 +114,52 @@ void i2c_init(int speed, int slaveadd)
_i2c_bus_reset();
/* clear lo master address */
- out_8((u8 *)IIC_LMADR, 0);
+ out_8(&i2c->lmadr, 0);
/* clear hi master address */
- out_8((u8 *)IIC_HMADR, 0);
+ out_8(&i2c->hmadr, 0);
/* clear lo slave address */
- out_8((u8 *)IIC_LSADR, 0);
+ out_8(&i2c->lsadr, 0);
/* clear hi slave address */
- out_8((u8 *)IIC_HSADR, 0);
+ out_8(&i2c->hsadr, 0);
/* Clock divide Register */
- /* get OPB frequency */
- freqOPB = get_OPB_freq();
- /* set divisor according to freqOPB */
- divisor = (freqOPB - 1) / 10000000;
+ /* set divisor according to freq_opb */
+ divisor = (get_OPB_freq() - 1) / 10000000;
if (divisor == 0)
divisor = 1;
- out_8((u8 *)IIC_CLKDIV, divisor);
+ out_8(&i2c->clkdiv, divisor);
/* no interrupts */
- out_8((u8 *)IIC_INTRMSK, 0);
+ out_8(&i2c->intrmsk, 0);
/* clear transfer count */
- out_8((u8 *)IIC_XFRCNT, 0);
+ out_8(&i2c->xfrcnt, 0);
/* clear extended control & stat */
/* write 1 in SRC SRS SWC SWS to clear these fields */
- out_8((u8 *)IIC_XTCNTLSS, 0xF0);
+ out_8(&i2c->xtcntlss, 0xF0);
/* Mode Control Register
Flush Slave/Master data buffer */
- out_8((u8 *)IIC_MDCNTL, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB);
+ out_8(&i2c->mdcntl, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB);
- val = in_8((u8 *)IIC_MDCNTL);
+ val = in_8(&i2c->mdcntl);
/* Ignore General Call, slave transfers are ignored,
* disable interrupts, exit unknown bus state, enable hold
* SCL 100kHz normaly or FastMode for 400kHz and above
*/
- val |= IIC_MDCNTL_EUBS|IIC_MDCNTL_HSCL;
+ val |= IIC_MDCNTL_EUBS | IIC_MDCNTL_HSCL;
if (speed >= 400000)
val |= IIC_MDCNTL_FSM;
- out_8((u8 *)IIC_MDCNTL, val);
+ out_8(&i2c->mdcntl, val);
/* clear control reg */
- out_8((u8 *)IIC_CNTL, 0x00);
+ out_8(&i2c->cntl, 0x00);
}
/* set to SPD bus as default bus upon powerup */
@@ -195,13 +198,14 @@ static int i2c_transfer(unsigned char cmd_type,
unsigned char data[],
unsigned short data_len)
{
- unsigned char* ptr;
+ struct ppc4xx_i2c *i2c = (struct ppc4xx_i2c *)I2C_BASE_ADDR;
+ u8 *ptr;
int reading;
- int tran,cnt;
+ int tran, cnt;
int result;
int status;
int i;
- uchar creg;
+ u8 creg;
if (data == 0 || data_len == 0) {
/* Don't support data transfer of no length or to address 0 */
@@ -219,12 +223,13 @@ static int i2c_transfer(unsigned char cmd_type,
}
/* Clear Stop Complete Bit */
- out_8((u8 *)IIC_STS, IIC_STS_SCMP);
+ out_8(&i2c->sts, IIC_STS_SCMP);
+
/* Check init */
i = 10;
do {
/* Get status */
- status = in_8((u8 *)IIC_STS);
+ status = in_8(&i2c->sts);
i--;
} while ((status & IIC_STS_PT) && (i > 0));
@@ -232,13 +237,16 @@ static int i2c_transfer(unsigned char cmd_type,
result = IIC_NOK_TOUT;
return(result);
}
+
/* flush the Master/Slave Databuffers */
- out_8((u8 *)IIC_MDCNTL, ((in_8((u8 *)IIC_MDCNTL))|IIC_MDCNTL_FMDB|IIC_MDCNTL_FSDB));
+ out_8(&i2c->mdcntl, in_8(&i2c->mdcntl) |
+ IIC_MDCNTL_FMDB | IIC_MDCNTL_FSDB);
+
/* need to wait 4 OPB clocks? code below should take that long */
/* 7-bit adressing */
- out_8((u8 *)IIC_HMADR, 0);
- out_8((u8 *)IIC_LMADR, chip);
+ out_8(&i2c->hmadr, 0);
+ out_8(&i2c->lmadr, chip);
tran = 0;
result = IIC_OK;
@@ -247,9 +255,10 @@ static int i2c_transfer(unsigned char cmd_type,
while (tran != cnt && (result == IIC_OK)) {
int bc,j;
- /* Control register =
- * Normal transfer, 7-bits adressing, Transfer up to bc bytes, Normal start,
- * Transfer is a sequence of transfers
+ /*
+ * Control register =
+ * Normal transfer, 7-bits adressing, Transfer up to
+ * bc bytes, Normal start, Transfer is a sequence of transfers
*/
creg |= IIC_CNTL_PT;
@@ -259,32 +268,36 @@ static int i2c_transfer(unsigned char cmd_type,
if ((!cmd_type && (ptr == addr)) || ((tran + bc) != cnt))
creg |= IIC_CNTL_CHT;
- if (reading)
+ if (reading) {
creg |= IIC_CNTL_READ;
- else
- for(j=0; j < bc; j++)
+ } else {
+ for(j = 0; j < bc; j++) {
/* Set buffer */
- out_8((u8 *)IIC_MDBUF, ptr[tran+j]);
- out_8((u8 *)IIC_CNTL, creg);
+ out_8(&i2c->mdbuf, ptr[tran + j]);
+ }
+ }
+ out_8(&i2c->cntl, creg);
- /* Transfer is in progress
+ /*
+ * Transfer is in progress
* we have to wait for upto 5 bytes of data
* 1 byte chip address+r/w bit then bc bytes
* of data.
* udelay(10) is 1 bit time at 100khz
* Doubled for slop. 20 is too small.
*/
- i = 2*5*8;
+ i = 2 * 5 * 8;
do {
/* Get status */
- status = in_8((u8 *)IIC_STS);
+ status = in_8(&i2c->sts);
udelay(10);
i--;
- } while ((status & IIC_STS_PT) && !(status & IIC_STS_ERR) && (i > 0));
+ } while ((status & IIC_STS_PT) && !(status & IIC_STS_ERR) &&
+ (i > 0));
if (status & IIC_STS_ERR) {
result = IIC_NOK;
- status = in_8((u8 *)IIC_EXTSTS);
+ status = in_8(&i2c->extsts);
/* Lost arbitration? */
if (status & IIC_EXTSTS_LA)
result = IIC_NOK_LA;
@@ -297,19 +310,21 @@ static int i2c_transfer(unsigned char cmd_type,
} else if ( status & IIC_STS_PT) {
result = IIC_NOK_TOUT;
}
+
/* Command is reading => get buffer */
if ((reading) && (result == IIC_OK)) {
/* Are there data in buffer */
if (status & IIC_STS_MDBS) {
/*
- * even if we have data we have to wait 4OPB clocks
- * for it to hit the front of the FIFO, after that
- * we can just read. We should check XFCNT here and
- * if the FIFO is full there is no need to wait.
+ * even if we have data we have to wait 4OPB
+ * clocks for it to hit the front of the FIFO,
+ * after that we can just read. We should check
+ * XFCNT here and if the FIFO is full there is
+ * no need to wait.
*/
udelay(1);
- for (j=0; j<bc; j++)
- ptr[tran+j] = in_8((u8 *)IIC_MDBUF);
+ for (j = 0; j < bc; j++)
+ ptr[tran + j] = in_8(&i2c->mdbuf);
} else
result = IIC_NOK_DATA;
}
@@ -324,7 +339,7 @@ static int i2c_transfer(unsigned char cmd_type,
creg = IIC_CNTL_RPST;
}
}
- return (result);
+ return result;
}
int i2c_probe(uchar chip)
@@ -338,17 +353,17 @@ int i2c_probe(uchar chip)
* address was <ACK>ed (i.e. there was a chip at that address which
* drove the data line low).
*/
- return (i2c_transfer(1, chip << 1, 0,0, buf, 1) != 0);
+ return (i2c_transfer(1, chip << 1, 0, 0, buf, 1) != 0);
}
-
-int i2c_read(uchar chip, uint addr, int alen, uchar * buffer, int len)
+static int ppc4xx_i2c_transfer(uchar chip, uint addr, int alen, uchar *buffer,
+ int len, int read)
{
uchar xaddr[4];
int ret;
if (alen > 4) {
- printf ("I2C read: addr len %d not supported\n", alen);
+ printf("I2C: addr len %d not supported\n", alen);
return 1;
}
@@ -373,50 +388,30 @@ int i2c_read(uchar chip, uint addr, int alen, uchar * buffer, int len)
* hidden in the chip address.
*/
if (alen > 0)
- chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
+ chip |= ((addr >> (alen * 8)) &
+ CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
#endif
- if ((ret = i2c_transfer(1, chip<<1, &xaddr[4-alen], alen, buffer, len)) != 0) {
- if (gd->have_console)
- printf( "I2c read: failed %d\n", ret);
+ if ((ret = i2c_transfer(read, chip << 1, &xaddr[4 - alen], alen,
+ buffer, len)) != 0) {
+ if (gd->have_console) {
+ printf("I2C %s: failed %d\n",
+ read ? "read" : "write", ret);
+ }
+
return 1;
}
+
return 0;
}
-int i2c_write(uchar chip, uint addr, int alen, uchar * buffer, int len)
+int i2c_read(uchar chip, uint addr, int alen, uchar * buffer, int len)
{
- uchar xaddr[4];
-
- if (alen > 4) {
- printf ("I2C write: addr len %d not supported\n", alen);
- return 1;
-
- }
-
- if (alen > 0) {
- xaddr[0] = (addr >> 24) & 0xFF;
- xaddr[1] = (addr >> 16) & 0xFF;
- xaddr[2] = (addr >> 8) & 0xFF;
- xaddr[3] = addr & 0xFF;
- }
-
-#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
- /*
- * EEPROM chips that implement "address overflow" are ones
- * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
- * address and the extra bits end up in the "chip address"
- * bit slots. This makes a 24WC08 (1Kbyte) chip look like
- * four 256 byte chips.
- *
- * Note that we consider the length of the address field to
- * still be one byte because the extra address bits are
- * hidden in the chip address.
- */
- if (alen > 0)
- chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
-#endif
+ return ppc4xx_i2c_transfer(chip, addr, alen, buffer, len, 1);
+}
- return (i2c_transfer(0, chip<<1, &xaddr[4-alen], alen, buffer, len ) != 0);
+int i2c_write(uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+ return ppc4xx_i2c_transfer(chip, addr, alen, buffer, len, 0);
}
#if defined(CONFIG_I2C_MULTI_BUS)
diff --git a/cpu/ppc4xx/u-boot.lds b/cpu/ppc4xx/u-boot.lds
new file mode 100644
index 0000000..2b47934
--- /dev/null
+++ b/cpu/ppc4xx/u-boot.lds
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include "config.h" /* CONFIG_BOARDDIR */
+
+#ifndef RESET_VECTOR_ADDRESS
+#define RESET_VECTOR_ADDRESS 0xfffffffc
+#endif
+
+OUTPUT_ARCH(powerpc)
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+PHDRS
+{
+ text PT_LOAD;
+ bss PT_LOAD;
+}
+
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ *(.text)
+ *(.got1)
+ } :text
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.eh_frame)
+ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
+ } :text
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+#ifdef CONFIG_440
+ .bootpg RESET_VECTOR_ADDRESS - 0xffc :
+ {
+ cpu/ppc4xx/start.o (.bootpg)
+
+ /*
+ * PPC440 board need a board specific object with the
+ * TLB definitions. This needs to get included right after
+ * start.o, since the first shadow TLB only covers 4k
+ * of address space.
+ */
+ CONFIG_BOARDDIR/init.o (.bootpg)
+ } :text = 0xffff
+#endif
+
+ .resetvec RESET_VECTOR_ADDRESS :
+ {
+ *(.resetvec)
+ } :text = 0xffff
+
+ . = RESET_VECTOR_ADDRESS + 0x4;
+
+ /*
+ * Make sure that the bss segment isn't linked at 0x0, otherwise its
+ * address won't be updated during relocation fixups. Note that
+ * this is a temporary fix. Code to dynamically the fixup the bss
+ * location will be added in the future. When the bss relocation
+ * fixup code is present this workaround should be removed.
+ */
+#if (RESET_VECTOR_ADDRESS == 0xfffffffc)
+ . |= 0x10;
+#endif
+
+ __bss_start = .;
+ .bss (NOLOAD) :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ } :bss
+
+ . = ALIGN(4);
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/cpu/pxa/timer.c b/cpu/pxa/timer.c
index e2df3a5..8d0f826 100644
--- a/cpu/pxa/timer.c
+++ b/cpu/pxa/timer.c
@@ -78,7 +78,7 @@ void set_timer (ulong t)
/* nop */
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
udelay_masked (usec);
}
diff --git a/cpu/s3c44b0/timer.c b/cpu/s3c44b0/timer.c
index 34184ab..6f1d8f6 100644
--- a/cpu/s3c44b0/timer.c
+++ b/cpu/s3c44b0/timer.c
@@ -75,7 +75,7 @@ void set_timer (ulong t)
timestamp = t;
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
ulong tmo;
diff --git a/cpu/sa1100/timer.c b/cpu/sa1100/timer.c
index 3f77e81..0207501 100644
--- a/cpu/sa1100/timer.c
+++ b/cpu/sa1100/timer.c
@@ -49,7 +49,7 @@ void set_timer (ulong t)
/* nop */
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
udelay_masked (usec);
}