summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/galileo-boards/ev96100/Makefile2
-rw-r--r--arch/mips/galileo-boards/ev96100/init.c (renamed from arch/mips/galileo-boards/generic/init.c)5
-rw-r--r--arch/mips/galileo-boards/ev96100/int-handler.S10
-rw-r--r--arch/mips/galileo-boards/ev96100/irq.c379
-rw-r--r--arch/mips/galileo-boards/ev96100/memory.c23
-rw-r--r--arch/mips/galileo-boards/ev96100/pci.c (renamed from arch/mips/galileo-boards/generic/pci.c)61
-rw-r--r--arch/mips/galileo-boards/ev96100/prom.c42
-rw-r--r--arch/mips/galileo-boards/ev96100/puts.c168
-rw-r--r--arch/mips/galileo-boards/ev96100/setup.c177
-rw-r--r--arch/mips/galileo-boards/ev96100/time.c68
-rw-r--r--arch/mips/galileo-boards/ev96100/uart.S92
-rw-r--r--arch/mips/galileo-boards/generic/Makefile2
-rw-r--r--arch/mips/galileo-boards/generic/prom-no.c50
13 files changed, 512 insertions, 567 deletions
diff --git a/arch/mips/galileo-boards/ev96100/Makefile b/arch/mips/galileo-boards/ev96100/Makefile
index 641664c7d..5e59068ad 100644
--- a/arch/mips/galileo-boards/ev96100/Makefile
+++ b/arch/mips/galileo-boards/ev96100/Makefile
@@ -17,6 +17,6 @@
O_TARGET:= ev96100.o
-obj-y := prom.o time.o irq.o int-handler.o setup.o puts.o uart.o memory.o
+obj-y := init.o pci.o time.o irq.o int-handler.o setup.o puts.o memory.o
include $(TOPDIR)/Rules.make
diff --git a/arch/mips/galileo-boards/generic/init.c b/arch/mips/galileo-boards/ev96100/init.c
index e6885bc47..320d95718 100644
--- a/arch/mips/galileo-boards/generic/init.c
+++ b/arch/mips/galileo-boards/ev96100/init.c
@@ -133,9 +133,10 @@ void __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
prom_envp = envp;
mips_machgroup = MACH_GROUP_GALILEO;
+ mips_machtype = MACH_EV96100;
prom_init_cmdline();
- /* 64 MB non-upgradable */
- add_memory_region(0, 64 << 20, BOOT_MEM_RAM);
+ /* 32 MB upgradable */
+ add_memory_region(0, 32 << 20, BOOT_MEM_RAM);
}
diff --git a/arch/mips/galileo-boards/ev96100/int-handler.S b/arch/mips/galileo-boards/ev96100/int-handler.S
index 19bf163d1..c53c44ee7 100644
--- a/arch/mips/galileo-boards/ev96100/int-handler.S
+++ b/arch/mips/galileo-boards/ev96100/int-handler.S
@@ -4,7 +4,6 @@
#include <asm/stackframe.h>
.text
- .set mips1
.set macro
.set noat
.align 5
@@ -48,8 +47,15 @@ NESTED(ev96100IRQ, PT_SIZE, sp)
la a1, ret_from_irq
jr a1
+ nop
-3: j spurious_interrupt
+3:
+ move a0, sp
+ jal mips_spurious_interrupt
+ nop
+ la a1, ret_from_irq
+ jr a1
+ nop
/* dbg: .asciz "\nev96100IRQ" */
END(ev96100IRQ)
diff --git a/arch/mips/galileo-boards/ev96100/irq.c b/arch/mips/galileo-boards/ev96100/irq.c
index 7a7b7d9de..6034a2bd5 100644
--- a/arch/mips/galileo-boards/ev96100/irq.c
+++ b/arch/mips/galileo-boards/ev96100/irq.c
@@ -5,7 +5,7 @@
*
* Copyright 2000 MontaVista Software Inc.
* Author: MontaVista Software, Inc.
- * ppopov@mvista.com or support@mvista.com
+ * ppopov@mvista.com or source@mvista.com
*
* This file was derived from Carsten Langgaard's
* arch/mips/mips-boards/atlas/atlas_int.c.
@@ -43,7 +43,7 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/timex.h>
-#include <linux/slab.h>
+#include <linux/malloc.h>
#include <linux/random.h>
#include <asm/bitops.h>
@@ -54,131 +54,120 @@
#include <asm/system.h>
#include <asm/galileo-boards/ev96100int.h>
+#ifdef CONFIG_REMOTE_DEBUG
+extern void breakpoint(void);
+extern int ev96100_remote_debug;
+extern int ev96100_remote_debug_line;
+#endif
+
+extern void puts(unsigned char *cp);
+extern void set_debug_traps(void);
extern void mips_timer_interrupt(int irq, struct pt_regs *regs);
extern asmlinkage void ev96100IRQ(void);
-irq_cpustat_t irq_stat[NR_CPUS];
+irq_cpustat_t irq_stat [NR_CPUS];
unsigned int local_bh_count[NR_CPUS];
unsigned int local_irq_count[NR_CPUS];
unsigned long spurious_count = 0;
irq_desc_t irq_desc[NR_IRQS];
-irq_desc_t *irq_desc_base = &irq_desc[0];
+irq_desc_t *irq_desc_base=&irq_desc[0];
+#if 0 /* unused at this time */
static struct irqaction timer_action = {
NULL, 0, 0, "R7000 timer/counter", NULL, NULL,
};
static struct hw_interrupt_type mips_timer = {
- "MIPS CPU Timer",
- NULL,
- NULL,
- NULL, /* unmask_irq */
- NULL, /* mask_irq */
- NULL, /* mask_and_ack */
- 0
+ "MIPS CPU Timer",
+ NULL,
+ NULL,
+ NULL, /* unmask_irq */
+ NULL, /* mask_irq */
+ NULL, /* mask_and_ack */
+ 0
};
+#endif
/* Function for careful CP0 interrupt mask access */
static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
{
- unsigned long status = read_32bit_cp0_register(CP0_STATUS);
- status &= ~((clr_mask & 0xFF) << 8);
- status |= (set_mask & 0xFF) << 8;
- write_32bit_cp0_register(CP0_STATUS, status);
+ unsigned long status = read_32bit_cp0_register(CP0_STATUS);
+ status &= ~((clr_mask & 0xFF) << 8);
+ status |= (set_mask & 0xFF) << 8;
+ write_32bit_cp0_register(CP0_STATUS, status);
}
static inline void mask_irq(unsigned int irq_nr)
{
- modify_cp0_intmask(irq_nr, 0);
+ modify_cp0_intmask(irq_nr, 0);
}
static inline void unmask_irq(unsigned int irq_nr)
{
- modify_cp0_intmask(0, irq_nr);
+ modify_cp0_intmask(0, irq_nr);
}
void disable_irq(unsigned int irq_nr)
{
- unsigned long flags;
+ unsigned long flags;
- save_and_cli(flags);
- mask_irq(irq_nr);
- restore_flags(flags);
+ save_and_cli(flags);
+ mask_irq(irq_nr);
+ restore_flags(flags);
}
void enable_irq(unsigned int irq_nr)
{
unsigned long flags;
-#if 0
- printk("enable irq %d\n", irq_nr);
- printk("status reg: %x, cause %x\n",
- read_32bit_cp0_register(CP0_STATUS),
- read_32bit_cp0_register(CP0_CAUSE));
-#endif
- save_and_cli(flags);
- unmask_irq(irq_nr);
- restore_flags(flags);
-#if 0
- printk("new status reg: %x, cause %x\n",
- read_32bit_cp0_register(CP0_STATUS),
- read_32bit_cp0_register(CP0_CAUSE));
-#endif
+ save_and_cli(flags);
+ unmask_irq(irq_nr);
+ restore_flags(flags);
}
void __init ev96100_time_init()
{
- puts("ev96100 time_init\n");
-
+ return;
}
int get_irq_list(char *buf)
{
- int i, len = 0, j;
- struct irqaction *action;
-
- len += sprintf(buf + len, " ");
- for (j = 0; j < smp_num_cpus; j++)
- len += sprintf(buf + len, "CPU%d ", j);
- *(char *) (buf + len++) = '\n';
-
- for (i = 0; i < NR_IRQS; i++) {
- action = irq_desc[i].action;
- if (!action || !action->handler)
- continue;
- len += sprintf(buf + len, "%3d: ", i);
- len += sprintf(buf + len, "%10u ", kstat_irqs(i));
- if (irq_desc[i].handler)
- len +=
- sprintf(buf + len, " %s ",
- irq_desc[i].handler->typename);
- else
- len += sprintf(buf + len, " None ");
- len += sprintf(buf + len, " %s", action->name);
- for (action = action->next; action; action = action->next) {
- len += sprintf(buf + len, ", %s", action->name);
- }
- len += sprintf(buf + len, "\n");
- }
- len += sprintf(buf + len, "BAD: %10lu\n", spurious_count);
- return len;
+ int i, len = 0, j;
+ struct irqaction * action;
+
+ len += sprintf(buf+len, " ");
+ for (j=0; j<smp_num_cpus; j++)
+ len += sprintf(buf+len, "CPU%d ",j);
+ *(char *)(buf+len++) = '\n';
+
+ for (i = 0 ; i < NR_IRQS ; i++) {
+ action = irq_desc[i].action;
+ if ( !action || !action->handler )
+ continue;
+ len += sprintf(buf+len, "%3d: ", i);
+ len += sprintf(buf+len, "%10u ", kstat_irqs(i));
+ if ( irq_desc[i].handler )
+ len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename );
+ else
+ len += sprintf(buf+len, " None ");
+ len += sprintf(buf+len, " %s",action->name);
+ for (action=action->next; action; action = action->next) {
+ len += sprintf(buf+len, ", %s", action->name);
+ }
+ len += sprintf(buf+len, "\n");
+ }
+ len += sprintf(buf+len, "BAD: %10lu\n", spurious_count);
+ return len;
}
-asmlinkage void do_IRQ(unsigned long cause, struct pt_regs *regs)
+asmlinkage void do_IRQ(unsigned long cause, struct pt_regs * regs)
{
struct irqaction *action;
int cpu;
- int status;
int irq;
- //printk("do_IRQ: cause %x *regs %x\n", cause, regs);
- /*
- * Service one interrupt only.
- * The "priority" is not really defined at this point.
- * This will change once we add the R7000 extensions.
- */
-// if (cause & CAUSEF_IP7)
-// irq = 7;
+ cpu = smp_processor_id();
+
if (cause & CAUSEF_IP6)
irq = 6;
else if (cause & CAUSEF_IP5)
@@ -193,159 +182,169 @@ asmlinkage void do_IRQ(unsigned long cause, struct pt_regs *regs)
irq = 1;
else if (cause & CAUSEF_IP0)
irq = 0;
- else
- return; /* should not happen */
+ else {
+ return; /* should not happen */
+ }
+ irq_enter(cpu,irq);
- cpu = smp_processor_id();
- irq_enter(cpu, irq);
kstat.irqs[cpu][irq]++;
- status = 0;
-
if (irq_desc[irq].handler && irq_desc[irq].handler->ack) {
- irq_desc[irq].handler->ack(irq);
+ irq_desc[irq].handler->ack(irq);
}
action = irq_desc[irq].action;
- if (action && action->handler) {
- //if (!(action->flags & SA_INTERRUPT)) __sti();
- //printk("irq %d, action->handler %x\n", irq, action->handler);
- do {
- status |= action->flags;
+ if (action && action->handler)
+ {
+ mask_irq(1<<irq);
+ if (!(action->flags & SA_INTERRUPT)) __sti(); /* reenable ints */
+ do {
action->handler(irq, action->dev_id, regs);
action = action->next;
- } while (action);
- //__cli();
- if (irq_desc[irq].handler) {
- printk("handler??\n");
- while (1);
- if (irq_desc[irq].handler->end)
- irq_desc[irq].handler->end(irq);
- else if (irq_desc[irq].handler->enable)
- irq_desc[irq].handler->enable(irq);
+ } while ( action );
+ __cli(); /* disable ints */
+ if (irq_desc[irq].handler)
+ {
+ /* revisit */
+ panic("Unprepared to handle irq_desc[%d].handler %x\n",
+ irq, (unsigned)irq_desc[irq].handler);
}
- } else {
+ unmask_irq(1<<irq);
+ }
+ else
+ {
spurious_count++;
- //printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq);
- printk("Unhandled interrupt %x, disabled\n", irq);
- disable_irq(1 << irq);
- if (irq_desc[irq].handler->end)
- irq_desc[irq].handler->end(irq);
+ printk("Unhandled interrupt %x, cause %x, disabled\n",
+ (unsigned)irq, (unsigned)cause);
+ disable_irq(1<<irq);
}
+ irq_exit(cpu,irq);
- irq_exit(cpu, irq);
-
+#if 0
if (softirq_active(cpu) & softirq_mask(cpu))
do_softirq();
+#endif
}
-int request_irq(unsigned int irq,
- void (*handler) (int, void *, struct pt_regs *),
- unsigned long irqflags, const char *devname, void *dev_id)
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+ unsigned long irqflags, const char * devname, void *dev_id)
{
- struct irqaction *old, **p, *action;
- unsigned long flags;
-
- /*
- * IRQs are number 0 through 7, where 0 corresponds to IP0 and
- * 7 corresponds to IP7. IP0 and IP1 are software interrupts. IP7
- * is typically the timer interrupt, unless the R7000 extensions are
- * used.
- */
-
- printk("request_irq %d, handler %x\n", irq, handler);
-
- if (irq >= NR_IRQS)
- return -EINVAL;
- if (!handler) {
- /* Free */
- for (p = &irq_desc[irq].action; (action = *p) != NULL;
- p = &action->next) {
- /* Found it - now free it */
- save_flags(flags);
- cli();
- *p = action->next;
- restore_flags(flags);
- kfree(action);
- return 0;
- }
- return -ENOENT;
- }
-
- action = (struct irqaction *)
- kmalloc(sizeof(struct irqaction), GFP_KERNEL);
- if (!action)
- return -ENOMEM;
- memset(action, 0, sizeof(struct irqaction));
-
- save_flags(flags);
- cli();
-
- action->handler = handler;
- action->flags = irqflags;
- action->mask = 0;
- action->name = devname;
- action->dev_id = dev_id;
- action->next = NULL;
-
- p = &irq_desc[irq].action;
-
- if ((old = *p) != NULL) {
- /* Can't share interrupts unless both agree to */
- if (!(old->flags & action->flags & SA_SHIRQ))
- return -EBUSY;
- /* add new interrupt at end of irq queue */
- do {
- p = &old->next;
- old = *p;
- } while (old);
- }
- *p = action;
- printk("action %x, action->handler %x\n",
- irq_desc[irq].action, irq_desc[irq].action->handler);
-
- enable_irq(1 << irq);
- restore_flags(flags);
- return 0;
+ struct irqaction *old, **p, *action;
+ unsigned long flags;
+
+ /*
+ * IRQs are number 0 through 7, where 0 corresponds to IP0 and
+ * 7 corresponds to IP7. IP0 and IP1 are software interrupts. IP7
+ * is typically the timer interrupt, unless the R7000 extensions are
+ * used.
+ */
+
+ if (irq >= NR_IRQS)
+ return -EINVAL;
+ if (!handler)
+ {
+ /* Free */
+ for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next)
+ {
+ /* Found it - now free it */
+ save_flags(flags);
+ cli();
+ *p = action->next;
+ disable_irq(1<<irq);
+ restore_flags(flags);
+ kfree(action);
+ return 0;
+ }
+ return -ENOENT;
+ }
+
+ action = (struct irqaction *)
+ kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+ if (!action)
+ return -ENOMEM;
+ memset(action, 0, sizeof(struct irqaction));
+
+ save_flags(flags);
+ cli();
+
+ action->handler = handler;
+ action->flags = irqflags;
+ action->mask = 0;
+ action->name = devname;
+ action->dev_id = dev_id;
+ action->next = NULL;
+
+ p = &irq_desc[irq].action;
+
+ if ((old = *p) != NULL) {
+ /* Can't share interrupts unless both agree to */
+ if (!(old->flags & action->flags & SA_SHIRQ))
+ return -EBUSY;
+ /* add new interrupt at end of irq queue */
+ do {
+ p = &old->next;
+ old = *p;
+ } while (old);
+ }
+ *p = action;
+ enable_irq(1<<irq);
+ restore_flags(flags);
+ return 0;
}
-
+
void free_irq(unsigned int irq, void *dev_id)
{
- printk("free_irq %d\n", irq);
- request_irq(irq, NULL, 0, NULL, dev_id);
+ request_irq(irq, NULL, 0, NULL, dev_id);
}
-unsigned long probe_irq_on(void)
+unsigned long probe_irq_on (void)
{
- return 0;
+ return 0;
}
-int probe_irq_off(unsigned long irqs)
+int probe_irq_off (unsigned long irqs)
{
- return 0;
+ return 0;
}
-int (*irq_cannonicalize) (int irq);
+int (*irq_cannonicalize)(int irq);
int ev96100_irq_cannonicalize(int i)
{
- return i;
+ return i;
}
void __init init_IRQ(void)
{
- puts("init_IRQ\n");
- memset(irq_desc, 0, sizeof(irq_desc));
- irq_cannonicalize = ev96100_irq_cannonicalize;
-
- /*
- irq_desc[EV96100INT_TIMER].handler = &mips_timer;
- irq_desc[EV96100INT_TIMER].action = &timer_action;
- irq_desc[EV96100INT_TIMER].action->handler = mips_timer_interrupt;
- */
+ memset(irq_desc, 0, sizeof(irq_desc));
+ irq_cannonicalize = ev96100_irq_cannonicalize;
+ set_except_vector(0, ev96100IRQ);
+
+#ifdef CONFIG_REMOTE_DEBUG
+ /* If local serial I/O used for debug port, enter kgdb at once */
+ if (ev96100_remote_debug) {
+ puts("Waiting for kgdb to connect...");
+ set_debug_traps();
+ breakpoint();
+ }
+#endif
+}
- set_except_vector(0, ev96100IRQ);
+void mips_spurious_interrupt(struct pt_regs *regs)
+{
+#if 1
+ return;
+#else
+ unsigned long status, cause;
+
+ printk("got spurious interrupt\n");
+ status = read_32bit_cp0_register(CP0_STATUS);
+ cause = read_32bit_cp0_register(CP0_CAUSE);
+ printk("status %x cause %x\n", status, cause);
+ printk("epc %x badvaddr %x \n", regs->cp0_epc, regs->cp0_badvaddr);
+// while(1);
+#endif
}
EXPORT_SYMBOL(irq_cannonicalize);
diff --git a/arch/mips/galileo-boards/ev96100/memory.c b/arch/mips/galileo-boards/ev96100/memory.c
index de045c366..2adccf0f8 100644
--- a/arch/mips/galileo-boards/ev96100/memory.c
+++ b/arch/mips/galileo-boards/ev96100/memory.c
@@ -48,10 +48,29 @@
* FIX ME!!!
*/
-void __init prom_meminit(void)
+
+int __init page_is_ram(unsigned long pagenr)
{
+ return 1;
}
-void prom_free_prom_memory(void)
+void prom_free_prom_memory (void)
{
}
+
+unsigned long __init prom_get_memsize(void)
+{
+ char *memsize_str;
+ unsigned int memsize;
+
+ memsize_str = prom_getenv("memsize");
+ if (!memsize_str) {
+ memsize = 32; /* set to 32 MB */
+ } else {
+#ifdef DEBUG
+ printk("prom_memsize: %s\n", memsize_str);
+#endif
+ memsize = simple_strtol(memsize_str, NULL, 0);
+ }
+ return memsize;
+}
diff --git a/arch/mips/galileo-boards/generic/pci.c b/arch/mips/galileo-boards/ev96100/pci.c
index f88bca012..2ea7f238a 100644
--- a/arch/mips/galileo-boards/generic/pci.c
+++ b/arch/mips/galileo-boards/ev96100/pci.c
@@ -1,4 +1,5 @@
/*
+ *
* BRIEF MODULE DESCRIPTION
* Galileo EV96100 board specific pci support.
*
@@ -41,12 +42,14 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <asm//gt64120.h>
#include <asm/galileo-boards/ev96100.h>
-#include <asm/gt64120.h>
#define PCI_ACCESS_READ 0
#define PCI_ACCESS_WRITE 1
+#undef DEBUG
+
static int
mips_pcibios_config_access(unsigned char access_type, struct pci_dev *dev,
unsigned char where, u32 *data)
@@ -309,10 +312,6 @@ pcibios_setup(char *str)
return str;
}
-struct pci_fixup pcibios_fixups[] = {
- { 0 }
-};
-
void __init
pcibios_update_resource(struct pci_dev *dev, struct resource *root,
struct resource *res, int resource)
@@ -333,7 +332,57 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root,
*/
void __init pcibios_fixup_bus(struct pci_bus *b)
{
- pci_read_bridge_bases(b);
+// pci_read_bridge_bases(b);
+}
+
+void __init ev96100_int_line_fixup(struct pci_dev *dev)
+{
+ unsigned int slot;
+ unsigned char irq;
+ unsigned long vendor;
+
+ /*
+ ** EV96100 interrupt routing for pci bus 0
+ ** NOTE: this are my experimental findings, since I do not
+ ** have Galileo's latest PLD equations.
+ **
+ ** The functions in irq.c assume the following irq numbering:
+ ** irq 2: CPU cause register bit IP2
+ ** irq 3: CPU cause register bit IP3
+ ** irq 4: CPU cause register bit IP4
+ ** irq 5: CPU cause register bit IP5
+ ** irq 6: CPU cause register bit IP6
+ ** irq 7: CPU cause register bit IP7
+ **
+ */
+
+#ifdef DEBUG
+ printk("ev96100_int_line_fixup bus %d\n", dev->bus->number);
+#endif
+ if (dev->bus->number != 0)
+ return;
+
+ slot = PCI_SLOT(dev->devfn);
+ pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &vendor);
+
+#ifdef DEBUG
+ printk("devfn %x, slot %d vendor %x\n", dev->devfn, slot, vendor);
+#endif
+
+ /* fixup irq line based on slot # */
+
+ if (slot == 8) {
+ dev->irq = 5;
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+ }
+ else if (slot == 9) {
+ dev->irq = 2;
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+ }
}
+struct pci_fixup pcibios_fixups[] = {
+ { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, ev96100_int_line_fixup },
+ { 0 }
+};
#endif /* CONFIG_PCI */
diff --git a/arch/mips/galileo-boards/ev96100/prom.c b/arch/mips/galileo-boards/ev96100/prom.c
deleted file mode 100644
index 75c3c8a6c..000000000
--- a/arch/mips/galileo-boards/ev96100/prom.c
+++ /dev/null
@@ -1,42 +0,0 @@
-
-/*
- * ev96100_prom.c
- *
- * BRIEF MODULE DESCRIPTION
- * Prom routines supplied by some boot codes.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- * pete_popov@mvista.com or support@mvista.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/stddef.h>
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-
-/* FIX ME */
-void __init prom_printf(char *fmt, ...)
-{
-}
diff --git a/arch/mips/galileo-boards/ev96100/puts.c b/arch/mips/galileo-boards/ev96100/puts.c
index 7c2f231e4..4354dfce3 100644
--- a/arch/mips/galileo-boards/ev96100/puts.c
+++ b/arch/mips/galileo-boards/ev96100/puts.c
@@ -1,4 +1,7 @@
+/*
+ * Debug routines which directly access the uart.
+ */
#include <linux/types.h>
#include <asm/galileo-boards/ev96100.h>
@@ -15,88 +18,127 @@
#define SERB_DATA 0x00
#define TX_BUSY 0x20
+#define TIMEOUT 0xffff
+#undef SLOW_DOWN
+
static const char digits[16] = "0123456789abcdef";
-static volatile unsigned char *const com1 = (unsigned char *) SERIAL_BASE;
+static volatile unsigned char * const com1 = (unsigned char *)SERIAL_BASE;
-void putch(const unsigned char c)
+#ifdef SLOW_DOWN
+static inline void slow_down()
{
- unsigned char ch;
- unsigned i;
-
- do {
- ch = com1[SERB_CMD];
- } while (0 == (ch & TX_BUSY));
- com1[SERB_DATA] = c;
+ int k;
+ for (k=0; k<10000; k++);
}
+#else
+#define slow_down()
+#endif
-void putchar(const unsigned char c)
+void
+putch(const unsigned char c)
{
- unsigned char ch;
- unsigned i;
-
- do {
- ch = com1[SERB_CMD];
- } while (0 == (ch & TX_BUSY));
- com1[SERB_DATA] = c;
+ unsigned char ch;
+ int i = 0;
+
+ do {
+ ch = com1[SERB_CMD];
+ slow_down();
+ i++;
+ if (i>TIMEOUT) {
+ break;
+ }
+ } while (0 == (ch & TX_BUSY));
+ com1[SERB_DATA] = c;
}
-void puts(unsigned char *cp)
+void
+putchar(const unsigned char c)
{
- unsigned char ch;
- unsigned i = 0;
-
- while (*cp) {
- do {
- ch = com1[SERB_CMD];
- } while (0 == (ch & TX_BUSY));
- com1[SERB_DATA] = *cp++;
- }
- putch('\r');
- putch('\n');
+ unsigned char ch;
+ int i = 0;
+
+ do {
+ ch = com1[SERB_CMD];
+ slow_down();
+ i++;
+ if (i>TIMEOUT) {
+ break;
+ }
+ } while (0 == (ch & TX_BUSY));
+ com1[SERB_DATA] = c;
}
-void fputs(unsigned char *cp)
+void
+puts(unsigned char *cp)
{
- unsigned char ch;
- unsigned i;
-
- while (*cp) {
+ unsigned char ch;
+ int i = 0;
+
+ while (*cp) {
+ do {
+ ch = com1[SERB_CMD];
+ slow_down();
+ i++;
+ if (i>TIMEOUT) {
+ break;
+ }
+ } while (0 == (ch & TX_BUSY));
+ com1[SERB_DATA] = *cp++;
+ }
+ putch('\r');
+ putch('\n');
+}
- do {
- ch = com1[SERB_CMD];
- } while (0 == (ch & TX_BUSY));
- com1[SERB_DATA] = *cp++;
- }
+void
+fputs(unsigned char *cp)
+{
+ unsigned char ch;
+ int i = 0;
+
+ while (*cp) {
+
+ do {
+ ch = com1[SERB_CMD];
+ slow_down();
+ i++;
+ if (i>TIMEOUT) {
+ break;
+ }
+ } while (0 == (ch & TX_BUSY));
+ com1[SERB_DATA] = *cp++;
+ }
}
-void put64(uint64_t ul)
+void
+put64(uint64_t ul)
{
- int cnt;
- unsigned ch;
-
- cnt = 16; /* 16 nibbles in a 64 bit long */
- putch('0');
- putch('x');
- do {
- cnt--;
- ch = (unsigned char) (ul >> cnt * 4) & 0x0F;
- putch(digits[ch]);
- } while (cnt > 0);
+ int cnt;
+ unsigned ch;
+
+ cnt = 16; /* 16 nibbles in a 64 bit long */
+ putch('0');
+ putch('x');
+ do {
+ cnt--;
+ ch = (unsigned char)(ul >> cnt * 4) & 0x0F;
+ putch(digits[ch]);
+ } while (cnt > 0);
}
-void put32(unsigned u)
+void
+put32(unsigned u)
{
- int cnt;
- unsigned ch;
-
- cnt = 8; /* 8 nibbles in a 32 bit long */
- putch('0');
- putch('x');
- do {
- cnt--;
- ch = (unsigned char) (u >> cnt * 4) & 0x0F;
- putch(digits[ch]);
- } while (cnt > 0);
+ int cnt;
+ unsigned ch;
+
+ cnt = 8; /* 8 nibbles in a 32 bit long */
+ putch('0');
+ putch('x');
+ do {
+ cnt--;
+ ch = (unsigned char)(u >> cnt * 4) & 0x0F;
+ putch(digits[ch]);
+ } while (cnt > 0);
}
diff --git a/arch/mips/galileo-boards/ev96100/setup.c b/arch/mips/galileo-boards/ev96100/setup.c
index bfcd479a1..5b6e3e7a4 100644
--- a/arch/mips/galileo-boards/ev96100/setup.c
+++ b/arch/mips/galileo-boards/ev96100/setup.c
@@ -5,7 +5,7 @@
*
* Copyright 2000 MontaVista Software Inc.
* Author: MontaVista Software, Inc.
- * ppopov@mvista.com or support@mvista.com
+ * ppopov@mvista.com or source@mvista.com
*
* This file was derived from Carsten Langgaard's
* arch/mips/mips-boards/atlas/atlas_setup.c.
@@ -38,129 +38,146 @@
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/mc146818rtc.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
#include <asm/cpu.h>
#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
#include <asm/irq.h>
+#include <asm/gt64120.h>
#include <asm/galileo-boards/ev96100.h>
#include <asm/galileo-boards/ev96100int.h>
-#include <asm/mipsregs.h>
+void (*__wbflush) (void);
+
#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
extern void console_setup(char *, int *);
char serial_console[20];
#endif
#ifdef CONFIG_REMOTE_DEBUG
-extern void rs_kgdb_hook(int);
-extern void saa9730_kgdb_hook(void);
extern void breakpoint(void);
-static int remote_debug = 0;
-static int kgdb_on_pci = 0;
+int ev96100_remote_debug;
+int ev96100_remote_debug_line;
#endif
-void (*board_time_init) (struct irqaction * irq);
+void (*board_time_init)(struct irqaction *irq);
extern void ev96100_time_init(struct irqaction *irq);
+extern char * __init prom_getcmdline(void);
extern void mips_reboot_setup(void);
extern struct rtc_ops no_rtc_ops;
extern struct resource ioport_resource;
-static void __init ev96100_irq_setup(void)
+void rm7000_wbflush()
{
- puts("ev96100_irq_setup");
- init_IRQ();
-
-#ifdef CONFIG_REMOTE_DEBUG
- /* If local serial I/O used for debug port, enter kgdb at once */
- /* Otherwise, this will be done after the SAA9730 is up */
- if (remote_debug && !kgdb_on_pci) {
- set_debug_traps();
- breakpoint();
- }
-#endif
+ __asm__ __volatile__ ("sync");
}
+unsigned char mac_0_1[12];
void __init ev96100_setup(void)
{
-#ifdef CONFIG_REMOTE_DEBUG
- int rs_putDebugChar(char);
- char rs_getDebugChar(void);
- int saa9730_putDebugChar(char);
- char saa9730_getDebugChar(void);
- extern int (*putDebugChar) (char);
- extern char (*getDebugChar) (void);
-#endif
- char *argptr;
-
- irq_setup = ev96100_irq_setup;
+ unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+ unsigned long status = read_32bit_cp0_register(CP0_STATUS);
+ unsigned long info = read_32bit_cp0_register(CP0_INFO);
- puts("ev96100_setup");
- puts("config reg:");
- put32(read_32bit_cp0_register(CP0_CONFIG));
- puts("");
+ char *argptr;
+ set_cp0_status(ST0_FR,0);
+ __wbflush = rm7000_wbflush;
+
+
+ if (config & 0x8) {
+ printk("Secondary cache is enabled\n");
+ }
+ else {
+ printk("Secondary cache is disabled\n");
+ }
+
+ if (status & (1<<27)) {
+ printk("User-mode cache ops enabled\n");
+ }
+ else {
+ printk("User-mode cache ops disabled\n");
+ }
+
+ printk("CP0 info reg: %x\n", (unsigned)info);
+ if (info & (1<<28)) {
+ printk("burst mode Scache RAMS\n");
+ }
+ else {
+ printk("pipelined Scache RAMS\n");
+ }
+
+ if ((info & (0x3<<26)) >> 26 == 0) {
+ printk("67 percent drive strength\n");
+ }
+ else if ((info & (0x3<<26)) >> 26 == 1) {
+ printk("50 percent drive strength\n");
+ }
+ else if ((info & (0x3<<26)) >> 26 == 2) {
+ printk("100 percent drive strength\n");
+ }
+ else if ((info & (0x3<<26)) >> 26 == 3) {
+ printk("83 percent drive strength\n");
+ }
+
+
+ if ((info & (0x3<<23)) >> 23 == 0) {
+ printk("Write Protocol: R4000 compatible\n");
+ }
+ else if ((info & (0x3<<23)) >> 23 == 1) {
+ printk("Write Protocol: Reserved\n");
+ }
+ else if ((info & (0x3<<23)) >> 23 == 2) {
+ printk("Write Protocol: Pipelined\n");
+ }
+ else if ((info & (0x3<<23)) >> 23 == 3) {
+ printk("Write Protocol: Write re-issue\n");
+ }
+
+ if (info & 0x1) {
+ printk("Atomic Enable is set\n");
+ }
-#ifdef CONFIG_SERIAL_CONSOLE
argptr = prom_getcmdline();
- if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) {
- int i = 0;
- char *s = prom_getenv("modetty0");
- while (s[i] >= '0' && s[i] <= '9')
- i++;
- strcpy(serial_console, "ttyS0,");
- strncpy(serial_console + 6, s, i);
- //prom_printf("Config serial console: %s\n", serial_console);
- puts("Config serial console: %s\n", serial_console);
- console_setup(serial_console, NULL);
+#ifdef CONFIG_SERIAL_CONSOLE
+ if (strstr(argptr, "console=") == NULL) {
+ argptr = prom_getcmdline();
+ strcat(argptr, " console=ttyS0,115200");
}
-#endif
+#endif
+
#ifdef CONFIG_REMOTE_DEBUG
- argptr = prom_getcmdline();
- if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) {
+ if (strstr(argptr, "kgdb=ttyS") != NULL) {
int line;
argptr += strlen("kgdb=ttyS");
- if (*argptr != '0' && *argptr != '1')
- printk("KGDB: Uknown serial line /dev/ttyS%c, "
- "falling back to /dev/ttyS1\n", *argptr);
- line = *argptr == '0' ? 0 : 1;
- printk("KGDB: Using serial line /dev/ttyS%d for session\n",
- line ? 1 : 0);
-
- if (line == 0) {
- rs_kgdb_hook(line);
- putDebugChar = rs_putDebugChar;
- getDebugChar = rs_getDebugChar;
- } else {
- saa9730_kgdb_hook();
- putDebugChar = saa9730_putDebugChar;
- getDebugChar = saa9730_getDebugChar;
- kgdb_on_pci = 1;
- }
-
- prom_printf
- ("KGDB: Using serial line /dev/ttyS%d for session, "
- "please connect your debugger\n", line ? 1 : 0);
-
- remote_debug = 1;
- /* Breakpoints and stuff are in ev96100_irq_setup() */
+ if (*argptr == '0')
+ ev96100_remote_debug_line = 0;
+ else if (*argptr == '1')
+ ev96100_remote_debug_line = 1;
+ else
+ puts("Unknown serial line /dev/ttyS%c\n", *argptr);
+
+ debugInitUart(ev96100_remote_debug_line);
+ ev96100_remote_debug = 1;
+ /* Breakpoints and stuff are in init_IRQ() */
}
#endif
- argptr = prom_getcmdline();
board_time_init = ev96100_time_init;
rtc_ops = &no_rtc_ops;
mips_reboot_setup();
-
- /*
- * reassign the start and end from the statically defined start and
- * end in kernel/resource.
- */
+ mips_io_port_base = KSEG1;
ioport_resource.start = GT_PCI_IO_BASE;
- //ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE;
- ioport_resource.end = 0xB1FFFFFF; /* what a hack! */
+ ioport_resource.end = GT_PCI_IO_BASE + 0x01ffffff;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+#endif
}
diff --git a/arch/mips/galileo-boards/ev96100/time.c b/arch/mips/galileo-boards/ev96100/time.c
index 80283c929..6aa4d07ae 100644
--- a/arch/mips/galileo-boards/ev96100/time.c
+++ b/arch/mips/galileo-boards/ev96100/time.c
@@ -5,7 +5,7 @@
*
* Copyright 2000 MontaVista Software Inc.
* Author: MontaVista Software, Inc.
- * ppopov@mvista.com or support@mvista.com
+ * ppopov@mvista.com or source@mvista.com
*
* This file was derived from Carsten Langgaard's
* arch/mips/mips-boards/atlas/atlas_rtc.c.
@@ -48,17 +48,14 @@
#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+extern unsigned long spurious_count;
extern volatile unsigned long wall_jiffies;
-static long last_rtc_update = 0;
unsigned long missed_heart_beats = 0;
static unsigned long r4k_offset; /* Amount to increment compare reg each time */
static unsigned long r4k_cur; /* What counter should be at next timer irq */
extern rwlock_t xtime_lock;
-
-static unsigned int timer_tick_count=0;
-
static inline void ack_r4ktimer(unsigned long newval)
{
write_32bit_cp0_register(CP0_COMPARE, newval);
@@ -72,35 +69,7 @@ static int set_rtc_mmss(unsigned long nowtime)
return retval;
}
-/*
- * There are a lot of conceptually broken versions of the MIPS timer interrupt
- * handler floating around. This one is rather different, but the algorithm
- * is probably more robust.
- */
-static unsigned long alive;
-void mips_timer_interrupt(struct pt_regs *regs)
-{
- unsigned long status;
- unsigned long ret_addr;
- int irq = 7; /* FIX ME */
-
- if (r4k_offset == 0) {
- goto null;
- }
-
- do {
- kstat.irqs[0][irq]++;
- do_timer(regs);
- r4k_cur += r4k_offset;
- ack_r4ktimer(r4k_cur);
-
- } while (((unsigned long)read_32bit_cp0_register(CP0_COUNT)
- - r4k_cur) < 0x7fffffff);
- return;
-null:
- ack_r4ktimer(0);
-}
/*
* Figure out the r4k offset, the amount to increment the compare
@@ -114,10 +83,10 @@ static unsigned long __init cal_r4koff(void)
return (count / HZ);
}
+
static unsigned long __init get_mips_time(void)
{
unsigned int year, mon, day, hour, min, sec;
- unsigned char save_control;
year = 2000;
mon = 10;
@@ -135,7 +104,7 @@ static unsigned long __init get_mips_time(void)
void __init time_init(void)
{
- unsigned int est_freq, flags;
+ unsigned int est_freq;
r4k_offset = cal_r4koff();
@@ -149,7 +118,7 @@ void __init time_init(void)
write_32bit_cp0_register(CP0_COMPARE, r4k_cur);
/* FIX ME */
- change_cp0_status(ST0_IM, IE_IRQ5);
+ set_cp0_status(ST0_IM, IE_IRQ5);
}
/* This is for machines which generate the exact clock. */
@@ -276,3 +245,30 @@ void do_settimeofday(struct timeval *tv)
write_unlock_irq (&xtime_lock);
}
+
+/*
+ * There are a lot of conceptually broken versions of the MIPS timer interrupt
+ * handler floating around. This one is rather different, but the algorithm
+ * is probably more robust.
+ */
+void mips_timer_interrupt(struct pt_regs *regs)
+{
+ int irq = 7; /* FIX ME */
+
+ if (r4k_offset == 0) {
+ goto null;
+ }
+
+ do {
+ kstat.irqs[0][irq]++;
+ do_timer(regs);
+ r4k_cur += r4k_offset;
+ ack_r4ktimer(r4k_cur);
+
+ } while (((unsigned long)read_32bit_cp0_register(CP0_COUNT)
+ - r4k_cur) < 0x7fffffff);
+ return;
+
+null:
+ ack_r4ktimer(0);
+}
diff --git a/arch/mips/galileo-boards/ev96100/uart.S b/arch/mips/galileo-boards/ev96100/uart.S
deleted file mode 100644
index 549bbb68d..000000000
--- a/arch/mips/galileo-boards/ev96100/uart.S
+++ /dev/null
@@ -1,92 +0,0 @@
-
-/*
- * Low level serial I/O routines.
- */
-#include <asm/asm.h>
-#include <linux/errno.h>
-#include <asm/current.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-#include <asm/isadep.h>
-#include <asm/unistd.h>
-
-#define SERIAL_BASE 0xbd000020
-#define SERB_DLABLO 0
-#define SERB_DLABHI 1
-#define SERB_FIFO 2
-#define SERB_DATA 0
-#define SERB_LCR 3
-#define SERB_MCR 4
-#define SERB_CMD 5
-
-#define SERA_DLABLO 0x08
-#define SERA_DLABHI 0x09
-#define SERA_DATA 0x08
-#define SERA_LCR 0x0B
-#define SERA_MCR 0x0C
-#define SERA_CMD 0x0D
-
-#define TX_BUSY 0x20
-
-/*
- * To calculate divisor for different baud rates:
- * divisor = 3686400/(baud rate x 16), where 3686400 is our
- * 3.6864MHz clock input.
- */
-
-/*
- * routine to initialize the serial DUART. Channel A only
- */
- .set noreorder
- .global init_serial
- .ent init_serial
-init_serial:
- li a0,SERIAL_BASE
-
-#if 0
- # init channel A
- li t0,0x0083
- sb t0,SERA_LCR(a0) # set DLAB
-
-# li t0,24 # 9600 baud
- li t0,2 # 115200 baud
- sb t0,SERA_DLABLO(a0) # set divisor
-
- li t0,0
- sb t0,SERA_DLABHI(a0)
-
- li t0,0x0003 # 8 data bits
- sb t0,SERA_LCR(a0)
-#endif
-
-#if 1
- # init channel B
- li t0,0x0083
- sb t0,SERB_LCR(a0) # set DLAB
-
- li t0,24
- sb t0,SERB_DLABLO(a0) # set divisor for 115200 baud
-
- li t0,0
- sb t0,SERB_DLABHI(a0)
-
- li t0,0x0003 # 8 data bits
- sb t0,SERB_LCR(a0)
-
- li t0,0 # no fifo
- sb t0,SERB_FIFO(a0)
-#endif
-
- li a0, 0xB4000000
- li t0, 0x002fffff
- sw t0, 0x464(a0)
-
-
- jr ra
- nop
-
- .size init_serial, . - init_serial;
- .end init_serial
-
- .set reorder
diff --git a/arch/mips/galileo-boards/generic/Makefile b/arch/mips/galileo-boards/generic/Makefile
index a65a76488..6dcb627c4 100644
--- a/arch/mips/galileo-boards/generic/Makefile
+++ b/arch/mips/galileo-boards/generic/Makefile
@@ -34,6 +34,6 @@
O_TARGET:= galboards.o
-obj-y := pci.o reset.o init.o cmdline.o
+obj-y := reset.o cmdline.o
include $(TOPDIR)/Rules.make
diff --git a/arch/mips/galileo-boards/generic/prom-no.c b/arch/mips/galileo-boards/generic/prom-no.c
deleted file mode 100644
index 826acad15..000000000
--- a/arch/mips/galileo-boards/generic/prom-no.c
+++ /dev/null
@@ -1,50 +0,0 @@
-
-/*
- * prom-no.c
- *
- * BRIEF MODULE DESCRIPTION
- * Stubs for prom routines.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- * frank_rowand@mvista.com or support@mvista.com
- * debbie_chu@mvista.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 <asm/galileo-boards/prom.h>
-
-static int no_printf (const char *fmt, ...)
-{
- /* nop */
-}
-
-static void no_flushcache()
-{
- /* nop */
-}
-
-struct prom_ops no_prom_ops = {
- &no_printf,
- &no_flushcache
-};