summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/config.in5
-rw-r--r--arch/mips/kernel/setup.c2
-rw-r--r--arch/mips/kernel/time.c46
-rw-r--r--arch/mips/kernel/traps.c7
-rw-r--r--arch/mips/mips-boards/atlas/atlas_int.c125
-rw-r--r--arch/mips/mips-boards/atlas/atlas_setup.c20
-rw-r--r--arch/mips/mips-boards/generic/Makefile4
-rw-r--r--arch/mips/mips-boards/generic/gdb_hook.c202
-rw-r--r--arch/mips/mips-boards/generic/init.c24
-rw-r--r--arch/mips/mips-boards/generic/printf.c115
-rw-r--r--arch/mips/mips-boards/malta/malta_int.c6
-rw-r--r--arch/mips/mips-boards/malta/malta_setup.c23
-rw-r--r--arch/mips/mm/init.c22
13 files changed, 489 insertions, 112 deletions
diff --git a/arch/mips/config.in b/arch/mips/config.in
index c2367d8c4..374cbb5de 100644
--- a/arch/mips/config.in
+++ b/arch/mips/config.in
@@ -89,12 +89,13 @@ if [ "$CONFIG_ACER_PICA_61" = "y" ]; then
fi
if [ "$CONFIG_MIPS_ATLAS" = "y" ]; then
define_bool CONFIG_PCI y
- define_bool CONFIG_ISA n
+ define_bool CONFIG_SWAP_IO_SPACE y
fi
if [ "$CONFIG_MIPS_MALTA" = "y" ]; then
define_bool CONFIG_I8259 y
define_bool CONFIG_PCI y
- define_bool CONFIG_ISA n
+ define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y
+ define_bool CONFIG_SWAP_IO_SPACE y
fi
if [ "$CONFIG_PMC_CP7000" = "y" ]; then
define_bool CONFIG_PCI y
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 31f906ef2..368300cf1 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -237,6 +237,8 @@ static inline void cpu_probe(void)
mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
MIPS_CPU_DIVEC;
mips_cpu.tlbsize = 48;
+ mips_cpu.icache.ways = 2;
+ mips_cpu.dcache.ways = 2;
break;
case PRID_IMP_R6000:
mips_cpu.cputype = CPU_R6000;
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 7b953e94f..b6e1f7a6c 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -5,6 +5,14 @@
* This file contains the time handling details for PC-style clocks as
* found in some MIPS systems.
*/
+/**************************************************************************
+ * 9 Nov, 2000.
+ * Changed init_cycle_counter() routine, use the mips_cpu structure.
+ *
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ *************************************************************************/
+
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/init.h>
@@ -449,42 +457,8 @@ char cyclecounter_available;
static inline void init_cycle_counter(void)
{
- switch(mips_cpu.cputype) {
- case CPU_UNKNOWN:
- case CPU_R2000:
- case CPU_R3000:
- case CPU_R3000A:
- case CPU_R3041:
- case CPU_R3051:
- case CPU_R3052:
- case CPU_R3081:
- case CPU_R3081E:
- case CPU_R6000:
- case CPU_R6000A:
- case CPU_R8000: /* Not shure about that one, play safe */
- cyclecounter_available = 0;
- break;
- case CPU_R4000PC:
- case CPU_R4000SC:
- case CPU_R4000MC:
- case CPU_R4200:
- case CPU_R4400PC:
- case CPU_R4400SC:
- case CPU_R4400MC:
- case CPU_R4600:
- case CPU_R10000:
- case CPU_R4300:
- case CPU_R4650:
- case CPU_R4700:
- case CPU_R5000:
- case CPU_R5432:
- case CPU_R5000A:
- case CPU_R4640:
- case CPU_NEVADA:
- case CPU_RM7000:
- cyclecounter_available = 1;
- break;
- }
+ if(mips_cpu.options & MIPS_CPU_COUNTER) cyclecounter_available = 1;
+ else cyclecounter_available = 0;
}
struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0,
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index d55619720..d3ea588f0 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -790,6 +790,7 @@ void __init trap_init(void)
extern char except_vec0_r4600, except_vec0_r2300;
extern char except_vec1_generic, except_vec2_generic;
extern char except_vec3_generic, except_vec3_r4000;
+ extern char except_vec_ejtag_debug;
unsigned long i;
if(mips_machtype == MACH_MIPS_MAGNUM_4000 ||
@@ -810,6 +811,12 @@ void __init trap_init(void)
for(i = 0; i <= 31; i++)
(void)set_except_vector(i, handle_reserved);
+ /*
+ * Copy the EJTAG debug exception vector handler code to it's final
+ * destination.
+ */
+ memcpy((void *)(KSEG0 + 0x300), &except_vec_ejtag_debug, 0x80);
+
/*
* Only some CPUs have the watch exceptions or a dedicated
* interrupt vector.
diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c
index 80d5ef652..8ff004b55 100644
--- a/arch/mips/mips-boards/atlas/atlas_int.c
+++ b/arch/mips/mips-boards/atlas/atlas_int.c
@@ -33,6 +33,7 @@
#include <asm/irq.h>
#include <asm/mips-boards/atlas.h>
#include <asm/mips-boards/atlasint.h>
+#include <asm/gdb-stub.h>
struct atlas_ictrl_regs *atlas_hw0_icregs
@@ -41,6 +42,15 @@ struct atlas_ictrl_regs *atlas_hw0_icregs
extern asmlinkage void mipsIRQ(void);
extern void do_IRQ(int irq, struct pt_regs *regs);
+unsigned long spurious_count = 0;
+irq_desc_t irq_desc[NR_IRQS];
+
+#if 0
+#define DEBUG_INT(x...) printk(x)
+#else
+#define DEBUG_INT(x...)
+#endif
+
void disable_atlas_irq(unsigned int irq_nr)
{
atlas_hw0_icregs->intrsten = (1 << irq_nr);
@@ -78,9 +88,79 @@ static struct hw_interrupt_type atlas_irq_type = {
NULL
};
+int get_irq_list(char *buf)
+{
+ int i, len = 0;
+ int num = 0;
+ struct irqaction *action;
+
+ for (i = 0; i < ATLASINT_END; i++, num++) {
+ action = irq_desc[i].action;
+ if (!action)
+ continue;
+ len += sprintf(buf+len, "%2d: %8d %c %s",
+ num, kstat.irqs[0][num],
+ (action->flags & SA_INTERRUPT) ? '+' : ' ',
+ action->name);
+ for (action=action->next; action; action = action->next) {
+ len += sprintf(buf+len, ",%s %s",
+ (action->flags & SA_INTERRUPT) ? " +" : "",
+ action->name);
+ }
+ len += sprintf(buf+len, " [hw0]\n");
+ }
+ return len;
+}
+
+int request_irq(unsigned int irq,
+ void (*handler)(int, void *, struct pt_regs *),
+ unsigned long irqflags,
+ const char * devname,
+ void *dev_id)
+{
+ struct irqaction *action;
+
+ DEBUG_INT("request_irq: irq=%d, devname = %s\n", irq, devname);
+
+ if (irq >= ATLASINT_END)
+ return -EINVAL;
+ if (!handler)
+ return -EINVAL;
+
+ action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+ if(!action)
+ return -ENOMEM;
+
+ action->handler = handler;
+ action->flags = irqflags;
+ action->mask = 0;
+ action->name = devname;
+ action->dev_id = dev_id;
+ action->next = 0;
+ irq_desc[irq].action = action;
+ enable_atlas_irq(irq);
+
+ return 0;
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+ struct irqaction *action;
+
+ if (irq >= ATLASINT_END) {
+ printk("Trying to free IRQ%d\n",irq);
+ return;
+ }
+
+ action = irq_desc[irq].action;
+ irq_desc[irq].action = NULL;
+ disable_atlas_irq(irq);
+ kfree(action);
+}
+
static inline int ls1bit32(unsigned int x)
{
- int b = 32, s;
+ int b = 31, s;
s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s;
s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s;
@@ -93,8 +173,9 @@ static inline int ls1bit32(unsigned int x)
void atlas_hw0_irqdispatch(struct pt_regs *regs)
{
+ struct irqaction *action;
unsigned long int_status;
- int irq;
+ int irq, cpu = smp_processor_id();
int_status = atlas_hw0_icregs->intstatus;
@@ -103,15 +184,45 @@ void atlas_hw0_irqdispatch(struct pt_regs *regs)
return;
irq = ls1bit32(int_status);
- do_IRQ(irq, regs);
+ action = irq_desc[irq].action;
+
+ DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq);
+
+ /* if action == NULL, then we don't have a handler for the irq */
+ if ( action == NULL ) {
+ printk("No handler for hw0 irq: %i\n", irq);
+ spurious_count++;
+ return;
+ }
+
+ irq_enter(cpu, irq);
+ kstat.irqs[0][irq]++;
+ action->handler(irq, action->dev_id, regs);
+ irq_exit(cpu, irq);
+
+ return;
+}
+
+unsigned long probe_irq_on (void)
+{
+ return 0;
}
+
+int probe_irq_off (unsigned long irqs)
+{
+ return 0;
+}
+
+#ifdef CONFIG_REMOTE_DEBUG
+extern void breakpoint(void);
+extern int remote_debug;
+#endif
+
void __init init_IRQ(void)
{
int i;
- init_generic_irq();
-
/*
* Mask out all interrupt by writing "1" to all bit position in
* the interrupt reset reg.
@@ -129,9 +240,7 @@ void __init init_IRQ(void)
}
#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) {
+ if (remote_debug) {
set_debug_traps();
breakpoint();
}
diff --git a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c
index d11a4d8ac..42546a93d 100644
--- a/arch/mips/mips-boards/atlas/atlas_setup.c
+++ b/arch/mips/mips-boards/atlas/atlas_setup.c
@@ -40,8 +40,7 @@ char serial_console[20];
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 remote_debug = 0;
#endif
extern struct rtc_ops atlas_rtc_ops;
@@ -60,7 +59,6 @@ void __init atlas_setup(void)
#endif
char *argptr;
- mips_io_port_base = KSEG1;
ioport_resource.end = 0x7fffffff;
#ifdef CONFIG_SERIAL_CONSOLE
@@ -97,7 +95,6 @@ void __init atlas_setup(void)
saa9730_kgdb_hook();
putDebugChar = saa9730_putDebugChar;
getDebugChar = saa9730_getDebugChar;
- kgdb_on_pci = 1;
}
prom_printf("KGDB: Using serial line /dev/ttyS%d for session, "
@@ -109,19 +106,10 @@ void __init atlas_setup(void)
#endif
argptr = prom_getcmdline();
+ if ((argptr = strstr(argptr, "nofpu")) != NULL)
+ mips_cpu.options &= ~MIPS_CPU_FPU;
+
rtc_ops = &atlas_rtc_ops;
mips_reboot_setup();
-
- /*
- * Setup the North bridge to do Master byte-lane swapping when
- * running in bigendian.
- * Be careful to use prom_printf after this.
- */
-#if defined(__MIPSEL__)
- GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT |
- GT_PCI0_CMD_SBYTESWAP_BIT);
-#else
- GT_WRITE(GT_PCI0_CMD_OFS, 0);
-#endif
}
diff --git a/arch/mips/mips-boards/generic/Makefile b/arch/mips/mips-boards/generic/Makefile
index c76f6fd46..8a2f0e6d8 100644
--- a/arch/mips/mips-boards/generic/Makefile
+++ b/arch/mips/mips-boards/generic/Makefile
@@ -39,4 +39,8 @@ O_TARGET := mipsboards.o
O_OBJS := mipsIRQ.o pci.o reset.o display.o init.o memory.o printf.o \
cmdline.o time.o
+ifdef CONFIG_REMOTE_DEBUG
+O_OBJS += gdb_hook.o
+endif
+
include $(TOPDIR)/Rules.make
diff --git a/arch/mips/mips-boards/generic/gdb_hook.c b/arch/mips/mips-boards/generic/gdb_hook.c
new file mode 100644
index 000000000..bb14774d9
--- /dev/null
+++ b/arch/mips/mips-boards/generic/gdb_hook.c
@@ -0,0 +1,202 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * This is the interface to the remote debugger stub.
+ *
+ */
+
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+
+#include <asm/serial.h>
+#include <asm/io.h>
+
+static struct serial_state rs_table[RS_TABLE_SIZE] = {
+ SERIAL_PORT_DFNS /* Defined in serial.h */
+};
+
+static struct async_struct kdb_port_info = {0};
+
+
+static __inline__ unsigned int serial_in(struct async_struct *info, int offset)
+{
+ return inb(info->port + offset);
+}
+
+static __inline__ void serial_out(struct async_struct *info, int offset,
+ int value)
+{
+ outb(value, info->port+offset);
+}
+
+void rs_kgdb_hook(int tty_no) {
+ int t;
+ struct serial_state *ser = &rs_table[tty_no];
+
+ kdb_port_info.state = ser;
+ kdb_port_info.magic = SERIAL_MAGIC;
+ kdb_port_info.port = ser->port;
+ kdb_port_info.flags = ser->flags;
+
+ /*
+ * Clear all interrupts
+ */
+ serial_in(&kdb_port_info, UART_LSR);
+ serial_in(&kdb_port_info, UART_RX);
+ serial_in(&kdb_port_info, UART_IIR);
+ serial_in(&kdb_port_info, UART_MSR);
+
+ /*
+ * Now, initialize the UART
+ */
+ serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */
+ if (kdb_port_info.flags & ASYNC_FOURPORT) {
+ kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS;
+ t = UART_MCR_DTR | UART_MCR_OUT1;
+ } else {
+ kdb_port_info.MCR
+ = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
+ t = UART_MCR_DTR | UART_MCR_RTS;
+ }
+
+ kdb_port_info.MCR = t; /* no interrupts, please */
+ serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR);
+
+ /*
+ * and set the speed of the serial port
+ * (currently hardwired to 9600 8N1
+ */
+
+ /* baud rate is fixed to 9600 (is this sufficient?)*/
+ t = kdb_port_info.state->baud_base / 9600;
+ /* set DLAB */
+ serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
+ serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */
+ serial_out(&kdb_port_info, UART_DLM, t >> 8); /* MS of divisor */
+ /* reset DLAB */
+ serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);
+}
+
+int rs_putDebugChar(char c)
+{
+
+ if (!kdb_port_info.state) { /* need to init device first */
+ return 0;
+ }
+
+ while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0)
+ ;
+
+ serial_out(&kdb_port_info, UART_TX, c);
+
+ return 1;
+}
+
+char rs_getDebugChar(void)
+{
+ if (!kdb_port_info.state) { /* need to init device first */
+ return 0;
+ }
+
+ while (!(serial_in(&kdb_port_info, UART_LSR) & 1))
+ ;
+
+ return(serial_in(&kdb_port_info, UART_RX));
+}
+
+
+#ifdef CONFIG_MIPS_ATLAS
+
+#include <asm/mips-boards/atlas.h>
+#include <asm/mips-boards/saa9730_uart.h>
+
+#define INB(a) inb((unsigned long)a)
+#define OUTB(x,a) outb(x,(unsigned long)a)
+
+/*
+ * This is the interface to the remote debugger stub
+ * if the Philips part is used for the debug port,
+ * called from the platform setup code.
+ *
+ * PCI init will not have been done yet, we make a
+ * universal assumption about the way the bootloader (YAMON)
+ * have located and set up the chip.
+ */
+static t_uart_saa9730_regmap *kgdb_uart = (void *)(ATLAS_SAA9730_REG + SAA9730_UART_REGS_ADDR);
+
+static int saa9730_kgdb_active = 0;
+
+void saa9730_kgdb_hook(void)
+{
+ volatile unsigned char t;
+
+ /*
+ * Clear all interrupts
+ */
+ t = INB(&kgdb_uart->Lsr);
+ t += INB(&kgdb_uart->Msr);
+ t += INB(&kgdb_uart->Thr_Rbr);
+ t += INB(&kgdb_uart->Iir_Fcr);
+
+ /*
+ * Now, initialize the UART
+ */
+ /* 8 data bits, one stop bit, no parity */
+ OUTB(SAA9730_LCR_DATA8, &kgdb_uart->Lcr);
+
+ /* baud rate is fixed to 9600 (is this sufficient?)*/
+ OUTB(0, &kgdb_uart->BaudDivMsb); /* HACK - Assumes standard crystal */
+ OUTB(23, &kgdb_uart->BaudDivLsb); /* HACK - known for MIPS Atlas */
+
+ /* Set RTS/DTR active */
+ OUTB(SAA9730_MCR_DTR | SAA9730_MCR_RTS, &kgdb_uart->Mcr);
+ saa9730_kgdb_active = 1;
+}
+
+int saa9730_putDebugChar(char c)
+{
+
+ if (!saa9730_kgdb_active) { /* need to init device first */
+ return 0;
+ }
+
+ while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_THRE))
+ ;
+ OUTB(c, &kgdb_uart->Thr_Rbr);
+
+ return 1;
+}
+
+char saa9730_getDebugChar(void)
+{
+ char c;
+
+ if (!saa9730_kgdb_active) { /* need to init device first */
+ return 0;
+ }
+ while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_DR))
+ ;
+
+ c = INB(&kgdb_uart->Thr_Rbr);
+ return(c);
+}
+
+#endif
diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c
index 9f8b4dd27..70b6767b3 100644
--- a/arch/mips/mips-boards/generic/init.c
+++ b/arch/mips/mips-boards/generic/init.c
@@ -22,7 +22,11 @@
#include <linux/string.h>
#include <linux/kernel.h>
+#include <asm/io.h>
#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/gt64120.h>
+#include <asm/mips-boards/malta.h>
/* Environment variable */
typedef struct
@@ -110,11 +114,25 @@ int __init prom_init(int argc, char **argv, char **envp)
mips_display_message("LINUX");
- setup_prom_printf();
+ /*
+ * Setup the North bridge to do Master byte-lane swapping when
+ * running in bigendian.
+ */
+#if defined(__MIPSEL__)
+ GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT |
+ GT_PCI0_CMD_SBYTESWAP_BIT);
+#else
+ GT_WRITE(GT_PCI0_CMD_OFS, 0);
+#endif
+
+#if defined(CONFIG_MIPS_MALTA)
+ mips_io_port_base = MALTA_PORT_BASE;
+#else
+ mips_io_port_base = KSEG1;
+#endif
+ setup_prom_printf(0);
prom_printf("\nLINUX started...\n");
-
prom_init_cmdline();
-
prom_meminit();
return 0;
diff --git a/arch/mips/mips-boards/generic/printf.c b/arch/mips/mips-boards/generic/printf.c
index 3c21ae8bf..4f3f6e845 100644
--- a/arch/mips/mips-boards/generic/printf.c
+++ b/arch/mips/mips-boards/generic/printf.c
@@ -25,31 +25,116 @@
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
-#include <asm/addrspace.h>
-#include <asm/mips-boards/generic.h>
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/serial.h>
-static char ppbuf[1024];
-void (*prom_print_str)(unsigned int out, char *s, int len);
+#ifdef CONFIG_MIPS_ATLAS
+/*
+ * Atlas registers are memory mapped on 64-bit aligned boundaries and
+ * only word access are allowed.
+ * When reading the UART 8 bit registers only the LSB are valid.
+ */
+unsigned int atlas_serial_in(struct async_struct *info, int offset)
+{
+ return (*(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) & 0xff);
+}
+
+void atlas_serial_out(struct async_struct *info, int offset, int value)
+{
+ *(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) = value;
+}
+
+#define serial_in atlas_serial_in
+#define serial_out atlas_serial_out
+
+#else
+static unsigned int serial_in(struct async_struct *info, int offset)
+{
+ return inb(info->port + offset);
+}
-void __init setup_prom_printf(void)
+static void serial_out(struct async_struct *info, int offset,
+ int value)
{
- prom_print_str = (void *)*(unsigned int *)YAMON_PROM_PRINT_ADDR;
+ outb(value, info->port + offset);
}
+#endif
+
+static struct serial_state rs_table[] = {
+ SERIAL_PORT_DFNS /* Defined in serial.h */
+};
+
+/*
+ * Hooks to fake "prom" console I/O before devices
+ * are fully initialized.
+ */
+static struct async_struct prom_port_info = {0};
+
+void __init setup_prom_printf(int tty_no) {
+ struct serial_state *ser = &rs_table[tty_no];
+
+ prom_port_info.state = ser;
+ prom_port_info.magic = SERIAL_MAGIC;
+ prom_port_info.port = ser->port;
+ prom_port_info.flags = ser->flags;
+
+ /* No setup of UART - assume YAMON left in sane state */
+}
+
+int putPromChar(char c)
+{
+ if (!prom_port_info.state) { /* need to init device first */
+ return 0;
+ }
+
+ while ((serial_in(&prom_port_info, UART_LSR) & UART_LSR_THRE) == 0)
+ ;
+
+ serial_out(&prom_port_info, UART_TX, c);
+
+ return 1;
+}
+
+char getPromChar(void)
+{
+ if (!prom_port_info.state) { /* need to init device first */
+ return 0;
+ }
+
+ while (!(serial_in(&prom_port_info, UART_LSR) & 1))
+ ;
+
+ return(serial_in(&prom_port_info, UART_RX));
+}
+
+static char buf[1024];
void __init prom_printf(char *fmt, ...)
{
- va_list args;
- int len;
+ va_list args;
+ int l;
+ char *p, *buf_end;
+ long flags;
+
+ int putPromChar(char);
- va_start(args, fmt);
- vsprintf(ppbuf, fmt, args);
- len = strlen(ppbuf);
+ /* Low level, brute force, not SMP safe... */
+ save_and_cli(flags);
+ va_start(args, fmt);
+ l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */
+ va_end(args);
- prom_print_str(0, ppbuf, len);
+ buf_end = buf + l;
- va_end(args);
- return;
-
+ for (p = buf; p < buf_end; p++) {
+ /* Crude cr/nl handling is better than none */
+ if(*p == '\n')putPromChar('\r');
+ putPromChar(*p);
+ }
+ restore_flags(flags);
}
diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c
index 8f90e6413..085fefcdb 100644
--- a/arch/mips/mips-boards/malta/malta_int.c
+++ b/arch/mips/mips-boards/malta/malta_int.c
@@ -154,7 +154,7 @@ int get_irq_list(char *buf)
}
-static int setup_irq(int irq, struct irqaction * new)
+static int setup_irq(unsigned int irq, struct irqaction * new)
{
int shared = 0;
struct irqaction *old, **p;
@@ -316,7 +316,7 @@ void malta_hw0_irqdispatch(struct pt_regs *regs)
if ( action == NULL )
return;
- irq_enter(cpu);
+ irq_enter(cpu, irq);
kstat.irqs[0][irq + 8]++;
do {
action->handler(irq, action->dev_id, regs);
@@ -324,7 +324,7 @@ void malta_hw0_irqdispatch(struct pt_regs *regs)
} while (action);
enable_irq(irq);
- irq_exit(cpu);
+ irq_exit(cpu, irq);
}
diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c
index f653ceb9e..944c35e51 100644
--- a/arch/mips/mips-boards/malta/malta_setup.c
+++ b/arch/mips/mips-boards/malta/malta_setup.c
@@ -39,9 +39,6 @@
#include <asm/mips-boards/prom.h>
#include <asm/mips-boards/malta.h>
#include <asm/mips-boards/maltaint.h>
-#ifdef CONFIG_BLK_DEV_IDE
-#include <asm/ide.h>
-#endif
#ifdef CONFIG_BLK_DEV_FD
#include <asm/floppy.h>
#endif
@@ -57,7 +54,6 @@ extern void set_debug_traps(void);
extern void rs_kgdb_hook(int);
extern void breakpoint(void);
static int remote_debug = 0;
-static int kgdb_on_pci = 0;
#endif
#ifdef CONFIG_BLK_DEV_IDE
@@ -86,7 +82,7 @@ static void __init malta_irq_setup(void)
maltaint_init();
#ifdef CONFIG_REMOTE_DEBUG
- if (remote_debug && !kgdb_on_pci) {
+ if (remote_debug) {
set_debug_traps();
breakpoint();
}
@@ -106,7 +102,6 @@ void __init malta_setup(void)
int i;
irq_setup = malta_irq_setup;
- mips_io_port_base = MALTA_PORT_BASE;
/* Request I/O space for devices used on the Malta board. */
for (i = 0; i < STANDARD_IO_RESOURCES; i++)
@@ -155,6 +150,10 @@ void __init malta_setup(void)
/* Breakpoints and stuff are in malta_irq_setup() */
}
#endif
+
+ argptr = prom_getcmdline();
+ if ((argptr = strstr(argptr, "nofpu")) != NULL)
+ mips_cpu.options &= ~MIPS_CPU_FPU;
rtc_ops = &malta_rtc_ops;
#ifdef CONFIG_BLK_DEV_IDE
@@ -164,16 +163,4 @@ void __init malta_setup(void)
fd_ops = &std_fd_ops;
#endif
mips_reboot_setup();
-
- /*
- * Setup the North bridge to do Master byte-lane swapping when
- * running in bigendian.
- * Be careful to use prom_printf after this.
- */
-#if defined(__MIPSEL__)
- GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT |
- GT_PCI0_CMD_SBYTESWAP_BIT);
-#else
- GT_WRITE(GT_PCI0_CMD_OFS, 0);
-#endif
}
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 7035b1574..cf0775cce 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -6,6 +6,14 @@
* Copyright (C) 1994 - 2000 by Ralf Baechle
* Copyright (C) 2000 Silicon Graphics, Inc.
*/
+/**************************************************************************
+ * 9 Nov, 2000.
+ * Use mips_cpu structure.
+ *
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ *************************************************************************/
+
#include <linux/config.h>
#include <linux/init.h>
#include <linux/signal.h>
@@ -121,17 +129,9 @@ static inline unsigned long setup_zero_pages(void)
{
unsigned long order, size;
struct page *page;
-
- switch (mips_cpu.cputype) {
- case CPU_R4000SC:
- case CPU_R4000MC:
- case CPU_R4400SC:
- case CPU_R4400MC:
- order = 3;
- break;
- default:
- order = 0;
- }
+
+ if(mips_cpu.options & MIPS_CPU_VCE) order = 3;
+ else order = 0;
empty_zero_page = __get_free_pages(GFP_KERNEL, order);
if (!empty_zero_page)