patch-2.1.9 linux/arch/sparc/kernel/head.S
Next file: linux/arch/sparc/kernel/idprom.c
Previous file: linux/arch/sparc/kernel/etrap.S
Back to the patch index
Back to the overall index
- Lines: 323
- Date:
Sat Nov 9 10:11:39 1996
- Orig file:
v2.1.8/linux/arch/sparc/kernel/head.S
- Orig date:
Mon May 6 12:26:03 1996
diff -u --recursive --new-file v2.1.8/linux/arch/sparc/kernel/head.S linux/arch/sparc/kernel/head.S
@@ -1,8 +1,9 @@
-/* $Id: head.S,v 1.57 1996/04/25 06:08:38 davem Exp $
+/* $Id: head.S,v 1.70 1996/10/31 06:28:29 davem Exp $
* head.S: The initial boot code for the Sparc port of Linux.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
* Copyright (C) 1995 Peter Zaitcev (Zaitcev@ipmce.su)
+ * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
*/
#include <linux/version.h>
@@ -60,10 +61,6 @@
.asciz "Sparc-Linux sun4 support not implemented yet\n\n"
.align 4
-sun4d_notsup:
- .asciz "Sparc-Linux sun4d support does not exist\n\n"
- .align 4
-
sun4e_notsup:
.asciz "Sparc-Linux sun4e support does not exist\n\n"
.align 4
@@ -147,7 +144,7 @@
t_bad79:BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d)
t_bad7e:BAD_TRAP(0x7e) BAD_TRAP(0x7f)
t_sunos:SUNOS_SYSCALL_TRAP /* SunOS System Call */
-t_sbkpt:BAD_TRAP(0x81) /* Software Breakpoint/KGDB */
+t_sbkpt:BREAKPOINT_TRAP /* Software Breakpoint/KGDB */
t_divz: BAD_TRAP(0x82) /* Divide by zero trap */
t_flwin:TRAP_ENTRY(0x83, do_flush_windows) /* Flush Windows Trap */
t_clwin:BAD_TRAP(0x84) /* Clean Windows Trap */
@@ -165,7 +162,8 @@
t_getcc:GETCC_TRAP /* Get Condition Codes */
t_setcc:SETCC_TRAP /* Set Condition Codes */
t_bada2:BAD_TRAP(0xa2) BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6)
-t_bada7:BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
+t_bada7:INDIRECT_SOLARIS_SYSCALL(156)
+t_bada8:BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
t_badac:BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0)
t_badb1:BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5)
t_badb6:BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba)
@@ -229,7 +227,9 @@
BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78)
BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d)
BAD_TRAP(0x7e) BAD_TRAP(0x7f)
- SUNOS_SYSCALL_TRAP BAD_TRAP(0x81) BAD_TRAP(0x82)
+ SUNOS_SYSCALL_TRAP
+ BREAKPOINT_TRAP
+ BAD_TRAP(0x82)
TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85)
BAD_TRAP(0x86) BAD_TRAP(0x87) SOLARIS_SYSCALL_TRAP
NETBSD_SYSCALL_TRAP BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c)
@@ -239,7 +239,7 @@
BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e)
BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP
BAD_TRAP(0xa2) BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6)
- BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
+ INDIRECT_SOLARIS_SYSCALL(156) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0)
BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5)
BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba)
@@ -295,7 +295,9 @@
BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78)
BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d)
BAD_TRAP(0x7e) BAD_TRAP(0x7f)
- SUNOS_SYSCALL_TRAP BAD_TRAP(0x81) BAD_TRAP(0x82)
+ SUNOS_SYSCALL_TRAP
+ BREAKPOINT_TRAP
+ BAD_TRAP(0x82)
TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85)
BAD_TRAP(0x86) BAD_TRAP(0x87) SOLARIS_SYSCALL_TRAP
NETBSD_SYSCALL_TRAP BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c)
@@ -305,7 +307,7 @@
BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e)
BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP
BAD_TRAP(0xa2) BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6)
- BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
+ INDIRECT_SOLARIS_SYSCALL(156) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0)
BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5)
BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba)
@@ -361,7 +363,9 @@
BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78)
BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d)
BAD_TRAP(0x7e) BAD_TRAP(0x7f)
- SUNOS_SYSCALL_TRAP BAD_TRAP(0x81) BAD_TRAP(0x82)
+ SUNOS_SYSCALL_TRAP
+ BREAKPOINT_TRAP
+ BAD_TRAP(0x82)
TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85)
BAD_TRAP(0x86) BAD_TRAP(0x87) SOLARIS_SYSCALL_TRAP
NETBSD_SYSCALL_TRAP BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c)
@@ -371,7 +375,7 @@
BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e)
BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP
BAD_TRAP(0xa2) BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6)
- BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
+ INDIRECT_SOLARIS_SYSCALL(156) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0)
BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5)
BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba)
@@ -417,6 +421,30 @@
C_LABEL(empty_bad_page_table): .skip 0x1000
C_LABEL(empty_zero_page): .skip 0x1000
+ .global C_LABEL(root_flags)
+ .global C_LABEL(ram_flags)
+ .global C_LABEL(root_dev)
+ .global C_LABEL(ramdisk_image)
+ .global C_LABEL(ramdisk_size)
+
+/* This stuff has to be in sync with SILO and other potential boot loaders
+ * Fields should be kept upward compatible and whenever any change is made,
+ * HdrS version should be incremented.
+ */
+ .ascii "HdrS"
+ .word LINUX_VERSION_CODE
+ .half 0x0201 /* HdrS version */
+C_LABEL(root_flags):
+ .half 1
+C_LABEL(root_dev):
+ .half 0
+C_LABEL(ram_flags):
+ .half 0
+C_LABEL(ramdisk_image):
+ .word 0
+C_LABEL(ramdisk_size):
+ .word 0
+ .word C_LABEL(reboot_command)
/* Cool, here we go. Pick up the romvec pointer in %o0 and stash it in
* %g7 and at prom_vector_p. And also quickly check whether we are on
@@ -460,10 +488,9 @@
/* %l6 will hold the offset we have to subtract
* from absolute symbols in order to access areas
* in our own image. If already mapped this is
- * just plain zero, else it is PAGE_OFFSET which is
- * also KERNBASE.
+ * just plain zero, else it is KERNBASE.
*/
- set PAGE_OFFSET, %l6
+ set KERNBASE, %l6
b copy_prom_lvl14
nop
@@ -519,6 +546,9 @@
be sun4_mutant_remap ! Ugh, it is...
nop
+ b sun4_normal_remap ! regular sun4, 2 level mmu
+ nop
+
remap_not_a_sun4:
lda [%g0] ASI_M_MMUREGS, %g1 ! same as ASI_PTE on sun4c
and %g1, 0x1, %g1 ! Test SRMMU Enable bit ;-)
@@ -669,7 +699,24 @@
b go_to_highmem ! Jump to high memory.
nop
-/* The following works for normal (ie. non Sun4/400) Sun4 MMU's */
+ /* The following is for non-4/4xx sun4 MMU's. */
+sun4_normal_remap:
+ mov 0, %g3 ! source base
+ set KERNBASE, %g4 ! destination base
+ set 0x300000, %g5 ! upper bound 3MB
+ mov 1, %l6
+ sll %l6, 18, %l6 ! sun4 mmu segmap size
+sun4_normal_loop:
+ lduha [%g3] ASI_SEGMAP, %g6 ! load phys_seg
+ stha %g6, [%g4] ASI_SEGMAP ! stort new virt mapping
+ add %g3, %l6, %g3 ! increment source pointer
+ subcc %g3, %g5, %g0 ! reached limit?
+ blu sun4_normal_loop ! nope, loop again
+ add %g4, %l6, %g4 ! delay, increment dest ptr
+ b go_to_highmem
+ nop
+
+ /* The following works for Sun4c MMU's */
sun4c_remap:
mov 0, %g3 ! source base
set KERNBASE, %g4 ! destination base
@@ -780,10 +827,6 @@
be 1f
nop
- cmp %l1, 'd'
- be no_sun4d_here ! God bless the person who
- nop ! tried to run this on sun4d.
-
cmp %l1, 'e'
be no_sun4e_here ! Could be a sun4e.
nop
@@ -797,6 +840,8 @@
ldub [%l1 + 0x4], %l1
cmp %l1, 'm' ! Test for sun4d, sun4e ?
be sun4m_init
+ cmp %l1, 'd' ! Let us see how the beast will die
+ be sun4m_init
nop
/* Jump into mmu context zero. */
@@ -807,6 +852,50 @@
nop
sun4m_init:
+ /* All sun4m processors can do hw mul/div/rem, patch 'em. */
+#define PATCH_IT(dst, src) \
+ set (dst), %g5; \
+ set (src), %g4; \
+ ld [%g4], %g3; \
+ st %g3, [%g5]; \
+ ld [%g4+0x4], %g3; \
+ st %g3, [%g5+0x4];
+
+ /* Signed multiply. */
+ PATCH_IT(.mul, .mul_patch)
+ PATCH_IT(.mul+0x08, .mul_patch+0x08)
+
+ /* Signed remainder. */
+ PATCH_IT(.rem, .rem_patch)
+ PATCH_IT(.rem+0x08, .rem_patch+0x08)
+ PATCH_IT(.rem+0x10, .rem_patch+0x10)
+ PATCH_IT(.rem+0x18, .rem_patch+0x18)
+ PATCH_IT(.rem+0x20, .rem_patch+0x20)
+ PATCH_IT(.rem+0x28, .rem_patch+0x28)
+
+ /* Signed division. */
+ PATCH_IT(.div, .div_patch)
+ PATCH_IT(.div+0x08, .div_patch+0x08)
+ PATCH_IT(.div+0x10, .div_patch+0x10)
+ PATCH_IT(.div+0x18, .div_patch+0x18)
+ PATCH_IT(.div+0x20, .div_patch+0x20)
+
+ /* Unsigned multiply. */
+ PATCH_IT(.umul, .umul_patch)
+ PATCH_IT(.umul+0x08, .umul_patch+0x08)
+
+ /* Unsigned remainder. */
+ PATCH_IT(.urem, .urem_patch)
+ PATCH_IT(.urem+0x08, .urem_patch+0x08)
+ PATCH_IT(.urem+0x10, .urem_patch+0x10)
+ PATCH_IT(.urem+0x18, .urem_patch+0x18)
+
+ /* Unsigned division. */
+ PATCH_IT(.udiv, .udiv_patch)
+ PATCH_IT(.udiv+0x08, .udiv_patch+0x08)
+ PATCH_IT(.udiv+0x10, .udiv_patch+0x10)
+
+#undef PATCH_IT
/* Ok, the PROM could have done funny things and apple cider could still
* be sitting in the fault status/address registers. Read them all to
@@ -873,13 +962,13 @@
/* Initialize the umask value for init_task just in case.
* But first make current_set[0] point to something useful.
*/
- set C_LABEL(init_task), %g4
+ set C_LABEL(init_task), %g6
set C_LABEL(current_set), %g2
- st %g4, [%g2]
+ st %g6, [%g2]
set C_LABEL(bootup_kernel_stack), %g3
- st %g3, [%g4 + TASK_KSTACK_PG]
- st %g0, [%g4 + THREAD_UMASK]
+ st %g3, [%g6 + TASK_KSTACK_PG]
+ st %g0, [%g6 + THREAD_UMASK]
/* Compute NWINDOWS and stash it away. Now uses %wim trick explained
* in the V8 manual. Ok, this method seems to work, Sparc is cool...
@@ -912,9 +1001,9 @@
#define PATCH_INSN(src, dest) \
set src, %g5; \
- set dest, %g6; \
+ set dest, %g2; \
ld [%g5], %g4; \
- st %g4, [%g6];
+ st %g4, [%g2];
/* Patch for window spills... */
PATCH_INSN(spnwin_patch1_7win, spnwin_patch1)
@@ -950,6 +1039,25 @@
PATCH_INSN(rirq_7win_patch5, rirq_patch5)
#endif
+ /* Now patch the kernel window flush sequences.
+ * This saves 2 traps on every switch and fork.
+ */
+ set 0x01000000, %g4
+ set flush_patch_one, %g5
+ st %g4, [%g5 + 0x18]
+ st %g4, [%g5 + 0x1c]
+ set flush_patch_two, %g5
+ st %g4, [%g5 + 0x18]
+ st %g4, [%g5 + 0x1c]
+ set flush_patch_three, %g5
+ st %g4, [%g5 + 0x18]
+ st %g4, [%g5 + 0x1c]
+ set flush_patch_exception, %g5
+ st %g4, [%g5 + 0x18]
+ st %g4, [%g5 + 0x1c]
+ set flush_patch_switch, %g5
+ st %g4, [%g5 + 0x18]
+ st %g4, [%g5 + 0x1c]
2:
sethi %hi( C_LABEL(nwindows) ), %g4
@@ -998,14 +1106,6 @@
nop
1:
ba 1b ! Cannot exit into KMON
- nop
-
-no_sun4d_here:
- ld [%g7 + 0x68], %o1
- set sun4d_notsup, %o0
- call %o1
- nop
- b halt_me
nop
no_sun4e_here:
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov