diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-07-10 23:47:44 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-07-10 23:47:44 +0000 |
commit | ce7a3f3db827012e90ceae068572d813643e3d32 (patch) | |
tree | 0ae05de73cea41d13e2f5c537dad97ae7e34fc33 /arch/mips | |
parent | c7c4310f7fc1485925d800628bf50b3aeab535ef (diff) |
Support for the Galileo Orion board. From Cort.
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/Makefile | 16 | ||||
-rw-r--r-- | arch/mips/config.in | 1 | ||||
-rw-r--r-- | arch/mips/defconfig-orion | 175 | ||||
-rw-r--r-- | arch/mips/kernel/Makefile | 4 | ||||
-rw-r--r-- | arch/mips/kernel/setup.c | 17 | ||||
-rw-r--r-- | arch/mips/orion/.cvsignore | 2 | ||||
-rw-r--r-- | arch/mips/orion/Makefile | 48 | ||||
-rw-r--r-- | arch/mips/orion/int-handler.S | 53 | ||||
-rw-r--r-- | arch/mips/orion/irq.c | 284 | ||||
-rw-r--r-- | arch/mips/orion/ld.script.orion | 113 | ||||
-rw-r--r-- | arch/mips/orion/misc.c | 102 | ||||
-rw-r--r-- | arch/mips/orion/no_initrd.c | 2 | ||||
-rw-r--r-- | arch/mips/orion/piggyback.c | 59 | ||||
-rw-r--r-- | arch/mips/orion/promcon.c | 172 | ||||
-rw-r--r-- | arch/mips/orion/setup.c | 127 |
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; +} |