summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips64/kernel/head.S219
1 files changed, 92 insertions, 127 deletions
diff --git a/arch/mips64/kernel/head.S b/arch/mips64/kernel/head.S
index bf74a983e..6703ad6bc 100644
--- a/arch/mips64/kernel/head.S
+++ b/arch/mips64/kernel/head.S
@@ -1,131 +1,96 @@
+/* $Id: head.S,v 1.6 2000/03/27 21:05:04 ulfc 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.
+ *
+ * Head.S contains the MIPS exception handler and startup code.
+ *
+ * Copyright (C) 1994, 1995 Waldorf Electronics
+ * Written by Ralf Baechle and Andreas Busse
+ * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#define __ASSEMBLY__
#include <linux/config.h>
#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/threads.h>
-#include <linux/time.h>
-#include <linux/timex.h>
-#include <linux/sched.h>
-
-#include <asm/atomic.h>
+#include <asm/asm.h>
+#include <asm/regdef.h>
#include <asm/processor.h>
-#include <asm/system.h>
-#include <asm/hardirq.h>
-
-#ifdef CONFIG_SGI_IP27
-
-#include <asm/sn/arch.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/agent.h>
-
-#define DOACTION 0xab
-
-static void sendintr(int destid, unsigned char status)
-{
- int level;
-
-#if (CPUS_PER_NODE == 2)
- /*
- * CPU slice A gets level CPU_ACTION_A
- * CPU slice B gets level CPU_ACTION_B
- */
- if (status == DOACTION)
- level = CPU_ACTION_A + cputoslice(destid);
- else /* DOTLBACTION */
- level = N_INTPEND_BITS + TLB_INTR_A + cputoslice(destid);
-
- /*
- * Convert the compact hub number to the NASID to get the correct
- * part of the address space. Then set the interrupt bit associated
- * with the CPU we want to send the interrupt to.
- */
- REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cputocnode(destid)), level);
-#else
- << Bomb! Must redefine this for more than 2 CPUS. >>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+
+ .text
+
+EXPORT(stext) # used for profiling
+EXPORT(_stext)
+
+ __INIT
+
+NESTED(kernel_entry, 16, sp) # kernel entry point
+
+#ifdef CONFIG_ARC64
+ /* We get launched at a XKPHYS address but the kernel is linked to
+ run at a KSEG0 address, so jump there. */
+ la t0, 1f
+ jr t0
+1:
#endif
-}
-
-#endif /* CONFIG_SGI_IP27 */
-
-/* The 'big kernel lock' */
-spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
-int smp_threads_ready = 0; /* Not used */
-static atomic_t smp_commenced = ATOMIC_INIT(0);
-struct cpuinfo_mips cpu_data[NR_CPUS];
-int smp_num_cpus; /* Number that came online. */
-int __cpu_number_map[NR_CPUS];
-int __cpu_logical_map[NR_CPUS];
-cycles_t cacheflush_time;
-
-static void smp_tune_scheduling (void)
-{
-}
-
-void __init smp_boot_cpus(void)
-{
- global_irq_holder = 0;
- current->processor = 0;
- init_idle();
- smp_tune_scheduling();
- smp_num_cpus = 1; /* for now */
- allowboot();
-}
-
-void __init smp_commence(void)
-{
- wmb();
- atomic_set(&smp_commenced,1);
-}
-
-static void stop_this_cpu(void *dummy)
-{
- /*
- * Remove this CPU
- */
- for (;;);
-}
-
-void smp_send_stop(void)
-{
- smp_call_function(stop_this_cpu, NULL, 1, 0);
- smp_num_cpus = 1;
-}
-
-/*
- * this function sends a 'reschedule' IPI to another CPU.
- * it goes straight through and wastes no time serializing
- * anything. Worst case is that we lose a reschedule ...
- */
-void smp_send_reschedule(int cpu)
-{
- panic("smp_send_reschedule\n");
-}
-
-/* Not really SMP stuff ... */
-int setup_profiling_timer(unsigned int multiplier)
-{
-}
-
-/*
- * Run a function on all other CPUs.
- * <func> The function to run. This must be fast and non-blocking.
- * <info> An arbitrary pointer to pass to the function.
- * <retry> If true, keep retrying until ready.
- * <wait> If true, wait until function has completed on other CPUs.
- * [RETURNS] 0 on success, else a negative status code.
- *
- * Does not return until remote CPUs are nearly ready to execute <func>
- * or are or have executed.
- */
-int
-smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
-{
- /* XXX - kinda important ;-) */
- panic("smp_call_function\n");
-}
-
-void flush_tlb_others (unsigned long cpumask, struct mm_struct *mm,
- unsigned long va)
-{
- panic("flush_tlb_others\n");
-}
+
+ ori sp, 0xf # align stack on 16 byte.
+ xori sp, 0xf
+
+ /* Note that all firmware passed argument registers still
+ have their values. */
+ jal prom_init # initialize firmware
+
+ CLI # disable interrupts
+
+ mfc0 t0, CP0_STATUS
+ li t1, ~(ST0_CU1|ST0_CU2|ST0_CU3)
+ and t0, t1
+ or t0, (ST0_CU0|ST0_KX|ST0_SX|ST0_FR)
+ mtc0 t0, CP0_STATUS
+
+ la $28, init_task_union # init current pointer
+ daddiu t0, $28, KERNEL_STACK_SIZE-32
+ sd t0, kernelsp
+ dsubu sp, t0, 4*SZREG # init stack pointer
+
+ jal start_kernel
+1: b 1b # just in case ...
+ END(kernel_entry)
+
+NESTED(bootstrap, 16, sp)
+#ifdef CONFIG_ARC64
+ /* We get launched at a XKPHYS address but the kernel is linked to
+ run at a KSEG0 address, so jump there. */
+ la t0, 1f
+ jr t0
+1:
+#endif
+ jal cboot
+ END(bootstrap)
+
+ __FINIT
+
+ .comm kernelsp, 8, 8 # current stackpointer
+ .comm current_pgd, 8, 8 # current page tables
+
+#define PAGE_SIZE 0x1000
+
+ .macro page name, order=0
+ .globl \name
+ .org . + (PAGE_SIZE << \order)
+\name: .size \name, (PAGE_SIZE << \order)
+ .type \name, @object
+ .endm
+
+ .align 12
+ .data
+
+ page swapper_pg_dir, 1
+ page invalid_pte_table, 1
+ page invalid_pmd_table, 1
+ page empty_bad_page_table, 1
+ page empty_bad_page