diff options
-rw-r--r-- | arch/mips/galileo-boards/ev96100/Makefile | 2 | ||||
-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.S | 10 | ||||
-rw-r--r-- | arch/mips/galileo-boards/ev96100/irq.c | 379 | ||||
-rw-r--r-- | arch/mips/galileo-boards/ev96100/memory.c | 23 | ||||
-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.c | 42 | ||||
-rw-r--r-- | arch/mips/galileo-boards/ev96100/puts.c | 168 | ||||
-rw-r--r-- | arch/mips/galileo-boards/ev96100/setup.c | 177 | ||||
-rw-r--r-- | arch/mips/galileo-boards/ev96100/time.c | 68 | ||||
-rw-r--r-- | arch/mips/galileo-boards/ev96100/uart.S | 92 | ||||
-rw-r--r-- | arch/mips/galileo-boards/generic/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/galileo-boards/generic/prom-no.c | 50 |
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 -}; |