summaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-07-10 23:47:44 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-07-10 23:47:44 +0000
commitce7a3f3db827012e90ceae068572d813643e3d32 (patch)
tree0ae05de73cea41d13e2f5c537dad97ae7e34fc33 /arch/mips
parentc7c4310f7fc1485925d800628bf50b3aeab535ef (diff)
Support for the Galileo Orion board. From Cort.
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/Makefile16
-rw-r--r--arch/mips/config.in1
-rw-r--r--arch/mips/defconfig-orion175
-rw-r--r--arch/mips/kernel/Makefile4
-rw-r--r--arch/mips/kernel/setup.c17
-rw-r--r--arch/mips/orion/.cvsignore2
-rw-r--r--arch/mips/orion/Makefile48
-rw-r--r--arch/mips/orion/int-handler.S53
-rw-r--r--arch/mips/orion/irq.c284
-rw-r--r--arch/mips/orion/ld.script.orion113
-rw-r--r--arch/mips/orion/misc.c102
-rw-r--r--arch/mips/orion/no_initrd.c2
-rw-r--r--arch/mips/orion/piggyback.c59
-rw-r--r--arch/mips/orion/promcon.c172
-rw-r--r--arch/mips/orion/setup.c127
15 files changed, 1168 insertions, 7 deletions
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index c433f10d7..1ea5c62e9 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -143,6 +143,15 @@ LOADADDR += 0x80080000
endif
#
+# Orion Board
+#
+ifdef CONFIG_ORION
+LIBS += arch/mips/orion/orionkern.a
+SUBDIRS += arch/mips/orion
+LINKSCRIPT = arch/mips/orion/ld.script.orion
+endif
+
+#
# Choosing incompatible machines durings configuration will result in
# error messages during linking. Select a default linkscript if
# none has been choosen above.
@@ -181,6 +190,13 @@ balo: vmlinux
endif
+ifdef CONFIG_ORION
+ORIONBOOT = $(MAKE) -C arch/$(ARCH)/orion
+
+orionboot:
+ $(ORIONBOOT) orionboot
+endif
+
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
zImage: vmlinux
diff --git a/arch/mips/config.in b/arch/mips/config.in
index 4cf16f8d1..07ab5da42 100644
--- a/arch/mips/config.in
+++ b/arch/mips/config.in
@@ -21,6 +21,7 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
fi
bool 'Support for DECstations (EXPERIMENTAL)' CONFIG_DECSTATION
bool 'Support for NEC DDB Vrc-5074 (EXPERIMENTAL)' CONFIG_DDB5074
+ bool 'Support for Galileo Evaluation board or CoSine Orion' CONFIG_ORION
fi
bool 'Support for Mips Magnum 4000' CONFIG_MIPS_MAGNUM_4000
bool 'Support for Olivetti M700-10' CONFIG_OLIVETTI_M700
diff --git a/arch/mips/defconfig-orion b/arch/mips/defconfig-orion
new file mode 100644
index 000000000..c0d2f0144
--- /dev/null
+++ b/arch/mips/defconfig-orion
@@ -0,0 +1,175 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_DDB5074 is not set
+CONFIG_ORION=y
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_SBUS is not set
+# CONFIG_ISA is not set
+# CONFIG_PCI is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+CONFIG_CPU_R5000=y
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_WB is not set
+
+#
+# General setup
+#
+# CONFIG_RTLINUX is not set
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_KCORE_ELF=y
+CONFIG_ELF_KERNEL=y
+# CONFIG_BINFMT_IRIX is not set
+# CONFIG_FORWARD_KEYBOARD is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+# CONFIG_MODULES is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+# CONFIG_UNIX is not set
+# CONFIG_INET is not set
+# CONFIG_ATM is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET_AUNUDP is not set
+# CONFIG_ECONET_NATIVE is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+# CONFIG_NETDEVICES is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_NCPFS_NLS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_MAGIC_SYSRQ is not set
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index e213c0d38..d140184a6 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -39,7 +39,9 @@ ifndef CONFIG_DECSTATION
ifndef CONFIG_BAGET_MIPS
O_OBJS += time.o
ifndef CONFIG_SGI_IP22
- OX_OBJS += irq.o
+ ifndef CONFIG_ORION
+ OX_OBJS += irq.o
+ endif
endif
endif
endif
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 809d13a85..99f254b69 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -1,5 +1,4 @@
-/* $Id: setup.c,v 1.28 2000/03/13 22:21:44 harald Exp $
- *
+/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
@@ -25,6 +24,7 @@
#include <linux/utsname.h>
#include <linux/a.out.h>
#include <linux/tty.h>
+#include <linux/bootmem.h>
#ifdef CONFIG_BLK_DEV_RAM
#include <linux/blk.h>
#endif
@@ -201,6 +201,9 @@ static inline void cpu_probe(void)
case PRID_IMP_R10000:
mips_cputype = CPU_R10000;
break;
+ case PRID_IMP_RM7000:
+ mips_cputype = CPU_R5000;
+ break;
default:
mips_cputype = CPU_UNKNOWN;
}
@@ -250,10 +253,6 @@ static void __init default_irq_setup(void)
void __init setup_arch(char **cmdline_p)
{
-#ifdef CONFIG_BLK_DEV_INITRD
- unsigned long tmp;
- unsigned long *initrd_header;
-#endif
void baget_setup(void);
void cobalt_setup(void);
void decstation_setup(void);
@@ -262,6 +261,7 @@ void __init setup_arch(char **cmdline_p)
void sni_rm200_pci_setup(void);
void sgi_setup(void);
void ddb_setup(void);
+ void orion_setup(void);
/* Save defaults for configuration-dependent routines. */
irq_setup = default_irq_setup;
@@ -318,6 +318,11 @@ void __init setup_arch(char **cmdline_p)
ddb_setup();
break;
#endif
+#ifdef CONFIG_ORION
+ case MACH_GROUP_ORION:
+ orion_setup();
+ break;
+#endif
default:
panic("Unsupported architecture");
}
diff --git a/arch/mips/orion/.cvsignore b/arch/mips/orion/.cvsignore
new file mode 100644
index 000000000..857dd22e9
--- /dev/null
+++ b/arch/mips/orion/.cvsignore
@@ -0,0 +1,2 @@
+.depend
+.*.flags
diff --git a/arch/mips/orion/Makefile b/arch/mips/orion/Makefile
new file mode 100644
index 000000000..a42da1b0d
--- /dev/null
+++ b/arch/mips/orion/Makefile
@@ -0,0 +1,48 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+#
+# Produce a bootimage for the IPSX
+# Copyright (C) 2000 Cort Dougan <cort@fsmlabs.com>
+#
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+OBJS = promcon.o char.o serial.8530.o orion.hw.init.o setup.o irq.o int-handler.o
+
+all: orionkern.a
+
+orionkern.a: $(OBJS) initrd.o #no_initrd.o
+ $(AR) rcs orionkern.a $(OBJS) initrd.o #no_initrd.o
+ sync
+
+initrd.c: piggyback ramdisk.image.gz
+ ./piggyback initrd < ramdisk.image.gz > initrd.c
+
+piggyback: piggyback.c
+ $(HOSTCC) $(HOSTCFLAGS) -o piggyback piggyback.c
+
+orionboot: orion.ctl
+
+patchapp: patchapp.c
+ $(HOSTCC) -o $@ $^
+
+orion.ctl: patchapp ../../../vmlinux
+ $(OBJCOPY) -Obinary ../../../vmlinux orion.nosym
+ ./patchapp orion.nosym orion
+ cp -f orion.bin orion.ctl
+
+# Don't build dependencies, this may die if $(CC) isn't gcc
+dep:
+
+clean:
+ rm -f patchapp orion.bin orion.nosym orion.ctl initrd.c
+
+dummy:
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips/orion/int-handler.S b/arch/mips/orion/int-handler.S
new file mode 100644
index 000000000..e5023b961
--- /dev/null
+++ b/arch/mips/orion/int-handler.S
@@ -0,0 +1,53 @@
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+ .text
+ .set mips1
+ .set reorder
+ .set macro
+ .set noat
+ .align 5
+
+NESTED(orionIRQ, PT_SIZE, sp)
+ SAVE_ALL
+ CLI # Important: mark KERNEL mode !
+ /*
+ * Get pending interrupts
+ */
+ mfc0 t0,CP0_CAUSE # get pending interrupts
+ mfc0 t1,CP0_STATUS # get enabled interrupts
+ and t0,t1 # isolate allowed ones
+ andi t0,0xff00 # isolate pending bits
+ sll t0,16 # shift the pending bits down
+ beqz t0,3f # no pending intrs, then spurious
+ nop # delay slot
+
+ /*
+ * Find irq with highest priority
+ * FIXME: This is slow - use binary search
+ */
+ la a0,7
+1: bltz t0,2f # found pending irq
+ subu a0,1
+ sll t0,1
+ b 1b
+ nop # delay slot
+
+call_do_IRQ:
+2: move a1,sp
+ jal do_IRQ
+ nop # delay slot
+
+ mfc0 t0,CP0_STATUS # disable interrupts
+ ori t0,1
+ xori t0,1
+ mtc0 t0,CP0_STATUS
+
+ la a1, ret_from_irq
+ jr a1
+
+3: j spurious_interrupt
+END(orionIRQ)
+
diff --git a/arch/mips/orion/irq.c b/arch/mips/orion/irq.c
new file mode 100644
index 000000000..f61690b85
--- /dev/null
+++ b/arch/mips/orion/irq.c
@@ -0,0 +1,284 @@
+/*
+ * Code to handle irqs on Orion boards
+ * -- Cort <cort@fsmlabs.com>
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/malloc.h>
+#include <linux/random.h>
+
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/orion.h>
+
+void (*board_time_init)(struct irqaction *irq);
+extern asmlinkage void orionIRQ(void);
+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];
+
+static void galileo_ack(unsigned int irq_nr)
+{
+ *((unsigned long *) (((unsigned)( 0x14000000 )|0xA0000000) + 0xC18) ) = (((( 0 )&0xff)<<24)+ ((( 0 )&0xff00)<<8)+ ((( 0 )&0xff0000)>>8)+ ((( 0 )&0xff000000)>>24)) ;
+}
+
+struct hw_interrupt_type galileo_pic = {
+ " Galileo ",
+ NULL,
+ NULL,
+ NULL, /* unmask_irq */
+ NULL, /* mask_irq */
+ galileo_ack, /* mask_and_ack */
+ 0
+};
+
+/* 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);
+}
+
+static inline void mask_irq(unsigned int irq_nr)
+{
+ modify_cp0_intmask(irq_nr, 0);
+}
+
+static inline void unmask_irq(unsigned int irq_nr)
+{
+ modify_cp0_intmask(0, irq_nr);
+}
+
+void disable_irq(unsigned int irq_nr)
+{
+ unsigned long flags;
+
+ save_and_cli(flags);
+ mask_irq(irq_nr);
+ restore_flags(flags);
+}
+
+void enable_irq(unsigned int irq_nr)
+{
+ unsigned long flags;
+
+ save_and_cli(flags);
+ unmask_irq(irq_nr);
+ restore_flags(flags);
+}
+
+/*static struct irqaction *irq_action[NR_IRQS] = {
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+*/
+void __init orion_time_init(struct irqaction *irq)
+{
+ __u32 timer_count;
+
+ irq_desc[2].handler = &galileo_pic;
+ irq_desc[2].action = irq;
+
+ /* This code was provided by the CoSine guys and despite its
+ * appearance init's the timer.
+ * -- Cort
+ */
+ *((__u32 *) (((unsigned)( 0x14000000 )|0xA0000000) + 0x864) ) = (((( 0 )&0xff)<<24)+ ((( 0 )&0xff00)<<8)+ ((( 0 )&0xff0000)>>8)+ ((( 0 )&0xff000000)>>24)) ;
+
+ *((__u32 *) (((unsigned)( 0x14000000 )|0xA0000000) + 0x850) ) = (((( 0 )&0xff)<<24)+ ((( 0 )&0xff00)<<8)+ ((( 0 )&0xff0000)>>8)+ ((( 0 )&0xff000000)>>24)) ;
+
+ timer_count = 300000000/100;
+
+ *((__u32 *) (((unsigned)( 0x14000000 )|0xA0000000) + 0x850) ) = (((( timer_count )&0xff)<<24)+ ((( timer_count )&0xff00)<<8)+ ((( timer_count )&0xff0000)>>8)+ ((( timer_count )&0xff000000)>>24)) ;
+
+ *((__u32 *) (((unsigned)( 0x14000000 )|0xA0000000) + 0xC1C) ) = (((( 0x100 )&0xff)<<24)+ ((( 0x100 )&0xff00)<<8)+ ((( 0x100 )&0xff0000)>>8)+ ((( 0x100 )&0xff000000)>>24)) ;
+
+ *((__u32 *) (((unsigned)( 0x14000000 )|0xA0000000) + 0x864) ) = (((( 0x03 )&0xff)<<24)+ ((( 0x03 )&0xff00)<<8)+ ((( 0x03 )&0xff0000)>>8)+ ((( 0x03 )&0xff000000)>>24)) ;
+
+ *((__u32 *) (((unsigned)( 0x14000000 )|0xA0000000) + 0xC18) ) = (((( 0 )&0xff)<<24)+ ((( 0 )&0xff00)<<8)+ ((( 0 )&0xff0000)>>8)+ ((( 0 )&0xff000000)>>24)) ;
+}
+
+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;
+}
+
+asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
+{
+ struct irqaction *action;
+ int do_random, cpu;
+ int status;
+
+ cpu = smp_processor_id();
+ irq_enter(cpu);
+ kstat.irqs[cpu][irq]++;
+ status = 0;
+
+ if (irq_desc[irq].handler->ack)
+ irq_desc[irq].handler->ack(irq);
+
+ action = irq_desc[irq].action;
+ if (action && action->handler)
+ {
+ if (!(action->flags & SA_INTERRUPT))
+ __sti();
+ do {
+ status |= action->flags;
+ action->handler(irq, action->dev_id, regs);
+ action = action->next;
+ } while ( action );
+ __cli();
+ if (irq_desc[irq].handler)
+ {
+ 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);
+ }
+ }
+
+ irq_exit(cpu);
+
+ if (softirq_state[cpu].active&softirq_state[cpu].mask)
+ do_softirq();
+
+ /* unmasking and bottom half handling is done magically for us. */
+}
+
+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;
+
+ 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;
+
+ save_flags(flags);
+ cli();
+
+ action->handler = handler;
+ action->flags = irqflags;
+ action->mask = 0;
+ action->name = devname;
+ action->dev_id = dev_id;
+ action->next = NULL;
+ enable_irq(irq);
+
+ 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;
+
+ restore_flags(flags);
+ return 0;
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+ request_irq(irq, NULL, 0, NULL, dev_id);
+}
+
+
+unsigned long probe_irq_on (void)
+{
+ return 0;
+}
+
+int probe_irq_off (unsigned long irqs)
+{
+ return 0;
+}
+
+int (*irq_cannonicalize)(int irq);
+
+int orion_irq_cannonicalize(int i)
+{
+ return i;
+}
+
+void __init init_IRQ(void)
+{
+
+ irq_cannonicalize = orion_irq_cannonicalize;
+ set_except_vector(0, orionIRQ);
+}
+
+EXPORT_SYMBOL(irq_cannonicalize);
+
diff --git a/arch/mips/orion/ld.script.orion b/arch/mips/orion/ld.script.orion
new file mode 100644
index 000000000..1c9faa3f3
--- /dev/null
+++ b/arch/mips/orion/ld.script.orion
@@ -0,0 +1,113 @@
+OUTPUT_FORMAT("elf32-bigmips")
+OUTPUT_ARCH(mips)
+ENTRY(kernel_entry)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0x80100000;
+ /* app_header is needed for the Orion bootloader -- Cort */
+ .app_header : { *(.app_header) }
+ .init : { *(.init) } =0
+ .text :
+ {
+ _ftext = . ;
+ *(.text)
+ *(.rodata)
+ *(.rodata1)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ } =0
+ _etext = .;
+ PROVIDE (etext = .);
+
+ . = ALIGN(8192);
+ .data.init_task : { *(.data.init_task) }
+
+ /* Startup code */
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(16);
+ __setup_start = .;
+ .setup.init : { *(.setup.init) }
+ __setup_end = .;
+ __initcall_start = .;
+ .initcall.init : { *(.initcall.init) }
+ __initcall_end = .;
+ . = ALIGN(4096); /* Align double page for init_task_union */
+ __init_end = .;
+
+ . = ALIGN(4096);
+ .data.page_aligned : { *(.data.idt) }
+
+ . = ALIGN(32);
+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+ .fini : { *(.fini) } =0
+ .reginfo : { *(.reginfo) }
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. It would
+ be more correct to do this:
+ . = .;
+ The current expression does not correctly handle the case of a
+ text segment ending precisely at the end of a page; it causes the
+ data segment to skip a page. The above expression does not have
+ this problem, but it will currently (2/95) cause BFD to allocate
+ a single segment, combining both text and data, for this case.
+ This will prevent the text segment from being shared among
+ multiple executions of the program; I think that is more
+ important than losing a page of the virtual address space (note
+ that no actual memory is lost; the page which is skipped can not
+ be referenced). */
+ . = .;
+ .data :
+ {
+ _fdata = . ;
+ *(.data)
+ CONSTRUCTORS
+ }
+ .data1 : { *(.data1) }
+ _gp = . + 0x8000;
+ .lit8 : { *(.lit8) }
+ .lit4 : { *(.lit4) }
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+ .got : { *(.got.plt) *(.got) }
+ .dynamic : { *(.dynamic) }
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata : { *(.sdata) }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ __bss_start = .;
+ _fbss = .;
+ .sbss : { *(.sbss) *(.scommon) }
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ _end = . ;
+ PROVIDE (end = .);
+ }
+ /* These are needed for ELF backends which have not yet been
+ converted to the new style linker. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ /* DWARF debug sections.
+ Symbols in the .debug DWARF section are relative to the beginning of the
+ section so we begin .debug at 0. It's not clear yet what needs to happen
+ for the others. */
+ .debug 0 : { *(.debug) }
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ .line 0 : { *(.line) }
+ /* These must appear regardless of . */
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+}
diff --git a/arch/mips/orion/misc.c b/arch/mips/orion/misc.c
new file mode 100644
index 000000000..1c6d9e2fa
--- /dev/null
+++ b/arch/mips/orion/misc.c
@@ -0,0 +1,102 @@
+/*
+ * Catch-all for Orion-specify code that doesn't fit easily elsewhere.
+ * -- Cort
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/hdreg.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/malloc.h>
+#include <linux/user.h>
+#include <linux/utsname.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#ifdef CONFIG_BLK_DEV_RAM
+#include <linux/blk.h>
+#endif
+#include <linux/ide.h>
+#ifdef CONFIG_RTC
+#include <linux/timex.h>
+#endif
+
+#include <asm/asm.h>
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/io.h>
+#include <asm/stackframe.h>
+#include <asm/system.h>
+#include <asm/cpu.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/mc146818rtc.h>
+
+char arcs_cmdline[CL_SIZE] = {0, };
+extern int _end;
+
+static unsigned char orion_rtc_read_data(unsigned long addr)
+{
+ return 0;
+}
+
+static void orion_rtc_write_data(unsigned char data, unsigned long addr)
+{
+}
+
+static int orion_rtc_bcd_mode(void)
+{
+ return 0;
+}
+
+struct rtc_ops orion_rtc_ops = {
+ &orion_rtc_read_data,
+ &orion_rtc_write_data,
+ &orion_rtc_bcd_mode
+};
+
+extern void InitCIB(void);
+extern void InitQpic(void);
+extern void InitCupid(void);
+
+void __init orion_setup(void)
+{
+ InitCIB();
+ InitQpic();
+ InitCupid();
+}
+
+#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
+
+
+
+int orion_sysinit(void)
+{
+ unsigned long mem_size, free_start, free_end, start_pfn, bootmap_size;
+
+ mips_machgroup = MACH_GROUP_ORION;
+ /* 64 MB non-upgradable */
+ mem_size = 32 << 20;
+
+ free_start = PHYSADDR(PFN_ALIGN(&_end));
+ free_end = mem_size;
+ start_pfn = PFN_UP((unsigned long)&_end);
+
+ /* Register all the contiguous memory with the bootmem allocator
+ and free it. Be careful about the bootmem freemap. */
+ bootmap_size = init_bootmem(start_pfn, mem_size >> PAGE_SHIFT);
+
+ /* Free the entire available memory after the _end symbol. */
+ free_start += bootmap_size;
+ free_bootmem(free_start, free_end-free_start);
+}
diff --git a/arch/mips/orion/no_initrd.c b/arch/mips/orion/no_initrd.c
new file mode 100644
index 000000000..fcf446a0f
--- /dev/null
+++ b/arch/mips/orion/no_initrd.c
@@ -0,0 +1,2 @@
+unsigned long *orion_initrd_start = 0;
+unsigned long orion_initrd_size = 0;
diff --git a/arch/mips/orion/piggyback.c b/arch/mips/orion/piggyback.c
new file mode 100644
index 000000000..1b03f684b
--- /dev/null
+++ b/arch/mips/orion/piggyback.c
@@ -0,0 +1,59 @@
+#include <stdio.h>
+#include <unistd.h>
+
+extern long ce_exec_config[];
+
+int main(int argc, char *argv[])
+{
+ int i, cnt, pos, len;
+ unsigned int cksum, val;
+ unsigned char *lp;
+ unsigned char buf[8192];
+ if (argc != 2)
+ {
+ fprintf(stderr, "usage: %s name <in-file >out-file\n",
+ argv[0]);
+ exit(1);
+ }
+ fprintf(stdout, "/*\n");
+ fprintf(stdout, "* Miscellaneous data structures:\n");
+ fprintf(stdout, "* WARNING - this file is automatically generated!\n");
+ fprintf(stdout, "*/\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "unsigned long orion_%s_start[] = {\n", argv[1]);
+ pos = 0;
+ cksum = 0;
+ while ((len = read(0, buf, sizeof(buf))) > 0)
+ {
+ cnt = 0;
+ lp = (unsigned char *)buf;
+ len = (len + 3) & ~3; /* Round up to longwords */
+ for (i = 0; i < len; i += 4)
+ {
+ if (cnt == 0)
+ {
+ fprintf(stdout, "\t");
+ }
+ fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
+ val = *(unsigned long *)lp;
+ cksum ^= val;
+ lp += 4;
+ if (++cnt == 4)
+ {
+ cnt = 0;
+ fprintf(stdout, ", /* %x */\n", pos+i-12);
+ fflush(stdout);
+ } else
+ {
+ fprintf(stdout, ",");
+ }
+ }
+ pos += len;
+ }
+ fprintf(stdout, "0 };\n");
+ fprintf(stdout, "unsigned long orion_%s_size = 0x%x;\n", argv[1], pos);
+ fflush(stdout);
+ fclose(stdout);
+ fprintf(stderr, "cksum = %x\n", cksum);
+ exit(0);
+}
diff --git a/arch/mips/orion/promcon.c b/arch/mips/orion/promcon.c
new file mode 100644
index 000000000..29b702f7f
--- /dev/null
+++ b/arch/mips/orion/promcon.c
@@ -0,0 +1,172 @@
+/*
+ * Wrap-around code for a console using the
+ * SGI PROM io-routines.
+ *
+ * Copyright (c) 1999 Ulf Carlsson
+ *
+ * Derived from DECstation promcon.c
+ * Copyright (c) 1998 Harald Koerfgen
+ */
+
+#include <linux/tty.h>
+#include <linux/major.h>
+#include <linux/ptrace.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/fs.h>
+/*
+#include <asm/sgialib.h>
+*/
+extern void prom_printf(char *fmt, ...);
+unsigned long splx(unsigned long mask){return 0;}
+#if 0
+unsigned long ramsize=0x100000;
+unsigned long RamSize(){return ramsize;}
+extern void prom_printf(char *fmt, ...);
+unsigned long splx(unsigned long mask){return 0;}
+long PssSetIntHandler(unsigned long intnum, void *handler){}
+long PssEnableInt(unsigned long intnum){}
+long PssDisableInt(unsigned long intnum){}
+unsigned long t_ident(char name[4], unsigned long node, unsigned long *tid){}
+#endif
+
+extern void SerialPollConout(unsigned char c);
+static void prom_console_write(struct console *co, const char *s,
+ unsigned count)
+{
+ unsigned i;
+
+ /*
+ * Now, do each character
+ */
+ for (i = 0; i < count; i++) {
+ if (*s == 10)
+ SerialPollConout(13);
+ SerialPollConout(*s++);
+ }
+}
+extern int prom_getchar(void);
+static int prom_console_wait_key(struct console *co)
+{
+ return prom_getchar();
+}
+
+extern void SerialPollInit(void);
+extern void SerialSetup(unsigned long baud, unsigned long console, unsigned long host, unsigned long intr_desc);
+static int __init prom_console_setup(struct console *co, char *options)
+{
+ SerialSetup(19200,1,1,3);
+ SerialPollInit();
+ SerialPollOn();
+ return 0;
+}
+
+static kdev_t prom_console_device(struct console *c)
+{
+ return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static struct console sercons =
+{
+ "ttyS",
+ prom_console_write,
+ NULL,
+ prom_console_device,
+ prom_console_wait_key,
+ NULL,
+ prom_console_setup,
+ CON_PRINTBUFFER,
+ -1,
+ 0,
+ NULL
+};
+
+/*
+ * Register console.
+ */
+
+void serial_console_init(void)
+{
+ register_console(&sercons);
+}
+
+extern void prom_putchar(int mychar);
+
+static char ppbuf[1000];
+
+
+void prom_printf(char *fmt, ...)
+{
+ va_list args;
+ char ch, *bptr;
+ int i;
+
+ va_start(args, fmt);
+ i = vsprintf(ppbuf, fmt, args);
+
+ bptr = ppbuf;
+
+ while((ch = *(bptr++)) != 0) {
+ if(ch == '\n')
+ prom_putchar('\r');
+
+ prom_putchar(ch);
+ }
+ va_end(args);
+ return;
+}
+
+
+
+void prom_putchar(int mychar){}
+int prom_getchar(void){return 0;}
+struct app_header_s {
+ unsigned long MAGIC_JMP;
+ unsigned long MAGIC_NOP;
+ unsigned long header_tag;
+ unsigned long header_flags;
+ unsigned long header_length;
+ unsigned long header_cksum;
+
+ void *load_addr;
+ void *end_addr;
+ void *start_addr;
+ char *app_name_p;
+ char *version_p;
+ char *date_p;
+ char *time_p;
+ unsigned long type;
+ unsigned long crc;
+ unsigned long reserved;
+};
+typedef struct app_header_s app_header_t;
+char linked_app_name[]="linux";
+char *linked_app_name_p=&linked_app_name[0];
+
+char linked_app_ver[]="2.4 -test1";
+char *linked_app_ver_p=&linked_app_ver[0];
+
+char linked_app_date[]="today";
+char *linked_app_date_p=&linked_app_date[0];
+
+char linked_app_time[]="now";
+char *linked_app_time_p=&linked_app_time[0];
+extern void *__bss_start;
+extern void *kernel_entry;
+
+app_header_t app_header __attribute__ ((section (".app_header"))) = {
+ (0x10000000 | (((sizeof(app_header_t)>>2)-1) & 0xffff)) ,
+ 0 ,
+ (((( 0x4321 ) & 0xFFFF) << 16) | (( 0x0100 ) & 0xFFFF)) ,
+ 0x80000000 ,
+ sizeof(app_header_t),
+ 0,
+ &app_header,
+ &__bss_start,
+ &kernel_entry,
+ linked_app_name,
+ linked_app_ver,
+ linked_app_date,
+ linked_app_time,
+ 0
+};
diff --git a/arch/mips/orion/setup.c b/arch/mips/orion/setup.c
new file mode 100644
index 000000000..8d4cc54f0
--- /dev/null
+++ b/arch/mips/orion/setup.c
@@ -0,0 +1,127 @@
+/*
+ * Catch-all for Orion-specific code that doesn't fit easily elsewhere.
+ * -- Cort
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/hdreg.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/malloc.h>
+#include <linux/user.h>
+#include <linux/utsname.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#include <linux/interrupt.h>
+#ifdef CONFIG_BLK_DEV_RAM
+#include <linux/blk.h>
+#endif
+#include <linux/ide.h>
+#ifdef CONFIG_RTC
+#include <linux/timex.h>
+#endif
+
+#include <asm/asm.h>
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/io.h>
+#include <asm/stackframe.h>
+#include <asm/system.h>
+#include <asm/cpu.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/mc146818rtc.h>
+#include <asm/orion.h>
+
+char arcs_cmdline[CL_SIZE] = { "console=ttyS0,19200" };
+extern int _end;
+
+static unsigned char orion_rtc_read_data(unsigned long addr)
+{
+ return 0;
+}
+
+static void orion_rtc_write_data(unsigned char data, unsigned long addr)
+{
+}
+
+static int orion_rtc_bcd_mode(void)
+{
+ return 0;
+}
+
+struct rtc_ops orion_rtc_ops = {
+ &orion_rtc_read_data,
+ &orion_rtc_write_data,
+ &orion_rtc_bcd_mode
+};
+
+extern void InitCIB(void);
+extern void InitQpic(void);
+extern void InitCupid(void);
+
+void __init orion_setup(void)
+{
+ extern void (*board_time_init)(struct irqaction *irq);
+ void orion_time_init(struct irqaction *);
+
+ rtc_ops = &orion_rtc_ops;
+ board_time_init = orion_time_init;
+ mips_io_port_base = GT64120_BASE;
+
+ InitCIB();
+ InitQpic();
+ InitCupid();
+}
+
+#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
+
+unsigned long mem_size;
+int __init prom_init(int a, char **b, char **c, int *d)
+{
+ unsigned long free_start, free_end, start_pfn, bootmap_size;
+ extern unsigned long orion_initrd_start[], orion_initrd_size;
+
+ mips_machgroup = MACH_GROUP_ORION;
+ /* 64 MB non-upgradable */
+ mem_size = 64 << 20;
+
+ free_start = PHYSADDR(PFN_ALIGN(&_end));
+ free_end = mem_size;
+ start_pfn = PFN_UP((unsigned long)&_end);
+
+ /* Register all the contiguous memory with the bootmem allocator
+ and free it. Be careful about the bootmem freemap. */
+ bootmap_size = init_bootmem(start_pfn, mem_size >> PAGE_SHIFT);
+
+ /* Free the entire available memory after the _end symbol. */
+ free_start += bootmap_size;
+ free_bootmem(free_start, free_end-free_start);
+
+ initrd_start = (ulong)orion_initrd_start;
+ initrd_end = (ulong)orion_initrd_start + (ulong)orion_initrd_size;
+ initrd_below_start_ok = 1;
+
+ return 0;
+}
+
+void prom_free_prom_memory (void)
+{
+}
+
+int page_is_ram(unsigned long pagenr)
+{
+ if ( pagenr < (mem_size >> PAGE_SHIFT) )
+ return 1;
+ return 0;
+}