summaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
committer <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
commitbeb116954b9b7f3bb56412b2494b562f02b864b1 (patch)
tree120e997879884e1b9d93b265221b939d2ef1ade1 /arch/mips
parent908d4681a1dc3792ecafbe64265783a86c4cccb6 (diff)
Import of Linux/MIPS 2.1.14
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/Makefile159
-rw-r--r--arch/mips/TODO176
-rw-r--r--arch/mips/acn/Makefile22
-rw-r--r--arch/mips/acn/reset.c12
-rw-r--r--arch/mips/acn/setup.c26
-rw-r--r--arch/mips/boot/Makefile32
-rw-r--r--arch/mips/boot/compressed/Makefile8
-rw-r--r--arch/mips/boot/compressed/cache.S19
-rw-r--r--arch/mips/boot/compressed/misc.c2
-rw-r--r--arch/mips/boot/mkboot.c660
-rw-r--r--arch/mips/config.in398
-rw-r--r--arch/mips/dec/Makefile24
-rw-r--r--arch/mips/dec/boot.S92
-rw-r--r--arch/mips/dec/decstation.S382
-rw-r--r--arch/mips/dec/decstation.c201
-rw-r--r--arch/mips/dec/hw-access.c26
-rw-r--r--arch/mips/dec/int-handler.S273
-rw-r--r--arch/mips/dec/ld.script47
-rw-r--r--arch/mips/dec/setup.c41
-rw-r--r--arch/mips/defconfig241
-rw-r--r--arch/mips/deskstation/Makefile22
-rw-r--r--arch/mips/deskstation/hw-access.c198
-rw-r--r--arch/mips/deskstation/int-handler.S (renamed from arch/mips/kernel/tyne.S)100
-rw-r--r--arch/mips/deskstation/setup.c141
-rw-r--r--arch/mips/doc/pagetables.txt87
-rw-r--r--arch/mips/jazz/Makefile26
-rw-r--r--arch/mips/jazz/g364.c415
-rw-r--r--arch/mips/jazz/g364.fnt4097
-rw-r--r--arch/mips/jazz/hw-access.c147
-rw-r--r--arch/mips/jazz/int-handler.S389
-rw-r--r--arch/mips/jazz/jazzdma.c515
-rw-r--r--arch/mips/jazz/setup.c137
-rw-r--r--arch/mips/kernel/Makefile81
-rw-r--r--arch/mips/kernel/branch.c193
-rw-r--r--arch/mips/kernel/entry.S661
-rw-r--r--arch/mips/kernel/gdb-low.S2
-rw-r--r--arch/mips/kernel/gdb-stub.c8
-rw-r--r--arch/mips/kernel/head.S422
-rw-r--r--arch/mips/kernel/ipc.c109
-rw-r--r--arch/mips/kernel/irq.c344
-rw-r--r--arch/mips/kernel/jazzdma.c518
-rw-r--r--arch/mips/kernel/ksyms.c40
-rw-r--r--arch/mips/kernel/magnum4000.S261
-rw-r--r--arch/mips/kernel/pica.S252
-rw-r--r--arch/mips/kernel/proc.c62
-rw-r--r--arch/mips/kernel/process.c207
-rw-r--r--arch/mips/kernel/ptrace.c282
-rw-r--r--arch/mips/kernel/setup.c328
-rw-r--r--arch/mips/kernel/signal.c442
-rw-r--r--arch/mips/kernel/syscall.c280
-rw-r--r--arch/mips/kernel/syscalls.h205
-rw-r--r--arch/mips/kernel/sysmips.c113
-rw-r--r--arch/mips/kernel/tags.c70
-rw-r--r--arch/mips/kernel/time.c292
-rw-r--r--arch/mips/kernel/traps.c451
-rw-r--r--arch/mips/kernel/tynedma.c36
-rw-r--r--arch/mips/kernel/unaligned.c457
-rw-r--r--arch/mips/kernel/vm86.c7
-rw-r--r--arch/mips/ld.script107
-rw-r--r--arch/mips/lib/Makefile36
-rw-r--r--arch/mips/lib/bcopy.c20
-rw-r--r--arch/mips/lib/beep.S21
-rw-r--r--arch/mips/lib/bitags.c161
-rw-r--r--arch/mips/lib/checksum.c158
-rw-r--r--arch/mips/lib/csum.S25
-rw-r--r--arch/mips/lib/dump_tlb.c45
-rw-r--r--arch/mips/lib/io.c24
-rw-r--r--arch/mips/lib/memmove.c39
-rw-r--r--arch/mips/lib/pmaxcon.c150
-rw-r--r--arch/mips/lib/pmaxio.S78
-rw-r--r--arch/mips/lib/strlen_user.S33
-rw-r--r--arch/mips/lib/strncpy_user.S48
-rw-r--r--arch/mips/lib/tinycon.c22
-rw-r--r--arch/mips/lib/watch.S69
-rw-r--r--arch/mips/man/de/man2/cacheflush.277
-rw-r--r--arch/mips/man/de/man2/syscall.260
-rw-r--r--arch/mips/man/man2/cacheflush.267
-rw-r--r--arch/mips/man/man2/syscall.261
-rw-r--r--arch/mips/man/man8/hardware.897
-rw-r--r--arch/mips/mips1/Makefile28
-rw-r--r--arch/mips/mips1/cache.S162
-rw-r--r--arch/mips/mips1/cpu.c91
-rw-r--r--arch/mips/mips1/fp-context.S159
-rw-r--r--arch/mips/mips1/memcpy.S206
-rw-r--r--arch/mips/mips1/memset.S27
-rw-r--r--arch/mips/mips1/pagetables.c86
-rw-r--r--arch/mips/mips1/r3000.S1125
-rw-r--r--arch/mips/mips1/showregs.c32
-rw-r--r--arch/mips/mips2/Makefile21
-rw-r--r--arch/mips/mips2/README3
-rw-r--r--arch/mips/mips2/cpu.c91
-rw-r--r--arch/mips/mips2/fp-context.S124
-rw-r--r--arch/mips/mips2/pagetables.c99
-rw-r--r--arch/mips/mips2/showregs.c32
-rw-r--r--arch/mips/mips3/Makefile25
-rw-r--r--arch/mips/mips3/cache.c309
-rw-r--r--arch/mips/mips3/cpu.c96
-rw-r--r--arch/mips/mips3/fp-context.S170
-rw-r--r--arch/mips/mips3/memcpy.S185
-rw-r--r--arch/mips/mips3/memset.c82
-rw-r--r--arch/mips/mips3/pagetables.c297
-rw-r--r--arch/mips/mips3/r4xx0.S (renamed from arch/mips/kernel/r4xx0.S)515
-rw-r--r--arch/mips/mips3/showregs.c36
-rw-r--r--arch/mips/mips4/Makefile21
-rw-r--r--arch/mips/mips4/README3
-rw-r--r--arch/mips/mips4/cpu.c106
-rw-r--r--arch/mips/mips4/pagetables.c122
-rw-r--r--arch/mips/mkdisk5
-rw-r--r--arch/mips/mm/Makefile27
-rw-r--r--arch/mips/mm/extable.c57
-rw-r--r--arch/mips/mm/fault.c73
-rw-r--r--arch/mips/mm/init.c221
-rw-r--r--arch/mips/mm/stack.c26
-rw-r--r--arch/mips/sni/Makefile28
-rw-r--r--arch/mips/sni/bios32.c264
-rw-r--r--arch/mips/sni/hw-access.c157
-rw-r--r--arch/mips/sni/int-handler.S193
-rw-r--r--arch/mips/sni/reset.c38
-rw-r--r--arch/mips/sni/setup.c108
119 files changed, 18532 insertions, 3554 deletions
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index baec00d70..c7ba5db9b 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -10,78 +10,166 @@
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
-# Copyright (C) 1994, 1995 by Waldorf Electronics,
-# written by Ralf Baechle
+# Copyright (C) 1994, 1995, 1996 by Ralf Baechle
+# DECStation modifications by Paul M. Antoine, 1996
+# ACN MIPS board modifications by Robin Farine (Robin.Farine@info.unine.ch)
+# and Didier Frick (dfrick@dial.eunet.ch), copyright (C) 1996 by ACN S.A.
#
-ifdef CONFIG_ELF_COMPILER
ifdef CONFIG_CPU_LITTLE_ENDIAN
-prefix = mipsel-linuxelf-
+cross-target = mipsel-linux-
+ifdef CONFIG_MIPS_ECOFF
+oformat = ecoff-littlemips
else
-prefix = mips-linuxelf-
+oformat = a.out-mips-little-linux
endif
else
-ifdef CONFIG_CPU_LITTLE_ENDIAN
-prefix = mipsel-linux-
+cross-target = mips-linux-
+ifdef CONFIG_MIPS_ECOFF
+oformat = ecoff-bigmips
else
-prefix = mips-linux-
+oformat = a.out-mips-big-linux
+endif
endif
+
+ifdef CONFIG_CROSS_COMPILE
+CROSS_COMPILE := $(cross-target)
+else
+CROSS_COMPILE :=
endif
-AS = $(prefix)as
-LD = $(prefix)ld
-LINKFLAGS = -N -Ttext 0x80000000
-#HOSTCC = gcc
-CC = $(prefix)gcc -D__KERNEL__ -I$(TOPDIR)/include
-CPP = $(CC) -E $(CFLAGS)
-AR = $(prefix)ar
-RANLIB = $(prefix)ranlib
-STRIP = $(prefix)strip
-NM = $(prefix)nm
+LINKFLAGS = -N
#
-# The new ELF GCC uses -G0 -mabicalls -fpic as default. We don't need PIC
+# The GCC uses -G 0 -mabicalls -fpic as default. We don't need PIC
# code in the kernel since it only slows down the whole thing. For the
# old GCC these options are just the defaults. At some point we might
-# make use of global pointer optimaztions.
+# make use of global pointer optimizations.
#
-ifdef CONFIG_OBJECT_ELF
-CFLAGS := $(CFLAGS) -G0 -mno-abicalls -fno-pic #-pipe
-endif
+# We also pass -G 0 to the linker to avoid generation of a .scommon section.
+#
+# The DECStation requires an ECOFF kernel for remote booting, other MIPS
+# machines may also. We build an ELF kernel and them convert it into an
+# ECOFF kernel.
+#
+CFLAGS += -G 0 -mno-abicalls -fno-pic
+LINKFLAGS += -G 0
ifdef CONFIG_REMOTE_DEBUG
CFLAGS := $(CFLAGS) -g
endif
+#
+# CPU dependand compiler/assembler options for optimization.
+#
ifdef CONFIG_CPU_R3000
CFLAGS := $(CFLAGS) -mcpu=r3000 -mips1
-ASFLAGS := $(ASFLAGS) -mcpu=r3000 -mips1
+SUBDIRS += arch/mips/mips1
+cpu-core = arch/mips/mips1/mips.o
endif
ifdef CONFIG_CPU_R6000
CFLAGS := $(CFLAGS) -mcpu=r6000 -mips2
-ASFLAGS := $(ASFLAGS) -mcpu=r6000 -mips2
+SUBDIRS += arch/mips/mips2
+cpu-core = arch/mips/mips2/mips.o
endif
ifdef CONFIG_CPU_R4X00
-CFLAGS := $(CFLAGS) -D__R4000__ -mcpu=r4400 -mips2
-ASFLAGS := $(ASFLAGS) -mcpu=r4400 -mips2
+ifdef CONFIG_OPTIMIZE_R4600
+CFLAGS := $(CFLAGS) -mcpu=r4600 -mips3
+else
+CFLAGS := $(CFLAGS) -mcpu=r4400 -mips3
endif
-ifdef CONFIG_CPU_R4600
-CFLAGS := $(CFLAGS) -D__R4000__ -mcpu=r4600 -mips2
-ASFLAGS := $(ASFLAGS) -mcpu=r4600 -mips2
+SUBDIRS += arch/mips/mips3
+cpu-core = arch/mips/mips3/mips.o
endif
ifdef CONFIG_CPU_R8000
-CFLAGS := $(CFLAGS) -D__R4000__ -mcpu=r8000 -mips2
-ASFLAGS := $(ASFLAGS) -mcpu=r8000 -mips2
+CFLAGS := $(CFLAGS) -mcpu=r8000 -mips4
+SUBDIRS += arch/mips/mips3
+cpu-core = arch/mips/mips3/mips.o
endif
ifdef CONFIG_CPU_R10000
-CFLAGS := $(CFLAGS) -D__R4000__ -mcpu=r8000 -mips2
-ASFLAGS := $(ASFLAGS) -mcpu=r8000 -mips2
+CFLAGS := $(CFLAGS) -mcpu=r8000 -mips4
+SUBDIRS += arch/mips/mips3
+cpu-core = arch/mips/mips3/mips.o
+endif
+
+#
+# Board dependand options and extra files
+#
+ifdef CONFIG_ACER_PICA_61
+ARCHIVES += arch/mips/jazz/jazz.o
+SUBDIRS += arch/mips/jazz
+LINKSCRIPT += arch/mips/ld.script
+LOADADDR += 0x80000000
+endif
+ifdef CONFIG_ACN_MIPS_BOARD
+ARCHIVES += arch/mips/acn/acn.o
+SUBDIRS += arch/mips/acn
+LINKSCRIPT += arch/mips/ld.script
+LOADADDR += 0x80000000
+endif
+ifdef CONFIG_MIPS_DECSTATION
+ARCHIVES += arch/mips/dec/dec.o
+SUBDIRS += arch/mips/dec
+LINKSCRIPT += arch/mips/ld.script
+LOADADDR += 0x80000000
endif
+ifdef CONFIG_DESKSTATION_RPC44
+ARCHIVES += arch/mips/deskstation/deskstation.o
+SUBDIRS += arch/mips/deskstation
+LINKSCRIPT += arch/mips/ld.script
+LOADADDR += 0x80000000
+endif
+ifdef CONFIG_DESKSTATION_TYNE
+ARCHIVES += arch/mips/deskstation/deskstation.o
+SUBDIRS += arch/mips/deskstation
+LINKSCRIPT += arch/mips/ld.script
+LOADADDR += 0x80000000
+endif
+ifdef CONFIG_MIPS_MAGNUM_3000
+LINKFLAGS += -Ttext 0x80100000
+endif
+ifdef CONFIG_MIPS_MAGNUM_4000
+ARCHIVES += arch/mips/jazz/jazz.o
+SUBDIRS += arch/mips/jazz
+LINKSCRIPT += arch/mips/ld.script
+LOADADDR += 0x80000000
+endif
+ifdef CONFIG_OLIVETTI_M700
+ARCHIVES += arch/mips/jazz/jazz.o
+SUBDIRS += arch/mips/jazz
+LINKSCRIPT += arch/mips/ld.script
+LOADADDR += 0x80000000
+endif
+ifdef CONFIG_SNI_RM200_PCI
+ARCHIVES += arch/mips/sni/sni.o
+SUBDIRS += arch/mips/sni
+LINKSCRIPT += arch/mips/ld.script
+LOADADDR += 0x80000000
+endif
+
+#
+# Choosing incompatible machines durings configuration will result in
+# error messages during linking
+#
+ifdef LINKSCRIPT
+LINKFLAGS += -T $(word 1,$(LINKSCRIPT))
+endif
+
+ifdef LOADADDR
+LINKFLAGS += -Ttext $(word 1,$(LOADADDR))
+endif
+
+#
+# The pipe options is bad for low-mem machines
+# Uncomment this if you want this. Helps most on diskless
+# Linux machines.
+#
+CFLAGS += #-pipe
HEAD := arch/mips/kernel/head.o
SUBDIRS := $(SUBDIRS) arch/mips/kernel arch/mips/mm arch/mips/lib
-ARCHIVES := arch/mips/kernel/kernel.o arch/mips/mm/mm.o $(ARCHIVES)
+ARCHIVES := $(cpu-core) arch/mips/kernel/kernel.o arch/mips/mm/mm.o $(ARCHIVES)
LIBS := arch/mips/lib/lib.a $(LIBS) arch/mips/lib/lib.a
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
@@ -96,6 +184,7 @@ zdisk: vmlinux
archclean:
@$(MAKEBOOT) clean
+ $(MAKE) -C arch/$(ARCH)/kernel clean
archdep:
@$(MAKEBOOT) dep
diff --git a/arch/mips/TODO b/arch/mips/TODO
index 29afd71f7..c5df56d0c 100644
--- a/arch/mips/TODO
+++ b/arch/mips/TODO
@@ -1,10 +1,166 @@
- - Check the definitions for F_EXLCK and F_SHLCK in include/asm-mips/fcntl.h
- for correctness and compatibility with MIPS ABI.
- - Check the definitions for O_NDELAY in include/asm-mips/fcntl.h for
- correctness and compatibility with MIPS ABI.
- - What are the fields l_sysid and pad in struct flock supposed to contain?
- Do we need to handle them in the kernel?
- - Check the resource limits defines in asm-mips/resource.h
- - Recheck struct stat in asm-mips/stat.h
- - Use timestruc_t in struct stat in asm/stat.h instead of time_t
- - cacheflush should check for illegal flags
+ - Kernel:
+ - fd_set_dma_addr() Virtuelle Adressen -> Bus adressen
+ - __pa() und __va() Makro Benutzer in include/asm-mips/ aendern
+ - The PICs in some RISC PC class machines are cascaded, in others not.
+ Yuck. If they're using PC crap part they should do it right ...
+ - Print a warning for R4600 V1.0 users; there is a problem with the
+ caches that isn't handled yet in the kernel.
+ - IP checksums overhaul. (Dave said he did for the SGI port)
+ - The networking related constants still aren't indentical with IRIX/ABI.
+ - Check the definitions for F_EXLCK and F_SHLCK in include/asm-mips/fcntl.h
+ for correctness and compatibility with MIPS ABI.
+ - Check the definitions for O_NDELAY in include/asm-mips/fcntl.h for
+ correctness and compatibility with MIPS ABI.
+ - What are the fields l_sysid and pad in struct flock supposed to contain?
+ Do we need to handle them in the kernel?
+ - Check the resource limits defines in asm-mips/resource.h
+ - Recheck struct stat in asm-mips/stat.h
+ - Use timestruc_t in struct stat in asm/stat.h instead of time_t
+ - asm-mips/termios.h is pretty hacked; it should be verified for ABI
+ conformance by someone who has the documentation.
+ - Cleanup include files. To many files include too many others.
+ - Fix asm-mips/elf.h. This is just good enough to make the thing compile.
+ - asm-mips/socket.h needs further fixes for ABI conformance.
+ - linux/types.h / asm-mips/types.h: FD_SETSIZE should be 1024, not 256.
+ 1024 is required by the ABI.
+ - asm-mips/socket.h: check the FIO* and SIO* defines.
+ - linux/sockios.h: The sockios aren't ABI compatible.
+ - For performance reasons the missing inline functions in asm-mips/string.h
+ should be implemented.
+ - For performance reasons the tlbflush code should be rewritten.
+ - Module support for the Sonic driver.
+ - From 1.3.17 on the kernel does no more compile with network support but
+ without procfs support included.
+ - /proc/cpuinfo should contain more information that just CPU model,
+ computer model and damn BogoMIPS.
+ - The sysmips(2) syscall needs to be tested. Some of the subcommands
+ are still missing.
+ - The whole kernel is junked with #if 0 ... #endif debug code. Cleanup.
+ - Use set_pte hook in page.h. It's the more effective and elegant way
+ than my solution which was just optimized just to better survives other
+ peoples kernel patches without rejects ...
+ - Build the machine vector in arch/mips/kernel/setup.c table using
+ constructors, not static initialization.
+ - Can the virtual address spaces of the kernel virtual memory and page
+ tables colide with each other? (Yes, when the kernel uses excessive
+ amounts of kernel virtual memory.)
+ - Test the memory protection with nuclear warheads model W-crashme ...
+ - die_if_kernel() should try to handle branch delay slots.
+ - Try to reduce dependencies between header files.
+ - Unroll some of the memset type assembler loops.
+ - Replace memcpy and friends by a highly optimized routine. Will probably
+ speed up scrolling by another 100 %. Certainly not required by the Acer,
+ but Magnum and Olivetti ...
+ - Hmm... Think that the i386 version of the kernel has a bug. It doesn't
+ set the carry flag for syscalls > NR_syscalls. Really unimportant.
+ - The size_t definitions in <linux/stddef.h> and <asm/types.h> are
+ incompatible.
+ - Cleanup the parameter passing to new execve-ed ELF/a.out executables.
+ - Cleanup drivers/char/keyboard.c and send it to Linus.
+ - No SMP support yet.
+ - Caches:
+ - sys_cacheflush should check for illegal flags
+ - The way cache flushing is being done in floppy.c is dangerous because
+ the flushing is actually a writeback invalidate. Could corrupt data.
+ - The kernel is very conservative about flushing the TLB/caches. Try
+ to eleminate flushing as far as possible.
+ - page colouring NEEDS to be implemented for R4000+ to circument the
+ page aliasing problem due to the stupid R4000 cache. There are
+ alternatives but they'd be dog slow.
+ - Allocate the swapper pgd dynamically.
+ - it is impossible to send signals >= 32 (send_sig() in kernel/exit.c)
+ - Which is the unit of RLIMIT_CPU?
+ - Eleminate invalid_pte_table. It contains only zeros just like
+ empty_zero_page.
+ - Writing to floppies doesn't work in 1.3.62.
+ - Cleanup the arch/mips/ directory structure. Split up kernel/ and mm/
+ in cpu dependand and machine dependand directories. Do this also for
+ the configfile.
+ - FIXME: resume() assumes current == prev.
+ - The timer interrupt runs with interrupts disabled. This means that
+ sometimes interrupts are off for a long time. Use some other strategy
+ for the jiffies stuff.
+ - Scrollback in the VGA console is broken.
+ - Modify pte_alloc() the same way as for Intel.
+ - Binutils 2.7:
+ - 2.6 introduces a new machine instruction waiti for the 4010. Is this
+ the same machine instruction as wait for R4200/R4300i/R4600? At least
+ the opcodes are the sames.
+ - strip --remove-section= with no other options also removes the symbols.
+ - Shouldn't the binutils support an ulwu macro?
+ - uld, ulw generate bad code for the special case when both registers are
+ the same.
+ - MIPS support in gprof is missing.
+ - When explicitly giving an nonexistant entry point as -e <entry> point
+ during loading a shared lib, ld should complain.
+ - The assembler dies when the argument to .gpword is a extern symbol.
+ - This source breaks GAS in binutils 2.7:
+ .macro ins
+ .if (3 | 16)
+ .endif
+ .endm
+
+ ins
+ - GNU libc 951215:
+ - There are lots of collisions between structures in the kernel header
+ files and the includes generated by the kernel.
+ - setjmp & friends fail for the 32 double register model of > MIPS3.
+ - R4400:
+ - Per once told me he found something he believes is a CPU bug. Ask him if
+ it's really a bug.
+ - R8000 in arch/mips/config.in:
+ - Can the R8000 do a TLB shutdown like the R4000 or is it like the R10000?
+ - Manpages:
+ - The sysmips(2) documentation needs to be completed.
+ - The cacheflush(2) and cachectl(2) documentation needs to be proof read
+ by a native speaker.
+ - Translate the manpages into as many foreign languages as possible.
+ - Send the corrected/translated manpages to the LDP/Andries Brouwer.
+ - GCC 2.7.2:
+ - The info files lack descriptions of some MIPS options like -mips4.
+ - The multilib support has no way to specify incompatible options
+ like -mabicalls and -fno-PIC. For such option pairs library compilation
+ is nonsense and breaks anyway.
+ - The following macros work but generate good code only for certain
+ data types. We only use get_unaligned() for accessing unaligned ints
+ and then GCC makes full score anyway ...
+
+#define get_unaligned(ptr) \
+ ({ \
+ struct __unal { \
+ __typeof__(*(ptr)) __x __attribute__((packed)); \
+ }; \
+ \
+ ((struct __unal *)(ptr))->__x; \
+ })
+
+#define put_unaligned(ptr,val) \
+ ({ \
+ struct __unal { \
+ __typeof__(*(ptr)) __x __attribute__((packed)); \
+ }; \
+ \
+ ((struct __unal *)(ptr))->__x = (val); \
+ })
+
+int
+foo(int *p)
+{
+ return get_unaligned(p);
+}
+
+int
+bar(int *p, int var)
+{
+ put_unaligned(p, var);
+}
+
+struct blah {
+ char x1 __attribute__((packed));
+ int x2 __attribute__((packed));
+};
+
+fasel(struct blah *p, int var)
+{
+ p->x2 = var;
+}
diff --git a/arch/mips/acn/Makefile b/arch/mips/acn/Makefile
new file mode 100644
index 000000000..3821d7b62
--- /dev/null
+++ b/arch/mips/acn/Makefile
@@ -0,0 +1,22 @@
+#
+# Makefile for the SNI specific part of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+all: sni.o
+O_TARGET := sni.o
+O_OBJS := hw-access.o int-handler.o reset.o setup.o
+
+int-handler.o: int-handler.S
+
+clean:
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips/acn/reset.c b/arch/mips/acn/reset.c
new file mode 100644
index 000000000..149fedd9d
--- /dev/null
+++ b/arch/mips/acn/reset.c
@@ -0,0 +1,12 @@
+/*
+ * linux/arch/mips/sni/process.c
+ *
+ * Reset the ACN board.
+ */
+#include <asm/io.h>
+#include <asm/system.h>
+
+void
+acn_hard_reset_now(void)
+{
+}
diff --git a/arch/mips/acn/setup.c b/arch/mips/acn/setup.c
new file mode 100644
index 000000000..5fe8731e5
--- /dev/null
+++ b/arch/mips/acn/setup.c
@@ -0,0 +1,26 @@
+/*
+ * Setup pointers to hardware dependand routines.
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ */
+#include <asm/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/vector.h>
+
+extern void acn_hard_reset_now(void);
+
+void
+sni_rm200_pci_setup(void)
+{
+ hard_reset_now = acn_hard_reset_now;
+}
diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile
index 93784137d..3a8698d34 100644
--- a/arch/mips/boot/Makefile
+++ b/arch/mips/boot/Makefile
@@ -8,12 +8,6 @@
# Copyright (C) 1995 by Ralf Baechle
#
-.c.s:
- $(CC) $(CFLAGS) -S $<
-.s.o:
- $(AS) $(ASFLAGS) -o $*.o $<
-.c.o:
- $(CC) $(CFLAGS) -c $<
.S.s:
$(CPP) $(CFLAGS) $< -o $*.s
.S.o:
@@ -22,11 +16,22 @@
OBJS = milo.o a.out.o
#
+# Drop some uninteresting sections in the kernel.
+# This is only relevant for ELF kernels but doesn't hurt a.out
+#
+drop-sections = .reginfo .mdebug
+strip-flags = $(addprefix --remove-section=,$(drop-sections))
+
+#
# Fake compressed boot
#
-zImage: $(CONFIGURE) $(TOPDIR)/vmlinux
- cp $(TOPDIR)/vmlinux $@
- $(STRIP) --discard-all $@
+zImage: $(CONFIGURE) mkboot $(TOPDIR)/vmlinux
+ $(OBJCOPY) $(strip-flags) $(TOPDIR)/vmlinux zImage.tmp
+ ./mkboot zImage.tmp zImage
+ rm -f zImage.tmp
+
+mkboot: mkboot.c
+ $(HOSTCC) -o $@ $^
zdisk: zImage
mcopy -n zImage a:vmlinux
@@ -35,13 +40,8 @@ dep:
$(CPP) -M *.[cS] > .depend
clean:
- rm -f zImage
+ rm -f zImage zImage.tmp mkboot
dummy:
-#
-# include a dependency file if one exists
-#
-ifeq (.depend,$(wildcard .depend))
-include .depend
-endif
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile
index 228ee83bc..e613fece0 100644
--- a/arch/mips/boot/compressed/Makefile
+++ b/arch/mips/boot/compressed/Makefile
@@ -1,5 +1,5 @@
#
-# linux/arch/i386/boot/compressed/Makefile
+# linux/arch/mips/boot/compressed/Makefile
#
# create a compressed vmlinux image from the original vmlinux
#
@@ -11,12 +11,6 @@ OBJECTS = $(HEAD) inflate.o unzip.o misc.o
CFLAGS = -O2 -DSTDC_HEADERS
-.c.s:
- $(CC) $(CFLAGS) -S $<
-.s.o:
- $(AS) $(ASFLAGS) -o $*.o $<
-.c.o:
- $(CC) $(CFLAGS) -c $<
.S.s:
$(CPP) $(CFLAGS) $< -o $*.s
.S.o:
diff --git a/arch/mips/boot/compressed/cache.S b/arch/mips/boot/compressed/cache.S
index 8e7fff0c1..3e6a3d57d 100644
--- a/arch/mips/boot/compressed/cache.S
+++ b/arch/mips/boot/compressed/cache.S
@@ -18,9 +18,10 @@
#include <asm/asm.h>
#include <asm/cachectl.h>
#include <asm/mipsregs.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
-#ifdef __R4000__
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS5)
/*
* Some bits in the config register
@@ -28,6 +29,8 @@
#define CONFIG_IB (1<<5)
#define CONFIG_DB (1<<4)
+#define CACHEBLOCKS 32
+
/*
* Flush instruction/data caches
*
@@ -48,7 +51,7 @@
/*
* Writeback data cache, even lines
*/
- li t1,CACHELINES-1
+ li t1,CACHEBLOCKS-1
1: cache Index_Writeback_Inv_D,0(t0)
cache Index_Writeback_Inv_D,32(t0)
cache Index_Writeback_Inv_D,64(t0)
@@ -76,7 +79,7 @@
mfc0 t1,CP0_CONFIG
andi t1,CONFIG_IB
bnez t1,do_icache
- li t1,CACHELINES-1
+ li t1,CACHEBLOCKS-1
1: cache Index_Writeback_Inv_D,16(t0)
cache Index_Writeback_Inv_D,48(t0)
cache Index_Writeback_Inv_D,80(t0)
@@ -104,7 +107,7 @@ do_icache: andi t1,a2,ICACHE
* Flush instruction cache, even lines
*/
lui t0,0x8000
- li t1,CACHELINES-1
+ li t1,CACHEBLOCKS-1
1: cache Index_Invalidate_I,0(t0)
cache Index_Invalidate_I,32(t0)
cache Index_Invalidate_I,64(t0)
@@ -132,7 +135,7 @@ do_icache: andi t1,a2,ICACHE
mfc0 t1,CP0_CONFIG
andi t1,CONFIG_DB
bnez t1,done
- li t1,CACHELINES-1
+ li t1,CACHEBLOCKS-1
1: cache Index_Invalidate_I,16(t0)
cache Index_Invalidate_I,48(t0)
cache Index_Invalidate_I,80(t0)
@@ -157,6 +160,6 @@ done: j ra
nop
END(sys_cacheflush)
-#else /* !defined (__R4000__) */
+#else
#error "No R3000 cacheflushing implemented yet!"
-#endif /* !defined (__R4000__) */
+#endif
diff --git a/arch/mips/boot/compressed/misc.c b/arch/mips/boot/compressed/misc.c
index 1e3bb5f82..625a75cd0 100644
--- a/arch/mips/boot/compressed/misc.c
+++ b/arch/mips/boot/compressed/misc.c
@@ -12,7 +12,7 @@
#include "gzip.h"
#include "lzw.h"
-#include <asm/segment.h>
+#include <asm/uaccess.h>
/*
* These are set up by the setup-routine at boot-time:
diff --git a/arch/mips/boot/mkboot.c b/arch/mips/boot/mkboot.c
new file mode 100644
index 000000000..c34332f99
--- /dev/null
+++ b/arch/mips/boot/mkboot.c
@@ -0,0 +1,660 @@
+/*
+ * Make a bootable image from a Linux/MIPS kernel.
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ *
+ * This file is written in plain Kernighan & Ritchie C as it has to run
+ * on all crosscompile hosts no matter how braindead. This code might
+ * also become part of Milo. It's therefore important that we don't use
+ * seek because the Seek() call of the Magnum 4000 ARC BIOS is broken.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+/*
+ * Define this for verbose debugging output.
+ */
+#undef VERBOSE
+
+/*
+ * Don't use the host's elf.h - it might be using incompatible defines
+ */
+
+#define EI_NIDENT 16
+
+/*
+ * Basic ELF types.
+ */
+typedef unsigned short Elf32_Half;
+typedef unsigned short Elf32_Section;
+typedef unsigned int Elf32_Word;
+typedef unsigned int Elf32_Addr;
+typedef unsigned int Elf32_Off;
+
+typedef struct
+{
+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
+ Elf32_Half e_type; /* Object file type */
+ Elf32_Half e_machine; /* Architecture */
+ Elf32_Word e_version; /* Object file version */
+ Elf32_Addr e_entry; /* Entry point virtual address */
+ Elf32_Off e_phoff; /* Program header table file offset */
+ Elf32_Off e_shoff; /* Section header table file offset */
+ Elf32_Word e_flags; /* Processor-specific flags */
+ Elf32_Half e_ehsize; /* ELF header size in bytes */
+ Elf32_Half e_phentsize; /* Program header table entry size */
+ Elf32_Half e_phnum; /* Program header table entry count */
+ Elf32_Half e_shentsize; /* Section header table entry size */
+ Elf32_Half e_shnum; /* Section header table entry count */
+ Elf32_Half e_shstrndx; /* Section header string table index */
+} Elf32_Ehdr;
+
+/*
+ * ELF magic number
+ */
+#define ELFMAG "\177ELF"
+#define SELFMAG 4
+
+#define EI_CLASS 4 /* File class byte index */
+#define ELFCLASSNONE 0 /* Invalid class */
+#define ELFCLASS32 1 /* 32-bit objects */
+#define ELFCLASS64 2 /* 64-bit objects */
+
+#define EI_DATA 5 /* Data encoding byte index */
+#define ELFDATA2LSB 1 /* 2's complement, little endian */
+#define ELFDATA2MSB 2 /* 2's complement, big endian */
+
+#define EI_VERSION 6 /* File version byte index */
+#define EV_CURRENT 1 /* Current version */
+
+/*
+ * Acceptable machine type in e_machine.
+ */
+#define EM_MIPS 8 /* MIPS R3000 big-endian */
+#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
+
+/*
+ * The type of ELF file we accept.
+ */
+#define ET_EXEC 2 /* Executable file */
+
+/*
+ * Definition of a single program header structure
+ */
+typedef struct
+{
+ Elf32_Word p_type; /* Segment type */
+ Elf32_Off p_offset; /* Segment file offset */
+ Elf32_Addr p_vaddr; /* Segment virtual address */
+ Elf32_Addr p_paddr; /* Segment physical address */
+ Elf32_Word p_filesz; /* Segment size in file */
+ Elf32_Word p_memsz; /* Segment size in memory */
+ Elf32_Word p_flags; /* Segment flags */
+ Elf32_Word p_align; /* Segment alignment */
+} Elf32_Phdr;
+
+/*
+ * Legal values for p_type
+ */
+#define PT_NULL 0 /* Program header table entry unused */
+#define PT_LOAD 1 /* Loadable program segment */
+#define PT_DYNAMIC 2 /* Dynamic linking information */
+#define PT_INTERP 3 /* Program interpreter */
+#define PT_NOTE 4 /* Auxiliary information */
+#define PT_SHLIB 5 /* Reserved */
+#define PT_PHDR 6 /* Entry for header table itself */
+#define PT_NUM 7 /* Number of defined types. */
+#define PT_LOPROC 0x70000000 /* Start of processor-specific */
+#define PT_HIPROC 0x7fffffff /* End of processor-specific */
+
+typedef struct
+{
+ Elf32_Word sh_name; /* Section name (string tbl index) */
+ Elf32_Word sh_type; /* Section type */
+ Elf32_Word sh_flags; /* Section flags */
+ Elf32_Addr sh_addr; /* Section virtual addr at execution */
+ Elf32_Off sh_offset; /* Section file offset */
+ Elf32_Word sh_size; /* Section size in bytes */
+ Elf32_Word sh_link; /* Link to another section */
+ Elf32_Word sh_info; /* Additional section information */
+ Elf32_Word sh_addralign; /* Section alignment */
+ Elf32_Word sh_entsize; /* Entry size if section holds table */
+} Elf32_Shdr;
+
+typedef struct
+{
+ Elf32_Word st_name; /* Symbol name (string tbl index) */
+ Elf32_Addr st_value; /* Symbol value */
+ Elf32_Word st_size; /* Symbol size */
+ unsigned char st_info; /* Symbol type and binding */
+ unsigned char st_other; /* No defined meaning, 0 */
+ Elf32_Section st_shndx; /* Section index */
+} Elf32_Sym;
+
+/* How to extract and insert information held in the st_info field. */
+#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val) ((val) & 0xf)
+
+/* Legal values for ST_BIND subfield of st_info (symbol binding). */
+#define STB_GLOBAL 1 /* Global symbol */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type). */
+#define STT_NOTYPE 0 /* Symbol type is unspecified */
+#define STT_OBJECT 1 /* Symbol is a data object */
+#define STT_FUNC 2 /* Symbol is a code object */
+
+static unsigned int
+get_Elf32_Half(unsigned char *p)
+{
+ return p[0] | (p[1] << 8);
+}
+#define get_Elf32_Section(p) get_Elf32_Half(p)
+
+static unsigned int
+get_Elf32_Word(unsigned char *p)
+{
+ return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+#define get_Elf32_Addr(p) get_Elf32_Word(p)
+#define get_Elf32_Off(p) get_Elf32_Word(p)
+
+static void
+put_byte(p, x)
+ unsigned char *p;
+ unsigned char x;
+{
+ p[0] = x;
+}
+
+static void
+put_half(p, x)
+ unsigned char *p;
+ unsigned short x;
+{
+ p[0] = x & 0xff;
+ p[1] = (x >> 8) & 0xff;
+}
+
+static void
+put_word(p, x)
+ unsigned char *p;
+ unsigned long x;
+{
+ p[0] = x & 0xff;
+ p[1] = (x >> 8) & 0xff;
+ p[2] = (x >> 16) & 0xff;
+ p[3] = (x >> 24) & 0xff;
+}
+
+/*
+ * Swap a program header in.
+ */
+static void
+get_elfph(p, ph)
+ unsigned char *p;
+ Elf32_Phdr *ph;
+{
+ ph->p_type = get_Elf32_Word(p);
+ ph->p_offset = get_Elf32_Off(p + 4);
+ ph->p_vaddr = get_Elf32_Addr(p + 8);
+ ph->p_paddr = get_Elf32_Addr(p + 12);
+ ph->p_filesz = get_Elf32_Word(p + 16);
+ ph->p_memsz = get_Elf32_Word(p + 20);
+ ph->p_flags = get_Elf32_Word(p + 24);
+ ph->p_align = get_Elf32_Word(p + 28);
+}
+
+/*
+ * Swap a section header in.
+ */
+static void
+get_elfsh(p, sh)
+ unsigned char *p;
+ Elf32_Shdr *sh;
+{
+ sh->sh_name = get_Elf32_Word(p);
+ sh->sh_type = get_Elf32_Word(p + 4);
+ sh->sh_flags = get_Elf32_Word(p + 8);
+ sh->sh_addr = get_Elf32_Addr(p + 12);
+ sh->sh_offset = get_Elf32_Off(p + 16);
+ sh->sh_size = get_Elf32_Word(p + 20);
+ sh->sh_link = get_Elf32_Word(p + 24);
+ sh->sh_info = get_Elf32_Word(p + 28);
+ sh->sh_addralign = get_Elf32_Word(p + 32);
+ sh->sh_entsize = get_Elf32_Word(p + 36);
+}
+
+/*
+ * Swap a section header in.
+ */
+static void
+get_elfsym(p, sym)
+ unsigned char *p;
+ Elf32_Sym *sym;
+{
+ sym->st_name = get_Elf32_Word(p);
+ sym->st_value = get_Elf32_Addr(p + 4);
+ sym->st_size = get_Elf32_Word(p + 8);
+ sym->st_info = *(p + 12);
+ sym->st_other = *(p + 13);
+ sym->st_shndx = get_Elf32_Section(p + 14);
+}
+
+/*
+ * The a.out magic number
+ */
+#define OMAGIC 0407 /* Code indicating object file or impure executable. */
+#define M_MIPS1 151 /* MIPS R3000/R3000 binary */
+#define M_MIPS2 152 /* MIPS R6000/R4000 binary */
+
+/*
+ * Compute and return an a.out magic number.
+ */
+#define AOUT_INFO(magic, type, flags) \
+ (((magic) & 0xffff) | \
+ (((int)(type) & 0xff) << 16) | \
+ (((flags) & 0xff) << 24))
+
+/*
+ * a.out symbols
+ */
+#define N_UNDF 0
+#define N_ABS 2
+#define N_TEXT 4
+#define N_DATA 6
+#define N_BSS 8
+#define N_FN 15
+#define N_EXT 1
+
+#define min(x,y) (((x)<(y))?(x):(y))
+
+static void
+do_read(fd, buf, size)
+ int fd;
+ char *buf;
+ ssize_t size;
+{
+ ssize_t rd;
+
+ while(size != 0) {
+ rd = read(fd, buf, size);
+ if (rd == -1) {
+ perror("Can't read from file.");
+ exit(1);
+ }
+ size -= rd;
+ }
+}
+
+static void
+writepad(fd, size)
+ int fd;
+ size_t size;
+{
+ static void *zeropage = NULL;
+ ssize_t written;
+
+ if (zeropage == NULL) {
+ zeropage = malloc(4096);
+ if (zeropage == NULL) {
+ fprintf(stderr, "Couldn't allocate zero buffer.\n");
+ exit(1);
+ }
+ memset(zeropage, '\0', 4096);
+ }
+ while(size != 0) {
+ written = write(fd, zeropage, min(4096, size));
+ if (written == -1) {
+ perror("Can't write to boot image");
+ exit(1);
+ }
+ size -= written;
+ }
+}
+
+static void
+do_write(fd, buf, size)
+ int fd;
+ char *buf;
+ ssize_t size;
+{
+ ssize_t written;
+
+ while(size != 0) {
+ written = write(fd, buf, size);
+ if (written == -1) {
+ perror("Can't write to boot image");
+ exit(1);
+ }
+ size -= written;
+ }
+}
+
+static int
+usage(program_name)
+ char *program_name;
+{
+ fprintf(stderr, "Usage: %s infile outfile\n", program_name);
+ exit(0);
+}
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char *infile, *outfile;
+ struct stat ifstat;
+ off_t ifsize;
+ void *image;
+ int ifd, ofd, i, symtabix, strtabix;
+ Elf32_Ehdr eh;
+ Elf32_Phdr *ph;
+ Elf32_Shdr *sh;
+ unsigned long vaddr, entry, bss, kernel_entry, kernel_end;
+ unsigned char ahdr[32];
+ Elf32_Sym sym;
+ int symnum;
+ char *symname;
+
+ /*
+ * Verify some basic assuptions about type sizes made in this code
+ */
+ if (sizeof(Elf32_Half) != 2) {
+ fprintf(stderr, "Fix mkboot: sizeof(Elf32_Half) != 2\n");
+ exit(1);
+ }
+ if (sizeof(Elf32_Word) != 4) {
+ fprintf(stderr, "Fix mkboot: sizeof(Elf32_Word) != 4\n");
+ exit(1);
+ }
+ if (sizeof(Elf32_Addr) != 4) {
+ fprintf(stderr, "Fix mkboot: sizeof(Elf32_Addr) != 4\n");
+ exit(1);
+ }
+
+ if (argc != 3)
+ usage(argv[0]);
+
+ infile = argv[1];
+ outfile = argv[2];
+
+ if (stat(infile, &ifstat) < 0) {
+ perror("Can't stat kernel image.");
+ exit(1);
+ }
+
+ if (!S_ISREG(ifstat.st_mode)) {
+ fprintf(stderr, "Input file isn't a regular file.\n");
+ exit(1);
+ }
+ ifsize = ifstat.st_size;
+
+ image = malloc((size_t)ifsize);
+ if (image == NULL) {
+ fprintf(stderr, "Can't allocate memory to read file\n");
+ exit(1);
+ }
+
+ /*
+ * Read the entire input file in.
+ */
+ ifd = open(infile, O_RDONLY);
+ if(ifd == 0) {
+ fprintf(stderr, "Can't open input file\n");
+ exit(1);
+ }
+ do_read(ifd, image, ifsize);
+ close(ifd);
+
+ /*
+ * Now swap the ELF header in. This is ugly but we the file
+ * we're reading might have different type sizes, byteorder
+ * or alignment than the host.
+ */
+ memcpy(eh.e_ident, image, sizeof(eh.e_ident));
+ if(memcmp(eh.e_ident, ELFMAG, SELFMAG)) {
+ fprintf(stderr, "Input file isn't a ELF file\n");
+ exit(1);
+ }
+ if(eh.e_ident[EI_CLASS] != ELFCLASS32) {
+ fprintf(stderr, "Input file isn't a 32 bit ELF file\n");
+ exit(1);
+ }
+ if(eh.e_ident[EI_DATA] != ELFDATA2LSB) {
+ fprintf(stderr, "Input file isn't a little endian ELF file\n");
+ exit(1);
+ }
+ if(eh.e_ident[EI_VERSION] != EV_CURRENT) {
+ fprintf(stderr, "Input file isn't a version %d ELF file\n",
+ EV_CURRENT);
+ exit(1);
+ }
+
+ /*
+ * Ok, so far the file looks ok. Now swap the rest of the header in
+ * and do some more paranoia checks.
+ */
+ eh.e_type = get_Elf32_Half(image + 16);
+ eh.e_machine = get_Elf32_Half(image + 18);
+ eh.e_version = get_Elf32_Word(image + 20);
+ eh.e_entry = get_Elf32_Addr(image + 24);
+ eh.e_phoff = get_Elf32_Off(image + 28);
+ eh.e_shoff = get_Elf32_Off(image + 32);
+ eh.e_flags = get_Elf32_Word(image + 36);
+ eh.e_ehsize = get_Elf32_Half(image + 40);
+ eh.e_phentsize = get_Elf32_Half(image + 42);
+ eh.e_phnum = get_Elf32_Half(image + 44);
+ eh.e_shentsize = get_Elf32_Half(image + 46);
+ eh.e_shnum = get_Elf32_Half(image + 48);
+ eh.e_shstrndx = get_Elf32_Half(image + 50);
+
+ if(eh.e_type != ET_EXEC) {
+ fprintf(stderr, "Input file isn't a executable.\n");
+ exit(1);
+ }
+ if(eh.e_machine != EM_MIPS && eh.e_machine != EM_MIPS_RS4_BE) {
+ fprintf(stderr, "Input file isn't a MIPS executable.\n");
+ exit(1);
+ }
+
+ /*
+ * Now read the program headers ...
+ */
+ ph = malloc(sizeof(Elf32_Phdr) * eh.e_phnum);
+ if (ph == NULL) {
+ fprintf(stderr, "No memory for program header table.\n");
+ exit(1);
+ }
+ for(i = 0;i < eh.e_phnum; i++)
+ get_elfph(image + eh.e_phoff + i * 32, ph + i);
+
+ /*
+ * ... and then the section headers.
+ */
+ sh = malloc(sizeof(Elf32_Shdr) * eh.e_shnum);
+ if (sh == NULL) {
+ fprintf(stderr, "No memory for section header table.\n");
+ exit(1);
+ }
+ for(i = 0;i < eh.e_shnum; i++)
+ get_elfsh(image + eh.e_shoff + (i * 40), sh + i);
+
+ /*
+ * Find the symboltable and the stringtable in the file.
+ */
+ for(i = 0;i < eh.e_shnum; i++) {
+ if (!strcmp (image + sh [eh.e_shstrndx].sh_offset + sh[i].sh_name,
+ ".symtab")) {
+ symtabix = i;
+ continue;
+ }
+ if (!strcmp (image + sh [eh.e_shstrndx].sh_offset + sh[i].sh_name,
+ ".strtab")) {
+ strtabix = i;
+ continue;
+ }
+ }
+
+ if (symtabix == -1) {
+ fprintf(stderr, "The executable doesn't have a symbol table\n");
+ exit(1);
+ }
+ if (strtabix == -1) {
+ fprintf(stderr, "The executable doesn't have a string table\n");
+ exit(1);
+ }
+
+ /*
+ * Dig for the two required symbols in the symbol table.
+ */
+ symnum = sh[symtabix].sh_size / 16;
+ for(i = 0;i < symnum;i++) {
+ get_elfsym(image + sh[symtabix].sh_offset + (i * 16), &sym);
+ symname = image + sh[strtabix].sh_offset + sym.st_name;
+ if (ELF32_ST_BIND(sym.st_info) != STB_GLOBAL)
+ continue;
+ if (ELF32_ST_TYPE(sym.st_info) != STT_NOTYPE &&
+ ELF32_ST_TYPE(sym.st_info) != STT_OBJECT &&
+ ELF32_ST_TYPE(sym.st_info) != STT_FUNC)
+ continue;
+ if (strcmp("kernel_entry", symname) == 0) {
+ kernel_entry = sym.st_value;
+ continue;
+ }
+ if (strcmp("_end", symname) == 0) {
+ kernel_end = sym.st_value;
+ continue;
+ }
+ }
+
+#ifdef VERBOSE
+ /*
+ * And print what we will be loaded into memory.
+ */
+ for(i = 0;i < eh.e_phnum; i++) {
+ if (ph[i].p_type != PT_LOAD) {
+ continue;
+ }
+ printf(" Offset: %08lx\n", ph[i].p_offset);
+ printf(" file size: %08lx\n", ph[i].p_filesz);
+ printf(" mem size: %08lx\n", ph[i].p_memsz);
+ printf(" Loading: %08lx - %08lx\n",
+ ph[i].p_vaddr, ph[i].p_vaddr + ph[i].p_filesz);
+ printf(" Zero mapping: %08lx - %08lx\n",
+ ph[i].p_vaddr + ph[i].p_filesz,
+ ph[i].p_vaddr + ph[i].p_memsz);
+ }
+#endif
+
+ /*
+ * Time to open the outputfile.
+ */
+ ofd = open(outfile, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+ if (ofd == -1) {
+ perror("Can't open boot image for output.");
+ exit(1);
+ }
+
+ /*
+ * First compute the layout of the file. We need to do this
+ * first because we can't seek back to the beginning due to the
+ * broken Seek() call in the Magnum firmware.
+ */
+ entry = vaddr = 0xffffffff;
+ bss = 0;
+ for(i = 0;i < eh.e_phnum; i++) {
+ if (ph[i].p_type != PT_LOAD)
+ continue;
+ if (vaddr == 0xffffffff)
+ entry = vaddr = ph[i].p_vaddr;
+ vaddr = ph[i].p_vaddr + ph[i].p_filesz;
+ bss = ph[i].p_memsz - ph[i].p_filesz;
+ }
+
+ /*
+ * In the next step we construct the boot image. The boot file
+ * looks essentially like a dump of the loaded kernel with a
+ * minimal header. Because Milo supports already a.out image
+ * we simply dump the image in an a.out image ... First let's
+ * write the header.
+ */
+
+ /*
+ * Create and write the a.out header.
+ */
+ put_word(ahdr, AOUT_INFO(OMAGIC, M_MIPS1, 0));
+ put_word(ahdr + 4, vaddr - entry); /* text size */
+ put_word(ahdr + 8, 0); /* data size */
+ put_word(ahdr + 12, bss); /* bss size */
+ put_word(ahdr + 16, 2 * 12); /* size of symbol table */
+// put_word(ahdr + 16, 0); /* size of symbol table */
+ put_word(ahdr + 20, entry); /* base address */
+ put_word(ahdr + 24, 0); /* size of text relocations */
+ put_word(ahdr + 28, 0); /* size of data relocations */
+ do_write(ofd, ahdr, 32);
+
+ /*
+ * Write text and data segment combined into the a.out text segment
+ * and a zero length data segment into the file.
+ */
+ vaddr = 0xffffffff;
+ bss = 0;
+ for(i = 0;i < eh.e_phnum; i++) {
+ if (ph[i].p_type != PT_LOAD)
+ continue;
+ if (vaddr == 0xffffffff)
+ vaddr = ph[i].p_vaddr;
+ writepad(ofd, ph[i].p_vaddr - vaddr); /* Write zero pad */
+ do_write(ofd, image + ph[i].p_offset, ph[i].p_filesz);
+ vaddr = ph[i].p_vaddr + ph[i].p_filesz;
+ bss = ph[i].p_memsz - ph[i].p_filesz;
+ }
+
+ /*
+ * Now write the symbol table. It has only two symbols,
+ * kernel_entry and _end which we need for booting.
+ */
+ put_word(ahdr , 4); /* n_un.n_strx */
+ put_byte(ahdr + 4, N_TEXT | N_EXT); /* n_type */
+ put_byte(ahdr + 5, 0); /* n_other */
+ put_half(ahdr + 6, 0); /* n_desc */
+ put_word(ahdr + 8, kernel_entry); /* n_value */
+ do_write(ofd, ahdr, 12);
+
+ put_word(ahdr , 4 + 13); /* n_un.n_strx */
+ put_byte(ahdr + 4, N_ABS | N_EXT); /* n_type */
+ put_byte(ahdr + 5, 0); /* n_other */
+ put_half(ahdr + 6, 0); /* n_desc */
+ put_word(ahdr + 8, kernel_end); /* n_value */
+ do_write(ofd, ahdr, 12);
+
+ /*
+ * Now write stringtable size and the strings.
+ */
+ put_word(ahdr, 4 + 20);
+ do_write(ofd, ahdr, 4);
+ do_write(ofd, "kernel_entry\0_end\0\0", 20);
+
+ /*
+ * That's is all ...
+ */
+ close(ofd);
+
+#ifdef VERBOSE
+ printf("Entry: %08lx\n", entry);
+ printf("Dumped image %08lx - %08lx\n", 0x80000000, vaddr);
+ printf("Extra bss at end: %08lx\n", bss);
+#endif
+
+ return 0;
+}
diff --git a/arch/mips/config.in b/arch/mips/config.in
index 6ecc5e698..3dd4c00c0 100644
--- a/arch/mips/config.in
+++ b/arch/mips/config.in
@@ -2,313 +2,173 @@
# For a description of the syntax of this configuration file,
# see the Configure script.
#
+mainmenu_name "Linux Kernel Configuration"
-comment 'Machine setup'
+mainmenu_option next_comment
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
-bool 'Support for Acer PICA 1 chipset' CONFIG_ACER_PICA_61 y
-bool 'Support for DECstation' CONFIG_DECSTATION n
-bool 'Support for Deskstation RPC44' CONFIG_DESKSTATION_RPC44 n
-bool 'Support for Deskstation Tyne' CONFIG_DESKSTATION_TYNE n
-bool 'Support for Mips Magnum 3000' CONFIG_MIPS_MAGNUM_3000 n
-bool 'Support for Mips Magnum 4000' CONFIG_MIPS_MAGNUM_4000 y
-if [ "$CONFIG_ACER_PICA_61" = "y" -o \
- "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \
- "$CONFIG_OLIVETTI_M700" = "y" ]; then
- echo "#define CONFIG_MIPS_JAZZ" >> $CONFIG_H
- echo "CONFIG_MIPS_JAZZ=y" >> $CONFIG
- CONFIG_MIPS_JAZZ=y
-fi
-
-comment 'CPU selection'
+mainmenu_option next_comment
+comment 'Machine selection'
-bool 'Generate code for R3000' CONFIG_CPU_R3000 n
-#bool 'Generate code for R6000' CONFIG_CPU_R6000 n
-bool 'Generate code for R4x00' CONFIG_CPU_R4X00 y
-bool 'Generate code for R4600' CONFIG_CPU_R4600 n
-bool 'Generate code for R8000' CONFIG_CPU_R8000 n
-bool 'Generate code for R10000' CONFIG_CPU_R10000 n
-bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN y
-bool 'Compile the kernel into the ELF object format' CONFIG_MIPS_ELF n
-if [ "$CONFIG_MIPS_ELF" = "y" ]; then
- bool 'Is your normal Linux/MIPS compiler the ELF compiler' CONFIG_ELF_COMPILER n
+bool 'Support for Acer PICA 1 chipset' CONFIG_ACER_PICA_61
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ bool 'Support for ACN MIPS Board' CONFIG_ACN_MIPS_BOARD
fi
-
-comment 'General setup'
-
-bool 'Normal floppy disk support' CONFIG_BLK_DEV_FD y
-bool 'Normal (MFM/RLL) disk and IDE disk/cdrom support' CONFIG_ST506 n
-if [ "$CONFIG_ST506" = "y" ]; then
- comment 'Please see block/drivers/README.ide for help/info on IDE drives'
- bool ' Use old (reliable) disk-only driver for primary i/f' CONFIG_BLK_DEV_HD y
- if [ "$CONFIG_BLK_DEV_HD" = "y" ]; then
- bool ' Include new IDE driver for secondary i/f support' CONFIG_BLK_DEV_IDE n
- else
- bool ' Use new IDE driver for primary/secondary i/f' CONFIG_BLK_DEV_IDE n
- fi
- if [ "$CONFIG_BLK_DEV_IDE" = "y" ]; then
- bool ' Include support for IDE CDROM (ATAPI)' CONFIG_BLK_DEV_IDECD n
- fi
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ bool 'Support for DECstation' CONFIG_MIPS_DECSTATION
fi
-
-bool 'XT harddisk support' CONFIG_BLK_DEV_XD n
-bool 'Networking support' CONFIG_NET y
-bool 'System V IPC' CONFIG_SYSVIPC n
-bool 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF n
-
-if [ "$CONFIG_NET" = "y" ]; then
-comment 'Networking options'
-bool 'TCP/IP networking' CONFIG_INET y
-if [ "$CONFIG_INET" = "y" ]; then
-bool 'IP: forwarding/gatewaying' CONFIG_IP_FORWARD n
-bool 'IP: multicasting' CONFIG_IP_MULTICAST n
-bool 'IP: firewalling' CONFIG_IP_FIREWALL n
-bool 'IP: accounting' CONFIG_IP_ACCT n
-bool 'IP: tunneling' CONFIG_NET_IPIP n
-if [ "$CONFIG_IP_FORWARD" = "y" -a "$CONFIG_IP_FIREWALL" = "y" ]; then
- bool 'IP: firewall packet logging' CONFIG_IP_FIREWALL_VERBOSE y
- bool 'IP: masquerading (ALPHA)' CONFIG_IP_MASQUERADE n
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ bool 'Support for Deskstation RPC44' CONFIG_DESKSTATION_RPC44
+ bool 'Support for Deskstation Tyne' CONFIG_DESKSTATION_TYNE
+ bool 'Support for Mips Magnum 3000' CONFIG_MIPS_MAGNUM_3000
+fi
+bool 'Support for Mips Magnum 4000' CONFIG_MIPS_MAGNUM_4000
+bool 'Support for Olivetti M700-10' CONFIG_OLIVETTI_M700
+if [ "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \
+ "$CONFIG_OLIVETTI_M700" = "y" ]; then
+ define_bool CONFIG_VIDEO_G364 y
fi
-comment '(it is safe to leave these untouched)'
-bool 'IP: PC/TCP compatibility mode' CONFIG_INET_PCTCP n
-bool 'IP: Reverse ARP' CONFIG_INET_RARP n
-bool 'IP: Assume subnets are local' CONFIG_INET_SNARL y
-bool 'IP: Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF n
-bool 'IP: Drop source routed frames' CONFIG_IP_NOSR y
+bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI
+if [ "$CONFIG_DESKSTATION_RPC44" = "y" -o \
+ "$CONFIG_DESKSTATION_TYNE" = "y" ]; then
+ define_bool CONFIG_MIPS_ARC y
fi
-bool 'The IPX protocol' CONFIG_IPX n
-bool 'Appletalk DDP' CONFIG_ATALK n
-bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25 n
-if [ "$CONFIG_AX25" = "y" ]; then
- bool 'Amateur Radio NET/ROM' CONFIG_NETROM n
+if [ "$CONFIG_ACER_PICA_61" = "y" -o \
+ "$CONFIG_OLIVETTI_M700" = "y" -o \
+ "$CONFIG_MIPS_MAGNUM_4000" = "y" ]; then
+ define_bool CONFIG_MIPS_JAZZ y
fi
+if [ "$CONFIG_ACN_MIPS_BOARD" = "y" ]; then
+ define_bool CONFIG_SERIAL_ONLY_CONSOLE y
+ define_bool CONFIG_NO_SWAPPER y
+ define_bool CONFIG_CUSTOM_UART y
+ define_bool CONFIG_CUSTOM_TIMER y
fi
+endmenu
-comment 'SCSI support'
-
-bool 'SCSI support?' CONFIG_SCSI n
-
-if [ "$CONFIG_SCSI" = "n" ]; then
-
-comment 'Skipping SCSI configuration options...'
-
-else
-
-comment 'SCSI support type (disk, tape, CDrom)'
-
-bool 'SCSI disk support' CONFIG_BLK_DEV_SD y
-bool 'SCSI tape support' CONFIG_CHR_DEV_ST y
-bool 'SCSI CDROM support' CONFIG_BLK_DEV_SR y
-bool 'SCSI generic support' CONFIG_CHR_DEV_SG n
-
-comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
-
-bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN n
-
-comment 'SCSI low-level drivers'
+mainmenu_option next_comment
+comment 'CPU selection'
-bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X y
-bool 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 n
-bool 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 y
-bool 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC n
-bool 'EATA-DMA (DPT,NEC&ATT for ISA,EISA,PCI) support' CONFIG_SCSI_EATA_DMA n
-bool 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F n
-bool 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN n
-bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 n
-if [ "$CONFIG_PCI" = "y" ]; then
- bool 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx n
+choice 'CPU type' \
+ "R3000 CONFIG_CPU_R3000 \
+ R6000 CONFIG_CPU_R6000 \
+ R4x00 CONFIG_CPU_R4X00 \
+ R8000 CONFIG_CPU_R8000 \
+ R10000 CONFIG_CPU_R10000" R4x00
+if [ "$CONFIG_CPU_R3000" = "y" -o \
+ "$CONFIG_CPU_R6000" = "y" -o \
+ "$CONFIG_CPU_R4X00" = "y" -o \
+ "$CONFIG_CPU_R8000" = "y" ]; then
+ define_bool CONFIG_TLB_SHUTDOWN y
fi
-bool 'Always IN2000 SCSI support (test release)' CONFIG_SCSI_IN2000 n
-bool 'PAS16 SCSI support' CONFIG_SCSI_PAS16 n
-bool 'QLOGIC SCSI support' CONFIG_SCSI_QLOGIC n
-bool 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE n
-bool 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 n
-bool 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR n
-bool '7000FASST SCSI support' CONFIG_SCSI_7000FASST n
-#bool 'EATA ISA/EISA (DPT PM2011/021/012/022/122/322) support' CONFIG_SCSI_EATA n
-#bool 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG n
+if [ "$CONFIG_CPU_R4X00" = "y" ]; then
+ bool "Optimize for R4600 only" CONFIG_OPTIMIZE_R4600
fi
+endmenu
+mainmenu_option next_comment
+comment 'General setup'
+define_bool CONFIG_BINFMT_ELF y
+define_bool CONFIG_BINFMT_AOUT n
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
+fi
+if [ "$CONFIG_MIPS_DECSTATION" = "y" ]; then
+ bool 'Compile the kernel into the ECOFF object format' CONFIG_ECOFF_KERNEL
+ comment 'Assuming little endian code required.'
+ define_bool CONFIG_CPU_LITTLE_ENDIAN y
+else
+ define_bool CONFIG_ELF_KERNEL y
+ bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
+fi
+bool 'Networking support' CONFIG_NET
+bool 'Limit memory to low 16MB' CONFIG_MAX_16M
+bool 'PCI bios support' CONFIG_PCI
+#if [ "$CONFIG_PCI" = "y" ]; then
+# if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+# bool ' PCI bridge optimization (experimental)' CONFIG_PCI_OPTIMIZE
+# fi
+#fi
+bool 'System V IPC' CONFIG_SYSVIPC
+endmenu
+
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+ bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
+ bool 'Kernel daemon support (e.g. autoload of modules)' CONFIG_KERNELD
+fi
+endmenu
+
+source drivers/block/Config.in
if [ "$CONFIG_NET" = "y" ]; then
-
-comment 'Network device support'
-
-bool 'Network device support?' CONFIG_NETDEVICES y
-if [ "$CONFIG_NETDEVICES" = "n" ]; then
-
-comment 'Skipping network driver configuration options...'
-
-else
-bool 'Dummy net driver support' CONFIG_DUMMY y
-bool 'SLIP (serial line) support' CONFIG_SLIP n
-if [ "$CONFIG_SLIP" = "y" ]; then
- bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED y
- bool ' 16 channels instead of 4' SL_SLIP_LOTS n
-fi
-bool 'PPP (point-to-point) support' CONFIG_PPP n
-if [ "$CONFIG_PPP" = "y" ]; then
- bool ' 16 channels instead of 4' CONFIG_PPP_LOTS n
-fi
-if [ "$CONFIG_AX25" = "y" ]; then
- bool 'Z8530 SCC kiss emulation driver for AX.25' CONFIG_SCC y
-fi
-bool 'PLIP (parallel port) support' CONFIG_PLIP n
-bool 'EQL (serial line load balancing) support' CONFIG_EQUALIZER n
-bool 'Load balancing support (experimental)' CONFIG_SLAVE_BALANCING n
-bool 'Do you want to be offered ALPHA test drivers' CONFIG_NET_ALPHA n
-bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC n
-if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then
- bool 'WD80*3 support' CONFIG_WD80x3 n
- bool 'SMC Ultra support' CONFIG_ULTRA n
-fi
-bool 'AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE n
-bool '3COM cards' CONFIG_NET_VENDOR_3COM n
-if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then
- bool '3c501 support' CONFIG_EL1 n
- bool '3c503 support' CONFIG_EL2 n
- if [ "$CONFIG_NET_ALPHA" = "y" ]; then
- bool '3c505 support' CONFIG_ELPLUS n
- bool '3c507 support' CONFIG_EL16 n
- fi
- bool '3c509/3c579 support' CONFIG_EL3 n
-fi
-bool 'Other ISA cards' CONFIG_NET_ISA n
-if [ "$CONFIG_NET_ISA" = "y" ]; then
- bool 'Arcnet support' CONFIG_ARCNET n
- bool 'Cabletron E21xx support' CONFIG_E2100 n
- bool 'DEPCA support' CONFIG_DEPCA n
- bool 'EtherWorks 3 support' CONFIG_EWRK3 n
- if [ "$CONFIG_NET_ALPHA" = "y" ]; then
- bool 'AT1700 support' CONFIG_AT1700 n
-# bool 'EtherExpressPro support' CONFIG_EEXPRESS_PRO n
- bool 'EtherExpress support' CONFIG_EEXPRESS n
- bool 'NI5210 support' CONFIG_NI52 n
- bool 'NI6510 support' CONFIG_NI65 n
- bool 'WaveLAN support' CONFIG_WAVELAN n
- fi
- bool 'HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS n
- bool 'HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN n
- bool 'NE2000/NE1000 support' CONFIG_NE2000 y
- if [ "$CONFIG_AX25" = "y" ]; then
- bool 'Ottawa PI and PI/2 support' CONFIG_PI y
- fi
- bool 'SK_G16 support' CONFIG_SK_G16 n
-fi
-bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA n
-if [ "$CONFIG_NET_EISA" = "y" ]; then
- if [ "$CONFIG_NET_ALPHA" = "y" ]; then
- bool 'Ansel Communications EISA 3200 support' CONFIG_AC3200 n
- fi
- bool 'Apricot Xen-II on board ethernet' CONFIG_APRICOT n
-# bool 'DEC 21040 PCI support' CONFIG_DEC_ELCP n
-# bool 'LPL T100V 100Mbs support' CONFIG_LPL_T100 n
-# bool 'PCnet32 (32 bit VLB and PCI LANCE) support' CONFIG_PCNET32 n
-# bool 'Zenith Z-Note support' CONFIG_ZNET n
+ source net/Config.in
fi
-if [ "$CONFIG_MIPS_JAZZ" = "y" ]; then
- bool 'MIPS JAZZ onboard SONIC ethernet support' CONFIG_MIPS_JAZZ_SONIC y
-fi
+mainmenu_option next_comment
+comment 'SCSI support'
-bool 'Pocket and portable adaptors' CONFIG_NET_POCKET n
-if [ "$CONFIG_NET_POCKET" = "y" ]; then
- bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP n
- bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 n
- bool 'D-Link DE620 pocket adaptor support' CONFIG_DE620 n
-# bool 'Silicom pocket adaptor support' CONFIG_SILICOM_PEA n
-# bool 'WaveLAN PCMCIA support' CONFIG_WaveLAN n
-# bool '3 Com 3c589 PCMCIA support' CONFIG_3C589 n
-fi
-bool 'Token Ring driver support' CONFIG_TR n
-if [ "$CONFIG_TR" = "y" ]; then
- bool 'IBM Tropic chipset based adaptor support' CONFIG_IBMTR y
-fi
-fi
+tristate 'SCSI support' CONFIG_SCSI
+
+if [ "$CONFIG_SCSI" != "n" ]; then
+ source drivers/scsi/Config.in
fi
+endmenu
-comment 'CD-ROM drivers'
+if [ "$CONFIG_NET" = "y" ]; then
+ mainmenu_option next_comment
+ comment 'Network device support'
-bool 'Sony CDU31A/CDU33A CDROM driver support' CONFIG_CDU31A n
-bool 'Mitsumi CDROM driver support' CONFIG_MCD n
-bool 'Matsushita/Panasonic CDROM driver support' CONFIG_SBPCD n
-if [ "$CONFIG_SBPCD" = "y" ]; then
- bool 'Matsushita/Panasonic second CDROM controller support' CONFIG_SBPCD2 n
- if [ "$CONFIG_SBPCD2" = "y" ]; then
- bool 'Matsushita/Panasonic third CDROM controller support' CONFIG_SBPCD3 n
- if [ "$CONFIG_SBPCD3" = "y" ]; then
- bool 'Matsushita/Panasonic fourth CDROM controller support' CONFIG_SBPCD4 n
- fi
+ bool 'Network device support' CONFIG_NETDEVICES
+ if [ "$CONFIG_NETDEVICES" = "y" ]; then
+ source drivers/net/Config.in
fi
+ endmenu
fi
-comment 'Filesystems'
+mainmenu_option next_comment
+comment 'ISDN subsystem'
-bool 'Standard (minix) fs support' CONFIG_MINIX_FS n
-bool 'Extended fs support' CONFIG_EXT_FS n
-bool 'Second extended fs support' CONFIG_EXT2_FS y
-bool 'xiafs filesystem support' CONFIG_XIA_FS n
-bool 'msdos fs support' CONFIG_MSDOS_FS n
-if [ "$CONFIG_MSDOS_FS" = "y" ]; then
-#bool 'umsdos: Unix like fs on top of std MSDOS FAT fs' CONFIG_UMSDOS_FS n
-comment 'Umsdos is not supported in 1.3.0: wait for 1.3.1'
-fi
-bool '/proc filesystem support' CONFIG_PROC_FS n
-if [ "$CONFIG_INET" = "y" ]; then
-bool 'NFS filesystem support' CONFIG_NFS_FS n
+tristate 'ISDN support' CONFIG_ISDN
+if [ "$CONFIG_ISDN" != "n" ]; then
+ source drivers/isdn/Config.in
fi
-if [ "$CONFIG_BLK_DEV_SR" = "y" -o "$CONFIG_CDU31A" = "y" -o "$CONFIG_MCD" = "y" -o "$CONFIG_SBPCD" = "y" -o "$CONFIG_BLK_DEV_IDECD" = "y" ]; then
- bool 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS y
-else
- bool 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS n
-fi
-bool 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS n
-bool 'System V and Coherent filesystem support' CONFIG_SYSV_FS n
+endmenu
-comment 'character devices'
+mainmenu_option next_comment
+comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
-bool 'Parallel printer support' CONFIG_PRINTER y
-bool 'Standard serial device support' CONFIG_SERIAL y
-bool 'Cyclades async mux support' CONFIG_CYCLADES n
-bool 'Logitech busmouse support' CONFIG_BUSMOUSE n
-bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE n
-if [ "$CONFIG_PSMOUSE" = "y" ]; then
-bool 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE n
+bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
+if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+ source drivers/cdrom/Config.in
fi
-bool 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE n
-bool 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE n
-
-bool 'QIC-02 tape support' CONFIG_QIC02_TAPE n
-if [ "$CONFIG_QIC02_TAPE" = "y" ]; then
-bool 'Do you want runtime configuration for QIC-02' CONFIG_QIC02_DYNCONF n
-if [ "$CONFIG_QIC02_DYNCONF" != "y" ]; then
+endmenu
-comment '>>> Edit configuration parameters in ./include/linux/tpqic02.h!'
-
-else
+source fs/Config.in
-comment '>>> Setting runtime QIC-02 configuration is done with qic02conf'
-comment '>>> Which is available from ftp://ftp.funet.fi/pub/OS/Linux/BETA/QIC-02/'
-
-fi
-fi
-
-bool 'QIC-117 tape support' CONFIG_FTAPE n
-if [ "$CONFIG_FTAPE" = "y" ]; then
-int ' number of ftape buffers' NR_FTAPE_BUFFERS 3
-fi
+source drivers/char/Config.in
+mainmenu_option next_comment
comment 'Sound'
-bool 'Sound card support' CONFIG_SOUND n
+tristate 'Sound card support' CONFIG_SOUND
+if [ "$CONFIG_SOUND" != "n" ]; then
+ source drivers/sound/Config.in
+fi
+endmenu
+mainmenu_option next_comment
comment 'Kernel hacking'
-bool 'Remote kernel debugging support' CONFIG_REMOTE_DEBUG n
-#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC n
-bool 'Kernel profiling support' CONFIG_PROFILE n
+#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
+#bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
+bool 'Kernel profiling support' CONFIG_PROFILE
if [ "$CONFIG_PROFILE" = "y" ]; then
int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
fi
-if [ "$CONFIG_SCSI" = "y" ]; then
-bool 'Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS y
-fi
+bool 'Cross compilation' CONFIG_CROSS_COMPILE
+endmenu
diff --git a/arch/mips/dec/Makefile b/arch/mips/dec/Makefile
new file mode 100644
index 000000000..92fc4a1ff
--- /dev/null
+++ b/arch/mips/dec/Makefile
@@ -0,0 +1,24 @@
+#
+# Makefile for the DECstation family specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+all: dec.o
+O_TARGET := dec.o
+O_OBJS := boot.o int-handler.o decstation.o hw-access.o setup.o
+
+boot.o: boot.S
+
+int-handler.o: int-handler.S
+
+clean:
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips/dec/boot.S b/arch/mips/dec/boot.S
new file mode 100644
index 000000000..587c43623
--- /dev/null
+++ b/arch/mips/dec/boot.S
@@ -0,0 +1,92 @@
+/*
+ * arch/mips/dec/boot.S
+ *
+ * Copyright (C) 1995, 1996 Paul M. Antoine
+ *
+ * Written by Ralf Baechle and Andreas Busse, modified for DECStation
+ * support by Paul Antoine.
+ *
+ * NOTE: There are references to R4X00 code in here, because there is an
+ * upgrade module for Personal DECStations with such a CPU!
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsconfig.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/bootinfo.h>
+
+/*
+ * dec_entry: Called by the boot PROM loader to do DECStation setup, prior
+ * to calling dec_setup() to fill in the boot_info structure.
+ *
+ * This code should also go in the boot loader for loading off
+ * floppy and HD... in addition to the tags code in dec_setup().
+ *
+ * FIXME: arrange for this code only to be linked in when building a
+ * kernel image to be booted via tftp from the boot prom??
+ */
+ .text
+ .globl dec_entry
+dec_entry:
+ /* Save the address of the REX call vector for later
+ * use in printing debug messages.
+ */
+ sw a3,pmax_rex_base
+ sw a2,rex_prom_magic
+ la a0,dec_signon
+ jal pmax_printf
+ nop
+
+ /* Now set up the bootinfo with things that
+ * should be loaded by the boot loader, except that
+ * for the moment we're booting using tftp.
+ */
+ jal dec_setup
+ nop
+/*
+ * Now we need to move exception vector handler routines that appear
+ * in head.S down to the right addresses, 'cos the DECStation loads
+ * kernels at 0x80030000... <sigh>
+ */
+
+/*
+ * First move the TLB refill code down to offset 0x000, at addr 0x80000000
+ */
+ la t0,except_vec0 # begining of exception code
+ la t1,except_vec1 # end of exception code
+ la t2,0x80000000 # where the code should live
+ lw t3,(t0) # get first word
+1: sw t3,(t2) # put it where it should go
+ addiu t0,4 # increment both pointers
+ addiu t2,4
+ lw t3,(t0) # will be in the delay slot
+ bne t0,t1,1b
+/*
+ * Now move the General Exception code down to offset 0x080 at 0x80000000
+ */
+ la t0,except_vec3 # begining of general exception code
+ la t1,end_except # end of general exception code
+ la t2,0x80000080 # where the code should live
+ lw t3,(t0) # get first word
+1: sw t3,(t2)
+ addiu t0,4
+ addiu t2,4
+ lw t3,(t0)
+ bne t0,t1,1b
+
+ la a0,dec_launch # say where we are going
+ jal pmax_printf
+ nop
+
+ la t0,mach_mem_upper # get upper memory bound
+ lw a0,(t0)
+ j kernel_entry
+ nop
+
+ .data
+ .align 2
+dec_signon: .ascii "\n\nLinux/MIPS DECStation Boot\n";
+ .asciiz "Copyright (C) Paul M. Antoine 1995, 1996 and others, 1994, 1995, 1996\n\n";
+dec_launch: .asciiz "Setup complete, launching kernel...\n";
diff --git a/arch/mips/dec/decstation.S b/arch/mips/dec/decstation.S
new file mode 100644
index 000000000..8c5f97764
--- /dev/null
+++ b/arch/mips/dec/decstation.S
@@ -0,0 +1,382 @@
+/*
+ * arch/mips/kernel/decstation.S
+ *
+ * Copyright (C) 1995, 1996 Paul M. Antoine
+ *
+ * Written by Ralf Baechle and Andreas Busse, modified for DECStation
+ * support by Paul Antoine.
+ *
+ * NOTE: There are references to R4X00 code in here, because I believe
+ * that there is an upgrade module for Personal DECStations with
+ * such CPU's!
+ *
+ * FIXME: still plenty to do in this file, as much of the code towards
+ * the end hasn't been modified to suit the DECStation's interrupts.
+ * (Paul, you need to fix this file to comply with NAPS. Won't be
+ * too hard - Ralf)
+ */
+#include <asm/asm.h>
+#include <asm/mipsconfig.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/decstation.h>
+#include <asm/stackframe.h>
+#include <asm/bootinfo.h>
+
+/*
+ * dec_entry: Called at boot in head.S to do DECStation setup, and to
+ * fill in the boot_info structure.
+ */
+ .text
+ .globl dec_entry
+dec_entry:
+ /* Save the address of the REX call vector for later
+ * use in printing debug messages.
+ */
+ sw a3,pmax_rex_base
+ la a0,dec_signon
+ jal pmax_printf
+ nop
+ /* Now set up the bootinfo structure with things that
+ * should be loaded by the boot loader, except that
+ * for the moment we're booting using tftp.
+ */
+ la t0,boot_info
+ li t1,0x40 # 64 TLB entries
+/*
+ * FIXME: Ideally, all DEC workstations should be supported, so here we
+ * should put some clevernesses to determine machine type and CPU
+ * type. Needs a hierarchy of DEC machine types. Perhaps Machine
+ * AND Model fields in bootinfo structure?
+ */
+ sw t1,OFFSET_BOOTINFO_TLB_ENTRIES(t0)
+ li t1,MACH_DECSTATION # Machine type
+ sw t1,(t0)
+ li t1,CPU_R3000A # CPU type
+ sw t1,OFFSET_BOOTINFO_CPUTYPE(t0)
+/*
+ * FIXME: the following should find the memory size from the boot PROM
+ */
+ li t1,0x80000000 # Lower memory bound
+ sw t1,OFFSET_BOOTINFO_MEMLOWER(t0)
+ li t1,0x88000000 # Upper memory bound (8MB)
+ sw t1,OFFSET_BOOTINFO_MEMUPPER(t0)
+/*
+ * FIXME: the following should determine the cache size a la the method
+ * used in MACH. For now we just guess - PMA.
+ */
+ li t1,0x100000 # 64K icache
+ sw t1,OFFSET_BOOTINFO_ICACHE_SIZE(t0)
+ li t1,0x100000 # 64K dcache
+ sw t1,OFFSET_BOOTINFO_DCACHE_SIZE(t0)
+
+/*
+ * FIXME: template for other bootinfo fields that probably need filling in...
+ *
+ li t1,0x80000000
+ sw t1,OFFSET_BOOTINFO_(t0)
+*/
+
+/*
+ * Now we need to move exception vector handler routines that appear
+ * in head.S down to the right addresses, 'cos the DECStation loads
+ * kernels at 0x80030000... <sigh>
+ */
+
+/*
+ * First move the TLB refill code down to offset 0x000, at addr 0x80000000
+ */
+ la t0,except_vec0 # begining of TLB exception code
+ la t1,except_vec1 # end of TLB exception code
+ la t2,0x80000000 # where the code should live
+ lw t3,(t0) # get first word
+1: sw t3,(t2) # put it where it should go
+ addiu t0,4 # increment both pointers
+ addiu t2,4
+ lw t3,(t0) # will be in the delay slot
+ bne t0,t1,1b
+
+/*
+ * Now move the General Exception code down to offset 0x080 at 0x80000000
+ */
+ la t0,except_vec3 # begining of general exception code
+ la t1,kernel_entry # end of general exception code
+ la t2,0x80000080 # where the code should live
+ lw t3,(t0) # get first word
+1: sw t3,(t2)
+ addiu t0,4
+ addiu t2,4
+ lw t3,(t0)
+ bne t0,t1,1b
+
+/*
+ * FIXME: Don't forget to set the gp regster... why do I need this?
+ */
+ la gp,_gp
+ la a0,dec_launch # say where we are going
+ jal pmax_printf
+ nop
+ j kernel_entry
+ nop
+
+ .data
+ .align 2
+dec_signon: .ascii "\n\nLinux/MIPS DECStation Boot\n";
+ .asciiz "Copyright (C) Paul M. Antoine 1995, 1996 and others, 1994, 1995, 1996\n\n";
+dec_launch: .asciiz "Launching kernel...\n";
+ .text
+ .set noreorder
+/*
+ * decstation_handle_int: Interrupt handler for Personal DECStation 5000/2x
+ *
+ * FIXME: this is *extremely* experimental, though it is probably o.k. for
+ * most DECStation models.
+ */
+ NESTED(decstation_handle_int, FR_SIZE, ra)
+ .set noat
+ SAVE_ALL
+ REG_S sp,FR_ORIG_REG2(sp)
+ CLI
+ .set at
+
+ /*
+ * 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
+/*
+ * FIXME: The following branch was:
+ * beqz t0,spurious_interrupt
+ *
+ * ...but the wonders of ecoff cause the gas assembler (ver 2.5.1 )
+ * to complain:
+ *
+ * "Can not represent relocation in this object file format"...
+ *
+ * hence this hack to branch foward a bit, and then jump <sigh>
+ * Perhaps a later version of gas will cope? - Paul
+ * (No, this is impossible in COFF as well as in ELF. - Ralf)
+ */
+ beqz t0,3f;
+ sll t0,16 # delay slot
+
+ /*
+ * Find irq with highest priority
+ * FIXME: This is slow
+ */
+ la t1,ll_vectors
+1: bltz t0,2f # found pending irq
+ sll t0,1
+ b 1b
+ subu t1,PTRSIZE # delay slot
+
+ /*
+ * Do the low-level stuff
+ */
+ .set reorder
+2: LOAD_L t0,(t1)
+ jr t0
+ .set noreorder
+ END(decstation_handle_int)
+
+/*
+ * FIXME: The hack mentioned above.
+ */
+3: j spurious_interrupt
+ nop
+
+/*
+ * FIXME: the rest of this is pretty suspect, as it's straight from
+ * jazz.S... and I really haven't altered it at all - Paul
+ */
+
+/*
+ * Used for keyboard driver's fake_keyboard_interrupt()
+ * (Paul, even for i386 this is no longer being used -- Ralf)
+ */
+ll_sw0: li s1,~IE_SW0
+ mfc0 t0,CP0_CAUSE
+ and t0,s1
+ mtc0 t0,CP0_CAUSE
+ PRINT("sw0 received...\n")
+ li t1,1
+ b call_real
+ li t3,PTRSIZE # delay slot, re-map to irq level 1
+
+ll_sw1: li s1,~IE_SW1
+ PANIC("Unimplemented sw1 handler")
+
+loc_no_irq: PANIC("Unimplemented loc_no_irq handler")
+loc_sound: PANIC("Unimplemented loc_sound handler")
+loc_video: PANIC("Unimplemented loc_video handler")
+loc_scsi: PANIC("Unimplemented loc_scsi handler")
+
+/*
+ * Ethernet interrupt, remapped to level 15
+ * NOTE: Due to a bug somewhere in the kernel I was not able
+ * to figure out, the PRINT() is necessary. Without this,
+ * I get a "gfp called nonatomically from interrupt 00000000".
+ * Only god knows why... Tell me if you find the reason!
+ * (You were fouled by the caches and this is the wrong file for this
+ * comment - Ralf)
+ * Andy, 6/16/95
+ */
+loc_ethernet: PANIC("Unimplemented loc_ethernet\n")
+
+/*
+ * Keyboard interrupt, remapped to level 1
+ */
+loc_keyboard: PANIC("Unimplemented loc_keyboard\n")
+
+loc_mouse: PANIC("Unimplemented loc_mouse handler")
+
+/*
+ * Serial port 1 IRQ, remapped to level 3
+ */
+loc_serial1: PANIC("Unimplemented loc_serial handler")
+
+/*
+ * Serial port 2 IRQ, remapped to level 4
+ */
+loc_serial2: PANIC("Unimplemented loc_serial handler")
+
+/*
+ * Parallel port IRQ, remapped to level 5
+ */
+loc_parallel: PANIC("Unimplemented loc_parallel handler")
+
+/*
+ * Floppy IRQ, remapped to level 6
+ */
+loc_floppy: PANIC("Unimplemented loc_floppy handler")
+
+/*
+ * Now call the real handler
+ */
+loc_call: lui s3,%hi(intr_count)
+ lw t2,%lo(intr_count)(s3)
+ la t0,IRQ_vectors # delay slot
+ addiu t2,1
+ sw t2,%lo(intr_count)(s3)
+
+ /*
+ * Temporarily disable interrupt source
+ */
+/* lhu t2,JAZZ_IO_IRQ_ENABLE
+*/
+ addu t0,t3 # make ptr to IRQ handler
+ LOAD_L t0,(t0)
+ and t2,s1 # delay slot
+/* sh t2,JAZZ_IO_IRQ_ENABLE */
+ jalr t0 # call IRQ handler
+ nor s1,zero,s1 # delay slot
+
+ /*
+ * Reenable interrupt
+ */
+/* lhu t2,JAZZ_IO_IRQ_ENABLE */
+ lw t1,%lo(intr_count)(s3) # delay slot
+ or t2,s1
+/* sh t2,JAZZ_IO_IRQ_ENABLE */
+
+ subu t1,1
+ jr v0
+ sw t1,%lo(intr_count)(s3)
+
+ll_tc3: PANIC("Unimplemented tc3 interrupt handler")
+
+ll_fpu: PANIC("Unimplemented fpu interrupt handler")
+
+ll_io_error: PANIC("Unimplemented I/O write timeout interrupt handler")
+
+ll_rtc: PANIC("Unimplemented RTC interrupt handler")
+
+/*
+ * Timer IRQ
+ * We remap the timer irq to be more similar to a IBM compatible
+ */
+ll_timer: PANIC("Timer interrupt!\n");
+/*
+ * CPU count/compare IRQ (unused)
+ */
+ll_reset: li a0,0
+ jal pmax_halt
+ li a1,0 # delay slot
+
+/*
+ * Now call the real handler
+ */
+call_real: lui s3,%hi(intr_count)
+ lw t2,%lo(intr_count)(s3)
+ la t0,IRQ_vectors # delay slot
+ addiu t2,1
+ sw t2,%lo(intr_count)(s3)
+
+ /*
+ * temporarily disable interrupt
+ */
+ mfc0 t2,CP0_STATUS
+ and t2,s1
+
+ addu t0,t3
+ LOAD_L t0,(t0)
+ mtc0 t2,CP0_STATUS # delay slot
+ jalr t0
+ nor s1,zero,s1 # delay slot
+
+ /*
+ * reenable interrupt
+ */
+ mfc0 t2,CP0_STATUS
+ or t2,s1
+ mtc0 t2,CP0_STATUS
+
+ lw t2,%lo(intr_count)(s3)
+ subu t2,1
+
+ jr v0
+ sw t2,%lo(intr_count)(s3) # delay slot
+
+/*
+ * Just for debugging... load a0 with address of the point inside the
+ * framebuffer at which you want to draw a line of 16x32 pixels.
+ * Maxine's framebuffer starts at 0xaa000000.
+ */
+ .set reorder
+ LEAF(drawline)
+ li t1,0xffffffff # set all pixels on
+ li t2,0x10 # we will write 16 words
+1: sw t1,(a0) # write the first word
+ addiu a0,a0,4 # move our framebuffer pointer
+ addiu t2,t2,-1 # one less to do
+ bnez t2,1b # finished?
+ jr ra
+ END(drawline)
+
+/*
+ * FIXME: I have begun to alter this table to reflect Personal DECStation
+ * (i.e. Maxine) interrupts... Paul.
+ */
+ .data
+ PTR ll_sw0 # SW0
+ PTR ll_sw1 # SW1
+ PTR ll_timer # Periodic interrupt
+ PTR ll_rtc # RTC periodic interrupt
+ PTR ll_io_error # Timeout on I/O writes
+ PTR ll_tc3 # TC slot 3, motherboard
+ PTR ll_reset # Halt keycode (CTRL+ALT+ENTER)
+ll_vectors: PTR ll_fpu # FPU
+
+local_vector: PTR loc_no_irq
+ PTR loc_parallel
+ PTR loc_floppy
+ PTR loc_sound
+ PTR loc_video
+ PTR loc_ethernet
+ PTR loc_scsi
+ PTR loc_keyboard
+ PTR loc_mouse
+ PTR loc_serial1
+ PTR loc_serial2
diff --git a/arch/mips/dec/decstation.c b/arch/mips/dec/decstation.c
new file mode 100644
index 000000000..f52a1510b
--- /dev/null
+++ b/arch/mips/dec/decstation.c
@@ -0,0 +1,201 @@
+/*
+ * arch/mips/dec/decstation.c
+ *
+ * Copyright (C) 1996 Paul M. Antoine
+ *
+ * Written by Paul Antoine.
+ *
+ * FIXME: still plenty to do in this file, as we don't yet fully fill
+ * the boot info structure with DEC-specific tags. Also still
+ * too specific to the Person Decstattion 5000/2x!!
+ */
+
+#include <asm/segment.h>
+#include <asm/dec/decstation.h>
+#include <asm/dec/maxine.h> /* FIXME: what about other decstations? */
+#include <asm/bootinfo.h>
+
+/*
+ * dec_setup: Called at boot from dec_entry() in boot.S to do
+ * DECStation-specific setup, and to fill in the kernel argument
+ * tags.
+ *
+ * FIXME: I'm not sure all DEC workstations are correctly supported. This
+ * code may not need to be here when booting off floppy or HD??
+ */
+
+unsigned long mach_mem_upper = 0;
+unsigned long mach_mem_lower = 0;
+unsigned long mips_dcache_size = 0;
+unsigned long mips_icache_size = 0;
+unsigned long rex_prom_magic; /* from boot.S */
+unsigned long dec_get_memory_size(void);
+
+void dec_setup(void)
+{
+ unsigned long int mem_mask = 0;
+ unsigned long tag_data_dummy, dec_sysid;
+ unsigned char dec_cpunum, dec_systype, dec_firmrev, dec_etc;
+ extern const char *linux_banner;
+
+ pmax_printf("%s\n", linux_banner);
+ /* First we need the memory upper bound before we can add tag entries... */
+ mach_mem_lower = 0x80000000L;
+ mach_mem_upper = mach_mem_lower + dec_get_memory_size();
+
+ /* First tag is always memory upper limit, right Stoned?? */
+ (void)bi_TagAdd(tag_memupper, ULONGSIZE, &mach_mem_upper);
+
+ /* We're obviously one of the DEC machines */
+ tag_data_dummy = MACH_GROUP_DEC;
+ (void)bi_TagAdd(tag_machgroup, ULONGSIZE, &tag_data_dummy);
+
+ /* Now let's try to figure out what type of DECStation we are */
+ pmax_printf("System id is: ");
+ if ((dec_sysid = pmax_getsysid()) != 0)
+ pmax_printf("%x\n", dec_sysid);
+ else
+ pmax_printf("unknown\n");
+
+ dec_cpunum = (dec_sysid & 0xff000000) >> 24;
+ dec_systype = (dec_sysid & 0xff0000) >> 16;
+ dec_firmrev = (dec_sysid & 0xff00) >> 8;
+ dec_etc = dec_sysid & 0xff;
+
+ /*
+ * FIXME: for now use the PROM to determine the CPU type - should
+ * probably just get the CPU to tell us.
+ */
+ pmax_printf("System has an ");
+ switch(dec_cpunum)
+ {
+ case 0x82:
+ {
+ pmax_printf("R3000 CPU\n");
+ tag_data_dummy = CPU_R3000A;
+ break;
+ }
+ case 0x84:
+ {
+ pmax_printf("R4000 CPU\n");
+ /* FIXME: assume a plain R4000PC for now */
+ tag_data_dummy = CPU_R4000PC;
+ break;
+ }
+ default:
+ {
+ pmax_printf("unknown CPU, code is %x\n", dec_cpunum);
+ /* FIXME: assume an R2000 for now */
+ tag_data_dummy = CPU_R2000;
+ break;
+ }
+ }
+ /* Add the CPU type */
+ (void)bi_TagAdd(tag_cputype, ULONGSIZE, &tag_data_dummy);
+
+ pmax_printf("System has firmware type: ");
+ if (dec_firmrev == 2)
+ pmax_printf("TCF0\n");
+ else
+ pmax_printf("TCF1\n");
+
+ pmax_printf("This DECStation is a: ");
+ switch(dec_systype) {
+ case 1: /* DS2100/3100 Pmax */
+ pmax_printf("DS2100/3100\n");
+ tag_data_dummy = MACH_DECSTATION;
+ break;
+ case 2: /* DS5000 3max */
+ pmax_printf("DS5000\n");
+ tag_data_dummy = MACH_DECSTATION;
+ break;
+ case 3: /* DS5000/100 3min */
+ pmax_printf("DS5000/1x0\n");
+ tag_data_dummy = MACH_DECSTATION;
+ break;
+ case 7: /* Personal DS5000/2x */
+ pmax_printf("Personal DS5000/2x\n");
+ tag_data_dummy = MACH_DECSTATION;
+ break;
+ default:
+ pmax_printf("unknown, id is: %x\n", dec_systype);
+ tag_data_dummy = MACH_UNKNOWN;
+ break;
+ }
+
+ /* Add the machine type */
+ (void)bi_TagAdd(tag_machtype, ULONGSIZE, &tag_data_dummy);
+
+ /* Add the number of tlb entries */
+ tag_data_dummy = 64;
+ (void)bi_TagAdd(tag_tlb_entries, ULONGSIZE, &tag_data_dummy);
+
+ /*
+ * Add the instruction cache size
+ * FIXME: should determine this somehow
+ */
+ tag_data_dummy = 0x100000; /* set it to 64K for now */
+ (void)bi_TagAdd(tag_icache_size, ULONGSIZE, &tag_data_dummy);
+ mips_icache_size = tag_data_dummy;
+
+ /*
+ * Add the data cache size
+ * FIXME: should determine this somehow
+ */
+ tag_data_dummy = 0x100000; /* set it to 64K for now */
+ (void)bi_TagAdd(tag_dcache_size, ULONGSIZE, &tag_data_dummy);
+ mips_dcache_size = tag_data_dummy;
+
+ /* FIXME: should determine vram_base properly */
+ tag_data_dummy = 0xa8000000;
+ (void)bi_TagAdd(tag_vram_base, ULONGSIZE, &tag_data_dummy);
+
+ /* FIXME: dummy drive info tag */
+ tag_data_dummy = 0;
+ (void)bi_TagAdd(tag_drive_info, ULONGSIZE, &tag_data_dummy);
+
+ /* FIXME: do we need a dummy tag at the end? */
+ tag_data_dummy = 0;
+ (void)bi_TagAdd(tag_dummy, 0, &tag_data_dummy);
+
+ pmax_printf("Added tags\n");
+} /* dec_setup */
+
+unsigned long dec_get_memory_size()
+{
+ int i, bitmap_size;
+ unsigned long mem_size = 0;
+ struct pmax_bitmap {
+ int pagesize;
+ unsigned char bitmap[64*1024*1024 - 4];
+ } *bm;
+
+ /* some free 64k */
+ bm = (struct pmax_bitmap *)0x8002f000;
+ bitmap_size = pmax_getbitmap(bm);
+
+ pmax_printf("Page size is: %x\n", bm->pagesize);
+ pmax_printf("Bitmap size is: %d bytes\n", bitmap_size);
+
+ for (i = 0; i < bitmap_size; i++)
+ {
+ /* FIXME: very simplistically only add full sets of pages */
+ if (bm->bitmap[i] == 0xff)
+ mem_size += (8 * bm->pagesize);
+ }
+ pmax_printf("Main memory size is: %d KB\n", (mem_size / 1024));
+ return(mem_size);
+} /* dec_get_memory_size */
+
+unsigned char maxine_rtc_read_data(unsigned long addr)
+{
+ char *rtc = (char *)(PMAX_RTC_BASE);
+ return(rtc[addr * 4]);
+} /* maxine_rtc_read_data */
+
+void maxine_rtc_write_data(unsigned char data, unsigned long addr)
+{
+ char *rtc = (char *)(PMAX_RTC_BASE);
+ rtc[addr * 4] = data;
+} /* maxine_rtc_read_data */
+
diff --git a/arch/mips/dec/hw-access.c b/arch/mips/dec/hw-access.c
new file mode 100644
index 000000000..31a8aabef
--- /dev/null
+++ b/arch/mips/dec/hw-access.c
@@ -0,0 +1,26 @@
+/*
+ * DECstation specific hardware access code.
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 by Paul Antoine
+ */
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <asm/mc146818rtc.h>
+#include <asm/vector.h>
+
+asmlinkage void decstation_handle_int(void);
+extern unsigned char maxine_rtc_read_data(unsigned long);
+extern void maxine_rtc_write_data(unsigned char, unsigned long);
+
+/*
+ * FIXME: Don't have any of the goo required to access fd etc.
+ */
+struct feature decstation_feature = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,
+ maxine_rtc_read_data,
+ maxine_rtc_write_data
+};
diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S
new file mode 100644
index 000000000..6692d657b
--- /dev/null
+++ b/arch/mips/dec/int-handler.S
@@ -0,0 +1,273 @@
+/*
+ * arch/mips/dec/int-handler.S
+ *
+ * Copyright (C) 1995, 1996 Paul M. Antoine
+ *
+ * Written by Ralf Baechle and Andreas Busse, modified for DECStation
+ * support by Paul Antoine.
+ *
+ * NOTE: There are references to R4X00 code in here, because there is an
+ * upgrade module for Personal DECStations with such a CPU!
+ *
+ * FIXME: still plenty to do in this file, as much of the code hasn't been
+ * modified to suit the DECStation's interrupts.
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsconfig.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/bootinfo.h>
+
+ .text
+ .set noreorder
+/*
+ * decstation_handle_int: Interrupt handler for Personal DECStation 5000/2x
+ *
+ * FIXME: this is *extremely* experimental, though it is probably o.k. for
+ * most DECStation models.
+ */
+ NESTED(decstation_handle_int, FR_SIZE, ra)
+ .set noat
+ SAVE_ALL
+ CLI
+ .set at
+
+ /*
+ * 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
+/*
+ * FIXME: The following branch was:
+ * beqz t0,spurious_interrupt
+ *
+ * ...but the wonders of ecoff cause the gas assembler (ver 2.5.1 )
+ * to complain:
+ *
+ * "Can not represent relocation in this object file format"...
+ *
+ * hence this hack to branch foward a bit, and then jump <sigh>
+ * Perhaps a later version of gas will cope? - Paul
+ */
+ beqz t0,3f;
+ sll t0,16 # delay slot
+
+ /*
+ * Find irq with highest priority
+ * FIXME: This is slow
+ */
+ la t1,ll_vectors
+1: bltz t0,2f # found pending irq
+ sll t0,1
+ b 1b
+ subu t1,PTRSIZE # delay slot
+
+ /*
+ * Do the low-level stuff
+ */
+2: lw t0,(t1)
+ jr t0
+ nop # delay slot
+ END(decstation_handle_int)
+
+/*
+ * FIXME: The hack mentioned above.
+ */
+3: j spurious_interrupt
+ nop
+
+/*
+ * FIXME: the rest of this is pretty suspect, as it's straight from
+ * jazz.S... and I really haven't altered it at all - Paul
+ */
+
+/*
+ * Used for keyboard driver's fake_keyboard_interrupt()
+ * (Paul, even for i386 this is no longer being used -- Ralf)
+ */
+ll_sw0: li s1,~IE_SW0
+ mfc0 t0,CP0_CAUSE
+ and t0,s1
+ mtc0 t0,CP0_CAUSE
+ PRINT("sw0 received...\n")
+ li t1,1
+ b call_real
+ li t3,PTRSIZE # delay slot, re-map to irq level 1
+
+ll_sw1: li s1,~IE_SW1
+ PANIC("Unimplemented sw1 handler")
+
+loc_no_irq: PANIC("Unimplemented loc_no_irq handler")
+loc_sound: PANIC("Unimplemented loc_sound handler")
+loc_video: PANIC("Unimplemented loc_video handler")
+loc_scsi: PANIC("Unimplemented loc_scsi handler")
+
+/*
+ * Ethernet interrupt, remapped to level 15
+ * NOTE: Due to a bug somewhere in the kernel I was not able
+ * to figure out, the PRINT() is necessary. Without this,
+ * I get a "gfp called nonatomically from interrupt 00000000".
+ * Only god knows why... Tell me if you find the reason!
+ * Andy, 6/16/95
+ */
+loc_ethernet: PANIC("Unimplemented loc_ethernet\n")
+
+/*
+ * Keyboard interrupt, remapped to level 1
+ */
+loc_keyboard: PANIC("Unimplemented loc_keyboard\n")
+
+loc_mouse: PANIC("Unimplemented loc_mouse handler")
+
+/*
+ * Serial port 1 IRQ, remapped to level 3
+ */
+loc_serial1: PANIC("Unimplemented loc_serial handler")
+
+/*
+ * Serial port 2 IRQ, remapped to level 4
+ */
+loc_serial2: PANIC("Unimplemented loc_serial handler")
+
+/*
+ * Parallel port IRQ, remapped to level 5
+ */
+loc_parallel: PANIC("Unimplemented loc_parallel handler")
+
+/*
+ * Floppy IRQ, remapped to level 6
+ */
+loc_floppy: PANIC("Unimplemented loc_floppy handler")
+
+/*
+ * Now call the real handler
+ */
+loc_call: lui s3,%hi(intr_count)
+ lw t2,%lo(intr_count)(s3)
+ la t0,IRQ_vectors # delay slot
+ addiu t2,1
+ sw t2,%lo(intr_count)(s3)
+
+ /*
+ * Temporarily disable interrupt source
+ */
+/* lhu t2,JAZZ_IO_IRQ_ENABLE
+*/
+ addu t0,t3 # make ptr to IRQ handler
+ lw t0,(t0)
+ and t2,s1 # delay slot
+/* sh t2,JAZZ_IO_IRQ_ENABLE */
+ jalr t0 # call IRQ handler
+ nor s1,zero,s1 # delay slot
+
+ /*
+ * Reenable interrupt
+ */
+/* lhu t2,JAZZ_IO_IRQ_ENABLE */
+ lw t1,%lo(intr_count)(s3) # delay slot
+ or t2,s1
+/* sh t2,JAZZ_IO_IRQ_ENABLE */
+
+ subu t1,1
+ jr v0
+ sw t1,%lo(intr_count)(s3)
+
+ll_tc3: PANIC("Unimplemented tc3 interrupt handler")
+
+ll_fpu: PANIC("Unimplemented fpu interrupt handler")
+
+ll_io_error: PANIC("Unimplemented I/O write timeout interrupt handler")
+
+ll_rtc: PANIC("Unimplemented RTC interrupt handler")
+
+/*
+ * Timer IRQ
+ * We remap the timer irq to be more similar to a IBM compatible
+ */
+ll_timer: PANIC("Timer interrupt!\n");
+/*
+ * CPU count/compare IRQ (unused)
+ */
+ll_reset: li a0,0
+ jal pmax_halt
+ li a1,0 # delay slot
+
+/*
+ * Now call the real handler
+ */
+call_real: lui s3,%hi(intr_count)
+ lw t2,%lo(intr_count)(s3)
+ la t0,IRQ_vectors # delay slot
+ addiu t2,1
+ sw t2,%lo(intr_count)(s3)
+
+ /*
+ * temporarily disable interrupt
+ */
+ mfc0 t2,CP0_STATUS
+ and t2,s1
+
+ addu t0,t3
+ lw t0,(t0)
+ mtc0 t2,CP0_STATUS # delay slot
+ jalr t0
+ nor s1,zero,s1 # delay slot
+
+ /*
+ * reenable interrupt
+ */
+ mfc0 t2,CP0_STATUS
+ or t2,s1
+ mtc0 t2,CP0_STATUS
+
+ lw t2,%lo(intr_count)(s3)
+ subu t2,1
+
+ jr v0
+ sw t2,%lo(intr_count)(s3) # delay slot
+
+/*
+ * Just for debugging... load a0 with address of the point inside the
+ * framebuffer at which you want to draw a line of 16x32 pixels.
+ * Maxine's framebuffer starts at 0xaa000000.
+ */
+ .set reorder
+ LEAF(drawline)
+ li t1,0xffffffff # set all pixels on
+ li t2,0x10 # we will write 16 words
+1: sw t1,(a0) # write the first word
+ addiu a0,a0,4 # move our framebuffer pointer
+ addiu t2,t2,-1 # one less to do
+ bnez t2,1b # finished?
+ jr ra
+ END(drawline)
+
+/*
+ * FIXME: I have begun to alter this table to reflect Personal DECStation
+ * (i.e. Maxine) interrupts... Paul.
+ */
+ .data
+ PTR ll_sw0 # SW0
+ PTR ll_sw1 # SW1
+ PTR ll_timer # Periodic interrupt
+ PTR ll_rtc # RTC periodic interrupt
+ PTR ll_io_error # Timeout on I/O writes
+ PTR ll_tc3 # TC slot 3, motherboard
+ PTR ll_reset # Halt keycode (CTRL+ALT+ENTER)
+ll_vectors: PTR ll_fpu # FPU
+
+local_vector: PTR loc_no_irq
+ PTR loc_parallel
+ PTR loc_floppy
+ PTR loc_sound
+ PTR loc_video
+ PTR loc_ethernet
+ PTR loc_scsi
+ PTR loc_keyboard
+ PTR loc_mouse
+ PTR loc_serial1
+ PTR loc_serial2
diff --git a/arch/mips/dec/ld.script b/arch/mips/dec/ld.script
new file mode 100644
index 000000000..f0cf33fc4
--- /dev/null
+++ b/arch/mips/dec/ld.script
@@ -0,0 +1,47 @@
+OUTPUT_FORMAT("ecoff-littlemips")
+OUTPUT_ARCH(mips)
+ENTRY(dec_entry)
+SECTIONS
+{
+ /* This is probably a little simplistic, and is based on work by
+ * Chris Fraser of Softway Pty Ltd as used in his port of Vsta to
+ * the DECStation - Paul M. Antoine 21/1/96.
+ */
+ . = 0x80030000;
+ .text :
+ {
+ *(.text)
+ . = ALIGN(0x10);
+ _etext = .;
+ __etext = .;
+ }
+ .lit8 : {
+ *(.lit8)
+ }
+ .lit4 : {
+ *(.lit4)
+ }
+ . = ALIGN(0x1000);
+ .data :
+ {
+ *(.data .rdata .rodata)
+ _edata = .;
+ __edata = .;
+ }
+ __bss_start = ALIGN(16) + 0x8000;
+ .sbss :
+ {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss :
+ {
+ *(.bss)
+ *(COMMON)
+ _end = ALIGN(4) ;
+ __end = ALIGN(4) ;
+ }
+ .reginfo : {
+ *(.reginfo)
+ }
+}
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
new file mode 100644
index 000000000..5037fbaae
--- /dev/null
+++ b/arch/mips/dec/setup.c
@@ -0,0 +1,41 @@
+/*
+ * Setup pointers to hardware dependand routines.
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ */
+#include <asm/ptrace.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/vector.h>
+
+extern struct feature decstation_feature;
+
+static void
+dec_irq_setup(void)
+{
+ /* FIXME: should set up the clock as per above? */
+ pmax_printf("Please write the IRQ setup code for the DECStation!\n");
+}
+
+void (*board_time_init)(struct irqaction *irq);
+
+static void dec_time_init(struct irqaction *irq)
+{
+ pmax_printf("Please write the time init code for the DECStation!\n");
+}
+
+void
+decstation_setup(void)
+{
+ irq_setup = dec_irq_setup;
+ board_time_init = dec_time_init;
+ /* FIXME: Setup fd_cacheflush */
+ feature = &decstation_feature; /* FIXME: Will go away */
+}
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
new file mode 100644
index 000000000..bb3635c25
--- /dev/null
+++ b/arch/mips/defconfig
@@ -0,0 +1,241 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
+# Machine selection
+#
+CONFIG_ACER_PICA_61=y
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_OLIVETTI_M700 is not set
+CONFIG_SNI_RM200_PCI=y
+CONFIG_MIPS_JAZZ=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_R6000 is not set
+CONFIG_CPU_R4X00=y
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+CONFIG_TLB_SHUTDOWN=y
+# CONFIG_OPTIMIZE_R4600 is not set
+
+#
+# General setup
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_ELF_KERNEL=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_NET=y
+# CONFIG_MAX_16M is not set
+# CONFIG_SYSVIPC is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Floppy, IDE, and other block devices
+#
+CONFIG_BLK_DEV_FD=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_IDEDISK is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_IDE_CHIPSETS is not set
+
+#
+# Additional Block Devices
+#
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+# CONFIG_NETLINK is not set
+# CONFIG_FIREWALL is not set
+# CONFIG_NET_ALIAS is not set
+CONFIG_INET=y
+# CONFIG_IP_FORWARD is not set
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ACCT is not set
+
+#
+# (it is safe to leave these untouched)
+#
+# CONFIG_INET_PCTCP is not set
+# CONFIG_INET_RARP is not set
+# CONFIG_NO_PATH_MTU_DISCOVERY is not set
+CONFIG_IP_NOSR=y
+CONFIG_SKB_LARGE=y
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_AX25 is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DTC3280 is not set
+CONFIG_SCSI_EATA_DMA=y
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SEAGATE is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+CONFIG_LANCE=y
+CONFIG_LANCE32=y
+# CONFIG_NET_VENDOR_SMC is not set
+CONFIG_NET_ISA=y
+# CONFIG_E2100 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_EWRK3 is not set
+# CONFIG_EEXPRESS is not set
+# CONFIG_HPLAN_PLUS is not set
+# CONFIG_HPLAN is not set
+# CONFIG_HP100 is not set
+# CONFIG_NE2000 is not set
+# CONFIG_NI52 is not set
+# CONFIG_NI65 is not set
+# CONFIG_SK_G16 is not set
+# CONFIG_NET_EISA is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FDDI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_NET_RADIO is not set
+# CONFIG_SLIP is not set
+# CONFIG_TR is not set
+CONFIG_MIPS_JAZZ_SONIC=y
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_EXT_FS is not set
+# CONFIG_EXT2_FS is not set
+# CONFIG_XIA_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_UMSDOS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_RNFS_BOOTP=y
+# CONFIG_RNFS_RARP is not set
+# CONFIG_SMB_FS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_HPFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Character devices
+#
+CONFIG_SERIAL=y
+# CONFIG_DIGI is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_STALDRV is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_PRINTER is not set
+# CONFIG_MOUSE is not set
+# CONFIG_UMISC is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_FTAPE is not set
+# CONFIG_APM is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PROFILE is not set
+CONFIG_CROSS_COMPILE=y
diff --git a/arch/mips/deskstation/Makefile b/arch/mips/deskstation/Makefile
new file mode 100644
index 000000000..8e1b6bb13
--- /dev/null
+++ b/arch/mips/deskstation/Makefile
@@ -0,0 +1,22 @@
+#
+# Makefile for the Deskstation family specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+all: deskstation.o
+O_TARGET := deskstation.o
+O_OBJS := hw-access.o int-handler.o setup.o
+
+int-handler.o: int-handler.S
+
+clean:
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips/deskstation/hw-access.c b/arch/mips/deskstation/hw-access.c
new file mode 100644
index 000000000..2d79e6f77
--- /dev/null
+++ b/arch/mips/deskstation/hw-access.c
@@ -0,0 +1,198 @@
+/*
+ * Low-level hardware access stuff for Deskstation rPC44/Tyne
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ */
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <asm/bootinfo.h>
+#include <asm/cache.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mc146818rtc.h>
+#include <asm/vector.h>
+
+extern int FLOPPY_IRQ;
+extern int FLOPPY_DMA;
+
+/*
+ * How to access the FDC's registers.
+ */
+static unsigned char
+fd_inb(unsigned int port)
+{
+ return inb_p(port);
+}
+
+static void
+fd_outb(unsigned char value, unsigned int port)
+{
+ outb_p(value, port);
+}
+
+/*
+ * How to access the floppy DMA functions.
+ */
+static void
+fd_enable_dma(void)
+{
+ enable_dma(FLOPPY_DMA);
+}
+
+static void
+fd_disable_dma(void)
+{
+ disable_dma(FLOPPY_DMA);
+}
+
+static int
+fd_request_dma(void)
+{
+ return request_dma(FLOPPY_DMA, "floppy");
+}
+
+static void
+fd_free_dma(void)
+{
+ free_dma(FLOPPY_DMA);
+}
+
+static void
+fd_clear_dma_ff(void)
+{
+ clear_dma_ff(FLOPPY_DMA);
+}
+
+static void
+fd_set_dma_mode(char mode)
+{
+ set_dma_mode(FLOPPY_DMA, mode);
+}
+
+static void
+fd_set_dma_addr(unsigned int addr)
+{
+ set_dma_addr(FLOPPY_DMA, addr);
+}
+
+static void
+fd_set_dma_count(unsigned int count)
+{
+ set_dma_count(FLOPPY_DMA, count);
+}
+
+static int
+fd_get_dma_residue(void)
+{
+ return get_dma_residue(FLOPPY_DMA);
+}
+
+static void
+fd_enable_irq(void)
+{
+ enable_irq(FLOPPY_IRQ);
+}
+
+static void
+fd_disable_irq(void)
+{
+ disable_irq(FLOPPY_IRQ);
+}
+
+void
+deskstation_fd_cacheflush(const void *addr, size_t size)
+{
+ cacheflush(addr, size, CF_DCACHE|CF_ALL);
+}
+
+/*
+ * RTC stuff (This is a guess on how Deskstation handles this ...)
+ */
+static unsigned char
+rtc_read_data(unsigned long addr)
+{
+ outb_p(addr, RTC_PORT(0));
+ return inb_p(RTC_PORT(1));
+}
+
+static void
+rtc_write_data(unsigned char data, unsigned long addr)
+{
+ outb_p(addr, RTC_PORT(0));
+ outb_p(data, RTC_PORT(1));
+}
+
+/*
+ * KLUDGE
+ */
+static unsigned long
+vdma_alloc(unsigned long paddr, unsigned long size)
+{
+ return 0;
+}
+
+#ifdef CONFIG_DESKSTATION_TYNE
+struct feature deskstation_tyne_feature = {
+ /*
+ * How to access the floppy controller's ports
+ */
+ fd_inb,
+ fd_outb,
+ /*
+ * How to access the floppy DMA functions.
+ */
+ fd_enable_dma,
+ fd_disable_dma,
+ fd_request_dma,
+ fd_free_dma,
+ fd_clear_dma_ff,
+ fd_set_dma_mode,
+ fd_set_dma_addr,
+ fd_set_dma_count,
+ fd_get_dma_residue,
+ fd_enable_irq,
+ fd_disable_irq,
+ /*
+ * How to access the RTC functions.
+ */
+ rtc_read_data,
+ rtc_write_data
+};
+#endif
+
+#ifdef CONFIG_DESKSTATION_RPC44
+struct feature deskstation_rpc44_feature = {
+ /*
+ * How to access the floppy controller's ports
+ */
+ fd_inb,
+ fd_outb,
+ /*
+ * How to access the floppy DMA functions.
+ */
+ fd_enable_dma,
+ fd_disable_dma,
+ fd_request_dma,
+ fd_free_dma,
+ fd_clear_dma_ff,
+ fd_set_dma_mode,
+ fd_set_dma_addr,
+ fd_set_dma_count,
+ fd_get_dma_residue,
+ fd_enable_irq,
+ fd_disable_irq,
+ /*
+ * How to access the RTC functions.
+ */
+ rtc_read_data,
+ rtc_write_data
+};
+#endif
diff --git a/arch/mips/kernel/tyne.S b/arch/mips/deskstation/int-handler.S
index 912f6d414..a52df711f 100644
--- a/arch/mips/kernel/tyne.S
+++ b/arch/mips/deskstation/int-handler.S
@@ -1,114 +1,120 @@
/*
- * arch/mips/kernel/tyne.S
+ * Deskstation rPC44/Tyne specific interrupt handler code
*
- * Deskstation Tyne specific Assembler code
- *
- * Copyright (C) 1994, 1995 Waldorf Electronics
- * written by Ralf Baechle and Andreas Busse
+ * Copyright (C) 1994, 1995, 1996 by Ralf Baechle
*/
#include <asm/asm.h>
#include <asm/mipsconfig.h>
#include <asm/mipsregs.h>
+#include <asm/regdef.h>
#include <asm/stackframe.h>
-/*
- * Deskstation Tyne interrupt handler
- */
+#error "FIXME - PORT_BASE is defined to port_base which breaks this file"
+
.text
.set noreorder
.set noat
.align 5
- NESTED(deskstation_tyne_handle_int, FR_SIZE, sp)
+ NESTED(deskstation_handle_int, FR_SIZE, sp)
SAVE_ALL
+ REG_S sp,FR_ORIG_REG2(sp)
CLI
.set at
lui s0,%hi(PORT_BASE)
- li t1,0x0f
- sb t1,%lo(PORT_BASE+0x20)(s0) # poll command
- lb t1,%lo(PORT_BASE+0x20)(s0) # read result
- li s1,1
- bgtz t1,Lpoll_second
- andi t1,t1,7
+ li a0,0x0f
+ sb a0,%lo(PORT_BASE+0x20)(s0) # poll command
+ lb a0,%lo(PORT_BASE+0x20)(s0) # read result
+ bgtz a0,poll_second
+ andi a0,7
+ beq a0,2,poll_second # cascade?
+ li s1,1 # delay slot
/*
* Acknowledge first pic
*/
lb t2,%lo(PORT_BASE+0x21)(s0)
lui s4,%hi(cache_21)
lb t0,%lo(cache_21)(s4)
- sllv s1,s1,t1
- or t0,t0,s1
+ sllv s1,s1,a0
+ or t0,s1
sb t0,%lo(cache_21)(s4)
sb t0,%lo(PORT_BASE+0x21)(s0)
lui s3,%hi(intr_count)
- lw t0,%lo(intr_count)(s3)
+ lw s7,%lo(intr_count)(s3)
li t2,0x20
sb t2,%lo(PORT_BASE+0x20)(s0)
/*
* Now call the real handler
*/
la t3,IRQ_vectors
- sll t2,t1,2
- addu t3,t3,t2
- lw t3,(t3)
- addiu t0,t0,1
+ sll t2,a0,PTRLOG
+ addu t3,t2
+ LONG_L t3,(t3)
+ addiu t0,s7,1
jalr t3
- sw t0,%lo(intr_count)(s3) # delay slot
- lw t0,%lo(intr_count)(s3)
+ sw t0,%lo(intr_count)(s3)
+ sw s7,%lo(intr_count)(s3)
/*
* Unblock first pic
*/
lbu t1,%lo(PORT_BASE+0x21)(s0)
lb t1,%lo(cache_21)(s4)
- subu t0,t0,1
- sw t0,%lo(intr_count)(s3)
nor s1,zero,s1
- and t1,t1,s1
+ and t1,s1
sb t1,%lo(cache_21)(s4)
jr v0
sb t1,%lo(PORT_BASE+0x21)(s0) # delay slot
+ /*
+ * Cascade interrupt from second PIC
+ */
.align 5
-Lpoll_second: li t1,0x0f
- sb t1,%lo(PORT_BASE+0xa0)(s0) # poll command
- lb t1,%lo(PORT_BASE+0xa0)(s0) # read result
- lui s4,%hi(cache_A1)
- bgtz t1,spurious_interrupt
- andi t1,t1,7
+poll_second: li a0,0x0f
+ sb a0,%lo(PORT_BASE+0xa0)(s0) # poll command
+ lb a0,%lo(PORT_BASE+0xa0)(s0) # read result
+ bgtz a0,3f
+ andi a0,7
/*
* Acknowledge second pic
*/
lbu t2,%lo(PORT_BASE+0xa1)(s0)
+ lui s4,%hi(cache_A1)
lb t3,%lo(cache_A1)(s4)
- sllv s1,s1,t1
- or t3,t3,s1
+ sllv s1,s1,a0
+ or t3,s1
sb t3,%lo(cache_A1)(s4)
sb t3,%lo(PORT_BASE+0xa1)(s0)
li t3,0x20
sb t3,%lo(PORT_BASE+0xa0)(s0)
lui s3,%hi(intr_count)
- lw t0,%lo(intr_count)(s3)
+ lw s7,%lo(intr_count)(s3)
sb t3,%lo(PORT_BASE+0x20)(s0)
/*
* Now call the real handler
*/
- la t0,IRQ_vectors
- sll t2,t1,2
- addu t0,t0,t2
- lw t0,32(t0)
- addiu t0,t0,1
- jalr t0
- sw t0,%lo(intr_count)(s3) # delay slot
- lw t0,%lo(intr_count)(s3)
+ la t3,IRQ_vectors
+ addiu a0,8
+ sll t2,a0,PTRLOG
+ addu t3,t2
+ LONG_L t3,(t3)
+ addiu t0,s7,1
+ jalr t3
+ sw t0,%lo(intr_count)(s3) # delay slot
+ sw s7,%lo(intr_count)(s3)
/*
* Unblock second pic
*/
lb t1,%lo(PORT_BASE+0xa1)(s0)
lb t1,%lo(cache_A1)(s4)
- subu t0,t0,1
- lw t0,%lo(intr_count)(s3)
+ subu t0,1
nor s1,zero,s1
and t1,t1,s1
sb t1,%lo(cache_A1)(s4)
jr v0
sb t1,%lo(PORT_BASE+0xa1)(s0) # delay slot
- END(deskstation_tyne_handle_int)
+
+/*
+ * "Jump extender" to reach spurious_interrupt
+ */
+3: j spurious_interrupt
+ nop # delay slot
+ END(deskstation_handle_int)
diff --git a/arch/mips/deskstation/setup.c b/arch/mips/deskstation/setup.c
new file mode 100644
index 000000000..fedab9c84
--- /dev/null
+++ b/arch/mips/deskstation/setup.c
@@ -0,0 +1,141 @@
+/*
+ * Setup pointers to hardware dependand routines.
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ */
+#include <asm/ptrace.h>
+#include <linux/config.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/processor.h>
+#include <asm/vector.h>
+
+/*
+ * Initial irq handlers.
+ */
+static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+
+/*
+ * IRQ2 is cascade interrupt to second interrupt controller
+ */
+static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL};
+
+extern asmlinkage void deskstation_handle_int(void);
+extern asmlinkage void deskstation_fd_cacheflush(const void *addr, size_t size);
+extern struct feature deskstation_tyne_feature;
+extern struct feature deskstation_rpc44_feature;
+
+#ifdef CONFIG_DESKSTATION_TYNE
+unsigned long mips_dma_cache_size = 0;
+unsigned long mips_dma_cache_base = KSEG0;
+
+static void
+tyne_irq_setup(void)
+{
+ set_except_vector(0, deskstation_handle_int);
+ request_region(0x20,0x20, "pic1");
+ request_region(0xa0,0x20, "pic2");
+ setup_x86_irq(2, &irq2);
+}
+#endif
+
+#ifdef CONFIG_DESKSTATION_RPC44
+static void
+rpc44_irq_setup(void)
+{
+ /*
+ * For the moment just steal the TYNE support. In the
+ * future, we need to consider merging the two -- imp
+ */
+ set_except_vector(0, deskstation_handle_int);
+ request_region(0x20,0x20, "pic1");
+ request_region(0xa0,0x20, "pic2");
+ setup_x86_irq(2, &irq2);
+ set_cp0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1);
+}
+#endif
+
+void (*board_time_init)(struct irqaction *irq);
+
+static void deskstation_time_init(struct irqaction *irq)
+{
+ /* set the clock to 100 Hz */
+ outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
+ outb_p(LATCH & 0xff , 0x40); /* LSB */
+ outb(LATCH >> 8 , 0x40); /* MSB */
+ setup_x86_irq(0, irq);
+}
+
+void
+deskstation_setup(void)
+{
+ tag *atag;
+
+ /*
+ * We just check if a tag_screen_info can be gathered
+ * in setup_arch(), if yes we don't proceed futher...
+ */
+ atag = bi_TagFind(tag_screen_info);
+ if (!atag) {
+ /*
+ * If no, we try to find the tag_arc_displayinfo which is
+ * always created by Milo for an ARC box (for now Milo only
+ * works on ARC boxes :) -Stoned.
+ */
+ atag = bi_TagFind(tag_arcdisplayinfo);
+ if (atag) {
+ screen_info.orig_x =
+ ((mips_arc_DisplayInfo*)TAGVALPTR(atag))->cursor_x;
+ screen_info.orig_y =
+ ((mips_arc_DisplayInfo*)TAGVALPTR(atag))->cursor_y;
+ screen_info.orig_video_cols =
+ ((mips_arc_DisplayInfo*)TAGVALPTR(atag))->columns;
+ screen_info.orig_video_lines =
+ ((mips_arc_DisplayInfo*)TAGVALPTR(atag))->lines;
+ }
+ }
+
+ switch(mips_machtype) {
+#ifdef CONFIG_DESKSTATION_TYNE
+ case MACH_DESKSTATION_TYNE:
+ atag = bi_TagFind(tag_dma_cache_size);
+ memcpy(&mips_dma_cache_size, TAGVALPTR(atag), atag->size);
+
+ atag = bi_TagFind(tag_dma_cache_base);
+ memcpy(&mips_dma_cache_base, TAGVALPTR(atag), atag->size);
+
+ irq_setup = tyne_irq_setup;
+ feature = &deskstation_tyne_feature; // Will go away
+ port_base = PORT_BASE_TYNE;
+ isa_slot_offset = 0xe3000000;
+ break;
+#endif
+#ifdef CONFIG_DESKSTATION_RPC44
+ case MACH_DESKSTATION_RPC44:
+ irq_setup = rpc44_irq_setup;
+ mips_memory_upper = KSEG0 + (32 << 20); /* xxx fixme imp */
+ feature = &deskstation_rpc44_feature; // Will go away
+ port_base = PORT_BASE_RPC44;
+ isa_slot_offset = 0xa0000000;
+ break;
+#endif
+ }
+ board_time_init = deskstation_time_init;
+ fd_cacheflush = deskstation_fd_cacheflush;
+ request_region(0x00,0x20,"dma1");
+ request_region(0x40,0x20,"timer");
+ request_region(0x70,0x10,"rtc");
+
+ if (mips_machtype == MACH_DESKSTATION_RPC44)
+ EISA_bus = 1;
+}
diff --git a/arch/mips/doc/pagetables.txt b/arch/mips/doc/pagetables.txt
new file mode 100644
index 000000000..3d900a194
--- /dev/null
+++ b/arch/mips/doc/pagetables.txt
@@ -0,0 +1,87 @@
+Format and handling of Linux/MIPS pagetables
+============================================
+
+This file describes the MIPS specific parts of the Linux pagetable handling.
+
+Opposed to other architecures like i386 or m68k architecture all MIPS
+CPUs only implement the TLB itself and a small set of functions to
+maintain it as hardware. The actual maintenance of the TLB's contents
+is implemented in software only.
+
+The TLB has a relativly small number of entries. This limits the
+maximum address space that can mapped by the TLB using 4kb pages and
+without consideration of wired entries to a maximum of 512kb for the
+R1000, 384kb for the R4000/4400 and 256kb for the R2000/R3000. This
+actual size of mappable space is even smaller due to the wired entries.
+
+Especially for processes with a huge working set of pages it is therefore
+important to make the process of reloading entries into the TLB as
+efficient as possible. This means:
+
+ - Choosing a data structure that can be handled as efficient as
+ possible.
+ - The implementation of the low level pagefault handling has to be
+ implemented in a efficient way.
+
+The Linux kernel itself implements three level page tables as a tree
+structure. Linux implementations that don't need three levels of page
+tables can fold one level of the page tables so that effectivly a two
+level page table remains. The exact size and content of the entries
+is upto the implementation.
+
+Opposed to this the MIPS hardware architecture implies by the data
+provided in the c0_context/c0_xcontext registers a simple array of
+4 byte elements (for R2000/R3000/R6000) or 8 byte elements (for the
+other 64bit members of the CPU family).
+
+The page tables are mapped to the address TLBMAP (which is usually
+defined as 0xe4000000 in <asm/mipsconfig.h). The page which contains
+the root of the page table of the current process, the "page directory"
+and is therefore mapped at (TLBMAP + (TLBMAP >> (12-2))) (this is the
+value of the define TLB_ROOT which is defined as 0xe4390000). That
+way the kernel itself can access the page tables as a tree structure
+while the exception handlers can work with maxiumum efficiency accessing
+the page tables as simple array.
+
+The tlb refill handler itself is very simple. For the R4x00 family it
+has just 14 instruction, for the R4600 and derivatives it can be
+optimized to 12 instruction, even further for the R10000. This
+exception handler is very simple and fast and therefore doesn't any
+checking for errors or special cases.
+
+It can therefore happen that the entry that is attempted to be reloaded
+isn't mapped via the pagetables thus resulting in a double tlb refill
+exception. Due to the EXL flag set in c0_status this exception goes
+through the general exception vector and from there to handle_tlbl.
+Handle_tlbl is a more complex exception handler that is - compared
+to the first handler - complex and called far less often. It features
+handling of special cases and some error checking for debugging. This
+second handler still doesn't reenable interrupts, change to the kernel
+stack or save registers to be as efficient as possible. Therefore
+only the two registers k0/k1 are available for use. All this is only
+done when do_page_fault() in arch/mips/mm/fault.c is called. For the
+normal case this handler just reloads the entry mapping the pte table
+which again contains the entries to be loaded in the tlb. Since the
+original fault address has been lost this exception handler cannot
+complete the job. So it just returns to the main program which after
+taking another exception via the first tlb refill handler reloads the
+originally missing entry into the TLB and continues normal execution.
+
+Another special in the Linux/MIPS page handling is the handling of
+pages in non-existant branches of the page tables. To avoid that
+the exception handlers have to handle this special case the kernel
+maps these ptes (page table entries) to invalid_pte_table. This is a
+4kb page full of invalid entries. On an attempted access to such an
+invalid page the kernel then reloads - eventuall via a double fault
+this invalid entry into the tlb. The CPU then takes a tlb invalid
+exception resulting in a call to do_page_fault() which usually will
+take the apropriate measures like sending SIGSEGV.
+
+Downsides of this implementation are it's complexity and the faster
+handling of the majority of exceptions is bought at the expense of
+having to handle page aliasing problems with the page tables (which
+are accessed at TLBMAP and in KSEG1) itself. This is done using
+uncached accesses which are especially on older machines with slow
+memory subsystems painfully slow. The implementation is done this
+way because for the original hardware which Linux/MIPS was intended for
+had a blindingly fast memory interface.
diff --git a/arch/mips/jazz/Makefile b/arch/mips/jazz/Makefile
new file mode 100644
index 000000000..3ee478fee
--- /dev/null
+++ b/arch/mips/jazz/Makefile
@@ -0,0 +1,26 @@
+#
+# Makefile for the Jazz family specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+all: jazz.o
+O_TARGET := jazz.o
+O_OBJS := hw-access.o int-handler.o jazzdma.o setup.o
+
+ifdef CONFIG_VIDEO_G364
+O_OBJS += g364.o
+endif
+
+int-handler.o: int-handler.S
+
+clean:
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips/jazz/g364.c b/arch/mips/jazz/g364.c
new file mode 100644
index 000000000..87d66e24c
--- /dev/null
+++ b/arch/mips/jazz/g364.c
@@ -0,0 +1,415 @@
+/*
+ * linux/drivers/char/g364.c
+ *
+ * Copyright (C) 1996 Wayne Hodgen
+ *
+ * Based on and using chunks of Jay Estabrooks tga.c
+ *
+ * This module exports the console io support for Inmos's G364 controller
+ * used in Mips Magnums and clones. Based on the hardware desc for the
+ * Olivetti M700-10 ie. an Inmos G364 based card in a dedicated video slot,
+ * 2MB dual ported VRAM with a 64 bit data path, 256 color lookup table,
+ * palette of 16.7M and a user definable 64x64 hardware cursor.
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/kd.h>
+#include <linux/malloc.h>
+#include <linux/major.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/types.h>
+
+#include "../../../drivers/char/kbd_kern.h"
+#include "../../../drivers/char/vt_kern.h"
+#include "../../../drivers/char/consolemap.h"
+#include "../../../drivers/char/selection.h"
+#include "../../../drivers/char/console_struct.h"
+
+extern void register_console(void (*proc)(const char *));
+extern void console_print(const char *);
+unsigned video_res_x;
+
+/*
+ * Various defines for the G364
+ */
+#define G364_MEM_BASE 0xe0800000
+#define G364_PORT_BASE 0xe0200000
+#define ID_REG 0xe0200000 /* Read only */
+#define BOOT_REG 0xe0280000
+#define TIMING_REG 0xe0280108 /* to 0x080170 - DON'T TOUCH! */
+#define MASK_REG 0xe0280200
+#define CTLA_REG 0xe0280300
+#define CURS_TOGGLE 0x800000
+#define BIT_PER_PIX 0x700000 /* bits 22 to 20 of Control A */
+#define DELAY_SAMPLE 0x080000
+#define PORT_INTER 0x040000
+#define PIX_PIPE_DEL 0x030000 /* bits 17 and 16 of Control A */
+#define PIX_PIPE_DEL2 0x008000 /* same as above - don't ask me why */
+#define TR_CYCLE_TOG 0x004000
+#define VRAM_ADR_INC 0x003000 /* bits 13 and 12 of Control A */
+#define BLANK_OFF 0x000800
+#define FORCE_BLANK 0x000400
+#define BLK_FUN_SWTCH 0x000200
+#define BLANK_IO 0x000100
+#define BLANK_LEVEL 0x000080
+#define A_VID_FORM 0x000040
+#define D_SYNC_FORM 0x000020
+#define FRAME_FLY_PAT 0x000010
+#define OP_MODE 0x000008
+#define INTL_STAND 0x000004
+#define SCRN_FORM 0x000002
+#define ENABLE_VTG 0x000001
+#define TOP_REG 0xe0280400
+#define CURS_PAL_REG 0xe0280508 /* to 0x080518 */
+#define CHKSUM_REG 0xe0280600 /* to 0x080610 - unused */
+#define CURS_POS_REG 0xe0280638
+#define CLR_PAL_REG 0xe0280800 /* to 0x080ff8 */
+#define CURS_PAT_REG 0xe0281000 /* to 0x081ff8 */
+#define MON_ID_REG 0xe0300000 /* unused */
+#define RESET_REG 0xe0380000 /* Write only */
+
+/*
+ * built-in font management constants
+ *
+ * NOTE: the built-in font is 8x16, and the video resolution
+ * is either 1280x1024 @ 60Hz or 1024x768 @ 60 or 78Hz.
+ */
+#define FONTSIZE_X 8 /* 8 pixels wide */
+#define FONTSIZE_Y 16 /* 16 pixels high */
+
+unsigned char g364_font[] = {
+#include "g364.fnt"
+};
+
+u32 g364_cursor[256] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0xffff0000,0,0,0,0xffff0000,0,0,0,0xffff0000,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+};
+
+#ifdef CONFIG_REMOTE_DEBUG
+/* #define DEBUG_G364 */
+
+extern int putDebugChar(char c);
+
+void
+putDebugString(char *d_str)
+{
+ while (*d_str != '\0') {
+ putDebugChar(*d_str);
+ d_str++;
+ }
+ if (*--d_str != '\n')
+ putDebugChar('\n');
+}
+#endif
+
+void g364_clear_screen(void);
+
+int cursor_initialised=0;
+
+unsigned long
+con_type_init(unsigned long kmem_start, const char **display_desc)
+{
+ can_do_color = 1;
+
+ /*
+ * fake the screen memory with some CPU memory
+ */
+ video_mem_base = kmem_start;
+ kmem_start += video_screen_size;
+ video_mem_term = kmem_start;
+ video_type = VIDEO_TYPE_MIPS_G364;
+ video_res_x = video_num_columns * FONTSIZE_X;
+
+ *display_desc = "G364";
+
+ return kmem_start;
+}
+
+void
+__set_origin(unsigned short offset)
+{
+ /*
+ * should not be called, but if so, do nothing...
+ */
+}
+
+/*
+ * Hide the cursor from view, during blanking, usually...
+ */
+void
+hide_cursor(void)
+{
+/* *(unsigned int *) CTLA_REG &= ~CURS_TOGGLE; */
+}
+
+void
+init_g364_cursor(void)
+{
+ volatile unsigned int *ptr = (unsigned int *) CURS_PAL_REG;
+
+ *ptr |= 0x00ffffff;
+ ptr[2] |= 0x00ffffff;
+ ptr[4] |= 0x00ffffff;
+
+ memcpy((unsigned int *)CURS_PAT_REG, &g364_cursor, 1024);
+ cursor_initialised = 1;
+}
+
+/*
+ * Set the cursor on.
+ */
+void
+set_cursor(int currcons)
+{
+/*
+ if (!cursor_initialised)
+ init_g364_cursor();
+
+ if (console_blanked)
+ return;
+
+ *(unsigned int *) CTLA_REG |= CURS_TOGGLE;
+*/
+}
+
+/*
+ * NOTE: get_scrmem() and set_scrmem() are here only because
+ * the VGA version of set_scrmem() has some direct VGA references.
+ */
+void
+get_scrmem(int currcons)
+{
+ memcpyw((unsigned short *)vc_scrbuf[currcons],
+ (unsigned short *)origin, video_screen_size);
+ origin = video_mem_start = (unsigned long)vc_scrbuf[currcons];
+ scr_end = video_mem_end = video_mem_start + video_screen_size;
+ pos = origin + y*video_size_row + (x<<1);
+}
+
+void
+set_scrmem(int currcons, long offset)
+{
+ if (video_mem_term - video_mem_base < offset + video_screen_size)
+ offset = 0; /* strange ... */
+ memcpyw((unsigned short *)(video_mem_base + offset),
+ (unsigned short *) origin, video_screen_size);
+ video_mem_start = video_mem_base;
+ video_mem_end = video_mem_term;
+ origin = video_mem_base + offset;
+ scr_end = origin + video_screen_size;
+ pos = origin + y*video_size_row + (x<<1);
+}
+
+/*
+ * Fill out later
+ */
+void
+set_palette(void)
+{
+ int i, j;
+ volatile unsigned int *ptr = (volatile unsigned int *) CLR_PAL_REG;
+
+ for (i = 0; i < 16; i++,ptr+=2) {
+ j = color_table[i];
+ *ptr = ((default_red[j] << 16) |
+ (default_grn[j] << 8) |
+ (default_blu[j]));
+ }
+}
+
+/*
+ * NOTE:
+ * this is here, and not in console.c, because the VGA version
+ * tests the controller type to see if color can be done. We *KNOW*
+ * that we can do color on the G364.
+ *
+ */
+
+int
+set_get_cmap(unsigned char * arg, int set)
+{
+ int i;
+
+ for (i=0; i<16; i++) {
+ if (set) {
+ if (!access_ok(VERIFY_READ, (void *)arg, 16*3)) goto fault;
+ if (__get_user(default_red[i], arg++)) goto fault;
+ if (__get_user(default_grn[i], arg++)) goto fault;
+ if (__get_user(default_blu[i], arg++)) goto fault;
+ } else {
+ if (!access_ok(VERIFY_WRITE, (void *)arg, 16*3)) goto fault;
+ if (__put_user(default_red[i], arg++)) goto fault;
+ if (__put_user(default_grn[i], arg++)) goto fault;
+ if (__put_user(default_blu[i], arg++)) goto fault;
+ }
+ }
+ if (set) {
+ for (i=0; i<MAX_NR_CONSOLES; i++)
+ if (vc_cons_allocated(i)) {
+ int j, k ;
+ for (j=k=0; j<16; j++) {
+ vc_cons[i].d->vc_palette[k++] = default_red[j];
+ vc_cons[i].d->vc_palette[k++] = default_grn[j];
+ vc_cons[i].d->vc_palette[k++] = default_blu[j];
+ }
+ }
+ set_palette() ;
+ }
+
+ return 0;
+
+fault:
+ return -EFAULT;
+}
+
+/*
+ * Adjust the screen to fit a font of a certain height
+ *
+ * Returns < 0 for error, 0 if nothing changed, and the number
+ * of lines on the adjusted console if changed.
+ *
+ * for now, we only support the built-in font...
+ */
+int
+con_adjust_height(unsigned long fontheight)
+{
+ return -EINVAL;
+}
+
+/*
+ * PIO_FONT support.
+ *
+ * for now, we will use/allow *only* our built-in font...
+ */
+int
+set_get_font(char * arg, int set, int ch512)
+{
+ return -EINVAL;
+}
+
+/*
+ * print a character to a graphics console.
+ */
+void
+g364_blitc(unsigned short charattr, unsigned long addr)
+{
+ int row, col, temp;
+ register unsigned long long *dst, *font_row;
+ register int i;
+ char c;
+
+ /*
+ * calculate (row,col) from addr and video_mem_base
+ */
+ temp = (addr - video_mem_base) >> 1;
+ col = temp % 128;
+ row = (temp - col) / 128;
+
+ /*
+ * calculate destination address
+ */
+ dst = (unsigned long long *) ( G364_MEM_BASE
+ + ( row * video_res_x * FONTSIZE_Y )
+ + ( col * FONTSIZE_X ) );
+
+ c = charattr & 0x00ff;
+ if (c == 0x20) {
+ for (i=0; i < FONTSIZE_Y; i++, dst += video_num_columns)
+ *dst = 0x00000000;
+ } else {
+ font_row = (unsigned long long *) &g364_font[(c << 7)];
+ for (i=0; i < FONTSIZE_Y; i++, font_row++, dst += video_num_columns)
+ *dst = *font_row;
+ }
+}
+
+/*
+ * print a character to a graphics console. Colour version, slower!
+ */
+void
+g364_blitc_colour(unsigned short charattr, unsigned long addr)
+{
+ int row, col, temp, c, attrib;
+ register unsigned int fgmask, bgmask;
+ register unsigned long long *dst, *font_row;
+ register int i, stride;
+
+ c = charattr & 0x00ff;
+ attrib = (charattr >> 8) & 0x00ff;
+
+ /*
+ * extract foreground and background indices
+ * NOTE: we always treat blink/underline bits as color for now...
+ */
+ fgmask = attrib & 0x0f;
+ bgmask = (attrib >> 4) & 0x0f;
+
+ /* i = (c & 0xff) << 7; NOTE: assumption of 128 bytes per character bitmap */
+
+ /*
+ * calculate (row,col) from addr and video_mem_base
+ */
+ temp = (addr - video_mem_base) >> 1;
+ col = temp % 128;
+ row = (temp - col) / 128;
+ stride = video_res_x / 8;
+
+ /*
+ * calculate destination address
+ */
+ dst = (unsigned long long *) ( G364_MEM_BASE
+ + ( row * video_res_x * FONTSIZE_Y )
+ + ( col * FONTSIZE_X ) );
+
+ font_row = (unsigned long long *) &g364_font[((c & 0xff) << 7)];
+
+ for (i=0; i < FONTSIZE_Y; i++, font_row++, dst += stride) {
+ *dst = *font_row;
+ }
+}
+
+/*
+ * dummy routines for the VESA blanking code, which is VGA only,
+ * so we don't have to carry that stuff around for the G364...
+ */
+void
+vesa_powerdown(void)
+{
+}
+
+void
+vesa_blank(void)
+{
+}
+
+void
+vesa_unblank(void)
+{
+}
+
+void
+set_vesa_blanking(const unsigned long arg)
+{
+}
diff --git a/arch/mips/jazz/g364.fnt b/arch/mips/jazz/g364.fnt
new file mode 100644
index 000000000..fd4890f03
--- /dev/null
+++ b/arch/mips/jazz/g364.fnt
@@ -0,0 +1,4097 @@
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x07,0x00,0x07,0x07,0x07,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x00,0x07,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x07,0x00,0x07,0x07,0x07,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x00,0x07,0x07,0x07,0x00,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x07,0x00,0x07,0x07,0x07,0x00,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x00,0x07,0x00,
+0x07,0x07,0x07,0x07,0x00,0x00,0x07,0x00,
+0x07,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x07,0x00,
+0x07,0x07,0x00,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x07,
+0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x07,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x07,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x07,
+0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x07,
+0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x07,
+0x07,0x00,0x00,0x07,0x07,0x07,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x07,0x07,0x07,0x07,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,
+0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x07,
+0x07,0x00,0x00,0x07,0x07,0x00,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x07,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x07,
+0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x07,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x00,0x00,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07,
+0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,
+0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
+0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x07,
+0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,
+0x07,0x07,0x07,0x00,0x07,0x00,0x07,0x07,
+0x07,0x07,0x07,0x07,0x00,0x07,0x00,0x07,
+0x07,0x07,0x07,0x00,0x07,0x00,0x07,0x07,
+0x07,0x07,0x07,0x07,0x00,0x07,0x00,0x07,
+0x07,0x07,0x07,0x00,0x07,0x00,0x07,0x07,
+0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,
+0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x00,0x00,0x07,0x00,0x07,0x00,0x00,
+0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x07,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07,
+0x07,0x00,0x00,0x07,0x07,0x07,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x00,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x07,0x07,0x07,0x07,
+0x07,0x00,0x07,0x07,0x07,0x00,0x07,0x07,
+0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x07,0x00,0x07,0x07,0x00,0x07,0x07,0x00,
+0x07,0x00,0x00,0x07,0x07,0x07,0x07,0x00,
+0x07,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x07,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x07,0x07,0x07,0x07,0x00,0x00,0x07,0x00,
+0x07,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x00,0x00,0x07,0x07,0x00,0x07,0x07,
+0x00,0x07,0x07,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x07,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x00,0x00,
+0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x07,0x00,0x07,0x07,0x00,0x07,0x07,0x00,
+0x07,0x00,0x00,0x07,0x07,0x07,0x07,0x00,
+0x07,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x07,
+0x00,0x00,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
+0x07,0x07,0x00,0x07,0x00,0x00,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x07,
+0x00,0x00,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x07,
+0x00,0x00,0x07,0x07,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x07,
+0x00,0x00,0x07,0x07,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x07,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x07,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x07,
+0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x07,
+0x00,0x07,0x00,0x07,0x07,0x00,0x07,0x07,
+0x00,0x07,0x00,0x07,0x07,0x07,0x07,0x07,
+0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,
+0x00,0x07,0x00,0x07,0x00,0x00,0x00,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x00,0x07,0x07,0x07,
+0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,
+0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,
+0x07,0x07,0x07,0x00,0x07,0x07,0x07,0x07,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x07,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x07,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
+0x07,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
+0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
+0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
+0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
+0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
+0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
+0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
+0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
+0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
+0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00,
+0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07,
+0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x07,
+0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x07,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0
diff --git a/arch/mips/jazz/hw-access.c b/arch/mips/jazz/hw-access.c
new file mode 100644
index 000000000..112941275
--- /dev/null
+++ b/arch/mips/jazz/hw-access.c
@@ -0,0 +1,147 @@
+/*
+ * Low-level hardware access stuff for Jazz family machines.
+ *
+ * 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.
+ *
+ * Copyright (C) 1995, 1996 by Ralf Baechle
+ */
+#include <linux/delay.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <asm/addrspace.h>
+#include <asm/cache.h>
+#include <asm/vector.h>
+#include <asm/jazz.h>
+#include <asm/jazzdma.h>
+#include <asm/mc146818rtc.h>
+
+static unsigned char
+fd_inb(unsigned int port)
+{
+ unsigned char c;
+
+ c = *(volatile unsigned char *) port;
+ udelay(1);
+
+ return c;
+}
+
+static void
+fd_outb(unsigned char value, unsigned int port)
+{
+ *(volatile unsigned char *) port = value;
+}
+
+/*
+ * How to access the floppy DMA functions.
+ */
+static void
+fd_enable_dma(void)
+{
+ vdma_enable(JAZZ_FLOPPY_DMA);
+}
+
+static void
+fd_disable_dma(void)
+{
+ vdma_disable(JAZZ_FLOPPY_DMA);
+}
+
+static int
+fd_request_dma(void)
+{
+ return 0;
+}
+
+static void
+fd_free_dma(void)
+{
+}
+
+static void
+fd_clear_dma_ff(void)
+{
+}
+
+static void
+fd_set_dma_mode(char mode)
+{
+ vdma_set_mode(JAZZ_FLOPPY_DMA, mode);
+}
+
+static void
+fd_set_dma_addr(unsigned int a)
+{
+ vdma_set_addr(JAZZ_FLOPPY_DMA, vdma_phys2log(PHYSADDR(a)));
+}
+
+static void
+fd_set_dma_count(unsigned int count)
+{
+ vdma_set_count(JAZZ_FLOPPY_DMA, count);
+}
+
+static int
+fd_get_dma_residue(void)
+{
+ return vdma_get_residue(JAZZ_FLOPPY_DMA);
+}
+
+static void
+fd_enable_irq(void)
+{
+}
+
+static void
+fd_disable_irq(void)
+{
+}
+
+void
+jazz_fd_cacheflush(const void *addr, size_t size)
+{
+ cacheflush((unsigned long)addr, size, CF_DCACHE|CF_ALL);
+}
+
+static unsigned char
+rtc_read_data(unsigned long addr)
+{
+ outb_p(addr, RTC_PORT(0));
+ return *(char *)JAZZ_RTC_BASE;
+}
+
+static void
+rtc_write_data(unsigned char data, unsigned long addr)
+{
+ outb_p(addr, RTC_PORT(0));
+ *(char *)JAZZ_RTC_BASE = data;
+}
+
+struct feature jazz_feature = {
+ /*
+ * How to access the floppy controller's ports
+ */
+ fd_inb,
+ fd_outb,
+ /*
+ * How to access the floppy DMA functions.
+ */
+ fd_enable_dma,
+ fd_disable_dma,
+ fd_request_dma,
+ fd_free_dma,
+ fd_clear_dma_ff,
+ fd_set_dma_mode,
+ fd_set_dma_addr,
+ fd_set_dma_count,
+ fd_get_dma_residue,
+ fd_enable_irq,
+ fd_disable_irq,
+ /*
+ * How to access the RTC functions.
+ */
+ rtc_read_data,
+ rtc_write_data
+};
diff --git a/arch/mips/jazz/int-handler.S b/arch/mips/jazz/int-handler.S
new file mode 100644
index 000000000..03c999124
--- /dev/null
+++ b/arch/mips/jazz/int-handler.S
@@ -0,0 +1,389 @@
+/*
+ * arch/mips/jazz/pica.S
+ *
+ * Copyright (C) 1995, 1996 by Ralf Baechle and Andreas Busse
+ *
+ * Jazz family specific stuff
+ *
+ * To do: On Jazz machines we remap some non-ISA interrupts to ISA
+ * interrupts. These interrupts should use their own vectors.
+ * Squeeze the last cycles out of the handlers. Only a dead
+ * cycle is a good cycle.
+ */
+#include <asm/asm.h>
+#include <asm/mipsconfig.h>
+#include <asm/mipsregs.h>
+#include <asm/jazz.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * jazz_handle_int: Interrupt handler for the ACER Pica-61 boards
+ */
+ .set noreorder
+
+ NESTED(jazz_handle_int, FR_SIZE, ra)
+ .set noat
+ SAVE_ALL
+ REG_S sp,FR_ORIG_REG2(sp)
+ CLI
+ .set at
+
+ /*
+ * 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
+ beqz t0,3f
+ sll t0,16 # delay slot
+
+ /*
+ * Find irq with highest priority
+ * FIXME: This is slow - use binary search
+ */
+ la t1,ll_vectors
+1: bltz t0,2f # found pending irq
+ sll t0,1
+ b 1b
+ subu t1,PTRSIZE # delay slot
+
+ /*
+ * Do the low-level stuff
+ */
+2: lw t0,(t1)
+ jr t0
+ nop # delay slot
+ END(jazz_handle_int)
+
+ll_sw0: li s1,~IE_SW0
+ mfc0 t0,CP0_CAUSE
+ and t0,s1
+ mtc0 t0,CP0_CAUSE
+ PANIC("Unimplemented sw0 handler")
+
+ll_sw1: li s1,~IE_SW1
+ mfc0 t0,CP0_CAUSE
+ and t0,s1
+ mtc0 t0,CP0_CAUSE
+ PANIC("Unimplemented sw1 handler")
+
+ll_local_dma: li s1,~IE_IRQ0
+ PANIC("Unimplemented local_dma handler")
+
+ll_local_dev: lbu t0,JAZZ_IO_IRQ_SOURCE
+#if PTRSIZE == 8 /* True 64 bit kernel */
+ dsll t0,1
+#endif
+ .set reorder
+ LONG_L t0,local_vector(t0)
+ jr t0
+ .set noreorder
+
+/*
+ * The braindead PICA hardware gives us no way to distinguish if we really
+ * received interrupt 7 from the (E)ISA bus or if we just received an
+ * interrupt with no findable cause. This sometimes happens with braindead
+ * cards. Oh well - for all the Jazz boxes slots are more or less just
+ * whistles and bells and we're aware of the problem.
+ */
+ll_isa_irq: lw a0,JAZZ_EISA_IRQ_ACK
+ lui s0,%hi(PORT_BASE_JAZZ)
+ li s1,1
+ andi t0,a0,8 # which pic?
+ bnez t0,ack_second
+ andi a0,7 # delay slot
+
+ /*
+ * Acknowledge first pic
+ */
+ lb t2,%lo(PORT_BASE_JAZZ)+0x21(s0)
+ lui s4,%hi(cache_21)
+ lb t0,%lo(cache_21)(s4)
+ sllv s1,s1,a0
+ or t0,s1
+ sb t0,%lo(cache_21)(s4)
+ sb t0,%lo(PORT_BASE_JAZZ)+0x21(s0)
+ lui s3,%hi(intr_count)
+ lw t0,%lo(intr_count)(s3)
+ li t2,0x20
+ sb t2,%lo(PORT_BASE_JAZZ)+0x20(s0)
+ /*
+ * Now call the real handler
+ */
+ la t3,IRQ_vectors
+ sll t2,a0,PTRLOG
+ addu t3,t2
+ LONG_L t3,(t3)
+ addiu t0,1
+ jalr t3
+ sw t0,%lo(intr_count)(s3) # delay slot
+ lw t0,%lo(intr_count)(s3)
+ /*
+ * Unblock first pic
+ */
+ lbu a0,%lo(PORT_BASE_JAZZ)+0x21(s0)
+ lb a0,%lo(cache_21)(s4)
+ subu t0,1
+ sw t0,%lo(intr_count)(s3)
+ nor s1,zero,s1
+ and a0,s1
+ sb a0,%lo(cache_21)(s4)
+ jr v0
+ sb a0,%lo(PORT_BASE_JAZZ)+0x21(s0) # delay slot
+
+ .align 5
+ack_second: /*
+ * Acknowledge second pic
+ */
+ lbu t2,%lo(PORT_BASE_JAZZ)+0xa1(s0)
+ lui s4,%hi(cache_A1)
+ lb t3,%lo(cache_A1)(s4)
+ sllv s1,s1,a0
+ or t3,s1
+ sb t3,%lo(cache_A1)(s4)
+ sb t3,%lo(PORT_BASE_JAZZ)+0xa1(s0)
+ li t3,0x20
+ sb t3,%lo(PORT_BASE_JAZZ)+0xa0(s0)
+ lui s3,%hi(intr_count)
+ lw t0,%lo(intr_count)(s3)
+ sb t3,%lo(PORT_BASE_JAZZ)+0x20(s0)
+ /*
+ * Now call the real handler
+ */
+ la t3,IRQ_vectors
+ addiu a0,8
+ sll t2,a0,PTRLOG
+ addu t3,t2
+ LONG_L t3,(t3)
+ addiu t0,1
+ jalr t3
+ sw t0,%lo(intr_count)(s3) # delay slot
+
+ lw t0,%lo(intr_count)(s3)
+ /*
+ * Unblock second pic
+ */
+ lb a0,%lo(PORT_BASE_JAZZ)+0xa1(s0)
+ lb a0,%lo(cache_A1)(s4)
+ subu t0,1
+ sw t0,%lo(intr_count)(s3)
+ nor s1,zero,s1
+ and a0,s1
+ sb a0,%lo(cache_A1)(s4)
+ jr v0
+ sb a0,%lo(PORT_BASE_JAZZ)+0xa1(s0) # delay slot
+
+/*
+ * Hmm... This is not just a plain PC clone so the question is
+ * which devices on Jazz machines can generate an (E)ISA NMI?
+ * (Writing to nonexistant memory?)
+ */
+ll_isa_nmi: li s1,~IE_IRQ3
+ PANIC("Unimplemented isa_nmi handler")
+
+/*
+ * Timer IRQ - remapped to be more similar to an IBM compatible.
+ *
+ * The timer interrupt is handled specially to insure that the jiffies
+ * variable is updated at all times. Specifically, the timer interrupt is
+ * just like the complete handlers except that it is invoked with interrupts
+ * disabled and should never re-enable them. If other interrupts were
+ * allowed to be processed while the timer interrupt is active, then the
+ * other interrupts would have to avoid using the jiffies variable for delay
+ * and interval timing operations to avoid hanging the system.
+ */
+ll_timer: lw zero,JAZZ_TIMER_REGISTER # timer irq cleared on read
+ li s1,~IE_IRQ4
+
+ lui s3,%hi(intr_count)
+ lw t2,%lo(intr_count)(s3)
+ addiu t2,1
+ sw t2,%lo(intr_count)(s3)
+
+ li a0,0
+ jal do_IRQ
+ move a1,sp # delay slot
+
+ mfc0 t0,CP0_STATUS # disable interrupts again
+ ori t0,1
+ xori t0,1
+ mtc0 t0,CP0_STATUS
+
+ lw t2,%lo(intr_count)(s3)
+ subu t2,1
+
+ j ret_from_sys_call
+ sw t2,%lo(intr_count)(s3) # delay slot
+
+/*
+ * CPU count/compare IRQ (unused)
+ */
+ll_count: j return
+ mtc0 zero,CP0_COMPARE
+
+#if 0
+/*
+ * Call the handler for the interrupt
+ * (Currently unused)
+ */
+call_real: lui s3,%hi(intr_count)
+ lw t2,%lo(intr_count)(s3)
+ la t0,IRQ_vectors
+ addiu t2,1
+ sw t2,%lo(intr_count)(s3)
+
+ /*
+ * temporarily disable interrupt
+ */
+ mfc0 t2,CP0_STATUS
+ and t2,s1
+
+ addu t0,t3
+ lw t0,(t0)
+ mtc0 t2,CP0_STATUS # delay slot
+ jalr t0
+ nor s1,zero,s1 # delay slot
+
+ /*
+ * reenable interrupt
+ */
+ mfc0 t2,CP0_STATUS
+ or t2,s1
+ mtc0 t2,CP0_STATUS
+
+ lw t2,%lo(intr_count)(s3)
+ subu t2,1
+
+ jr v0
+ sw t2,%lo(intr_count)(s3)
+#endif
+
+ .data
+ PTR ll_sw0 # SW0
+ PTR ll_sw1 # SW1
+ PTR ll_local_dma # Local DMA
+ PTR ll_local_dev # Local devices
+ PTR ll_isa_irq # ISA IRQ
+ PTR ll_isa_nmi # ISA NMI
+ PTR ll_timer # Timer
+ll_vectors: PTR ll_count # Count/Compare IRQ
+
+ /*
+ * Interrupt handlers for local devices.
+ */
+ .text
+loc_no_irq: PANIC("Unimplemented loc_no_irq handler")
+/*
+ * Parallel port IRQ, remapped to level 5
+ */
+loc_parallel: li s1,~JAZZ_IE_PARALLEL
+ li a0,JAZZ_PARALLEL_IRQ
+ b loc_call
+ li t3,PTRSIZE*JAZZ_PARALLEL_IRQ # delay slot
+
+/*
+ * Floppy IRQ, remapped to level 6
+ */
+loc_floppy: li s1,~JAZZ_IE_FLOPPY
+ li a0,JAZZ_FLOPPY_IRQ
+ b loc_call
+ li t3,PTRSIZE*JAZZ_FLOPPY_IRQ # delay slot
+
+/*
+ * Sound? What sound hardware (whistle) ???
+ */
+loc_sound: PANIC("Unimplemented loc_sound handler")
+loc_video: PANIC("Unimplemented loc_video handler")
+
+/*
+ * Ethernet interrupt handler, remapped to level 13
+ */
+loc_ethernet: li s1,~JAZZ_IE_ETHERNET
+ li a0,JAZZ_ETHERNET_IRQ
+ b loc_call
+ li t3,PTRSIZE*JAZZ_ETHERNET_IRQ # delay slot
+
+loc_scsi: PANIC("Unimplemented loc_scsi handler")
+
+/*
+ * Keyboard interrupt handler
+ */
+loc_keyboard: li s1,~JAZZ_IE_KEYBOARD
+ li a0,JAZZ_KEYBOARD_IRQ
+ b loc_call
+ li t3,PTRSIZE*JAZZ_KEYBOARD_IRQ # re-map to irq level 1
+
+loc_mouse: PANIC("Unimplemented loc_mouse handler")
+
+/*
+ * Serial port 1 IRQ, remapped to level 3
+ */
+loc_serial1: li s1,~JAZZ_IE_SERIAL1
+ li a0,JAZZ_SERIAL1_IRQ
+ b loc_call
+ li t3,PTRSIZE*JAZZ_SERIAL1_IRQ # delay slot
+
+/*
+ * Serial port 2 IRQ, remapped to level 4
+ */
+loc_serial2: li s1,~JAZZ_IE_SERIAL2
+ li a0,JAZZ_SERIAL2_IRQ
+ b loc_call
+ li t3,PTRSIZE*JAZZ_SERIAL2_IRQ # delay slot
+
+/*
+ * Call the interrupt handler for an interrupt generated by a
+ * local device.
+ */
+loc_call: lui s3,%hi(intr_count)
+ lw t2,%lo(intr_count)(s3)
+ la t0,IRQ_vectors # delay slot
+ addiu t2,1
+ sw t2,%lo(intr_count)(s3)
+
+ /*
+ * Temporarily disable interrupt source
+ */
+ lhu t2,JAZZ_IO_IRQ_ENABLE
+ addu t0,t3 # make ptr to IRQ handler
+ lw t0,(t0)
+ and t2,s1 # delay slot
+ sh t2,JAZZ_IO_IRQ_ENABLE
+ jalr t0 # call IRQ handler
+ nor s1,zero,s1 # delay slot
+
+ /*
+ * Reenable interrupt
+ */
+ lhu t2,JAZZ_IO_IRQ_ENABLE
+ lw t1,%lo(intr_count)(s3) # delay slot
+ or t2,s1
+ sh t2,JAZZ_IO_IRQ_ENABLE
+
+ subu t1,1
+ jr v0
+ sw t1,%lo(intr_count)(s3) # delay slot
+
+/*
+ * "Jump extender" to reach spurious_interrupt
+ */
+3: j spurious_interrupt
+ nop # delay slot
+
+/*
+ * Vectors for interrupts generated by local devices
+ */
+ .data
+local_vector: PTR loc_no_irq
+ PTR loc_parallel
+ PTR loc_floppy
+ PTR loc_sound
+ PTR loc_video
+ PTR loc_ethernet
+ PTR loc_scsi
+ PTR loc_keyboard
+ PTR loc_mouse
+ PTR loc_serial1
+ PTR loc_serial2
diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c
new file mode 100644
index 000000000..3663f33d8
--- /dev/null
+++ b/arch/mips/jazz/jazzdma.c
@@ -0,0 +1,515 @@
+/*
+ * arch/mips/jazz/jazzdma.c
+ *
+ * Mips Jazz DMA controller support
+ * Copyright (C) 1995, 1996 by Andreas Busse
+ *
+ * NOTE: Some of the argument checking could be removed when
+ * things have settled down. Also, instead of returning 0xffffffff
+ * on failure of vdma_alloc() one could leave page #0 unused
+ * and return the more usual NULL pointer as logical address.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <asm/cache.h>
+#include <asm/mipsregs.h>
+#include <asm/mipsconfig.h>
+#include <asm/jazz.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/dma.h>
+#include <asm/jazzdma.h>
+
+/*
+ * Set this to one to enable additional vdma debug code.
+ */
+#define CONF_DEBUG_VDMA 0
+
+static unsigned long vdma_pagetable_start = 0;
+static unsigned long vdma_pagetable_end = 0;
+
+/*
+ * Debug stuff
+ */
+#define vdma_debug ((CONF_DEBUG_VDMA) ? debuglvl : 0)
+
+static int debuglvl = 3;
+
+/*
+ * Initialize the pagetable with a one-to-one mapping of
+ * the first 16 Mbytes of main memory and declare all
+ * entries to be unused. Using this method will at least
+ * allow some early device driver operations to work.
+ */
+static __inline__ void
+vdma_pgtbl_init(void)
+{
+ int i;
+ unsigned long paddr = 0;
+ VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
+
+ for (i=0; i<VDMA_PGTBL_ENTRIES; i++)
+ {
+ pgtbl[i].frame = paddr;
+ pgtbl[i].owner = VDMA_PAGE_EMPTY;
+ paddr += VDMA_PAGESIZE;
+ }
+}
+
+/*
+ * Initialize the Jazz R4030 dma controller
+ */
+unsigned long vdma_init(unsigned long memory_start, unsigned long memory_end)
+{
+ /*
+ * Allocate 32k of memory for DMA page tables.
+ * This needs to be page aligned and should be
+ * uncached to avoid cache flushing after every
+ * update.
+ */
+ vdma_pagetable_start = KSEG1ADDR((memory_start + 4095) & ~4095);
+ vdma_pagetable_end = vdma_pagetable_start + VDMA_PGTBL_SIZE;
+ cacheflush(vdma_pagetable_start, VDMA_PGTBL_SIZE, CF_DCACHE|CF_ALL);
+
+ /*
+ * Clear the R4030 translation table
+ */
+ vdma_pgtbl_init();
+
+ r4030_write_reg32(JAZZ_R4030_TRSTBL_BASE,PHYSADDR(vdma_pagetable_start));
+ r4030_write_reg32(JAZZ_R4030_TRSTBL_LIM,VDMA_PGTBL_SIZE);
+ r4030_write_reg32(JAZZ_R4030_TRSTBL_INV,0);
+
+ printk("VDMA: R4030 DMA pagetables initialized.\n");
+
+ return KSEG0ADDR(vdma_pagetable_end);
+}
+
+/*
+ * Allocate DMA pagetables using a simple first-fit algorithm
+ */
+unsigned long vdma_alloc(unsigned long paddr, unsigned long size)
+{
+ VDMA_PGTBL_ENTRY *entry = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
+ int first;
+ int last;
+ int pages;
+ unsigned int frame;
+ unsigned long laddr;
+ int i;
+
+ /* check arguments */
+
+ if (paddr > 0x1fffffff)
+ {
+ if (vdma_debug)
+ printk("vdma_alloc: Invalid physical address: %08lx\n",paddr);
+ return VDMA_ERROR; /* invalid physical address */
+ }
+ if (size > 0x400000 || size == 0)
+ {
+ if (vdma_debug)
+ printk("vdma_alloc: Invalid size: %08lx\n",size);
+ return VDMA_ERROR; /* invalid physical address */
+ }
+
+ /*
+ * Find free chunk
+ */
+ pages = (size + 4095) >> 12; /* no. of pages to allocate */
+ first = 0;
+ while (1)
+ {
+ while (entry[first].owner != VDMA_PAGE_EMPTY &&
+ first < VDMA_PGTBL_ENTRIES)
+ first++;
+ if (first+pages > VDMA_PGTBL_ENTRIES) /* nothing free */
+ return VDMA_ERROR;
+
+ last = first+1;
+ while (entry[last].owner == VDMA_PAGE_EMPTY && last-first < pages)
+ last++;
+
+ if (last-first == pages)
+ break; /* found */
+ }
+
+ /*
+ * Mark pages as allocated
+ */
+ laddr = (first << 12) + (paddr & (VDMA_PAGESIZE-1));
+ frame = paddr & ~(VDMA_PAGESIZE-1);
+
+ for (i=first; i<last; i++)
+ {
+ entry[i].frame = frame;
+ entry[i].owner = laddr;
+ frame += VDMA_PAGESIZE;
+ }
+
+ /*
+ * Update translation table and return logical start address
+ */
+ r4030_write_reg32(JAZZ_R4030_TRSTBL_INV,0);
+
+ if (vdma_debug > 1)
+ printk("vdma_alloc: Allocated %d pages starting from %08lx\n",
+ pages,laddr);
+
+ if (vdma_debug > 2)
+ {
+ printk("LADDR: ");
+ for (i=first; i<last; i++)
+ printk("%08x ",i<<12);
+ printk("\nPADDR: ");
+ for (i=first; i<last; i++)
+ printk("%08x ",entry[i].frame);
+ printk("\nOWNER: ");
+ for (i=first; i<last; i++)
+ printk("%08x ",entry[i].owner);
+ printk("\n");
+ }
+
+ return laddr;
+}
+
+/*
+ * Free previously allocated dma translation pages
+ * Note that this does NOT change the translation table,
+ * it just marks the free'd pages as unused!
+ */
+int vdma_free(unsigned long laddr)
+{
+ VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
+ int i;
+
+ i = laddr >> 12;
+
+ if (pgtbl[i].owner != laddr)
+ {
+ printk("vdma_free: trying to free other's dma pages, laddr=%8lx\n",
+ laddr);
+ return -1;
+ }
+
+ while (pgtbl[i].owner == laddr && i < VDMA_PGTBL_ENTRIES)
+ {
+ pgtbl[i].owner = VDMA_PAGE_EMPTY;
+ i++;
+ }
+
+ if (vdma_debug > 1)
+ printk("vdma_free: freed %ld pages starting from %08lx\n",
+ i-(laddr>>12),laddr);
+
+ return 0;
+}
+
+/*
+ * Map certain page(s) to another physical address.
+ * Caller must have allocated the page(s) before.
+ */
+int vdma_remap(unsigned long laddr, unsigned long paddr, unsigned long size)
+{
+ VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
+ int first, pages, npages;
+
+ if (laddr > 0xffffff)
+ {
+ if (vdma_debug)
+ printk("vdma_map: Invalid logical address: %08lx\n",laddr);
+ return -EINVAL; /* invalid logical address */
+ }
+ if (paddr > 0x1fffffff)
+ {
+ if (vdma_debug)
+ printk("vdma_map: Invalid physical address: %08lx\n",paddr);
+ return -EINVAL; /* invalid physical address */
+ }
+
+ npages = pages = (((paddr & (VDMA_PAGESIZE-1)) + size) >> 12) + 1;
+ first = laddr >> 12;
+ if (vdma_debug)
+ printk("vdma_remap: first=%x, pages=%x\n",first,pages);
+ if (first+pages > VDMA_PGTBL_ENTRIES)
+ {
+ if (vdma_debug)
+ printk("vdma_alloc: Invalid size: %08lx\n",size);
+ return -EINVAL;
+ }
+
+ paddr &= ~(VDMA_PAGESIZE-1);
+ while (pages > 0 && first < VDMA_PGTBL_ENTRIES)
+ {
+ if (pgtbl[first].owner != laddr)
+ {
+ if (vdma_debug)
+ printk("Trying to remap other's pages.\n");
+ return -EPERM; /* not owner */
+ }
+ pgtbl[first].frame = paddr;
+ paddr += VDMA_PAGESIZE;
+ first++;
+ pages--;
+ }
+
+ /*
+ * Update translation table
+ */
+ r4030_write_reg32(JAZZ_R4030_TRSTBL_INV,0);
+
+ if (vdma_debug > 2)
+ {
+ int i;
+ pages = (((paddr & (VDMA_PAGESIZE-1)) + size) >> 12) + 1;
+ first = laddr >> 12;
+ printk("LADDR: ");
+ for (i=first; i<first+pages; i++)
+ printk("%08x ",i<<12);
+ printk("\nPADDR: ");
+ for (i=first; i<first+pages; i++)
+ printk("%08x ",pgtbl[i].frame);
+ printk("\nOWNER: ");
+ for (i=first; i<first+pages; i++)
+ printk("%08x ",pgtbl[i].owner);
+ printk("\n");
+ }
+
+ return 0;
+}
+
+/*
+ * Translate a physical address to a logical address.
+ * This will return the logical address of the first
+ * match.
+ */
+unsigned long vdma_phys2log(unsigned long paddr)
+{
+ int i;
+ int frame;
+ VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
+
+ frame = paddr & ~(VDMA_PAGESIZE-1);
+
+ for (i=0; i<VDMA_PGTBL_ENTRIES; i++)
+ {
+ if (pgtbl[i].frame == frame)
+ break;
+ }
+
+ if (i == VDMA_PGTBL_ENTRIES)
+ return ~0UL;
+
+ return (i<<12) + (paddr & (VDMA_PAGESIZE-1));
+}
+
+/*
+ * Translate a logical DMA address to a physical address
+ */
+unsigned long vdma_log2phys(unsigned long laddr)
+{
+ VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
+
+ return pgtbl[laddr >> 12].frame + (laddr & (VDMA_PAGESIZE-1));
+}
+
+/*
+ * Print DMA statistics
+ */
+void vdma_stats(void)
+{
+ int i;
+
+ printk("vdma_stats: CONFIG: %08x\n",
+ r4030_read_reg32(JAZZ_R4030_CONFIG));
+ printk("R4030 translation table base: %08x\n",
+ r4030_read_reg32(JAZZ_R4030_TRSTBL_BASE));
+ printk("R4030 translation table limit: %08x\n",
+ r4030_read_reg32(JAZZ_R4030_TRSTBL_LIM));
+ printk("vdma_stats: INV_ADDR: %08x\n",
+ r4030_read_reg32(JAZZ_R4030_INV_ADDR));
+ printk("vdma_stats: R_FAIL_ADDR: %08x\n",
+ r4030_read_reg32(JAZZ_R4030_R_FAIL_ADDR));
+ printk("vdma_stats: M_FAIL_ADDR: %08x\n",
+ r4030_read_reg32(JAZZ_R4030_M_FAIL_ADDR));
+ printk("vdma_stats: IRQ_SOURCE: %08x\n",
+ r4030_read_reg32(JAZZ_R4030_IRQ_SOURCE));
+ printk("vdma_stats: I386_ERROR: %08x\n",
+ r4030_read_reg32(JAZZ_R4030_I386_ERROR));
+ printk("vdma_chnl_modes: ");
+ for (i=0; i<8; i++)
+ printk("%04x ",
+ (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_MODE+(i<<5)));
+ printk("\n");
+ printk("vdma_chnl_enables: ");
+ for (i=0; i<8; i++)
+ printk("%04x ",
+ (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(i<<5)));
+ printk("\n");
+}
+
+/*
+ * DMA transfer functions
+ */
+
+/*
+ * Enable a DMA channel. Also clear any error conditions.
+ */
+void vdma_enable(int channel)
+{
+ int status;
+
+ if (vdma_debug)
+ printk("vdma_enable: channel %d\n",channel);
+
+ /*
+ * Check error conditions first
+ */
+ status = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5));
+ if (status & 0x400)
+ printk("VDMA: Channel %d: Address error!\n",channel);
+ if (status & 0x200)
+ printk("VDMA: Channel %d: Memory error!\n",channel);
+
+ /*
+ * Clear all interrupt flags
+ */
+ r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5),
+ R4030_TC_INTR | R4030_MEM_INTR | R4030_ADDR_INTR);
+
+ /*
+ * Enable the desired channel
+ */
+ r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5),
+ r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5)) |
+ R4030_CHNL_ENABLE);
+}
+
+/*
+ * Disable a DMA channel
+ */
+void vdma_disable(int channel)
+{
+ if (vdma_debug)
+ {
+ int status = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5));
+
+ printk("vdma_disable: channel %d\n",channel);
+ printk("VDMA: channel %d status: %04x (%s) mode: "
+ "%02x addr: %06x count: %06x\n",
+ channel,status,((status & 0x600) ? "ERROR" : "OK"),
+ (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_MODE+(channel<<5)),
+ (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_ADDR+(channel<<5)),
+ (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_COUNT+(channel<<5)));
+ }
+
+ r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5),
+ r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5)) &
+ ~R4030_CHNL_ENABLE);
+
+ /*
+ * After disabling a DMA channel a remote bus register should be
+ * read to ensure that the current DMA acknowledge cycle is completed.
+ */
+ *((volatile unsigned int *)JAZZ_DUMMY_DEVICE);
+}
+
+/*
+ * Set DMA mode. This function accepts the mode values used
+ * to set a PC-style DMA controller. For the SCSI and FDC
+ * channels, we also set the default modes each time we're
+ * called.
+ * NOTE: The FAST and BURST dma modes are supported by the
+ * R4030 Rev. 2 and PICA chipsets only. I leave them disabled
+ * for now.
+ */
+void vdma_set_mode(int channel, int mode)
+{
+ if (vdma_debug)
+ printk("vdma_set_mode: channel %d, mode 0x%x\n", channel, mode);
+
+ switch(channel)
+ {
+ case JAZZ_SCSI_DMA: /* scsi */
+ r4030_write_reg32(JAZZ_R4030_CHNL_MODE+(channel<<5),
+/* R4030_MODE_FAST | */
+/* R4030_MODE_BURST | */
+ R4030_MODE_INTR_EN |
+ R4030_MODE_WIDTH_16 |
+ R4030_MODE_ATIME_80);
+ break;
+
+ case JAZZ_FLOPPY_DMA: /* floppy */
+ r4030_write_reg32(JAZZ_R4030_CHNL_MODE+(channel<<5),
+/* R4030_MODE_FAST | */
+/* R4030_MODE_BURST | */
+ R4030_MODE_INTR_EN |
+ R4030_MODE_WIDTH_8 |
+ R4030_MODE_ATIME_120);
+ break;
+
+ case JAZZ_AUDIOL_DMA:
+ case JAZZ_AUDIOR_DMA:
+ printk("VDMA: Audio DMA not supported yet.\n");
+ break;
+
+ default:
+ printk("VDMA: vdma_set_mode() called with unsupported channel %d!\n",
+ channel);
+ }
+
+ switch(mode)
+ {
+ case DMA_MODE_READ:
+ r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5),
+ r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5)) &
+ ~R4030_CHNL_WRITE);
+ break;
+
+ case DMA_MODE_WRITE:
+ r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5),
+ r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5)) |
+ R4030_CHNL_WRITE);
+ break;
+
+ default:
+ printk("VDMA: vdma_set_mode() called with unknown dma mode 0x%x\n",mode);
+ }
+}
+
+/*
+ * Set Transfer Address
+ */
+void vdma_set_addr(int channel, long addr)
+{
+ if (vdma_debug)
+ printk("vdma_set_addr: channel %d, addr %lx\n",channel,addr);
+
+ r4030_write_reg32(JAZZ_R4030_CHNL_ADDR+(channel<<5),addr);
+}
+
+/*
+ * Set Transfer Count
+ */
+void vdma_set_count(int channel, int count)
+{
+ if (vdma_debug)
+ printk("vdma_set_count: channel %d, count %08x\n",channel,(unsigned)count);
+
+ r4030_write_reg32(JAZZ_R4030_CHNL_COUNT+(channel<<5),count);
+}
+
+/*
+ * Get Residual
+ */
+int vdma_get_residue(int channel)
+{
+ int residual;
+
+ residual = r4030_read_reg32(JAZZ_R4030_CHNL_COUNT+(channel<<5));
+
+ if (vdma_debug)
+ printk("vdma_get_residual: channel %d: residual=%d\n",channel,residual);
+
+ return residual;
+}
diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c
new file mode 100644
index 000000000..c5f5b1d77
--- /dev/null
+++ b/arch/mips/jazz/setup.c
@@ -0,0 +1,137 @@
+/*
+ * Setup pointers to hardware dependand routines.
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ */
+#include <asm/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/jazz.h>
+#include <asm/processor.h>
+#include <asm/vector.h>
+#include <asm/io.h>
+
+/*
+ * Initial irq handlers.
+ */
+static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+
+/*
+ * IRQ2 is cascade interrupt to second interrupt controller
+ */
+static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL};
+
+extern asmlinkage void jazz_handle_int(void);
+extern asmlinkage void jazz_fd_cacheflush(const void *addr, size_t size);
+extern struct feature jazz_feature;
+extern void (*ibe_board_handler)(struct pt_regs *regs);
+extern void (*dbe_board_handler)(struct pt_regs *regs);
+
+static void
+jazz_irq_setup(void)
+{
+ set_except_vector(0, jazz_handle_int);
+ r4030_write_reg16(JAZZ_IO_IRQ_ENABLE,
+ JAZZ_IE_ETHERNET |
+ JAZZ_IE_SERIAL1 |
+ JAZZ_IE_SERIAL2 |
+ JAZZ_IE_PARALLEL |
+ JAZZ_IE_FLOPPY);
+ r4030_read_reg16(JAZZ_IO_IRQ_SOURCE); /* clear pending IRQs */
+ r4030_read_reg32(JAZZ_R4030_INVAL_ADDR); /* clear error bits */
+ set_cp0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1);
+ request_region(0x20, 0x20, "pic1");
+ request_region(0xa0, 0x20, "pic2");
+ setup_x86_irq(2, &irq2);
+}
+
+void (*board_time_init)(struct irqaction *irq);
+
+static void jazz_time_init(struct irqaction *irq)
+{
+ /* set the clock to 100 Hz */
+ r4030_write_reg32(JAZZ_TIMER_INTERVAL, 9);
+ setup_x86_irq(0, irq);
+}
+
+/*
+ * The ibe/dbe exceptions are signaled by onboard hardware and should get
+ * a board specific handlers to get maximum available information. Bus
+ * errors are always symptom of hardware malfunction or a kernel error.
+ * We should try to handle this case a bit more gracefully than just
+ * zapping the process ...
+ */
+static void jazz_be_board_handler(struct pt_regs *regs)
+{
+ u32 jazz_is, jazz_ia;
+
+ /*
+ * Give some debugging aid ...
+ */
+ jazz_is = r4030_read_reg32(JAZZ_R4030_IRQ_SOURCE);
+ jazz_ia = r4030_read_reg32(JAZZ_R4030_INVAL_ADDR);
+ printk("Interrupt Source == %08x\n", jazz_is);
+ printk("Invalid Address Register == %08x\n", jazz_ia);
+ show_regs(regs);
+
+ /*
+ * Assume it would be too dangerous to continue ...
+ */
+ force_sig(SIGBUS, current);
+}
+
+void
+jazz_setup(void)
+{
+ tag *atag;
+
+ /*
+ * we just check if a tag_screen_info can be gathered
+ * in setup_arch(), if yes we don't proceed futher...
+ */
+ atag = bi_TagFind(tag_screen_info);
+ if (!atag) {
+ /*
+ * If no, we try to find the tag_arc_displayinfo which is
+ * always created by Milo for an ARC box (for now Milo only
+ * works on ARC boxes :) -Stoned.
+ */
+ atag = bi_TagFind(tag_arcdisplayinfo);
+ if (atag) {
+ screen_info.orig_x =
+ ((mips_arc_DisplayInfo*)TAGVALPTR(atag))->cursor_x;
+ screen_info.orig_y =
+ ((mips_arc_DisplayInfo*)TAGVALPTR(atag))->cursor_y;
+ screen_info.orig_video_cols =
+ ((mips_arc_DisplayInfo*)TAGVALPTR(atag))->columns;
+ screen_info.orig_video_lines =
+ ((mips_arc_DisplayInfo*)TAGVALPTR(atag))->lines;
+ }
+ }
+ irq_setup = jazz_irq_setup;
+ board_time_init = jazz_time_init;
+ fd_cacheflush = jazz_fd_cacheflush;
+ feature = &jazz_feature; // Will go away
+ port_base = PORT_BASE_JAZZ;
+ isa_slot_offset = 0xe3000000;
+ request_region(0x00,0x20,"dma1");
+ request_region(0x40,0x20,"timer");
+ /* The RTC is outside the port address space */
+
+ if (mips_machtype == MACH_MIPS_MAGNUM_4000
+ && mips_machtype == MACH_OLIVETTI_M700)
+ EISA_bus = 1;
+ /*
+ * The Jazz hardware provides additional information for
+ * bus errors, so we use an special handler.
+ */
+ ibe_board_handler = jazz_be_board_handler;
+ dbe_board_handler = jazz_be_board_handler;
+}
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 0086f60cf..b76c723b2 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -1,94 +1,51 @@
#
-# Makefile for the linux kernel.
+# Makefile for the Linux/MIPS kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
-.c.s:
- $(CC) $(CFLAGS) -S $<
-.s.o:
- $(AS) $(ASFLAGS) -o $*.o $<
-.c.o:
- $(CC) $(CFLAGS) -c $<
.S.s:
$(CPP) $(CFLAGS) $< -o $*.s
.S.o:
$(CC) $(CFLAGS) -c $< -o $*.o
-OBJS = process.o signal.o entry.o traps.o irq.o ptrace.o vm86.o ioport.o \
- setup.o bios32.o tynedma.o
-
-include ../../../.config
+all: kernel.o head.o
+EXTRA_ASFLAGS = -mips3 -mcpu=r4000
+O_TARGET := kernel.o
+O_OBJS := branch.o process.o signal.o entry.o traps.o irq.o ptrace.o vm86.o \
+ ioport.o setup.o syscall.o sysmips.o time.o bios32.o ipc.o ksyms.o \
+ unaligned.o tags.o
#
# Kernel debugging
#
-
ifdef CONFIG_REMOTE_DEBUG
-OBJS += gdb-low.o gdb-stub.o
+O_OBJS += gdb-low.o gdb-stub.o
endif
#
-# Board specific code
+# Depending from some other kernel option
#
-
-ifdef CONFIG_MIPS_JAZZ
-OBJS += jazzdma.o
-endif
-
-ifdef CONFIG_ACER_PICA_61
-OBJS += pica.o
-endif
-
-ifdef CONFIG_DESKSTATION_TYNE
-OBJS += tyne.o
-endif
-
-ifdef CONFIG_MIPS_MAGNUM_4000
-OBJS += magnum4000.o
+ifdef CONFIG_PROC_FS
+O_OBJS += proc.o
endif
#
-# CPU model specific code
+# Since we add the same object files to O_OBJS for different configurations.
+# O_OBJS might contain duplicate files. We correct this by filtering out
+# duplicate files. Just to avoid users having to know about all the
+# compatibility stuff between various boards and boards.
#
-ifdef CONFIG_CPU_R4X00
-OBJS += r4xx0.o
-endif
-
-ifdef CONFIG_CPU_R4600
-OBJS += r4xx0.o
-endif
+O_OBJS := $(sort $(O_OBJS))
all: kernel.o head.o
entry.o: entry.S
-
+exception.o: exception.S
head.o: head.S
-magnum4000.o: magnum4000.S
-
-pica.o: pica.S
-
-r4xx0.o: r4xx0.S
-
-tyne.o: tyne.S
-
-kernel.o: $(OBJS)
- $(LD) -r -o kernel.o $(OBJS)
- sync
-
-dep:
- $(CPP) -M *.[cS] > .depend
+clean:
-modules:
-
-dummy:
-
-#
-# include a dependency file if one exists
-#
-ifeq (.depend,$(wildcard .depend))
-include .depend
-endif
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
new file mode 100644
index 000000000..32705b320
--- /dev/null
+++ b/arch/mips/kernel/branch.c
@@ -0,0 +1,193 @@
+/*
+ * Branch and jump emulation.
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <asm/branch.h>
+#include <asm/inst.h>
+#include <asm/ptrace.h>
+#include <asm/uaccess.h>
+
+/*
+ * Compute the return address and do emulate branch and instruction
+ * simulation, if required.
+ */
+int __compute_return_epc(struct pt_regs *regs)
+{
+ unsigned int *addr, bit, fcr31;
+ long epc;
+ union mips_instruction insn;
+
+ epc = regs->cp0_epc;
+ if (epc & 3) {
+ printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
+ force_sig(SIGBUS, current);
+ return -EFAULT;
+ }
+
+ /*
+ * Read the instruction
+ */
+ addr = (unsigned int *) (unsigned long) epc;
+ if (__get_user(insn.word, addr)) {
+ force_sig(SIGSEGV, current);
+ return -EFAULT;
+ }
+
+ regs->regs[0] = 0;
+ switch (insn.i_format.opcode) {
+ /*
+ * jr and jalr are in r_format format.
+ */
+ case spec_op:
+ switch (insn.r_format.func) {
+ case jalr_op:
+ regs->regs[insn.r_format.rd] = epc + 8;
+ /* Fall through */
+ case jr_op:
+ regs->cp0_epc = regs->regs[insn.r_format.rs];
+ break;
+ }
+ break;
+
+ /*
+ * This group contains:
+ * bltz_op, bgez_op, bltzl_op, bgezl_op,
+ * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
+ */
+ case bcond_op:
+ switch (insn.i_format.rt) {
+ case bltz_op:
+ case bltzl_op:
+ if (regs->regs[insn.i_format.rs] < 0)
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+
+ case bgez_op:
+ case bgezl_op:
+ if (regs->regs[insn.i_format.rs] >= 0)
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+
+ case bltzal_op:
+ case bltzall_op:
+ regs->regs[31] = epc + 8;
+ if (regs->regs[insn.i_format.rs] < 0)
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+
+ case bgezal_op:
+ case bgezall_op:
+ regs->regs[31] = epc + 8;
+ if (regs->regs[insn.i_format.rs] >= 0)
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+ }
+ break;
+
+ /*
+ * These are unconditional and in j_format.
+ */
+ case jal_op:
+ regs->regs[31] = regs->cp0_epc + 8;
+ case j_op:
+ epc += 4;
+ epc >>= 28;
+ epc <<= 28;
+ epc |= (insn.j_format.target << 2);
+ regs->cp0_epc = epc;
+ break;
+
+ /*
+ * These are conditional and in i_format.
+ */
+ case beq_op:
+ case beql_op:
+ if (regs->regs[insn.i_format.rs] ==
+ regs->regs[insn.i_format.rt])
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+
+ case bne_op:
+ case bnel_op:
+ if (regs->regs[insn.i_format.rs] !=
+ regs->regs[insn.i_format.rt])
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+
+ case blez_op: /* not really i_format */
+ case blezl_op:
+ /* rt field assumed to be zero */
+ if (regs->regs[insn.i_format.rs] <= 0)
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+
+ case bgtz_op:
+ case bgtzl_op:
+ /* rt field assumed to be zero */
+ if (regs->regs[insn.i_format.rs] > 0)
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+
+ /*
+ * And now the FPA/cp1 branch instructions.
+ */
+ case cop1_op:
+ asm ("cfc1\t%0,$31":"=r" (fcr31));
+ bit = (insn.i_format.rt >> 2);
+ bit += bit ? 24 : 23;
+ switch (insn.i_format.rt) {
+ case 0: /* bc1f */
+ case 2: /* bc1fl */
+ if (~fcr31 & (1 << bit))
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+
+ case 1: /* bc1t */
+ case 3: /* bc1tl */
+ if (fcr31 & (1 << bit))
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+ }
+ break;
+ }
+
+ return 0;
+}
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 787e2bbf4..6072afae2 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -1,28 +1,31 @@
/*
- * arch/mips/kernel/entry.S
+ * Low level exception handling
*
- * Copyright (C) 1994, 1995 Waldorf Electronics
- * written by Ralf Baechle and Andreas Busse
+ * 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.
+ *
+ * Copyright (C) 1994, 1995 by Ralf Baechle
*/
/*
* entry.S contains the system-call and fault low-level handling routines.
* This also contains the timer-interrupt handler, as well as all interrupts
- * and faults that can result in a task-switch. The ISA dependend TLB
- * code is in arch/mips/kernel/tlb.S
+ * and faults that can result in a task-switch. The ISA dependent TLB
+ * code is in arch/mips/<ISA-level>/<cputype>.S
*/
-
#include <linux/sys.h>
#include <asm/asm.h>
#include <asm/errno.h>
-#include <asm/segment.h>
#include <asm/mipsregs.h>
#include <asm/mipsconfig.h>
-#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/stackframe.h>
#include <asm/processor.h>
+#include <asm/regdef.h>
+#include <asm/fpregdef.h>
+#include <asm/unistd.h>
/*
* These are offsets into the task-struct.
@@ -36,6 +39,16 @@ flags = 20
errno = 24
exec_domain = 60
+#ifdef __SMP__
+#error "Fix this for SMP"
+#else
+#define current current_set
+#endif
+
+/*
+ * Heia ... The %lo, %hi and %HI stuff is too strong for the ELF assembler
+ * and the ABI to cope with ...
+ */
.text
.set noreorder
.align 4
@@ -50,126 +63,16 @@ handle_bottom_half:
jal do_bottom_half
mtc0 t0,CP0_STATUS # delay slot
mtc0 s3,CP0_STATUS # Restore old IRQ state
- j 9f
+ b 9f
sw s1,%lo(intr_count)(s0) # delay slot
-reschedule:
- lui ra,%hi(ret_from_sys_call)
- j schedule
- addiu ra,%lo(ret_from_sys_call) # delay slot
-
- .align 5
- NESTED(handle_sys, FR_SIZE, sp)
- .set noat
- SAVE_ALL
- STI
- .set at
- /*
- * Compute return address. We assume that syscalls never
- * appear in delay slots. For the Linux/MIPS libc this
- * assumption is always true.
- */
- lw t3,FR_EPC(sp)
- lw s1,FR_REG2(sp)
- li t0,-ENOSYS
- addiu t3,4
- sw t3,FR_EPC(sp)
- li t2,NR_syscalls
- bge s1,t2,ret_from_sys_call
- sw t0,FR_REG2(sp) # delay slot
- sll s1,PTRLOG
- lw s1,sys_call_table(s1)
- lw s0,current
-
- beqz s1,ret_from_sys_call
- lw t0,flags(s0) # delay slot
- sll t0,26 # PF_TRACESYS
- bltz t0,1f
- sw zero,errno(s0) # delay slot
-
-#if 0
- lw t0,FR_ORIG_REG2(sp)
- beq t0,4,1f
- nop
- la t0,sys_call_names
- lw t1,FR_ORIG_REG2(sp)
- sll t1,2
- addu t0,t1
- lw a1,(t0)
- PRINT("%s(")
- lw a1,FR_REG4(sp)
- lw a2,FR_REG5(sp)
- lw a3,FR_REG6(sp)
- PRINT("%08lx, %08lx, %08lx, ")
- lw a1,FR_REG7(sp)
- lw a2,FR_EPC(sp)
- lw a3,FR_REG31(sp)
- PRINT("%08lx) epc %08lx ra %08lx ")
-1:
-#endif
- lw a0,FR_REG4(sp)
- lw a1,FR_REG5(sp)
- lw a2,FR_REG6(sp)
- lw a3,FR_REG7(sp)
- lw t0,FR_REG3(sp)
- jalr s1 # do the real work
- sw t0,PTRSIZE*4(sp) # delay slot
-
-#if 0
- lw t0,FR_ORIG_REG2(sp)
- beq t0,4,1f
- nop
- sw v0,xxx
- lw a1,xxx
- PRINT("res %08lx\n")
- lw v0,xxx
- .data
-xxx: .word 0
- .text
-1:
-#endif
-
- lw t0,errno(s0)
- sw v0,FR_REG2(sp) # save return value
- subu t0,zero,t0
- beqz t0,ret_from_sys_call
+reschedule: jal schedule
nop # delay slot
- /*
- * Fixme: should set error flag
- */
- j ret_from_sys_call
- sw t0,FR_REG2(sp) # delay slot
-
- .align 4
-1: jal syscall_trace
- nop # delay slot
-
- lw a0,FR_REG4(sp)
- lw a1,FR_REG5(sp)
- lw a2,FR_REG6(sp)
- lw a3,FR_REG7(sp)
- lw t0,FR_REG3(sp)
- jalr s1 # do the real work
- sw t0,PTRSIZE*4(sp) # delay slot
-
- lw t0,errno(s0)
- sw v0,FR_REG2(sp)
- subu t0,zero,t0 # delay slot
- beqz t0,1f
- nop # delay slot
- /*
- * Fixme: should set error flag
- */
-1: jal syscall_trace
- sw t0,FR_REG2(sp) # delay slot
-
- .align 4
- .globl ret_from_sys_call
-ret_from_sys_call:
+EXPORT(ret_from_sys_call)
lw t0,intr_count # bottom half
bnez t0,return
-9:
- lw t0,bh_mask # delay slot
+
+9: lw t0,bh_mask # delay slot
lw t1,bh_active # unused delay slot
and t0,t1
bnez t0,handle_bottom_half
@@ -187,15 +90,11 @@ ret_from_sys_call:
lw s0,current
lw t0,task
- lw t1,state(s0) # state
- beq s0,t0,return # task[0] cannot have signals
- lw t0,counter(s0) # counter
- bnez t1,reschedule # state == 0 ?
lw a0,blocked(s0)
+ beq s0,t0,return # task[0] cannot have signals
# save blocked in a0 for
# signal handling
- beqz t0,reschedule # counter == 0 ?
- lw t0,signal(s0)
+ lw t0,signal(s0) # delay slot
nor t1,zero,a0
and t1,t0,t1
beqz t1,return
@@ -203,423 +102,225 @@ ret_from_sys_call:
jal do_signal
move a1,sp # delay slot
-
+
.set noat
- .globl return
-return: RESTORE_ALL
+EXPORT(return)
+ RESTORE_ALL
ERET
.set at
- END(handle_sys)
/*
- * Beware: interrupt, fast_interrupt and bad_interrupt have unusal
- * calling conventions!
+ * Beware: timer_interrupt, interrupt, fast_interrupt and bad_interrupt
+ * have unusual calling conventions to speedup the mess.
*
- * t1 - interrupt number
+ * a0 - interrupt number
* s2 - destroyed
* return values:
* v0 - return routine
+ *
+ * The timer interrupt is handled specially to insure that the jiffies
+ * variable is updated at all times. Specifically, the timer interrupt is
+ * just like the complete handlers except that it is invoked with interrupts
+ * disabled and should never re-enable them. If other interrupts were
+ * allowed to be processed while the timer interrupt is active, then the
+ * other interrupts would have to avoid using the jiffies variable for delay
+ * and interval timing operations to avoid hanging the system.
*/
.text
.set at
.align 5
- NESTED(interrupt, FR_SIZE, sp)
+NESTED(timer_interrupt, FR_SIZE, sp)
+ move s2,ra
+ jal do_IRQ
+ move a1,sp # delay slot
+ .set reorder
+ la v0,ret_from_sys_call
+ jr s2
+ .set noreorder
+ END(timer_interrupt)
+
+ .align 5
+NESTED(interrupt, FR_SIZE, sp)
move s2,ra
mfc0 t0,CP0_STATUS # enable IRQs
ori t0,0x1f
xori t0,0x1e
mtc0 t0,CP0_STATUS
- move a0,t1
jal do_IRQ
move a1,sp # delay slot
mfc0 t0,CP0_STATUS # disable IRQs
ori t0,1
xori t0,1
+ mtc0 t0,CP0_STATUS
+ .set reorder
la v0,ret_from_sys_call
jr s2
- mtc0 t0,CP0_STATUS # delay slot
+ .set noreorder
END(interrupt)
.align 5
- NESTED(fast_interrupt, FR_SIZE, sp)
+NESTED(fast_interrupt, FR_SIZE, sp)
+ .set reorder
move s2,ra
- move a0,t1
jal do_fast_IRQ
- move a1,sp # delay slot
- lui v0,%hi(return)
+ la v0,return
jr s2
- addiu v0,%lo(return) # delay slot
+ .set noreorder
END(fast_interrupt)
- LEAF(bad_interrupt)
/*
* Don't return & unblock the pic
*/
+LEAF(bad_interrupt)
+ .set reorder
+ lw t0,%lo(intr_count)(s3)
+ subu t0,1
+ .set noreorder
j return
- nop
+ sw t0,%lo(intr_count)(s3) # delay slot
END(bad_interrupt)
- .align 5
- LEAF(spurious_interrupt)
+ .text
+ .align 5
+LEAF(spurious_interrupt)
/*
- * Nothing happened... (whistle)
+ * Someone tried to fool us by sending an interrupt but we
+ * couldn't find a cause for it.
*/
- lui t1,%hi(spurious_count)
- lw t0,%lo(spurious_count)(t1)
- la v0,return
- addiu t0,1
- jr ra
- sw t0,%lo(spurious_count)(t1)
+ lui t1,%hi(spurious_count)
+ lw t0,%lo(spurious_count)(t1)
+ la v0,return
+ addiu t0,1
+ jr ra
+ sw t0,%lo(spurious_count)(t1)
END(spurious_interrupt)
-
-
/*
- * Build a default exception handler for the other R4x00 exceptions
+ * Build a default exception handler for the exceptions that don't need
+ * special handlers. If you didn't know yet - I *like* playing games with
+ * the C preprocessor ...
*/
-#define BUILD_HANDLER(exception) \
+#define __BUILD_clear_none(exception) \
+ REG_S sp,FR_ORIG_REG2(sp); /* sp < 0 */
+#define __BUILD_clear_sys(exception) \
+ REG_S v0,FR_ORIG_REG2(sp); \
+ REG_S a3,FR_ORIG_REG7(sp);
+#define __BUILD_clear_fpe(exception) \
+ REG_S sp,FR_ORIG_REG2(sp); /* sp < 0 */ \
+ cfc1 a1,fcr31; \
+ li a2,~(0x3f<<12); \
+ and a2,a1; \
+ ctc1 a2,fcr31;
+#define __BUILD_clear_watch(exception) \
+ REG_S sp,FR_ORIG_REG2(sp); /* sp < 0 */ \
+ mtc0 zero,CP0_WATCHLO; \
+ mtc0 zero,CP0_WATCHHI
+#define __BUILD_clear_ade(exception) \
+ REG_S sp,FR_ORIG_REG2(sp); /* sp < 0 */ \
+ MFC0 t0,CP0_BADVADDR; \
+ REG_S t0,FR_BADVADDR(sp);
+#define __BUILD_silent(exception)
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+#define fmt "Got %s at %08x.\n"
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
+#define fmt "Got %s at %016Lx.\n"
+#endif
+#define __BUILD_verbose(exception) \
+ la a1,8f; \
+ TEXT (#exception); \
+ REG_L a2,FR_EPC(sp); \
+ PRINT(fmt)
+#define __BUILD_count(exception) \
+ .set reorder; \
+ lw t0,exception_count_##exception; \
+ addiu t0,1; \
+ sw t0,exception_count_##exception; \
+ .set noreorder; \
+ .data; \
+EXPORT(exception_count_##exception); \
+ .word 0; \
+ .text;
+#define BUILD_HANDLER(exception,handler,clear,verbose) \
+ .text; \
.align 5; \
NESTED(handle_##exception, FR_SIZE, sp); \
.set noat; \
SAVE_ALL; \
+ __BUILD_clear_##clear(exception); \
STI; \
.set at; \
- la a1,8f; \
- TEXT (#exception); \
- lw a2,FR_EPC(sp); \
- PRINT("Got %s at %08x.\n"); \
- li a0,0; \
- li t0,-1; /* not a sys call */ \
- sw t0,FR_ORIG_REG2(sp); \
- jal do_##exception; \
+ __BUILD_##verbose(exception); \
+ REG_S sp,FR_ORIG_REG2(sp); /* not a sys call */ \
+ jal do_##handler; \
move a0,sp; /* delay slot */ \
j ret_from_sys_call; \
nop; /* delay slot */ \
END(handle_##exception)
- BUILD_HANDLER(adel)
- BUILD_HANDLER(ades)
- BUILD_HANDLER(ibe)
- BUILD_HANDLER(dbe)
- BUILD_HANDLER(ov)
- BUILD_HANDLER(fpe)
- BUILD_HANDLER(bp)
- BUILD_HANDLER(tr)
- BUILD_HANDLER(ri)
- BUILD_HANDLER(cpu)
- BUILD_HANDLER(vcei)
- BUILD_HANDLER(vced)
- BUILD_HANDLER(watch)
- BUILD_HANDLER(reserved)
-
+ BUILD_HANDLER(adel,ade,ade,silent) /* #4 */
+ BUILD_HANDLER(ades,ade,ade,silent) /* #5 */
+ BUILD_HANDLER(ibe,ibe,none,verbose) /* #6 */
+ BUILD_HANDLER(dbe,dbe,none,verbose) /* #7 */
+ BUILD_HANDLER(sys,sys,none,silent) /* #8 */
+ BUILD_HANDLER(bp,bp,none,silent) /* #9 */
+ BUILD_HANDLER(ri,ri,none,silent) /* #10 */
+ BUILD_HANDLER(cpu,cpu,none,silent) /* #11 */
+ BUILD_HANDLER(ov,ov,none,silent) /* #12 */
+ BUILD_HANDLER(tr,tr,none,silent) /* #13 */
+ BUILD_HANDLER(vcei,vcei,none,verbose) /* #14 */
+ BUILD_HANDLER(fpe,fpe,fpe,silent) /* #15 */
+ BUILD_HANDLER(watch,watch,watch,verbose) /* #23 */
+ BUILD_HANDLER(vced,vced,none,verbose) /* #31 */
+ BUILD_HANDLER(reserved,reserved,none,verbose) /* others */
/*
* Exception handler table with 32 entries.
* This might be extended to handle software exceptions
*/
.bss
- .align 2
- EXPORT(exception_handlers)
- .fill 32,4,0
+ .align PTRLOG
+EXPORT(exception_handlers)
+ .fill 32,PTRSIZE,0
+
+/*
+ * Interrupt handler table with 16 entries.
+ */
+EXPORT(IRQ_vectors)
+ .fill 16,PTRSIZE,0
/*
* Table of syscalls
*/
.data
- EXPORT(sys_call_table)
- PTR sys_setup /* 0 */
- PTR sys_exit
- PTR sys_fork
- PTR sys_read
- PTR sys_write
- PTR sys_open /* 5 */
- PTR sys_close
- PTR sys_waitpid
- PTR sys_creat
- PTR sys_link
- PTR sys_unlink /* 10 */
- PTR sys_execve
- PTR sys_chdir
- PTR sys_time
- PTR sys_mknod
- PTR sys_chmod /* 15 */
- PTR sys_chown
- PTR sys_break
- PTR sys_stat
- PTR sys_lseek
- PTR sys_getpid /* 20 */
- PTR sys_mount
- PTR sys_umount
- PTR sys_setuid
- PTR sys_getuid
- PTR sys_stime /* 25 */
- PTR sys_ptrace
- PTR sys_alarm
- PTR sys_fstat
- PTR sys_pause
- PTR sys_utime /* 30 */
- PTR sys_stty
- PTR sys_gtty
- PTR sys_access
- PTR sys_nice
- PTR sys_ftime /* 35 */
- PTR sys_sync
- PTR sys_kill
- PTR sys_rename
- PTR sys_mkdir
- PTR sys_rmdir /* 40 */
- PTR sys_dup
- PTR sys_pipe
- PTR sys_times
- PTR sys_prof
- PTR sys_brk /* 45 */
- PTR sys_setgid
- PTR sys_getgid
- PTR sys_signal
- PTR sys_geteuid
- PTR sys_getegid /* 50 */
- PTR sys_acct
- PTR sys_phys
- PTR sys_lock
- PTR sys_ioctl
- PTR sys_fcntl /* 55 */
- PTR sys_mpx
- PTR sys_setpgid
- PTR sys_ulimit
- PTR sys_olduname
- PTR sys_umask /* 60 */
- PTR sys_chroot
- PTR sys_ustat
- PTR sys_dup2
- PTR sys_getppid
- PTR sys_getpgrp /* 65 */
- PTR sys_setsid
- PTR sys_sigaction
- PTR sys_sgetmask
- PTR sys_ssetmask
- PTR sys_setreuid /* 70 */
- PTR sys_setregid
- PTR sys_sigsuspend
- PTR sys_sigpending
- PTR sys_sethostname
- PTR sys_setrlimit /* 75 */
- PTR sys_getrlimit
- PTR sys_getrusage
- PTR sys_gettimeofday
- PTR sys_settimeofday
- PTR sys_getgroups /* 80 */
- PTR sys_setgroups
- PTR sys_select
- PTR sys_symlink
- PTR sys_lstat
- PTR sys_readlink /* 85 */
- PTR sys_uselib
- PTR sys_swapon
- PTR sys_reboot
- PTR old_readdir
- PTR sys_mmap /* 90 */
- PTR sys_munmap
- PTR sys_truncate
- PTR sys_ftruncate
- PTR sys_fchmod
- PTR sys_fchown /* 95 */
- PTR sys_getpriority
- PTR sys_setpriority
- PTR sys_profil
- PTR sys_statfs
- PTR sys_fstatfs /* 100 */
- PTR sys_ioperm
- PTR sys_socketcall
- PTR sys_syslog
- PTR sys_setitimer
- PTR sys_getitimer /* 105 */
- PTR sys_newstat
- PTR sys_newlstat
- PTR sys_newfstat
- PTR sys_uname
- PTR sys_iopl /* 110 */
- PTR sys_vhangup
- PTR sys_idle
- PTR sys_vm86
- PTR sys_wait4
- PTR sys_swapoff /* 115 */
- PTR sys_sysinfo
- PTR sys_ipc
- PTR sys_fsync
- PTR sys_sigreturn
- PTR sys_clone /* 120 */
- PTR sys_setdomainname
- PTR sys_newuname
- PTR 0 #sys_modify_ldt
- PTR sys_adjtimex
- PTR sys_mprotect /* 125 */
- PTR sys_sigprocmask
- PTR sys_create_module
- PTR sys_init_module
- PTR sys_delete_module
- PTR sys_get_kernel_syms /* 130 */
- PTR sys_quotactl
- PTR sys_getpgid
- PTR sys_fchdir
- PTR sys_bdflush
- PTR sys_sysfs /* 135 */
- PTR sys_personality
- PTR 0 /* for afs_syscall */
- PTR sys_setfsuid
- PTR sys_setfsgid
- PTR sys_llseek /* 140 */
- PTR sys_getdents
- PTR sys_select
- PTR sys_flock
- .space (NR_syscalls-140)*4
+ .align PTRLOG
+EXPORT(sys_call_table)
+ /*
+ * Reserved space for all the SVR4, SVR, BSD43 and POSIX
+ * flavoured syscalls.
+ */
+ .space (__NR_Linux)*PTRSIZE
- .bss
- EXPORT(IRQ_vectors)
- .fill 16,4,0
+ /*
+ * Linux flavoured syscalls.
+ */
+#define SYS(call, narg) PTR call
+#include "syscalls.h"
- .text
-sys_call_names:
- TTABLE ("setup")
- TTABLE ("exit")
- TTABLE ("fork")
- TTABLE ("read")
- TTABLE ("write")
- TTABLE ("open")
- TTABLE ("close")
- TTABLE ("waitpid")
- TTABLE ("creat")
- TTABLE ("link")
- TTABLE ("unlink")
- TTABLE ("execve")
- TTABLE ("chdir")
- TTABLE ("time")
- TTABLE ("mknod")
- TTABLE ("chmod")
- TTABLE ("chown")
- TTABLE ("break")
- TTABLE ("stat")
- TTABLE ("lseek")
- TTABLE ("getpid")
- TTABLE ("mount")
- TTABLE ("umount")
- TTABLE ("setuid")
- TTABLE ("getuid")
- TTABLE ("stime")
- TTABLE ("ptrace")
- TTABLE ("alarm")
- TTABLE ("fstat")
- TTABLE ("pause")
- TTABLE ("utime")
- TTABLE ("stty")
- TTABLE ("gtty")
- TTABLE ("access")
- TTABLE ("nice")
- TTABLE ("ftime")
- TTABLE ("sync")
- TTABLE ("kill")
- TTABLE ("rename")
- TTABLE ("mkdir")
- TTABLE ("rmdir")
- TTABLE ("dup")
- TTABLE ("pipe")
- TTABLE ("times")
- TTABLE ("prof")
- TTABLE ("brk")
- TTABLE ("setgid")
- TTABLE ("getgid")
- TTABLE ("signal")
- TTABLE ("geteuid")
- TTABLE ("getegid")
- TTABLE ("acct")
- TTABLE ("phys")
- TTABLE ("lock")
- TTABLE ("ioctl")
- TTABLE ("fcntl")
- TTABLE ("mpx")
- TTABLE ("setpgid")
- TTABLE ("ulimit")
- TTABLE ("olduname")
- TTABLE ("umask")
- TTABLE ("chroot")
- TTABLE ("ustat")
- TTABLE ("dup2")
- TTABLE ("getppid")
- TTABLE ("getpgrp")
- TTABLE ("setsid")
- TTABLE ("sigaction")
- TTABLE ("sgetmask")
- TTABLE ("ssetmask")
- TTABLE ("setreuid")
- TTABLE ("setregid")
- TTABLE ("sigsuspend")
- TTABLE ("sigpending")
- TTABLE ("sethostname")
- TTABLE ("setrlimit")
- TTABLE ("getrlimit")
- TTABLE ("getrusage")
- TTABLE ("gettimeofday")
- TTABLE ("settimeofday")
- TTABLE ("getgroups")
- TTABLE ("setgroups")
- TTABLE ("select")
- TTABLE ("symlink")
- TTABLE ("lstat")
- TTABLE ("readlink")
- TTABLE ("uselib")
- TTABLE ("swapon")
- TTABLE ("reboot")
- TTABLE ("readdir")
- TTABLE ("mmap")
- TTABLE ("munmap")
- TTABLE ("truncate")
- TTABLE ("ftruncate")
- TTABLE ("fchmod")
- TTABLE ("fchown")
- TTABLE ("getpriority")
- TTABLE ("setpriority")
- TTABLE ("profil")
- TTABLE ("statfs")
- TTABLE ("fstatfs")
- TTABLE ("ioperm")
- TTABLE ("socketcall")
- TTABLE ("syslog")
- TTABLE ("setitimer")
- TTABLE ("getitimer")
- TTABLE ("newstat")
- TTABLE ("newlstat")
- TTABLE ("newfstat")
- TTABLE ("uname")
- TTABLE ("iopl")
- TTABLE ("vhangup")
- TTABLE ("idle")
- TTABLE ("vm86")
- TTABLE ("wait4")
- TTABLE ("swapoff")
- TTABLE ("sysinfo")
- TTABLE ("ipc")
- TTABLE ("fsync")
- TTABLE ("sigreturn")
- TTABLE ("clone")
- TTABLE ("setdomainname")
- TTABLE ("newuname")
- TTABLE ("modify_ldt (unused)")
- TTABLE ("adjtimex")
- TTABLE ("mprotect")
- TTABLE ("sigprocmask")
- TTABLE ("create_module")
- TTABLE ("init_module")
- TTABLE ("delete_module")
- TTABLE ("get_kernel_syms")
- TTABLE ("quotactl")
- TTABLE ("getpgid")
- TTABLE ("fchdir")
- TTABLE ("bdflush")
- TTABLE ("sysfs")
- TTABLE ("personality")
- TTABLE ("afs_syscall") /* for afs_syscall */
- TTABLE ("setfsuid")
- TTABLE ("setfsgid")
- TTABLE ("llseek")
- TTABLE ("sys_getdents")
- TTABLE ("sys_select")
- TTABLE ("sys_flock")
+/*
+ * Number of arguments of each syscall
+ * FIXME: This table contains huge empty areas wasting memory.
+ */
+EXPORT(sys_narg_table)
+ /*
+ * Reserved space for all the SVR4, SVR, BSD43 and POSIX
+ * flavoured syscalls.
+ */
+ .space (__NR_Linux)
+
+ /*
+ * Linux flavoured syscalls.
+ */
+#undef SYS
+#define SYS(call, narg) .byte narg
+#include "syscalls.h"
diff --git a/arch/mips/kernel/gdb-low.S b/arch/mips/kernel/gdb-low.S
index ea775e732..9b948a845 100644
--- a/arch/mips/kernel/gdb-low.S
+++ b/arch/mips/kernel/gdb-low.S
@@ -9,9 +9,9 @@
#include <linux/sys.h>
#include <asm/asm.h>
-#include <asm/segment.h>
#include <asm/mipsregs.h>
#include <asm/mipsconfig.h>
+#include <asm/regdef.h>
#include <asm/stackframe.h>
#include <asm/gdb-stub.h>
diff --git a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c
index 7708feac0..9a3240152 100644
--- a/arch/mips/kernel/gdb-stub.c
+++ b/arch/mips/kernel/gdb-stub.c
@@ -68,10 +68,10 @@
#include <linux/signal.h>
#include <linux/kernel.h>
+#include <asm/addrspace.h>
#include <asm/asm.h>
#include <asm/mipsregs.h>
-#include <asm/segment.h>
-#include <asm/cachectl.h>
+#include <asm/cache.h>
#include <asm/system.h>
#include <asm/gdb-stub.h>
@@ -407,7 +407,7 @@ static int hexToInt(char **ptr, int *intValue)
}
/*
- * This function does all command procesing for interfacing to gdb. It
+ * This function does all command processing for interfacing to gdb. It
* returns 1 if you should skip the instruction at the trap address, 0
* otherwise.
*/
@@ -605,7 +605,7 @@ void handle_exception (struct gdb_regs *regs)
* NB: We flush both caches, just to be sure...
*/
- sys_cacheflush((void *)KSEG0,KSEG1-KSEG0,BCACHE);
+ cacheflush((void *)KSEG0, KSEG1-KSEG0, CF_BCACHE|CF_ALL);
return;
/* NOTREACHED */
break;
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index a2cb43de3..82de12ff5 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -1,16 +1,30 @@
/*
* arch/mips/kernel/head.S
*
- * Copyright (C) 1994, 1995 Waldorf Electronics
+ * Copyright (C) 1994, 1995 Waldorf Electronics, 1996 Paul M. Antoine
* Written by Ralf Baechle and Andreas Busse
+ * Modified for DECStation and hence R3000 support by Paul M. Antoine
+ * Additional R3000 support by Didier Frick <dfrick@dial.eunet.ch>
+ * for ACN S.A, Copyright (C) 1996 by ACN S.A
*
* Head.S contains the MIPS exception handler and startup code.
+ *
+ * FIXME: Note that the #ifdef's for R4X00 assume R3000 is the #else
+ * case, which is a little naughty. We also do NOT need the
+ * dec_entry goo at the begining of all this - PMA
+ * FIXME: This #ifdef stuff is ugly and I should move the tlb/exception
+ * handler code out into some other file - Ralf
+ * Take the zillions of (_MIPS_ISA == _MIPS_ISA_MIPSx) as a temporary
+ * solution. I know how they look ...
*/
+#include <linux/config.h> /* For the DECstation hacks */
#include <linux/tasks.h>
+#include <asm/addrspace.h>
#include <asm/asm.h>
-#include <asm/segment.h>
-#include <asm/cachectl.h>
+#include <asm/processor.h>
+#include <asm/regdef.h>
+#include <asm/cache.h>
#include <asm/mipsregs.h>
#include <asm/mipsconfig.h>
#include <asm/stackframe.h>
@@ -18,14 +32,33 @@
#define PAGE_SIZE 0x1000
+/*
+ * FIXME: I still think the following should be in an include file (see
+ * also the reference in arch/mips/mips1/r3000.S - PMA
+ */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+#define MODE_GLOBAL 0x0100 /* shared for all processes */
+#define MODE_ALIAS 0x00e0
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS5)
#define MODE_GLOBAL 0x0001 /* shared for all processes */
#define MODE_ALIAS 0x0016 /* uncachable */
+#endif
- .text
- .set mips3
/*
+ * The two symbols begin_except and end_except mark the range that is copied
+ * to KSEG0 on startup.
+ */
+EXPORT(begin_except)
+ .text
+/*
* This is space for the interrupt handlers.
- * They are located at virtual address KSEG[01] (physical 0x0)
+ * After trap_init() they are located at virtual address KSEG0.
+ *
+ * For some machine where the kernel doesn't get directly loaded to KSEG0
+ * the exceptionhandler get copied to KSEG0. They therefore must be
+ * relocatable code.
*/
/*
* TLB refill, EXL == 0
@@ -33,6 +66,17 @@
.set noreorder
.set noat
LEAF(except_vec0)
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+ mfc0 k1,CP0_CONTEXT
+ nop
+ lw k0,(k1) # May cause another exception
+ mfc0 k1,CP0_EPC # Get the return address
+ srl k0,12 # Convert to EntryLo format
+ mtc0 k0,CP0_ENTRYLO0
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS5)
+ .set mips3
dmfc0 k1,CP0_CONTEXT
dsra k1,1
lwu k0,(k1) # May cause another exception
@@ -41,37 +85,103 @@
dsrl k1,6 # Convert to EntryLo format
dmtc0 k0,CP0_ENTRYLO0
dmtc0 k1,CP0_ENTRYLO1
+#endif
+#ifndef CONFIG_OPTIMIZE_R4600
nop # Needed for R4[04]00 pipeline
+#endif
tlbwr
nop # Needed for R4[04]00 pipeline
nop
+#ifndef CONFIG_OPTIMIZE_R4600
nop
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+ jr k1
+ rfe
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS5)
eret
/*
- * Workaround for R4000 bug. For explanation see MIPS
- * docs. Note that this that obscure that it wont almost
- * never happen. Well, but Mips writes about it's bugs.
+ * Partial workaround for R4000 bug. For explanation see
+ * MIPS docs. Note that this that obscure that it wont
+ * almost never happen. Well, but Mips writes about it's bugs.
*/
nop
eret
+#endif
END(except_vec0)
+/******************************************************************************/
+
/*
* XTLB refill, EXL == 0
- * Should never be reached
+ * Should never be reached on R4000.
*/
.org except_vec0+0x80
- LEAF(except_vec1)
- PANIC("XTLB Refill exception.\n")
-1: j 1b
+ NESTED(except_vec1, 0, sp)
+ .set noat
+ /*
+ * Register saving is delayed as long as we don't know
+ * which registers really need to be saved.
+ */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+ mfc0 k1,CP0_CONTEXT
nop
+ lw k0,(k1) # May cause another exception
+ mfc0 k1,CP0_EPC # Get the return address
+ srl k0,12 # Convert to EntryLo format
+ mtc0 k0,CP0_ENTRYLO0
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS5)
+ mfc0 k1,CP0_CONTEXT
+ dsra k1,1
+ lwu k0,(k1) # May cause another exception
+ lwu k1,4(k1)
+ dsrl k0,6 # Convert to EntryLo format
+ dsrl k1,6 # Convert to EntryLo format
+ dmtc0 k0,CP0_ENTRYLO0
+ dmtc0 k1,CP0_ENTRYLO1
+#endif
+ nop # Needed for R4[04]00 pipeline
+ tlbwr
+ nop # Needed for R4[04]00 pipeline
+ nop
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+ jr k1
+ rfe
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS5)
+ nop
+ eret
+#endif
+ /*
+ * Partial workaround for R4000 bug. For explanation see
+ * MIPS docs. Note that this that obscure that it wont
+ * almost never happen. Well, but Mips writes about it's bugs.
+ */
+ nop
+ eret
END(except_vec1)
+/******************************************************************************/
+
/*
* Cache Error
*/
.org except_vec1+0x80
LEAF(except_vec2)
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
+ /*
+ * On the R3000, this is the "Uncached TLB Miss" handler.
+ */
+ j except_vec0
+ nop
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS5)
/*
* Famous last words: unreached
*/
@@ -79,8 +189,11 @@
PRINT("Cache error exception: c0_errorepc == %08x\n")
1: j 1b
nop
+#endif
END(except_vec2)
+/******************************************************************************/
+
/*
* General exception vector.
*/
@@ -90,6 +203,8 @@
/*
* Register saving is delayed as long as we don't know
* which registers really need to be saved.
+ * Except for k1 which MUST be preserved to allow
+ * nested TLB refill exceptions on the R3000.
*/
mfc0 k1,CP0_CAUSE
la k0,exception_handlers
@@ -107,46 +222,89 @@
END(except_vec3)
.set at
+EXPORT(end_except)
+
/******************************************************************************/
/*
* Kernel entry
*/
.set noreorder
+
NESTED(kernel_entry, 16, sp)
/*
+ * The following two symbols are used for kernel profiling.
+ */
+ EXPORT(stext)
+ EXPORT(_stext)
+
+ /*
+ * Initialize the global pointer, if required.
+ */
+ LOAD_GP
+
+ /*
+ * First setup stack for kernel and init
+ */
+ la sp,init_user_stack+(KERNEL_STACK_SIZE-4*SZREG)
+ la t0,init_kernel_stack+(KERNEL_STACK_SIZE)
+ LONG_S t0,kernelsp
+
+ /*
* Clear BSS first so that there are no surprises...
*/
la t0,_edata
la t1,_end
- sw zero,(t0)
-1: addiu t0,4
+ sb zero,(t0)
+1: addiu t0,1
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1)
+ /*
+ * Paul, this clears one word too much - Ralf
+ */
+ bne t0,t1,1b
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS3) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS4)
bnel t0,t1,1b
- sw zero,(t0)
+#endif
+ sb zero,(t0) # delay slot
+
+ /*
+ * Get the memory upper limit the bootloader passed to us
+ * in a0
+ */
+ sw a0,mips_memory_upper
+
+ /*
+ * Get the very one tags we need early in the boot process
+ */
+ jal bi_EarlySnarf
+ nop
/*
* Initialize low level part of memory management
+ * First flush the TLB to make sure that we don't get a
+ * TLB shutdown during wire_mappings.
*/
jal tlbflush
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+ nop
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
mtc0 zero,CP0_WIRED # delay slot
+#endif
jal wire_mappings
nop
- jal tlbflush
- nop
-
- /*
- * Stack for kernel and init
- */
- la sp,init_user_stack+PAGE_SIZE-24
- la t0,init_kernel_stack+PAGE_SIZE
- sw t0,kernelsp
/*
* Disable coprocessors
*/
mfc0 t0,CP0_STATUS
- li t1,~(ST0_CU0|ST0_CU1|ST0_CU2|ST0_CU3)
+ li t1,~(ST0_CU1|ST0_CU2|ST0_CU3)
and t0,t1
+ li t1,ST0_CU0
+ or t0,ST0_CU0
mtc0 t0,CP0_STATUS
1: jal start_kernel
@@ -167,13 +325,18 @@
* Get base address of map0 table for the
* the board we're running on
*/
- la t0,boot_info
- lw t1,OFFSET_BOOTINFO_MACHTYPE(t0)
- la t0,map0table
- sll t1,PTRLOG # machtype used as index
+ lw t1,mips_machgroup # mips_machgroup is set by
+ # bi_EarlySnarf()
+ la t0,map0table
+ sll t1,PTRLOG # machgroup used as index
addu t0,t1
- lw t0,(t0) # get base address
-
+ lw t1,mips_machtype # mips_machtype is set by
+ # bi_EarlySnarf()
+ lw t0,(t0) # load table @ for the group
+ sll t1,PTRLOG # machtype used as index
+ addu t0,t1
+ lw t0,(t0) # load table @ for the box
+ nop
/*
* Get number of wired TLB entries and
* loop over selected map0 table.
@@ -182,18 +345,33 @@
move t2,zero # TLB entry counter
addiu t3,t1,1 # wire one additional entry
beqz t1,2f # null, exit
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+ nop
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
mtc0 t3,CP0_WIRED # delay slot
+#endif
addiu t0,8
1: lw t4,24(t0) # PageMask
ld t5,0(t0) # entryHi
ld t6,8(t0) # entryLo0
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
ld t7,16(t0) # entryLo1
+#endif
addiu t2,1 # increment ctr
mtc0 t2,CP0_INDEX # set TLB entry
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+ nop
+ mtc0 t5,CP0_ENTRYHI
+ nop
+ mtc0 t6,CP0_ENTRYLO0
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
mtc0 t4,CP0_PAGEMASK
dmtc0 t5,CP0_ENTRYHI
dmtc0 t6,CP0_ENTRYLO0
dmtc0 t7,CP0_ENTRYLO1
+#endif
addiu t0,32
bne t1,t2,1b # next TLB entry
tlbwi # delay slot
@@ -202,21 +380,40 @@
* We use only 4k pages. Therefore the PageMask register
* is expected to be setup for 4k pages.
*/
-2: li t0,PM_4K
+2:
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
+ li t0,PM_4K
mtc0 t0,CP0_PAGEMASK
+#endif
/*
* Now map the pagetables
*/
mtc0 zero,CP0_INDEX
la t0,TLB_ROOT
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+ mtc0 t0,CP0_ENTRYHI
+ nop
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
dmtc0 t0,CP0_ENTRYHI
+#endif
la t0,swapper_pg_dir-KSEG1
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+ srl t0,12
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
srl t0,6
+#endif
ori t0,(MODE_ALIAS|MODE_GLOBAL) # uncachable, dirty, valid
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+ mtc0 t0,CP0_ENTRYLO0
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
dmtc0 t0,CP0_ENTRYLO0
li t0,MODE_GLOBAL
dmtc0 t0,CP0_ENTRYLO1
+#endif
nop
tlbwi # delayed
@@ -227,54 +424,18 @@
* NEVER be changed.
*/
li t0,TLBMAP
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+ srl t0,1 # this is a guess!
+ mtc0 t0,CP0_CONTEXT
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
dsll t0,1
dmtc0 t0,CP0_CONTEXT
+#endif
jr ra # delay slot
nop
END(wire_mappings)
-/*
- * Just for debugging...
- */
- .set noreorder
- LEAF(beep)
- lw t0,beepflag
- nop
- bnez t0,1f
- lbu t0,0xe2000061
- xori t0,3
- sb t0,0xe2000061
- li t0,1
- sw t0,beepflag
-1: jr ra
- nop
- END(beep)
-
- .bss
-beepflag: .word 0
- .text
-
-/*
- * Compute kernel code checksum to check kernel code against corruption
- */
- LEAF(csum)
- jal sys_cacheflush
- move t8,ra # delay slot
- li t0,KSEG1
- la t1,final
- li t2,KSEG1
- or t0,t2
- or t1,t2
- move v0,zero
-1: lw t2,(t0)
- addiu t0,4
- bne t0,t1,1b
- xor v0,t2
- jr t8
- nop
- END(csum)
-final:
-
.data
/*
* Build an entry for table of wired entries
@@ -292,6 +453,11 @@ final:
* following by EntryHi/EntryLo pairs and page mask.
* Since everything must be quad-aligned (8) we insert
* some dummy zeros.
+ *
+ * Keep in mind that the PFN does not depend on the page size in the
+ * TLB page mask register. See milo's lib/dumptlb.c for how to decode
+ * and encode these entries. Don't see the same routine in the linux
+ * kernel distribution, since it is older and unreliable.
*/
/*
@@ -299,25 +465,56 @@ final:
* Add your own stuff here but don't forget to define your
* target system in bootinfo.h
*/
+/* First indirection level on the 'group' */
+map0table: PTR map0table_unknown # machgroup = unknown
+ PTR map0table_jazz # machgroup = JAZZ
+ PTR map0table_dec # machgroup = DEC
+ PTR map0table_arc # machgroup = ARC
+ PTR map0table_sni_rm # machgroup = SNI_RM
+ PTR map0table_acn # machgroup = ACN
+ .word 0 # pad
+
+/* table for group 'unknown' */
+map0table_unknown: PTR map0_dummy # machtype = unknown
+ .word 0 # pad
+
+/* table for group 'Jazz' */
+map0table_jazz: PTR map0_pica61 # Acer Pica-61
+ PTR map0_magnum4000 # MIPS Magnum 4000PC (RC4030)
+ PTR map0_magnum4000 # Olivetti M700 (*same* table)
+ .word 0 # pad
-map0table: PTR map0_dummy # machtype = unknown
- PTR map0_rpc # Deskstation rPC44
+/* table for group 'Dec' */
+map0table_dec: PTR map0_dummy # DEC Personal DECStation 5000/2x (for now)
+ .word 0 # pad
+
+/* table for group 'ARC' */
+map0table_arc: PTR map0_rpc # Deskstation rPC44
PTR map0_tyne # Deskstation Tyne
- PTR map0_pica61 # Acer Pica-61
- PTR map0_magnum4000 # MIPS Magnum 4000PC (RC4030)
+/* table for group 'SNI_RM' */
+map0table_sni_rm: PTR map0_sni_rm200_pci # SNI RM200 PCI
+ .word 0
+
+/* table for group 'ACN' */
+map0table_acn: PTR map0_dummy # ACN mips board
+ .word 0
+
+/* dummy table */
map0_dummy: .word 0 # 0 entries
.align 3
/*
- * Initial mappings for Deskstation rPC boards.
- * RB: Untested goodie - I don't have such a board.
+ * Deskstation rpc44 mappings. This machine has its EISA bus at physical
+ * address 0xa0000000 which we map for 32M, but that doesn't match EISA
+ * spec. Not sure what to do about this. Its I/O ports are memory mapped
+ * at physical memory location 0xb0000000.
*/
map0_rpc: .word 2 # no. of wired TLB entries
.word 0 # pad for alignment
-MAPDATA(0xffffffffe0000000, 0x04020017, 0x00000001, PM_1M) # VESA DMA cache
-MAPDATA(0xffffffffe2000000, 0x24000017, 0x04000017, PM_16M) # VESA I/O and memory space
+MAPDATA(0xffffffffe0000000, 0x02800017, 0x00000011, PM_16M) # ISA Memory space
+MAPDATA(0xffffffffe2000000, 0x02c00017, 0x00000011, PM_64K) # ISA I/O Space
/*
* Initial mappings for Deskstation Tyne boards.
@@ -325,23 +522,18 @@ MAPDATA(0xffffffffe2000000, 0x24000017, 0x04000017, PM_16M) # VESA I/O and memor
map0_tyne: .word 2 # no. of wired TLB entries
.word 0 # pad for alignment
-MAPDATA(0xffffffffe0000000, 0x04020017, 0x00000001, PM_1M) # VESA DMA cache
+MAPDATA(0xffffffffe0000000, 0x04020017, 0x00000011, PM_1M) # VESA DMA cache
MAPDATA(0xffffffffe2000000, 0x24000017, 0x04000017, PM_16M) # VESA I/O and memory space
/*
* Initial mapping for ACER PICA-61 boards.
- * FIXME: These are rather preliminary since many drivers, such as serial,
- * parallel, scsi and ethernet need some changes to distinguish between "local"
- * (built-in) and "optional" (ISA/PCI) I/O hardware. Local video ram is mapped
- * to the same location as the bios maps it to. Console driver has been changed
- * accordingly (new video type: VIDEO_TYPE_PICA_S3).
* FIXME: Remove or merge some of the mappings.
*/
map0_pica61: .word 7 # no. wired TLB entries
.word 0 # dummy
-MAPDATA(0xffffffffe0000000, 0x02000017, 0x00000001, PM_64K) # Local I/O space
-MAPDATA(0xffffffffe0100000, 0x03c00017, 0x00000001, PM_4K) # Interrupt source register
+MAPDATA(0xffffffffe0000000, 0x02000017, 0x00000011, PM_64K) # Local I/O space
+MAPDATA(0xffffffffe0100000, 0x03c00017, 0x00000011, PM_4K) # Interrupt source register
MAPDATA(0xffffffffe0200000, 0x01800017, 0x01804017, PM_1M) # Local video control
MAPDATA(0xffffffffe0400000, 0x01808017, 0x0180c017, PM_1M) # Extended video control
MAPDATA(0xffffffffe0800000, 0x01000017, 0x01010017, PM_4M) # Local video memory (BIOS mapping)
@@ -350,23 +542,27 @@ MAPDATA(0xffffffffffffe000, 0x00000001, 0x0001ffd7, PM_4K) # PCR (???)
/*
* Initial mapping for Mips Magnum 4000PC systems.
- * Do you believe me now that the Acer and Mips boxes are nearly the same ? :-)
* FIXME: Remove or merge some of the mappings.
*/
-
map0_magnum4000:
.word 8 # no. wired TLB entries
.word 0 # dummy
-MAPDATA(0xffffffffe1000000, 0x03ffc013, 0x00000001, 0x7e000) # 0
-MAPDATA(0xffffffffe0000000, 0x02000017, 0x00000001, 0x1e000) # 1 local I/O
-MAPDATA(0xffffffffe0100000, 0x03c00017, 0x00000001, 0) # 2 IRQ source
-MAPDATA(0xffffffffe0200000, 0x01800017, 0x01804017, 0x1fe000) # 3 local video ctrl
-MAPDATA(0xffffffffe0400000, 0x01808017, 0x0180c017, 0x1fe000) # 4 ext. video ctrl
-MAPDATA(0xffffffffe0800000, 0x01000017, 0x01010017, 0x7fe000) # 5 local video mem.
-MAPDATA(0xffffffffe2000000, 0x02400017, 0x02440017, 0x1ffe000) # 6 ISA I/O and mem.
-MAPDATA(0xffffffffffffe000, 0x00000001, 0x0001ffd7, 0) # 7 PCR
+MAPDATA(0xffffffffe1000000, 0x03ffc013, 0x00000011, PM_256K) # 0
+MAPDATA(0xffffffffe0000000, 0x02000017, 0x00000011, PM_64K) # 1 local I/O
+MAPDATA(0xffffffffe0100000, 0x03c00017, 0x00000011, PM_4K) # 2 IRQ source
+MAPDATA(0xffffffffe0200000, 0x01800017, 0x01804017, PM_1M) # 3 local video ctrl
+MAPDATA(0xffffffffe0400000, 0x01808017, 0x0180c017, PM_1M) # 4 ext. video ctrl
+MAPDATA(0xffffffffe0800000, 0x01000017, 0x01010017, PM_4M) # 5 local video mem.
+MAPDATA(0xffffffffe2000000, 0x02400017, 0x02440017, PM_16M) # 6 ISA I/O and mem.
+MAPDATA(0xffffffffffffe000, 0x00000001, 0x0001ffd7, PM_4K) # 7 PCR
+/*
+ * The RM200 doesn't need any wired entries.
+ */
+map0_sni_rm200_pci:
+ .word 0 # no. wired TLB entries
+ .word 0 # dummy
.text
@@ -374,35 +570,19 @@ MAPDATA(0xffffffffffffe000, 0x00000001, 0x0001ffd7, 0) # 7 PCR
.globl swapper_pg_dir
swapper_pg_dir = . + (KSEG1-KSEG0)
-/*
- * The page tables are initialized to only 4MB here - the final page
- * tables are set up later depending on memory size.
- */
.org 0x2000
- EXPORT(pg0)
-
- .org 0x3000
EXPORT(empty_bad_page)
- .org 0x4000
+ .org 0x3000
EXPORT(empty_bad_page_table)
- .org 0x5000
+ .org 0x4000
EXPORT(empty_zero_page)
- .org 0x6000
+ .org 0x5000
EXPORT(invalid_pte_table)
- .org 0x7000
-
-/*
- * floppy_track_buffer is used to buffer one track of floppy data: it
- * has to be separate from the tmp_floppy area, as otherwise a single-
- * sector read/write can mess it up. It can contain one full cylinder (sic) of
- * data (36*2*512 bytes).
- */
- EXPORT(floppy_track_buffer)
- .fill 512*2*36,1,0
+ .org 0x6000
EXPORT(cache_error_buffer)
.fill 32*4,1,0
diff --git a/arch/mips/kernel/ipc.c b/arch/mips/kernel/ipc.c
new file mode 100644
index 000000000..336965acf
--- /dev/null
+++ b/arch/mips/kernel/ipc.c
@@ -0,0 +1,109 @@
+/*
+ * linux/arch/mips/kernel/ipc.c
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/MIPS
+ * platform.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly. FIXME: Get rid of this wrapper.
+ */
+asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
+{
+#ifdef CONFIG_SYSVIPC
+ int version;
+
+ version = call >> 16; /* hack for backward compatibility */
+ call &= 0xffff;
+
+ if (call <= SEMCTL)
+ switch (call) {
+ case SEMOP:
+ return sys_semop (first, (struct sembuf *)ptr, second);
+ case SEMGET:
+ return sys_semget (first, second, third);
+ case SEMCTL: {
+ union semun fourth;
+ int err;
+ if (!ptr)
+ return -EINVAL;
+ if ((err = verify_area (VERIFY_READ, ptr, sizeof(long))))
+ return err;
+ get_from_user(fourth.__pad, ptr);
+ return sys_semctl (first, second, third, fourth);
+ }
+ default:
+ return -EINVAL;
+ }
+ if (call <= MSGCTL)
+ switch (call) {
+ case MSGSND:
+ return sys_msgsnd (first, (struct msgbuf *) ptr,
+ second, third);
+ case MSGRCV:
+ switch (version) {
+ case 0: {
+ struct ipc_kludge tmp;
+ int err;
+ if (!ptr)
+ return -EINVAL;
+ if ((err = verify_area (VERIFY_READ, ptr, sizeof(tmp))))
+ return err;
+ memcpy_fromfs (&tmp,(struct ipc_kludge *) ptr,
+ sizeof (tmp));
+ return sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third);
+ }
+ case 1: default:
+ return sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third);
+ }
+ case MSGGET:
+ return sys_msgget ((key_t) first, second);
+ case MSGCTL:
+ return sys_msgctl (first, second, (struct msqid_ds *) ptr);
+ default:
+ return -EINVAL;
+ }
+ if (call <= SHMCTL)
+ switch (call) {
+ case SHMAT:
+ switch (version) {
+ case 0: default: {
+ ulong raddr;
+ int err;
+ if ((err = verify_area(VERIFY_WRITE, (ulong*) third, sizeof(ulong))))
+ return err;
+ err = sys_shmat (first, (char *) ptr, second, &raddr);
+ if (err)
+ return err;
+ put_user (raddr, (ulong *) third);
+ return 0;
+ }
+ case 1: /* iBCS2 emulator entry point */
+ if (get_fs() != get_ds())
+ return -EINVAL;
+ return sys_shmat (first, (char *) ptr, second, (ulong *) third);
+ }
+ case SHMDT:
+ return sys_shmdt ((char *)ptr);
+ case SHMGET:
+ return sys_shmget (first, second, third);
+ case SHMCTL:
+ return sys_shmctl (first, second, (struct shmid_ds *) ptr);
+ default:
+ return -EINVAL;
+ }
+ return -EINVAL;
+#else /* CONFIG_SYSVIPC */
+ return -ENOSYS;
+#endif /* CONFIG_SYSVIPC */
+}
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index 608a0b431..a6f257c88 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -8,125 +8,120 @@
* instead of just grabbing them. Thus setups with different IRQ numbers
* shouldn't result in any weird surprises, and installing new handlers
* should be easier.
- */
-
-/*
- * IRQ's are in fact implemented a bit like signal handlers for the kernel.
- * Naturally it's not a 1:1 relation, but there are similarities.
- */
-
-/*
- * Mips support by Ralf Baechle and Andreas Busse
*
- * The Deskstation Tyne is almost completely like an IBM compatible PC with
- * another type of microprocessor. Therefore this code is almost completely
- * the same. More work needs to be done to support Acer PICA and other
- * machines.
+ * Mips support by Ralf Baechle and Andreas Busse
*/
-
-#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/kernel_stat.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/jazz.h>
+#include <asm/mipsregs.h>
#include <asm/system.h>
+#include <asm/vector.h>
unsigned char cache_21 = 0xff;
unsigned char cache_A1 = 0xff;
unsigned long spurious_count = 0;
-void disable_irq(unsigned int irq_nr)
+/*
+ * (un)mask_irq, disable_irq() and enable_irq() only handle (E)ISA and
+ * PCI devices. Other onboard hardware needs specific routines.
+ */
+static inline void mask_irq(unsigned int irq_nr)
{
- unsigned long flags;
unsigned char mask;
mask = 1 << (irq_nr & 7);
- save_flags(flags);
if (irq_nr < 8) {
- cli();
cache_21 |= mask;
outb(cache_21,0x21);
- restore_flags(flags);
- return;
+ } else {
+ cache_A1 |= mask;
+ outb(cache_A1,0xA1);
}
- cli();
- cache_A1 |= mask;
- outb(cache_A1,0xA1);
- restore_flags(flags);
}
-void enable_irq(unsigned int irq_nr)
+static inline void unmask_irq(unsigned int irq_nr)
{
- unsigned long flags;
unsigned char mask;
mask = ~(1 << (irq_nr & 7));
- save_flags(flags);
if (irq_nr < 8) {
- cli();
cache_21 &= mask;
outb(cache_21,0x21);
- restore_flags(flags);
- return;
+ } else {
+ cache_A1 &= mask;
+ outb(cache_A1,0xA1);
}
+}
+
+void disable_irq(unsigned int irq_nr)
+{
+ unsigned long flags;
+
+ save_flags(flags);
cli();
- cache_A1 &= mask;
- outb(cache_A1,0xA1);
+ mask_irq(irq_nr);
+ restore_flags(flags);
+}
+
+void enable_irq(unsigned int irq_nr)
+{
+ unsigned long flags;
+ save_flags(flags);
+ cli();
+ unmask_irq(irq_nr);
restore_flags(flags);
}
/*
- * Pointers to the low-level handlers: first the general ones, then the
- * fast ones, then the bad ones.
+ * Low-level interrupt handlers: first the timer interrupt, then the
+ * general, then the fast and finally the bad interrupt handler.
*/
+extern void timer_interrupt(void);
extern void interrupt(void);
extern void fast_interrupt(void);
extern void bad_interrupt(void);
-/*
- * Initial irq handlers.
- */
-struct irqaction {
- void (*handler)(int, struct pt_regs *);
- unsigned long flags;
- unsigned long mask;
- const char *name;
-};
-
-static struct irqaction irq_action[16] = {
- { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
- { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
- { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
- { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
- { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
- { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
- { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
- { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }
+static struct irqaction *irq_action[16] = {
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL
};
int get_irq_list(char *buf)
{
int i, len = 0;
- struct irqaction * action = irq_action;
+ struct irqaction * action;
- for (i = 0 ; i < 16 ; i++, action++) {
- if (!action->handler)
+ for (i = 0 ; i < 16 ; i++) {
+ action = irq_action[i];
+ if (!action)
continue;
- len += sprintf(buf+len, "%2d: %8d %c %s\n",
+ len += sprintf(buf+len, "%2d: %8u %c %s",
i, kstat.interrupts[i],
(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, "\n");
}
return len;
}
@@ -140,14 +135,17 @@ int get_irq_list(char *buf)
*/
asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
{
- struct irqaction * action = irq + irq_action;
-#if 0
-if (irq > 0) {
- printk("in do_IRQ with irq=%d\n",irq);
-}
-#endif
+ struct irqaction * action = *(irq + irq_action);
+ int do_random = 0;
+
kstat.interrupts[irq]++;
- action->handler(irq, regs);
+ while (action) {
+ do_random |= action->flags;
+ action->handler(irq, action->dev_id, regs);
+ action = action->next;
+ }
+ if (do_random & SA_SAMPLE_RANDOM)
+ add_interrupt_randomness(irq);
}
/*
@@ -157,129 +155,159 @@ if (irq > 0) {
*/
asmlinkage void do_fast_IRQ(int irq)
{
- struct irqaction * action = irq + irq_action;
+ struct irqaction * action = *(irq + irq_action);
+ int do_random = 0;
kstat.interrupts[irq]++;
- action->handler(irq, NULL);
+ while (action) {
+ do_random |= action->flags;
+ action->handler(irq, action->dev_id, NULL);
+ action = action->next;
+ }
+ if (do_random & SA_SAMPLE_RANDOM)
+ add_interrupt_randomness(irq);
}
-#define SA_PROBE SA_ONESHOT
+/*
+ * Used only for setup of PC style interrupts and therefore still
+ * called setup_x86_irq. Later on I'll provide a machine specific
+ * function with similar purpose. Idea is to put all interrupts
+ * in a single table and differenciate them just by number.
+ */
+int setup_x86_irq(int irq, struct irqaction * new)
+{
+ int shared = 0;
+ struct irqaction *old, **p;
+ unsigned long flags;
+
+ p = irq_action + irq;
+ if ((old = *p) != NULL) {
+ /* Can't share interrupts unless both agree to */
+ if (!(old->flags & new->flags & SA_SHIRQ))
+ return -EBUSY;
+
+ /* Can't share interrupts unless both are same type */
+ if ((old->flags ^ new->flags) & SA_INTERRUPT)
+ return -EBUSY;
+
+ /* add new interrupt at end of irq queue */
+ do {
+ p = &old->next;
+ old = *p;
+ } while (old);
+ shared = 1;
+ }
+
+ if (new->flags & SA_SAMPLE_RANDOM)
+ rand_initialize_irq(irq);
-int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *),
- unsigned long irqflags, const char * devname)
+ save_flags(flags);
+ cli();
+ *p = new;
+
+ if (!shared) {
+ if (new->flags & SA_INTERRUPT)
+ set_int_vector(irq,fast_interrupt);
+ else
+ if (irq == 0)
+ set_int_vector(irq,timer_interrupt);
+ else
+ set_int_vector(irq,interrupt);
+ unmask_irq(irq);
+ }
+ restore_flags(flags);
+ return 0;
+}
+
+int request_irq(unsigned int irq,
+ void (*handler)(int, void *, struct pt_regs *),
+ unsigned long irqflags,
+ const char * devname,
+ void *dev_id)
{
+ int retval;
struct irqaction * action;
- unsigned long flags;
if (irq > 15)
return -EINVAL;
- action = irq + irq_action;
- if (action->handler)
- return -EBUSY;
if (!handler)
return -EINVAL;
- save_flags(flags);
- cli();
+
+ 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;
- if (!(action->flags & SA_PROBE)) { /* SA_ONESHOT is used by probing */
- /*
- * FIXME: Does the SA_INTERRUPT flag make any sense on MIPS???
- */
- if (action->flags & SA_INTERRUPT)
- set_int_vector(irq,fast_interrupt);
- else
- set_int_vector(irq,interrupt);
- }
- if (irq < 8) {
- cache_21 &= ~(1<<irq);
- outb(cache_21,0x21);
- } else {
- cache_21 &= ~(1<<2);
- cache_A1 &= ~(1<<(irq-8));
- outb(cache_21,0x21);
- outb(cache_A1,0xA1);
- }
- restore_flags(flags);
- return 0;
-}
+ action->next = NULL;
+ action->dev_id = dev_id;
+
+ retval = setup_x86_irq(irq, action);
-void free_irq(unsigned int irq)
+ if (retval)
+ kfree(action);
+ return retval;
+}
+
+void free_irq(unsigned int irq, void *dev_id)
{
- struct irqaction * action = irq + irq_action;
+ struct irqaction * action, **p;
unsigned long flags;
if (irq > 15) {
printk("Trying to free IRQ%d\n",irq);
return;
}
- if (!action->handler) {
- printk("Trying to free free IRQ%d\n",irq);
+ for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
+ if (action->dev_id != dev_id)
+ continue;
+
+ /* Found it - now free it */
+ save_flags(flags);
+ cli();
+ *p = action->next;
+ if (!irq[irq_action]) {
+ mask_irq(irq);
+ set_int_vector(irq, bad_interrupt);
+ }
+ restore_flags(flags);
+ kfree(action);
return;
}
- save_flags(flags);
- cli();
- if (irq < 8) {
- cache_21 |= 1 << irq;
- outb(cache_21,0x21);
- } else {
- cache_A1 |= 1 << (irq-8);
- outb(cache_A1,0xA1);
- }
- set_int_vector(irq,bad_interrupt);
- action->handler = NULL;
- action->flags = 0;
- action->mask = 0;
- action->name = NULL;
- restore_flags(flags);
+ printk("Trying to free free IRQ%d\n",irq);
}
-static void no_action(int cpl, struct pt_regs * regs) { }
-
-unsigned int probe_irq_on (void)
+unsigned long probe_irq_on (void)
{
unsigned int i, irqs = 0, irqmask;
unsigned long delay;
- /* first, snaffle up any unassigned irqs */
+ /* first, enable any unassigned irqs */
for (i = 15; i > 0; i--) {
- if (!request_irq(i, no_action, SA_PROBE, "probe")) {
+ if (!irq_action[i]) {
enable_irq(i);
irqs |= (1 << i);
}
}
/* wait for spurious interrupts to mask themselves out again */
- for (delay = jiffies + 2; delay > jiffies; ); /* min 10ms delay */
+ for (delay = jiffies + HZ/10; delay > jiffies; )
+ /* about 100ms delay */;
/* now filter out any obviously spurious interrupts */
irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21;
- for (i = 15; i > 0; i--) {
- if (irqs & (1 << i) & irqmask) {
- irqs ^= (1 << i);
- free_irq(i);
- }
- }
-#ifdef DEBUG
- printk("probe_irq_on: irqs=0x%04x irqmask=0x%04x\n", irqs, irqmask);
-#endif
- return irqs;
+ return irqs & ~irqmask;
}
-int probe_irq_off (unsigned int irqs)
+int probe_irq_off (unsigned long irqs)
{
unsigned int i, irqmask;
irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21;
- for (i = 15; i > 0; i--) {
- if (irqs & (1 << i)) {
- free_irq(i);
- }
- }
#ifdef DEBUG
- printk("probe_irq_off: irqs=0x%04x irqmask=0x%04x\n", irqs, irqmask);
+ printk("probe_irq_off: irqs=0x%04lx irqmask=0x%04x\n", irqs, irqmask);
#endif
irqs &= irqmask;
if (!irqs)
@@ -294,41 +322,7 @@ void init_IRQ(void)
{
int i;
- switch (boot_info.machtype) {
- case MACH_MIPS_MAGNUM_4000:
- case MACH_ACER_PICA_61:
- r4030_write_reg16(JAZZ_IO_IRQ_ENABLE,
- JAZZ_IE_ETHERNET |
- JAZZ_IE_SERIAL1 |
- JAZZ_IE_SERIAL2 |
- JAZZ_IE_PARALLEL |
- JAZZ_IE_FLOPPY);
- r4030_read_reg16(JAZZ_IO_IRQ_SOURCE); /* clear pending IRQs */
- set_cp0_status(ST0_IM, IE_IRQ4 | IE_IRQ1);
- /* set the clock to 100 Hz */
- r4030_write_reg32(JAZZ_TIMER_INTERVAL, 9);
- break;
- case MACH_DESKSTATION_TYNE:
- /* set the clock to 100 Hz */
- outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
- outb_p(LATCH & 0xff , 0x40); /* LSB */
- outb(LATCH >> 8 , 0x40); /* MSB */
-
- if (request_irq(2, no_action, SA_INTERRUPT, "cascade"))
- printk("Unable to get IRQ2 for cascade\n");
- break;
- default:
- panic("Unknown machtype in init_IRQ");
- }
-
for (i = 0; i < 16 ; i++)
set_int_vector(i, bad_interrupt);
-
- /* initialize the bottom half routines. */
- for (i = 0; i < 32; i++) {
- bh_base[i].routine = NULL;
- bh_base[i].data = NULL;
- }
- bh_active = 0;
- intr_count = 0;
+ irq_setup();
}
diff --git a/arch/mips/kernel/jazzdma.c b/arch/mips/kernel/jazzdma.c
deleted file mode 100644
index 1d535e716..000000000
--- a/arch/mips/kernel/jazzdma.c
+++ /dev/null
@@ -1,518 +0,0 @@
-/*
- * jazzdma.c
- *
- * Mips Jazz DMA controller support
- * (C) 1995 Andreas Busse
- *
- * NOTE: Some of the argument checkings could be removed when
- * things have settled down. Also, instead of returning 0xffffffff
- * on failure of vdma_alloc() one could leave page #0 unused
- * and return the more usual NULL pointer as logical address.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <asm/mipsregs.h>
-#include <asm/mipsconfig.h>
-#include <asm/jazz.h>
-#include <asm/io.h>
-#include <asm/segment.h>
-#include <asm/dma.h>
-#include <asm/jazzdma.h>
-
-
-static unsigned long vdma_pagetable_start = 0;
-static unsigned long vdma_pagetable_end = 0;
-
-/*
- * Debug stuff
- */
-
-#define DEBUG_VDMA 0
-#define vdma_debug ((DEBUG_VDMA) ? debuglvl : 0)
-
-static int debuglvl = 3;
-
-/*
- * Local prototypes
- */
-
-static void vdma_pgtbl_init(void);
-
-
-/*
- * Initialize the Jazz R4030 dma controller
- */
-
-unsigned long vdma_init(unsigned long memory_start, unsigned long memory_end)
-{
-
- /*
- * Allocate 32k of memory for DMA page tables.
- * This needs to be page aligned and should be
- * uncached to avoid cache flushing after every
- * update.
- */
-
- vdma_pagetable_start = KSEG1ADDR((memory_start + 4095) & ~ 4095);
- vdma_pagetable_end = vdma_pagetable_start + VDMA_PGTBL_SIZE;
-
-
- /*
- * Clear the R4030 translation table
- */
-
- vdma_pgtbl_init();
-
- r4030_write_reg32(JAZZ_R4030_TRSTBL_BASE,PHYSADDR(vdma_pagetable_start));
- r4030_write_reg32(JAZZ_R4030_TRSTBL_LIM,VDMA_PGTBL_SIZE);
- r4030_write_reg32(JAZZ_R4030_TRSTBL_INV,0);
-
- printk("VDMA: R4030 DMA pagetables initialized.\n");
- return(KSEG0ADDR(vdma_pagetable_end));
-}
-
-/*
- * Allocate DMA pagetables using a simple first-fit algorithm
- */
-
-unsigned long vdma_alloc(unsigned long paddr, unsigned long size)
-{
- VDMA_PGTBL_ENTRY *entry = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
- int first;
- int last;
- int pages;
- unsigned int frame;
- unsigned long laddr;
- int i;
-
- /* check arguments */
-
- if (paddr > 0x1fffffff) {
- if (vdma_debug)
- printk("vdma_alloc: Invalid physical address: %08lx\n",paddr);
- return (VDMA_ERROR); /* invalid physical address */
- }
- if (size > 0x400000 || size == 0) {
- if (vdma_debug)
- printk("vdma_alloc: Invalid size: %08lx\n",size);
- return (VDMA_ERROR); /* invalid physical address */
- }
-
- /* find free chunk */
-
- pages = (size + 4095) >> 12; /* no. of pages to allocate */
- first = 0;
- while (1) {
- while (entry[first].owner != VDMA_PAGE_EMPTY && first < VDMA_PGTBL_ENTRIES)
- first++;
- if (first+pages > VDMA_PGTBL_ENTRIES) /* nothing free */
- return (VDMA_ERROR);
-
- last = first+1;
- while (entry[last].owner == VDMA_PAGE_EMPTY && last-first < pages)
- last++;
-
- if (last-first == pages)
- break; /* found */
- }
-
- /* mark pages as allocated */
-
- laddr = (first << 12) + (paddr & (VDMA_PAGESIZE-1));
- frame = paddr & ~(VDMA_PAGESIZE-1);
-
- for (i=first; i<last; i++) {
- entry[i].frame = frame;
- entry[i].owner = laddr;
- frame += VDMA_PAGESIZE;
- }
-
- /*
- * update translation table and
- * return logical start address
- */
-
- r4030_write_reg32(JAZZ_R4030_TRSTBL_INV,0);
-
- if (vdma_debug > 1)
- printk("vdma_alloc: Allocated %d pages starting from %08lx\n",
- pages,laddr);
-
- if (vdma_debug > 2) {
- printk("LADDR: ");
- for (i=first; i<last; i++)
- printk("%08x ",i<<12);
- printk("\nPADDR: ");
- for (i=first; i<last; i++)
- printk("%08x ",entry[i].frame);
- printk("\nOWNER: ");
- for (i=first; i<last; i++)
- printk("%08x ",entry[i].owner);
- printk("\n");
- }
-
- return(laddr);
-}
-
-
-/*
- * Free previously allocated dma translation pages
- * Note that this does NOT change the translation table,
- * it just marks the free'd pages as unused!
- */
-
-int vdma_free(unsigned long laddr)
-{
- VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
- int i;
-
- i = laddr >> 12;
-
- if (pgtbl[i].owner != laddr) {
- printk("vdma_free: trying to free other's dma pages, laddr=%8lx\n",laddr);
- return -1;
- }
-
- while (pgtbl[i].owner == laddr && i < VDMA_PGTBL_ENTRIES) {
- pgtbl[i].owner = VDMA_PAGE_EMPTY;
- i++;
- }
-
- if (vdma_debug > 1)
- printk("vdma_free: freed %ld pages starting from %08lx\n",
- i-(laddr>>12),laddr);
-
- return 0;
-}
-
-/*
- * Map certain page(s) to another physical address.
- * Caller must have allocated the page(s) before.
- */
-
-int vdma_remap(unsigned long laddr, unsigned long paddr, unsigned long size)
-{
- VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
- int first;
- int pages;
-
- if (laddr > 0xffffff) {
- if (vdma_debug)
- printk("vdma_map: Invalid logical address: %08lx\n",laddr);
- return -EINVAL; /* invalid logical address */
- }
- if (paddr > 0x1fffffff) {
- if (vdma_debug)
- printk("vdma_map: Invalid physical address: %08lx\n",paddr);
- return -EINVAL; /* invalid physical address */
- }
-
- pages = (((paddr & (VDMA_PAGESIZE-1)) + size) >> 12) + 1;
- first = laddr >> 12;
- if (vdma_debug)
- printk("vdma_remap: first=%x, pages=%x\n",first,pages);
- if (first+pages > VDMA_PGTBL_ENTRIES) {
- if (vdma_debug)
- printk("vdma_alloc: Invalid size: %08lx\n",size);
- return -EINVAL;
- }
-
- paddr &= ~(VDMA_PAGESIZE-1);
- while (pages > 0 && first < VDMA_PGTBL_ENTRIES) {
- if (pgtbl[first].owner != laddr) {
- if (vdma_debug)
- printk("Trying to remap other's pages.\n");
- return -EPERM; /* not owner */
- }
- pgtbl[first].frame = paddr;
- paddr += VDMA_PAGESIZE;
- first++;
- pages--;
- }
-
- /* update translation table */
-
- r4030_write_reg32(JAZZ_R4030_TRSTBL_INV,0);
-
-
- if (vdma_debug > 2) {
- int i;
- pages = (((paddr & (VDMA_PAGESIZE-1)) + size) >> 12) + 1;
- first = laddr >> 12;
- printk("LADDR: ");
- for (i=first; i<first+pages; i++)
- printk("%08x ",i<<12);
- printk("\nPADDR: ");
- for (i=first; i<first+pages; i++)
- printk("%08x ",pgtbl[i].frame);
- printk("\nOWNER: ");
- for (i=first; i<first+pages; i++)
- printk("%08x ",pgtbl[i].owner);
- printk("\n");
- }
-
- return 0;
-}
-
-/*
- * Translate a physical address to a logical address.
- * This will return the logical address of the first
- * match.
- */
-
-unsigned long vdma_phys2log(unsigned long paddr)
-{
- int i;
- int frame;
- VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
-
- frame = paddr & ~(VDMA_PAGESIZE-1);
-
- for (i=0; i<VDMA_PGTBL_ENTRIES; i++) {
- if (pgtbl[i].frame == frame)
- break;
- }
-
- if (i == VDMA_PGTBL_ENTRIES)
- return(0xffffffff);
-
- return((i<<12) + (paddr & (VDMA_PAGESIZE-1)));
-}
-
-/*
- * Translate a logical DMA address to a physical address
- */
-unsigned long vdma_log2phys(unsigned long laddr)
-{
- VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
-
- return(pgtbl[laddr >> 12].frame + (laddr & (VDMA_PAGESIZE-1)));
-}
-
-
-/*
- * initialize the pagetable with a one-to-one mapping of
- * the first 16 Mbytes of main memory and declare all
- * entries to be unused. Using this method will at least
- * allow some early device driver operations to work.
- */
-
-static void vdma_pgtbl_init(void)
-{
- int i;
- unsigned long paddr = 0;
- VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *)vdma_pagetable_start;
-
- for (i=0; i<VDMA_PGTBL_ENTRIES; i++) {
- pgtbl[i].frame = paddr;
- pgtbl[i].owner = VDMA_PAGE_EMPTY;
- paddr += VDMA_PAGESIZE;
- }
-
-/* vdma_stats(); */
-}
-
-/*
- * Print DMA statistics
- */
-
-void vdma_stats(void)
-{
- int i;
-
- printk("vdma_stats: CONFIG: %08x\n",
- r4030_read_reg32(JAZZ_R4030_CONFIG));
- printk("R4030 translation table base: %08x\n",
- r4030_read_reg32(JAZZ_R4030_TRSTBL_BASE));
- printk("R4030 translation table limit: %08x\n",
- r4030_read_reg32(JAZZ_R4030_TRSTBL_LIM));
- printk("vdma_stats: INV_ADDR: %08x\n",
- r4030_read_reg32(JAZZ_R4030_INV_ADDR));
- printk("vdma_stats: R_FAIL_ADDR: %08x\n",
- r4030_read_reg32(JAZZ_R4030_R_FAIL_ADDR));
- printk("vdma_stats: M_FAIL_ADDR: %08x\n",
- r4030_read_reg32(JAZZ_R4030_M_FAIL_ADDR));
- printk("vdma_stats: IRQ_SOURCE: %08x\n",
- r4030_read_reg32(JAZZ_R4030_IRQ_SOURCE));
- printk("vdma_stats: I386_ERROR: %08x\n",
- r4030_read_reg32(JAZZ_R4030_I386_ERROR));
- printk("vdma_chnl_modes: ");
- for (i=0; i<8; i++)
- printk("%04x ",(unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_MODE+(i<<5)));
- printk("\n");
- printk("vdma_chnl_enables: ");
- for (i=0; i<8; i++)
- printk("%04x ",(unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(i<<5)));
- printk("\n");
-}
-
-
-/*
- * DMA transfer functions
- */
-
-/*
- * Enable a DMA channel. Also clear any error conditions.
- */
-void vdma_enable(int channel)
-{
- int status;
-
- if (vdma_debug)
- printk("vdma_enable: channel %d\n",channel);
-
- /*
- * Check error conditions first
- */
- status = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5));
- if (status & 0x400)
- printk("VDMA: Channel %d: Address error!\n",channel);
- if (status & 0x200)
- printk("VDMA: Channel %d: Memory error!\n",channel);
-
- /*
- * Clear all interrupt flags
- */
- r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5),
- R4030_TC_INTR | R4030_MEM_INTR | R4030_ADDR_INTR);
-
- /*
- * Enable the desired channel
- */
- r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5),
- r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5)) |
- R4030_CHNL_ENABLE);
-}
-
-/*
- * Disable a DMA channel
- */
-void vdma_disable(int channel)
-{
- if (vdma_debug)
- {
- int status = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5));
-
- printk("vdma_disable: channel %d\n",channel);
- printk("VDMA: channel %d status: %04x (%s) mode: %02x addr: %06x count: %06x\n",
- channel,status,((status & 0x600) ? "ERROR" : "OK"),
- (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_MODE+(channel<<5)),
- (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_ADDR+(channel<<5)),
- (unsigned)r4030_read_reg32(JAZZ_R4030_CHNL_COUNT+(channel<<5)));
- }
-
- r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5),
- r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5)) &
- ~R4030_CHNL_ENABLE);
-
- /*
- * After disabling a DMA channel a remote bus register should be
- * read to ensure that the current DMA acknowledge cycle is completed.
- */
-
- *((volatile unsigned int *)JAZZ_DUMMY_DEVICE);
-}
-
-/*
- * Set DMA mode. This function accepts the mode values used
- * to set a PC-style DMA controller. For the SCSI and FDC
- * channels, we also set the default modes each time we're
- * called.
- * NOTE: The FAST and BURST dma modes are supported by the
- * R4030 Rev. 2 and PICA chipsets only. I leave them disabled
- * for now.
- */
-void vdma_set_mode(int channel, int mode)
-{
- if (vdma_debug)
- printk("vdma_set_mode: channel %d, mode 0x%x\n",channel,mode);
-
- switch(channel)
- {
- case JAZZ_SCSI_DMA: /* scsi */
- r4030_write_reg32(JAZZ_R4030_CHNL_MODE+(channel<<5),
-/* R4030_MODE_FAST | */
-/* R4030_MODE_BURST | */
- R4030_MODE_INTR_EN |
- R4030_MODE_WIDTH_16 |
- R4030_MODE_ATIME_80);
- break;
-
- case JAZZ_FLOPPY_DMA: /* floppy */
- r4030_write_reg32(JAZZ_R4030_CHNL_MODE+(channel<<5),
-/* R4030_MODE_FAST | */
-/* R4030_MODE_BURST | */
- R4030_MODE_INTR_EN |
- R4030_MODE_WIDTH_8 |
- R4030_MODE_ATIME_120);
- break;
-
- case JAZZ_AUDIOL_DMA:
- case JAZZ_AUDIOR_DMA:
- printk("VDMA: Audio DMA not supported yet.\n");
- break;
-
- default:
- printk("VDMA: vdma_set_mode() called with unsupported channel %d!\n",channel);
- }
-
- switch(mode)
- {
- case DMA_MODE_READ:
- r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5),
- r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5)) &
- ~R4030_CHNL_WRITE);
- break;
-
- case DMA_MODE_WRITE:
- r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5),
- r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5)) |
- R4030_CHNL_WRITE);
- break;
-
- default:
- printk("VDMA: vdma_set_mode() called with unknown dma mode 0x%x\n",mode);
- }
-}
-
-/*
- * Set Transfer Address
- */
-void vdma_set_addr(int channel, long addr)
-{
- if (vdma_debug)
- printk("vdma_set_addr: channel %d, addr %lx\n",channel,addr);
-
- r4030_write_reg32(JAZZ_R4030_CHNL_ADDR+(channel<<5),addr);
-}
-
-/*
- * Set Transfer Count
- */
-void vdma_set_count(int channel, int count)
-{
- if (vdma_debug)
- printk("vdma_set_count: channel %d, count %08x\n",channel,(unsigned)count);
-
- r4030_write_reg32(JAZZ_R4030_CHNL_COUNT+(channel<<5),count);
-}
-
-/*
- * Get Residual
- */
-int vdma_get_residue(int channel)
-{
- int residual;
-
- residual = r4030_read_reg32(JAZZ_R4030_CHNL_COUNT+(channel<<5));
-
- if (vdma_debug)
- printk("vdma_get_residual: channel %d: residual=%d\n",channel,residual);
-
- return(residual);
-}
-
-
-/* end of file jazzdma.h */
diff --git a/arch/mips/kernel/ksyms.c b/arch/mips/kernel/ksyms.c
new file mode 100644
index 000000000..c80bf588a
--- /dev/null
+++ b/arch/mips/kernel/ksyms.c
@@ -0,0 +1,40 @@
+/*
+ * Export MIPS-specific functions needed for loadable modules.
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ */
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <asm/cache.h>
+#include <asm/dma.h>
+#include <asm/floppy.h>
+#include <asm/io.h>
+
+static struct symbol_table arch_symbol_table = {
+#include <linux/symtab_begin.h>
+ X(EISA_bus),
+ /*
+ * String functions
+ */
+ X(__generic_memset_b),
+ X(__generic_memset_dw),
+ /*
+ * Functions to control caches.
+ */
+ X(cacheflush),
+ X(fd_cacheflush),
+ /*
+ * Base address of ports for Intel style I/O.
+ */
+ X(port_base),
+#include <linux/symtab_end.h>
+};
+
+void arch_syms_export(void)
+{
+ register_symtab(&arch_symbol_table);
+}
diff --git a/arch/mips/kernel/magnum4000.S b/arch/mips/kernel/magnum4000.S
deleted file mode 100644
index 45e62d88d..000000000
--- a/arch/mips/kernel/magnum4000.S
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * arch/mips/kernel/magnum4000.S
- *
- * Copyright (C) 1995 Waldorf Electronics
- * written by Ralf Baechle and Andreas Busse
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/jazz.h>
-#include <asm/stackframe.h>
-
-/*
- * mips_magnum_4000_handle_int: Interrupt handler for Mips Magnum 4000
- */
- .set noreorder
-
- NESTED(mips_magnum_4000_handle_int, FR_SIZE, ra)
- .set noat
- SAVE_ALL
- CLI
- .set at
-
- /*
- * 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
- beqz t0,spurious_interrupt
- sll t0,16 # delay slot
-
- /*
- * Find irq with highest priority
- * FIXME: This is slow
- */
- la t1,ll_vectors
-1: bltz t0,2f # found pending irq
- sll t0,1
- b 1b
- subu t1,PTRSIZE # delay slot
-
- /*
- * Do the low-level stuff
- */
-2: lw t0,(t1)
- jr t0
- nop # delay slot
- END(mips_magnum_4000_handle_int)
-
-/*
- * Used for keyboard driver's fake_keyboard_interrupt()
- */
-ll_sw0: li s1,~IE_SW0
- mfc0 t0,CP0_CAUSE
- and t0,s1
- mtc0 t0,CP0_CAUSE
- PRINT("sw0 received...\n")
- li t1,1
- b call_real
- li t3,PTRSIZE # delay slot, re-map to irq level 1
-
-ll_sw1: li s1,~IE_SW1
- PANIC("Unimplemented sw1 handler")
-
-ll_local_dma: li s1,~IE_IRQ0
- PANIC("Unimplemented local_dma handler")
-
-ll_local_dev: lbu t0,JAZZ_IO_IRQ_SOURCE
-#if __mips == 3
- dsll t0,1
- ld t0,local_vector(t0)
-#else /* 32 bit */
- lw t0,local_vector(t0)
-#endif
- jr t0
- nop
-
-
-loc_no_irq: PANIC("Unimplemented loc_no_irq handler")
-loc_sound: PANIC("Unimplemented loc_sound handler")
-loc_video: PANIC("Unimplemented loc_video handler")
-loc_scsi: PANIC("Unimplemented loc_scsi handler")
-
-/*
- * Keyboard interrupt handler
- */
-loc_keyboard: li s1,~JAZZ_IE_KEYBOARD
- li t1,JAZZ_KEYBOARD_IRQ
- b loc_call
- li t3,PTRSIZE*JAZZ_KEYBOARD_IRQ # delay slot
-
-/*
- * Ethernet interrupt handler, remapped to level 2
- */
-loc_ethernet: /* PRINT ("ethernet IRQ\n"); */
- li s1,~JAZZ_IE_ETHERNET
- li t1,JAZZ_ETHERNET_IRQ
- b loc_call
- li t3,PTRSIZE*JAZZ_ETHERNET_IRQ # delay slot
-
-
-loc_mouse: PANIC("Unimplemented loc_mouse handler")
-
-/*
- * Serial port 1 IRQ, remapped to level 3
- */
-loc_serial1: li s1,~JAZZ_IE_SERIAL1
- li t1,JAZZ_SERIAL1_IRQ
- b loc_call
- li t3,PTRSIZE*JAZZ_SERIAL1_IRQ # delay slot
-
-/*
- * Serial port 2 IRQ, remapped to level 4
- */
-loc_serial2: li s1,~JAZZ_IE_SERIAL2
- li t1,JAZZ_SERIAL2_IRQ
- b loc_call
- li t3,PTRSIZE*JAZZ_SERIAL2_IRQ # delay slot
-
-/*
- * Parallel port IRQ, remapped to level 5
- */
-loc_parallel: li s1,~JAZZ_IE_PARALLEL
- li t1,JAZZ_PARALLEL_IRQ
- b loc_call
- li t3,PTRSIZE*JAZZ_PARALLEL_IRQ # delay slot
-
-/*
- * Floppy IRQ, remapped to level 6
- */
-loc_floppy: li s1,~JAZZ_IE_FLOPPY
- li t1,JAZZ_FLOPPY_IRQ
- b loc_call
- li t3,PTRSIZE*JAZZ_FLOPPY_IRQ # delay slot
-
-/*
- * Now call the real handler
- */
-loc_call: lui s3,%hi(intr_count)
- lw t2,%lo(intr_count)(s3)
- la t0,IRQ_vectors # delay slot
- addiu t2,1
- sw t2,%lo(intr_count)(s3)
-
- /*
- * Temporarily disable interrupt source
- */
- lhu t2,JAZZ_IO_IRQ_ENABLE
- addu t0,t3 # make ptr to IRQ handler
- lw t0,(t0)
- and t2,s1 # delay slot
- sh t2,JAZZ_IO_IRQ_ENABLE
- jalr t0 # call IRQ handler
- nor s1,zero,s1 # delay slot
-
- /*
- * Reenable interrupt
- */
- lhu t2,JAZZ_IO_IRQ_ENABLE
- lw t1,%lo(intr_count)(s3) # delay slot
- or t2,s1
- sh t2,JAZZ_IO_IRQ_ENABLE
-
- subu t1,1
- jr v0
- sw t1,%lo(intr_count)(s3)
-
-ll_eisa_irq: li s1,~IE_IRQ2
- PANIC("Unimplemented eisa_irq handler")
-
-ll_eisa_nmi: li s1,~IE_IRQ3
- PANIC("Unimplemented eisa_nmi handler")
-
-/*
- * Timer IRQ
- * We remap the timer irq to be more similar to a IBM compatible
- */
-ll_timer: lw t0,JAZZ_TIMER_REGISTER # timer irq cleared on read
- li s1,~IE_IRQ4
- li t1,0
- b call_real
- li t3,0 # delay slot, re-map to irq level 0
-
-/*
- * CPU count/compare IRQ (unused)
- */
-ll_count: j return
- mtc0 zero,CP0_COMPARE
-
-/*
- * Now call the real handler
- */
-call_real: lui s3,%hi(intr_count)
- lw t2,%lo(intr_count)(s3)
- la t0,IRQ_vectors # delay slot
- addiu t2,1
- sw t2,%lo(intr_count)(s3)
-
- /*
- * temporarily disable interrupt
- */
- mfc0 t2,CP0_STATUS
- and t2,s1
-
- addu t0,t3
- lw t0,(t0)
- mtc0 t2,CP0_STATUS # delay slot
- jalr t0
- nor s1,zero,s1 # delay slot
-
- /*
- * reenable interrupt
- */
- mfc0 t2,CP0_STATUS
- or t2,s1
- mtc0 t2,CP0_STATUS
-
- lw t2,%lo(intr_count)(s3)
- subu t2,1
-
- jr v0
- sw t2,%lo(intr_count)(s3)
-
-/*
- * Just for debugging...
- */
- LEAF(drawline)
- li t1,0xffffffff
- li t2,0x100
-1: sw t1,(a0)
- addiu a0,a0,4
- addiu t2,t2,-1
- bnez t2,1b
- nop
- jr ra
- nop
- END(drawline)
-
-
- .data
- PTR ll_sw0 # SW0
- PTR ll_sw1 # SW1
- PTR ll_local_dma # Local DMA
- PTR ll_local_dev # Local devices
- PTR ll_eisa_irq # EISA IRQ
- PTR ll_eisa_nmi # EISA NMI
- PTR ll_timer # Timer
-ll_vectors: PTR ll_count # Count/Compare IRQ
-
-local_vector: PTR loc_no_irq
- PTR loc_parallel
- PTR loc_floppy
- PTR loc_sound
- PTR loc_video
- PTR loc_ethernet
- PTR loc_scsi
- PTR loc_keyboard
- PTR loc_mouse
- PTR loc_serial1
- PTR loc_serial2
diff --git a/arch/mips/kernel/pica.S b/arch/mips/kernel/pica.S
deleted file mode 100644
index 036aa3139..000000000
--- a/arch/mips/kernel/pica.S
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * arch/mips/kernel/pica.S
- *
- * Copyright (C) 1995 Waldorf Electronics
- * written by Ralf Baechle and Andreas Busse
- *
- * Acer PICA 61 specific stuff
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/jazz.h>
-#include <asm/pica.h>
-#include <asm/stackframe.h>
-
-/*
- * acer_pica_61_handle_int: Interrupt handler for the ACER Pica-61 boards
- * FIXME: this is *very* experimental!
- */
- .set noreorder
-
- NESTED(acer_pica_61_handle_int, FR_SIZE, ra)
- .set noat
- SAVE_ALL
- CLI
- .set at
-
- /*
- * 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
- beqz t0,spurious_interrupt
- sll t0,16 # delay slot
-
- /*
- * Find irq with highest priority
- * FIXME: This is slow - use binary search
- */
- la t1,ll_vectors
-1: bltz t0,2f # found pending irq
- sll t0,1
- b 1b
- subu t1,PTRSIZE # delay slot
-
- /*
- * Do the low-level stuff
- */
-2: lw t0,(t1)
- jr t0
- nop # delay slot
- END(acer_pica_61_handle_int)
-
-/*
- * Used for keyboard driver's fake_keyboard_interrupt()
- */
-ll_sw0: li s1,~IE_SW0
- mfc0 t0,CP0_CAUSE
- and t0,s1
- mtc0 t0,CP0_CAUSE
- PRINT("sw0 received...\n")
- li t1,1
- b call_real
- li t3,PTRSIZE # delay slot, re-map to irq level 1
-
-ll_sw1: li s1,~IE_SW1
- PANIC("Unimplemented sw1 handler")
-
-ll_local_dma: li s1,~IE_IRQ0
- PANIC("Unimplemented local_dma handler")
-
-ll_local_dev: lbu t0,JAZZ_IO_IRQ_SOURCE
-#if __mips == 3
- dsll t0,1
- ld t0,local_vector(t0)
-#else /* 32 bit */
- lw t0,local_vector(t0)
-#endif
- jr t0
- nop
-
-
-loc_no_irq: PANIC("Unimplemented loc_no_irq handler")
-/*
- * Parallel port IRQ, remapped to level 5
- */
-loc_parallel: li s1,~JAZZ_IE_PARALLEL
- li t1,JAZZ_PARALLEL_IRQ
- b loc_call
- li t3,PTRSIZE*JAZZ_PARALLEL_IRQ # delay slot
-
-/*
- * Floppy IRQ, remapped to level 6
- */
-loc_floppy: li s1,~JAZZ_IE_FLOPPY
- li t1,JAZZ_FLOPPY_IRQ
- b loc_call
- li t3,PTRSIZE*JAZZ_FLOPPY_IRQ # delay slot
-
-/*
- * Now call the real handler
- */
-loc_call: lui s3,%hi(intr_count)
- lw t2,%lo(intr_count)(s3)
- la t0,IRQ_vectors # delay slot
- addiu t2,1
- sw t2,%lo(intr_count)(s3)
-
- /*
- * Temporarily disable interrupt source
- */
- lhu t2,JAZZ_IO_IRQ_ENABLE
- addu t0,t3 # make ptr to IRQ handler
- lw t0,(t0)
- and t2,s1 # delay slot
- sh t2,JAZZ_IO_IRQ_ENABLE
- jalr t0 # call IRQ handler
- nor s1,zero,s1 # delay slot
-
- /*
- * Reenable interrupt
- */
- lhu t2,JAZZ_IO_IRQ_ENABLE
- lw t1,%lo(intr_count)(s3) # delay slot
- or t2,s1
- sh t2,JAZZ_IO_IRQ_ENABLE
-
- subu t1,1
- jr v0
- sw t1,%lo(intr_count)(s3) # delay slot
-
-ll_isa_irq: li s1,~IE_IRQ2
- PANIC("Unimplemented isa_irq handler")
-
-ll_isa_nmi: li s1,~IE_IRQ3
- PANIC("Unimplemented isa_nmi handler")
-
-/*
- * Timer IRQ
- * We remap the timer irq to be more similar to an IBM compatible
- */
-ll_timer: lw zero,JAZZ_TIMER_REGISTER # timer irq cleared on read
- li s1,~IE_IRQ4
- li t1,0
- b call_real
- li t3,0 # delay slot, re-map to irq level 0
-
-/*
- * CPU count/compare IRQ (unused)
- */
-ll_count: j return
- mtc0 zero,CP0_COMPARE
-
-/*
- * Now call the real handler
- */
-call_real: lui s3,%hi(intr_count)
- lw t2,%lo(intr_count)(s3)
- la t0,IRQ_vectors
- addiu t2,1
- sw t2,%lo(intr_count)(s3)
-
- /*
- * temporarily disable interrupt
- */
- mfc0 t2,CP0_STATUS
- and t2,s1
-
- addu t0,t3
- lw t0,(t0)
- mtc0 t2,CP0_STATUS # delay slot
- jalr t0
- nor s1,zero,s1 # delay slot
-
- /*
- * reenable interrupt
- */
- mfc0 t2,CP0_STATUS
- or t2,s1
- mtc0 t2,CP0_STATUS
-
- lw t2,%lo(intr_count)(s3)
- subu t2,1
-
- jr v0
- sw t2,%lo(intr_count)(s3)
-
- .data
- PTR ll_sw0 # SW0
- PTR ll_sw1 # SW1
- PTR ll_local_dma # Local DMA
- PTR ll_local_dev # Local devices
- PTR ll_isa_irq # ISA IRQ
- PTR ll_isa_nmi # ISA NMI
- PTR ll_timer # Timer
-ll_vectors: PTR ll_count # Count/Compare IRQ
-
-
-/*
- * Sound? What sound hardware (whistle) ???
- */
-loc_sound: PANIC("Unimplemented loc_sound handler")
-loc_video: PANIC("Unimplemented loc_video handler")
-
-/*
- * Ethernet interrupt handler, remapped to level 2
- */
-loc_ethernet: li s1,~JAZZ_IE_ETHERNET
- li t1,JAZZ_ETHERNET_IRQ
- b loc_call
- li t3,PTRSIZE*JAZZ_ETHERNET_IRQ # delay slot
-
-loc_scsi: PANIC("Unimplemented loc_scsi handler")
-
-/*
- * Keyboard interrupt handler
- */
-loc_keyboard: li s1,~JAZZ_IE_KEYBOARD
- li t1,JAZZ_KEYBOARD_IRQ
- b loc_call
- li t3,PTRSIZE*JAZZ_KEYBOARD_IRQ # re-map to irq level 1
-
-loc_mouse: PANIC("Unimplemented loc_mouse handler")
-
-/*
- * Serial port 1 IRQ, remapped to level 3
- */
-loc_serial1: li s1,~JAZZ_IE_SERIAL1
- li t1,JAZZ_SERIAL1_IRQ
- b loc_call
- li t3,PTRSIZE*JAZZ_SERIAL1_IRQ # delay slot
-
-/*
- * Serial port 2 IRQ, remapped to level 4
- */
-loc_serial2: li s1,~JAZZ_IE_SERIAL2
- li t1,JAZZ_SERIAL2_IRQ
- b loc_call
- li t3,PTRSIZE*JAZZ_SERIAL2_IRQ # delay slot
-
-local_vector: PTR loc_no_irq
- PTR loc_parallel
- PTR loc_floppy
- PTR loc_sound
- PTR loc_video
- PTR loc_ethernet
- PTR loc_scsi
- PTR loc_keyboard
- PTR loc_mouse
- PTR loc_serial1
- PTR loc_serial2
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
new file mode 100644
index 000000000..0e2803dd3
--- /dev/null
+++ b/arch/mips/kernel/proc.c
@@ -0,0 +1,62 @@
+/*
+ * linux/arch/mips/kernel/proc.c
+ *
+ * Copyright (C) 1995, 1996 Ralf Baechle
+ */
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+
+unsigned long dflushes = 0;
+unsigned long iflushes = 0;
+unsigned long unaligned_instructions;
+
+/*
+ * BUFFER is PAGE_SIZE bytes long.
+ *
+ * Currently /proc/cpuinfo is being abused to print data about the
+ * number of date/instruction cacheflushes.
+ */
+int get_cpuinfo(char *buffer)
+{
+ const char *cpu_name[] = CPU_NAMES;
+ const char *mach_group_names[] = GROUP_NAMES;
+ const char *mach_unknown_names[] = GROUP_UNKNOWN_NAMES;
+ const char *mach_jazz_names[] = GROUP_JAZZ_NAMES;
+ const char *mach_dec_names[] = GROUP_DEC_NAMES;
+ const char *mach_arc_names[] = GROUP_ARC_NAMES;
+ const char *mach_sni_rm_names[] = GROUP_SNI_RM_NAMES;
+ const char **mach_group_to_name[] = { mach_unknown_names, mach_jazz_names,
+ mach_dec_names, mach_arc_names, mach_sni_rm_names};
+ unsigned int version = read_32bit_cp0_register(CP0_PRID);
+ int len;
+
+ len = sprintf(buffer, "cpu\t\t\t: MIPS\n");
+ len += sprintf(buffer + len, "cpu model\t\t: %s V%d.%d\n",
+ cpu_name[mips_cputype <= CPU_LAST ?
+ mips_cputype :
+ CPU_UNKNOWN],
+ (version >> 4) & 0x0f,
+ version & 0x0f);
+ len += sprintf(buffer + len, "system type\t\t: %s %s\n",
+ mach_group_names[mips_machgroup],
+ mach_group_to_name[mips_machgroup][mips_machtype]);
+ len += sprintf(buffer + len, "BogoMIPS\t\t: %lu.%02lu\n",
+ (loops_per_sec + 2500) / 500000,
+ ((loops_per_sec + 2500) / 5000) % 100);
+#if defined (__MIPSEB__)
+ len += sprintf(buffer + len, "byteorder\t\t: big endian\n");
+#endif
+#if defined (__MIPSEL__)
+ len += sprintf(buffer + len, "byteorder\t\t: little endian\n");
+#endif
+ len += sprintf(buffer + len, "D-cache flushes\t\t: %lu\n",
+ dflushes);
+ len += sprintf(buffer + len, "I-cache flushes\t\t: %lu\n",
+ iflushes);
+ len += sprintf(buffer + len, "unaligned accesses\t: %lu\n",
+ unaligned_instructions);
+
+ return len;
+}
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index dd69c3208..2ce906ea4 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -2,13 +2,13 @@
* linux/arch/mips/kernel/process.c
*
* Copyright (C) 1995 Ralf Baechle
- * written by Ralf Baechle
- */
-
-/*
- * This file handles the architecture-dependent parts of process handling..
+ *
+ * Modified for R3000/DECStation support by Paul M. Antoine 1995, 1996
+ *
+ * This file handles the architecture-dependent parts of initialization,
+ * though it does not yet currently fully support the DECStation,
+ * or R3000 - PMA.
*/
-
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -17,13 +17,16 @@
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/malloc.h>
-#include <linux/ldt.h>
+#include <linux/mman.h>
+#include <linux/sys.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <asm/bootinfo.h>
-#include <asm/segment.h>
+#include <asm/cache.h>
+#include <asm/uaccess.h>
#include <asm/pgtable.h>
+#include <asm/sgidefs.h>
#include <asm/system.h>
#include <asm/mipsregs.h>
#include <asm/processor.h>
@@ -32,185 +35,111 @@
asmlinkage void ret_from_sys_call(void);
-asmlinkage int sys_pipe(unsigned long * fildes)
-{
- int fd[2];
- int error;
-
- error = verify_area(VERIFY_WRITE,fildes,8);
- if (error)
- return error;
- error = do_pipe(fd);
- if (error)
- return error;
- put_fs_long(fd[0],0+fildes);
- put_fs_long(fd[1],1+fildes);
- return 0;
-}
-
-asmlinkage int sys_idle(void)
-{
- if (current->pid != 0)
- return -EPERM;
-
- /* endless idle loop with no priority at all */
- current->counter = -100;
- for (;;) {
- /*
- * R4[26]00 have wait, R4[04]00 don't.
- */
- if (wait_available && !need_resched)
- __asm__(".set\tmips3\n\t"
- "wait\n\t"
- ".set\tmips0\n\t");
- schedule();
- }
-}
-
-/*
- * This routine reboots the machine by asking the keyboard
- * controller to pulse the reset-line low. We try that for a while,
- * and if it doesn't work, we do some other stupid things.
- * Should be ok for Deskstation Tynes. Reseting others needs to be
- * investigated...
- */
-static inline void kb_wait(void)
-{
- int i;
-
- for (i=0; i<0x10000; i++)
- if ((inb_p(0x64) & 0x02) == 0)
- break;
-}
-
/*
- * Hard reset for Deskstation Tyne
- * No hint how this works on Pica boards.
+ * Free current thread data structures etc..
*/
-void hard_reset_now(void)
-{
- int i, j;
-
- sti();
- for (;;) {
- for (i=0; i<100; i++) {
- kb_wait();
- for(j = 0; j < 100000 ; j++)
- /* nothing */;
- outb(0xfe,0x64); /* pulse reset low */
- }
- }
-}
-
-void show_regs(struct pt_regs * regs)
+void exit_thread(void)
{
/*
- * Saved main processor registers
- */
- printk("$0 : %08x %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
- 0, regs->reg1, regs->reg2, regs->reg3,
- regs->reg4, regs->reg5, regs->reg6, regs->reg7);
- printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
- regs->reg8, regs->reg9, regs->reg10, regs->reg11,
- regs->reg12, regs->reg13, regs->reg14, regs->reg15);
- printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
- regs->reg16, regs->reg17, regs->reg18, regs->reg19,
- regs->reg20, regs->reg21, regs->reg22, regs->reg23);
- printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx\n",
- regs->reg24, regs->reg25, regs->reg28, regs->reg29,
- regs->reg30, regs->reg31);
-
- /*
- * Saved cp0 registers
+ * Nothing to do
*/
- printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\n",
- regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
}
-/*
- * Free current thread data structures etc..
- */
-void exit_thread(void)
+void flush_thread(void)
{
/*
* Nothing to do
*/
}
-void flush_thread(void)
+void release_thread(struct task_struct *dead_task)
{
/*
* Nothing to do
*/
}
-
+
void copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
- struct task_struct * p, struct pt_regs * regs)
+ struct task_struct * p, struct pt_regs * regs)
{
struct pt_regs * childregs;
+ long childksp;
+ childksp = p->kernel_stack_page + KERNEL_STACK_SIZE - 8;
/*
* set up new TSS
*/
childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 1;
*childregs = *regs;
- childregs->reg2 = 0;
- regs->reg2 = p->pid;
- childregs->reg29 = usp;
- p->tss.ksp = (p->kernel_stack_page + PAGE_SIZE - 8);
- p->tss.reg29 = (unsigned long) childregs; /* new sp */
- p->tss.reg31 = (unsigned long) ret_from_sys_call;
+ childregs->regs[2] = (__register_t) 0; /* Child gets zero as return value */
+ childregs->regs[7] = (__register_t) 0; /* Clear error flag */
+ regs->regs[2] = (__register_t) p->pid;
+ if (childregs->cp0_status & ST0_CU0)
+ childregs->regs[29] = (__register_t) childksp;
+ else
+ childregs->regs[29] = (__register_t) usp;
+ p->tss.ksp = childksp;
+ p->tss.reg29 = (__register_t)(long) childregs; /* new sp */
+ p->tss.reg31 = (__register_t) ret_from_sys_call;
+
+ /*
+ * Copy thread specific flags.
+ */
+ p->tss.mflags = p->tss.mflags;
/*
* New tasks loose permission to use the fpu. This accelerates context
* switching for most programs since they don't use the fpu.
*/
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
p->tss.cp0_status = read_32bit_cp0_register(CP0_STATUS) &
- ~(ST0_CU3|ST0_CU2|ST0_CU1|ST0_KSU|ST0_ERL|ST0_EXL);
+ ~(ST0_CU3|ST0_CU2|ST0_CU1);
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
+ p->tss.cp0_status = read_32bit_cp0_register(CP0_STATUS) &
+ ~(ST0_CU3|ST0_CU2|ST0_CU1|ST0_KSU|ST0_ERL|ST0_EXL);
+#endif
childregs->cp0_status &= ~(ST0_CU3|ST0_CU2|ST0_CU1);
}
/*
- * fill in the user structure for a core dump..
+ * Do necessary setup to start up a newly executed thread.
*/
-void dump_thread(struct pt_regs * regs, struct user * dump)
+extern void (*switch_to_user_mode)(struct pt_regs *regs);
+
+void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
{
+ set_fs(USER_DS);
+ regs->cp0_epc = (__register_t) pc;
/*
- * To do...
+ * New thread loses kernel privileges.
*/
+ switch_to_user_mode(regs);
+ regs->regs[29] = (__register_t) sp;
+ regs->regs[31] = 0;
}
-asmlinkage int sys_fork(struct pt_regs regs)
-{
- return do_fork(COPYVM | SIGCHLD, regs.reg29, &regs);
-}
-
-asmlinkage int sys_clone(struct pt_regs regs)
+/*
+ * fill in the fpu structure for a core dump..
+ *
+ * Actually this is "int dump_fpu (struct pt_regs * regs, struct user *fpu)"
+ */
+int dump_fpu (int shutup_the_gcc_warning_about_elf_fpregset_t)
{
- unsigned long clone_flags;
- unsigned long newsp;
+ int fpvalid = 0;
+ /*
+ * To do...
+ */
- newsp = regs.reg4;
- clone_flags = regs.reg5;
- if (!newsp)
- newsp = regs.reg29;
- if (newsp == regs.reg29)
- clone_flags |= COPYVM;
- return do_fork(clone_flags, newsp, &regs);
+ return fpvalid;
}
/*
- * sys_execve() executes a new program.
+ * fill in the user structure for a core dump..
*/
-asmlinkage int sys_execve(struct pt_regs regs)
+void dump_thread(struct pt_regs * regs, struct user * dump)
{
- int error;
- char * filename;
-
- error = getname((char *) regs.reg4, &filename);
- if (error)
- return error;
- error = do_execve(filename, (char **) regs.reg5, (char **) regs.reg6, &regs);
- putname(filename);
- return error;
+ /*
+ * To do...
+ */
}
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 6f35ceb67..93fae9961 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -1,7 +1,12 @@
-/* ptrace.c */
-/* By Ross Biro 1/23/92 */
-/* edited by Linus Torvalds */
-
+/*
+ * Ptrace(2) syscall for MIPS. Based on arch/i386/kernel/ptrace.c.
+ *
+ * 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.
+ *
+ * Copyright (C) 1995, 1996 by Ralf Baechle.
+ */
#include <linux/head.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -10,11 +15,10 @@
#include <linux/ptrace.h>
#include <linux/user.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/system.h>
-#if 0
/*
* does not yet catch signals sent when the child dies.
* in exit.c or in signal.c.
@@ -24,9 +28,6 @@
/* 1 = access 0 = no access */
#define FLAG_MASK 0x00044dd5
-/* set's the trap flag. */
-#define TRAP_FLAG 0x100
-
/*
* this is the number to subtract from the top of the stack. To find
* the local frame.
@@ -34,7 +35,8 @@
#define MAGICNUMBER 68
/* change a pid into a task struct. */
-static inline struct task_struct * get_task(int pid)
+static inline struct task_struct *
+get_task(int pid)
{
int i;
@@ -46,16 +48,15 @@ static inline struct task_struct * get_task(int pid)
}
/*
- * this routine will get a word off of the processes privileged stack.
- * the offset is how far from the base addr as stored in the TSS.
- * this routine assumes that all the privileged stacks are in our
- * data space.
+ * This routine will get a word off of the processes privileged stack.
+ * The offset is how far from the base addr as stored in the TSS.
*/
-static inline int get_stack_long(struct task_struct *task, int offset)
+static inline int
+get_stack_long(struct task_struct *task, int offset)
{
unsigned char *stack;
- stack = (unsigned char *)task->tss.esp0;
+ stack = (unsigned char *)(unsigned long)task->tss.reg29;
stack += offset;
return (*((int *)stack));
}
@@ -66,12 +67,13 @@ static inline int get_stack_long(struct task_struct *task, int offset)
* this routine assumes that all the privileged stacks are in our
* data space.
*/
-static inline int put_stack_long(struct task_struct *task, int offset,
+static inline int
+put_stack_long(struct task_struct *task, int offset,
unsigned long data)
{
unsigned char * stack;
- stack = (unsigned char *) task->tss.esp0;
+ stack = (unsigned char *)(unsigned long)task->tss.reg29;
stack += offset;
*(unsigned long *) stack = data;
return 0;
@@ -83,16 +85,19 @@ static inline int put_stack_long(struct task_struct *task, int offset,
* and that it is in the task area before calling this: this routine does
* no checking.
*/
-static unsigned long get_long(struct vm_area_struct * vma, unsigned long addr)
+static unsigned long
+get_long(struct task_struct * tsk,
+ struct vm_area_struct * vma, unsigned long addr)
{
pgd_t * pgdir;
+ pmd_t * pgmiddle;
pte_t * pgtable;
unsigned long page;
repeat:
- pgdir = PAGE_DIR_OFFSET(vma->vm_task, addr);
+ pgdir = pgd_offset(vma->vm_mm, addr);
if (pgd_none(*pgdir)) {
- do_no_page(vma, addr, 0);
+ do_no_page(tsk, vma, addr, 0);
goto repeat;
}
if (pgd_bad(*pgdir)) {
@@ -100,14 +105,23 @@ repeat:
pgd_clear(pgdir);
return 0;
}
- pgtable = (pte_t *) (PAGE_PTR(addr) + pgd_page(*pgdir));
+ pgmiddle = pmd_offset(pgdir, addr);
+ if (pmd_none(*pgmiddle)) {
+ do_no_page(tsk, vma, addr, 0);
+ goto repeat;
+ }
+ if (pmd_bad(*pgmiddle)) {
+ printk("ptrace: bad page middle %08lx\n", pmd_val(*pgmiddle));
+ pmd_clear(pgmiddle);
+ return 0;
+ }
+ pgtable = pte_offset(pgmiddle, addr);
if (!pte_present(*pgtable)) {
- do_no_page(vma, addr, 0);
+ do_no_page(tsk, vma, addr, 0);
goto repeat;
}
- page = pte_page(*pgtable);
/* this is a hack for non-kernel-mapped video buffers and similar */
- if (page >= high_memory)
+ if (MAP_NR(page) < max_mapnr)
return 0;
page += addr & ~PAGE_MASK;
return *(unsigned long *) page;
@@ -122,17 +136,19 @@ repeat:
* Now keeps R/W state of page so that a text page stays readonly
* even if a debugger scribbles breakpoints into it. -M.U-
*/
-static void put_long(struct vm_area_struct * vma, unsigned long addr,
- unsigned long data)
+static void
+put_long(struct task_struct * tsk,
+ struct vm_area_struct * vma, unsigned long addr, unsigned long data)
{
pgd_t *pgdir;
+ pmd_t *pgmiddle;
pte_t *pgtable;
unsigned long page;
repeat:
- pgdir = PAGE_DIR_OFFSET(vma->vm_task, addr);
+ pgdir = pgd_offset(vma->vm_mm, addr);
if (!pgd_present(*pgdir)) {
- do_no_page(vma, addr, 1);
+ do_no_page(tsk, vma, addr, 1);
goto repeat;
}
if (pgd_bad(*pgdir)) {
@@ -140,33 +156,47 @@ repeat:
pgd_clear(pgdir);
return;
}
- pgtable = (pte_t *) (PAGE_PTR(addr) + pgd_page(*pgdir));
+ pgmiddle = pmd_offset(pgdir, addr);
+ if (pmd_none(*pgmiddle)) {
+ do_no_page(tsk, vma, addr, 1);
+ goto repeat;
+ }
+ if (pmd_bad(*pgmiddle)) {
+ printk("ptrace: bad page middle %08lx\n", pmd_val(*pgmiddle));
+ pmd_clear(pgmiddle);
+ return;
+ }
+ pgtable = pte_offset(pgmiddle, addr);
if (!pte_present(*pgtable)) {
- do_no_page(vma, addr, 1);
+ do_no_page(tsk, vma, addr, 1);
goto repeat;
}
page = pte_page(*pgtable);
if (!pte_write(*pgtable)) {
- do_wp_page(vma, addr, 1);
+ do_wp_page(tsk, vma, addr, 1);
goto repeat;
}
-/* this is a hack for non-kernel-mapped video buffers and similar */
- if (page < high_memory) {
- page += addr & ~PAGE_MASK;
- *(unsigned long *) page = data;
- }
-/* we're bypassing pagetables, so we have to set the dirty bit ourselves */
-/* this should also re-instate whatever read-only mode there was before */
- *pgtable = pte_mkdirty(mk_pte(page, vma->vm_page_prot));
- invalidate();
+ /*
+ * This is a hack for non-kernel-mapped video buffers and similar
+ */
+ if (page >= high_memory)
+ *(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
+ /*
+ * We're bypassing pagetables, so we have to set the dirty bit
+ * ourselves. This should also re-instate whatever read-only mode
+ * there was before
+ */
+ set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
+ flush_tlb();
}
-static struct vm_area_struct * find_extend_vma(struct task_struct * tsk, unsigned long addr)
+static struct vm_area_struct *
+find_extend_vma(struct task_struct * tsk, unsigned long addr)
{
struct vm_area_struct * vma;
addr &= PAGE_MASK;
- vma = find_vma(tsk, addr);
+ vma = find_vma(tsk->mm, addr);
if (!vma)
return NULL;
if (vma->vm_start <= addr)
@@ -184,8 +214,9 @@ static struct vm_area_struct * find_extend_vma(struct task_struct * tsk, unsigne
* This routine checks the page boundaries, and that the offset is
* within the task area. It then calls get_long() to read a long.
*/
-static int read_long(struct task_struct * tsk, unsigned long addr,
- unsigned long * result)
+static int
+read_long(struct task_struct * tsk, unsigned long addr,
+ unsigned long * result)
{
struct vm_area_struct * vma = find_extend_vma(tsk, addr);
@@ -200,8 +231,8 @@ static int read_long(struct task_struct * tsk, unsigned long addr,
if (!vma_high || vma_high->vm_start != vma->vm_end)
return -EIO;
}
- low = get_long(vma, addr & ~(sizeof(long)-1));
- high = get_long(vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1));
+ low = get_long(tsk, vma, addr & ~(sizeof(long)-1));
+ high = get_long(tsk, vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1));
switch (addr & (sizeof(long)-1)) {
case 1:
low >>= 8;
@@ -218,7 +249,7 @@ static int read_long(struct task_struct * tsk, unsigned long addr,
}
*result = low;
} else
- *result = get_long(vma, addr);
+ *result = get_long(tsk, vma, addr);
return 0;
}
@@ -226,8 +257,9 @@ static int read_long(struct task_struct * tsk, unsigned long addr,
* This routine checks the page boundaries, and that the offset is
* within the task area. It then calls put_long() to write a long.
*/
-static int write_long(struct task_struct * tsk, unsigned long addr,
- unsigned long data)
+static int
+write_long(struct task_struct * tsk, unsigned long addr,
+ unsigned long data)
{
struct vm_area_struct * vma = find_extend_vma(tsk, addr);
@@ -242,8 +274,8 @@ static int write_long(struct task_struct * tsk, unsigned long addr,
if (!vma_high || vma_high->vm_start != vma->vm_end)
return -EIO;
}
- low = get_long(vma, addr & ~(sizeof(long)-1));
- high = get_long(vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1));
+ low = get_long(tsk, vma, addr & ~(sizeof(long)-1));
+ high = get_long(tsk, vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1));
switch (addr & (sizeof(long)-1)) {
case 0: /* shouldn't happen, but safety first */
low = data;
@@ -267,23 +299,18 @@ static int write_long(struct task_struct * tsk, unsigned long addr,
high |= data >> 8;
break;
}
- put_long(vma, addr & ~(sizeof(long)-1),low);
- put_long(vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1),high);
+ put_long(tsk, vma, addr & ~(sizeof(long)-1),low);
+ put_long(tsk, vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1),high);
} else
- put_long(vma, addr, data);
+ put_long(tsk, vma, addr, data);
return 0;
}
-#endif
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage int
+sys_ptrace(long request, long pid, long addr, long data)
{
-#if 1
- return -ENOSYS;
-#else
struct task_struct *child;
struct user * dummy;
- int i;
-
dummy = NULL;
@@ -304,8 +331,10 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
return -EPERM;
if ((!child->dumpable ||
(current->uid != child->euid) ||
+ (current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
+ (current->gid != child->sgid) ||
(current->gid != child->gid)) && !suser())
return -EPERM;
/* the same process cannot be attached many times */
@@ -330,7 +359,6 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
return -ESRCH;
switch (request) {
- /* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: {
unsigned long tmp;
@@ -341,22 +369,21 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
return res;
res = verify_area(VERIFY_WRITE, (void *) data, sizeof(long));
if (!res)
- put_fs_long(tmp,(unsigned long *) data);
+ put_user(tmp, (unsigned long *)data);
return res;
}
- /* read the word at location addr in the USER area. */
+#if 0
+ /*
+ * Read the word at location addr in the USER area.
+ */
case PTRACE_PEEKUSR: {
unsigned long tmp;
int res;
- if ((addr & 3) || addr < 0 ||
- addr > sizeof(struct user) - 3)
+ if (addr < 0 || addr > sizeof(struct user) - 3)
return -EIO;
- res = verify_area(VERIFY_WRITE, (void *) data, sizeof(long));
- if (res)
- return res;
tmp = 0; /* Default return condition */
if(addr < 17*sizeof(long)) {
addr = addr >> 2; /* temporary hack. */
@@ -366,23 +393,23 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
addr == FS || addr == GS ||
addr == CS || addr == SS)
tmp &= 0xffff;
- };
- if(addr >= (long) &dummy->u_debugreg[0] &&
- addr <= (long) &dummy->u_debugreg[7]){
- addr -= (long) &dummy->u_debugreg[0];
- addr = addr >> 2;
- tmp = child->debugreg[addr];
- };
- put_fs_long(tmp,(unsigned long *) data);
+ }
+ put_user(tmp, (unsigned long *)data);
return 0;
}
-
- /* when I and D space are separate, this will have to be fixed. */
- case PTRACE_POKETEXT: /* write the word at location addr. */
+#endif
+ /*
+ * Write the word at location addr.
+ */
+ case PTRACE_POKETEXT:
case PTRACE_POKEDATA:
return write_long(child,addr,data);
- case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+ /*
+ * Write the word at location addr in the user area.
+ */
+ case PTRACE_POKEUSR:
+#if 0
if ((addr & 3) || addr < 0 ||
addr > sizeof(struct user) - 3)
return -EIO;
@@ -404,112 +431,79 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
}
/* Do not allow the user to set the debug register for kernel
address space */
- if(addr < 17){
+ if(addr < 17) {
if (put_stack_long(child, sizeof(long)*addr-MAGICNUMBER, data))
return -EIO;
return 0;
- };
-
- /* We need to be very careful here. We implicitly
- want to modify a portion of the task_struct, and we
- have to be selective about what portions we allow someone
- to modify. */
-
- addr = addr << 2; /* Convert back again */
- if(addr >= (long) &dummy->u_debugreg[0] &&
- addr <= (long) &dummy->u_debugreg[7]){
-
- if(addr == (long) &dummy->u_debugreg[4]) return -EIO;
- if(addr == (long) &dummy->u_debugreg[5]) return -EIO;
- if(addr < (long) &dummy->u_debugreg[4] &&
- ((unsigned long) data) >= 0xbffffffd) return -EIO;
-
- if(addr == (long) &dummy->u_debugreg[7]) {
- data &= ~DR_CONTROL_RESERVED;
- for(i=0; i<4; i++)
- if ((0x5f54 >> ((data >> (16 + 4*i)) & 0xf)) & 1)
- return -EIO;
- };
-
- addr -= (long) &dummy->u_debugreg;
- addr = addr >> 2;
- child->debugreg[addr] = data;
- return 0;
- };
+ }
+
return -EIO;
+#endif
- case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+ /*
+ * Continue and stop at next (return from) syscall.
+ */
+ case PTRACE_SYSCALL:
case PTRACE_CONT: { /* restart after signal. */
- long tmp;
-
- if ((unsigned long) data > NSIG)
+ if ((unsigned long) data > _NSIG)
return -EIO;
if (request == PTRACE_SYSCALL)
child->flags |= PF_TRACESYS;
else
child->flags &= ~PF_TRACESYS;
child->exit_code = data;
- child->state = TASK_RUNNING;
- /* make sure the single step bit is not set. */
- tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG;
- put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp);
+ wake_up_process(child);
return 0;
}
-/*
- * make the child exit. Best I can do is send it a sigkill.
- * perhaps it should be put in the status that it wants to
- * exit.
- */
+ /*
+ * Make the child exit. Best I can do is send it a sigkill.
+ * perhaps it should be put in the status that it wants to
+ * exit.
+ */
case PTRACE_KILL: {
- long tmp;
-
- child->state = TASK_RUNNING;
+ if (child->state == TASK_ZOMBIE) /* already dead */
+ return 0;
+ wake_up_process(child);
child->exit_code = SIGKILL;
- /* make sure the single step bit is not set. */
- tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG;
- put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp);
return 0;
}
case PTRACE_SINGLESTEP: { /* set the trap flag. */
- long tmp;
+ /*
+ * Not supported yet.
+ */
+ return -ENOSYS;
if ((unsigned long) data > NSIG)
return -EIO;
- child->flags &= ~PF_TRACESYS;
- tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) | TRAP_FLAG;
- put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp);
- child->state = TASK_RUNNING;
+ wake_up_process(child);
child->exit_code = data;
- /* give it a chance to run. */
+ /*
+ * give it a chance to run.
+ */
return 0;
}
case PTRACE_DETACH: { /* detach a process that was attached. */
- long tmp;
-
if ((unsigned long) data > NSIG)
return -EIO;
child->flags &= ~(PF_PTRACED|PF_TRACESYS);
- child->state = TASK_RUNNING;
+ wake_up_process(child);
child->exit_code = data;
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
- /* make sure the single step bit is not set. */
- tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG;
- put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp);
return 0;
}
default:
return -EIO;
}
-#endif
}
-asmlinkage void syscall_trace(void)
+asmlinkage void
+syscall_trace(void)
{
if ((current->flags & (PF_PTRACED|PF_TRACESYS))
!= (PF_PTRACED|PF_TRACESYS))
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index f5037fbd7..30304abda 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -2,10 +2,12 @@
* linux/arch/mips/kernel/setup.c
*
* Copyright (C) 1995 Linus Torvalds
- * Copyright (C) 1995 Ralf Baechle
+ * Copyright (C) 1995, 1996 Ralf Baechle
+ * Copyright (C) 1996 Stoned Elipot
*/
-
+#include <linux/config.h>
#include <linux/errno.h>
+#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
@@ -14,15 +16,20 @@
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/malloc.h>
-#include <linux/ldt.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 <asm/asm.h>
#include <asm/bootinfo.h>
+#include <asm/cache.h>
+#include <asm/io.h>
#include <asm/vector.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <asm/stackframe.h>
#include <asm/system.h>
@@ -31,177 +38,256 @@
*/
struct feature *feature;
-#ifdef CONFIG_ACER_PICA_61
-void acer_pica_61_handle_int(void);
-struct feature acer_pica_61_feature = {
- acer_pica_61_handle_int
-};
-#endif
-#ifdef CONFIG_DECSTATION
-void decstation_handle_handle_int(void);
-struct feature decstation_feature = {
- decstation_handle_handle_int
-};
-#endif
-#ifdef CONFIG_DESKSTATION_RPC44
-void deskstation_rpc44_handle_int(void);
-struct feature deskstation_rpc44_feature = {
- deskstation_rpc44_handle_int
-};
-#endif
-#ifdef CONFIG_DESKSTATION_TYNE
-void deskstation_tyne_handle_int(void);
-struct feature deskstation_tyne_feature = {
- deskstation_tyne_handle_int
-};
-#endif
-#ifdef CONFIG_MIPS_MAGNUM_4000
-void mips_magnum_4000_handle_int(void);
-struct feature mips_magnum_4000_feature = {
- mips_magnum_4000_handle_int
-};
-#endif
+/*
+ * What to do to keep the caches consistent with memory
+ * We don't use the normal cacheflush routine to keep Tyne caches happier.
+ */
+void (*fd_cacheflush)(const void *addr, size_t size);
/*
- * Tell us the machine setup..
+ * Not all of the MIPS CPUs have the "wait" instruction available. This
+ * is set to true if it is available. The wait instruction stops the
+ * pipeline and reduces the power consumption of the CPU very much.
*/
-char wait_available; /* set if the "wait" instruction available */
+char wait_available;
/*
- * Bus types ..
+ * There are several bus types available for MIPS machines. "RISC PC"
+ * type machines have ISA, EISA or PCI available, some DECstations have
+ * Turbochannel, SGI has GIO, there are lots of VME boxes ...
+ * This flag is set if a EISA slots are available.
*/
int EISA_bus = 0;
/*
- * Setup options
+ * Do a hardware reset.
*/
-struct drive_info_struct drive_info;
-struct screen_info screen_info = SCREEN_INFO;
+void (*hard_reset_now)(void);
+
+/*
+ * Milo passes some information to the kernel that looks like as if it
+ * had been returned by a Intel PC BIOS. Milo doesn't fill the passed
+ * drive_info and Linux can find out about this anyway, so I'm going to
+ * remove this sometime. screen_info contains information about the
+ * resolution of the text screen. For VGA graphics based machine this
+ * information is being use to continue the screen output just below
+ * the BIOS printed text and with the same text resolution.
+ */
+struct drive_info_struct drive_info = DEFAULT_DRIVE_INFO;
+struct screen_info screen_info = DEFAULT_SCREEN_INFO;
+
+/*
+ * setup informations
+ *
+ * These are intialized so they are in the .data section
+ */
+unsigned long mips_memory_upper = KSEG0; /* this is set by kernel_entry() */
+unsigned long mips_cputype = CPU_UNKNOWN;
+unsigned long mips_machtype = MACH_UNKNOWN; /* this is set by bi_EarlySnarf() */
+unsigned long mips_machgroup = MACH_GROUP_UNKNOWN; /* this is set by bi_EarlySnarf() */
+unsigned long mips_tlb_entries = 48; /* this is set by bi_EarlySnarf() */
+unsigned long mips_vram_base = KSEG0;
-unsigned char aux_device_present;
-extern int ramdisk_size;
extern int root_mountflags;
extern int _end;
extern char empty_zero_page[PAGE_SIZE];
/*
- * Initialise this structure so that it will be placed in the
- * .data section of the object file
- */
-struct bootinfo boot_info = BOOT_INFO;
-
-/*
* This is set up by the setup-routine at boot-time
*/
#define PARAM empty_zero_page
-#if 0
-#define ORIG_ROOT_DEV (*(unsigned short *) (PARAM+0x1FC))
-#define AUX_DEVICE_INFO (*(unsigned char *) (PARAM+0x1FF))
-#endif
+#define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))
+#define INITRD_START (*(unsigned long *) (PARAM+0x218))
+#define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
static char command_line[CL_SIZE] = { 0, };
+ char saved_command_line[CL_SIZE];
-#if 0
/*
- * Code for easy access to new style bootinfo
- *
- * Parameter: tag -- taglist entry
- *
- * returns : (tag *) -- pointer to taglist entry, NULL for not found
+ * The board specific setup routine sets irq_setup to point to a board
+ * specific setup routine.
*/
-tag *
-bi_TagFind(enum bi_tag tag)
+void (*irq_setup)(void);
+
+static void default_irq_setup(void)
{
- /* TBD */
- return 0;
+ panic("Unknown machtype in init_IRQ");
}
-/*
- * Only for taglist creators (bootloaders)
- *
- * Parameter: tag -- (enum bi_tag) taglist entry
- *
- * returns : 1 -- success
- * 0 -- failure
- */
-int
-bi_TagAdd(enum bi_tag tag, unsigned long size, void *tagdata)
+static void default_fd_cacheflush(const void *addr, size_t size)
{
- /* TBD */
- return 0;
}
-#endif /* 0 */
-void setup_arch(char **cmdline_p,
- unsigned long * memory_start_p, unsigned long * memory_end_p)
+static asmlinkage void
+default_cacheflush(unsigned long addr, unsigned long nbytes, unsigned int flags)
{
- unsigned long memory_start, memory_end;
+ /*
+ * Someone didn't set his cacheflush() handler ...
+ */
+ panic("default_cacheflush() called.\n");
+}
+asmlinkage void (*cacheflush)(unsigned long addr, unsigned long nbytes, unsigned int flags) = default_cacheflush;
- switch(boot_info.machtype)
- {
-#ifdef CONFIG_ACER_PICA_61
- case MACH_ACER_PICA_61:
- feature = &acer_pica_61_feature;
+static __inline__ void
+cpu_init(void)
+{
+ asmlinkage void handle_reserved(void);
+ void mips1_cpu_init(void);
+ void mips2_cpu_init(void);
+ void mips3_cpu_init(void);
+ void mips4_cpu_init(void);
+ int i;
+
+ /*
+ * Setup default vectors
+ */
+ for (i=0;i<=31;i++)
+ set_except_vector(i, handle_reserved);
+
+ switch(mips_cputype) {
+#ifdef CONFIG_CPU_R3000
+ case CPU_R2000: case CPU_R3000: case CPU_R3000A: case CPU_R3041:
+ case CPU_R3051: case CPU_R3052: case CPU_R3081: case CPU_R3081E:
+ mips1_cpu_init();
+ break;
+#endif
+#ifdef CONFIG_CPU_R6000
+ case CPU_R6000: case CPU_R6000A:
+ mips2_cpu_init();
break;
#endif
-#ifdef CONFIG_DECSTATION
- case MACH_DECSTATION:
- feature = &decstation_feature;
+#ifdef CONFIG_CPU_R4X00
+ case CPU_R4000MC: case CPU_R4400MC: case CPU_R4000SC:
+ case CPU_R4400SC: case CPU_R4000PC: case CPU_R4400PC:
+ case CPU_R4200: case CPU_R4300: /* case CPU_R4640: */
+ case CPU_R4600: case CPU_R4700:
+ mips3_cpu_init();
break;
#endif
-#ifdef CONFIG_DESKSTATION_RPC
- case MACH_DESKSTATION_RPC:
- feature = &deskstation_rpc44_feature;
+#ifdef CONFIG_CPU_R8000
+ case CPU_R8000: case CPU_R5000:
+ printk("Detected unsupported CPU type %s.\n",
+ cpu_names[mips_cputype]);
+ panic("Can't handle CPU");
break;
#endif
-#ifdef CONFIG_DESKSTATION_TYNE
- case MACH_DESKSTATION_TYNE:
- feature = &deskstation_tyne_feature;
+#ifdef CONFIG_CPU_R10000
+ case CPU_R10000:
+ mips4_cpu_init();
+#endif
+ case CPU_UNKNOWN:
+ default:
+ panic("Unknown or unsupported CPU type");
+ }
+}
+
+void setup_arch(char **cmdline_p,
+ unsigned long * memory_start_p, unsigned long * memory_end_p)
+{
+ unsigned long memory_end;
+ tag* atag;
+ void decstation_setup(void);
+ void deskstation_setup(void);
+ void jazz_setup(void);
+ void sni_rm200_pci_setup(void);
+
+ /* Perhaps a lot of tags are not getting 'snarfed' - */
+ /* please help yourself */
+
+ atag = bi_TagFind(tag_cputype);
+ memcpy(&mips_cputype, TAGVALPTR(atag), atag->size);
+
+ cpu_init();
+
+ atag = bi_TagFind(tag_vram_base);
+ memcpy(&mips_vram_base, TAGVALPTR(atag), atag->size);
+
+ irq_setup = default_irq_setup;
+ fd_cacheflush = default_fd_cacheflush;
+
+ switch(mips_machgroup)
+ {
+#ifdef CONFIG_MIPS_DECSTATION
+ case MACH_GROUP_DEC:
+ decstation_setup();
break;
#endif
-#ifdef CONFIG_MIPS_MAGNUM_4000
- case MACH_MIPS_MAGNUM_4000:
- feature = &mips_magnum_4000_feature;
+#if defined(CONFIG_MIPS_ARC)
+/* Perhaps arch/mips/deskstation should be renommed arch/mips/arc.
+ * For now CONFIG_MIPS_ARC means DeskStation. -Stoned.
+ */
+ case MACH_GROUP_ARC:
+ deskstation_setup();
+ break;
+#endif
+#ifdef CONFIG_MIPS_JAZZ
+ case MACH_GROUP_JAZZ:
+ jazz_setup();
+ break;
+#endif
+#ifdef CONFIG_SNI_RM200_PCI
+ case MACH_GROUP_SNI_RM:
+ sni_rm200_pci_setup();
break;
#endif
default:
panic("Unsupported architecture");
}
-#if 0
- ROOT_DEV = ORIG_ROOT_DEV;
-#else
- ROOT_DEV = 0x021c; /* fd0H1440 */
-/* ROOT_DEV = 0x0101; */ /* ram */
-/* ROOT_DEV = 0x00ff; */ /* NFS */
+ atag = bi_TagFind(tag_drive_info);
+ memcpy(&drive_info, TAGVALPTR(atag), atag->size);
+
+ memory_end = mips_memory_upper;
+ /*
+ * Due to prefetching and similar mechanism the CPU sometimes
+ * generates addresses beyond the end of memory. We leave the size
+ * of one cache line at the end of memory unused to make shure we
+ * don't catch this type of bus errors.
+ */
+ memory_end -= 32;
+ memory_end &= PAGE_MASK;
+
+#ifdef CONFIG_BLK_DEV_RAM
+ rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
+ rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
+ rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
#endif
- memcpy(&drive_info, &boot_info.drive_info, sizeof(drive_info));
-#if 0
- aux_device_present = AUX_DEVICE_INFO;
+#ifdef CONFIG_MAX_16M
+ /*
+ * There is a quite large number of different PC chipset based boards
+ * available and so I include this option here just in case ...
+ */
+ if (memory_end > PAGE_OFFSET + 16*1024*1024)
+ memory_end = PAGE_OFFSET + 16*1024*1024;
#endif
- memory_end = boot_info.memupper;
- memory_end &= PAGE_MASK;
- ramdisk_size = boot_info.ramdisk_size;
- if (boot_info.mount_root_rdonly)
- root_mountflags |= MS_RDONLY;
- memory_start = (unsigned long) &_end;
- memory_start += (ramdisk_size << 10);
+ atag= bi_TagFind(tag_screen_info);
+ if (atag)
+ memcpy(&screen_info, TAGVALPTR(atag), atag->size);
+
+ atag = bi_TagFind(tag_command_line);
+ if (atag)
+ memcpy(&command_line, TAGVALPTR(atag), atag->size);
+ printk("Command line: '%s'\n", command_line);
+
+ memcpy(saved_command_line, command_line, CL_SIZE);
+ saved_command_line[CL_SIZE-1] = '\0';
*cmdline_p = command_line;
- *memory_start_p = memory_start;
+ *memory_start_p = (unsigned long) &_end;
*memory_end_p = memory_end;
-#if 0
- /*
- * Check that struct pt_regs is defined properly
- * (Should be optimized away, but gcc 2.6.3 is too bad..)
- */
- if (FR_SIZE != sizeof(struct pt_regs) ||
- FR_SIZE & 7)
- {
- panic("Check_definition_of_struct_pt_regs\n");
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (LOADER_TYPE) {
+ initrd_start = INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
+ initrd_end = initrd_start+INITRD_SIZE;
+ if (initrd_end > memory_end) {
+ printk("initrd extends beyond end of memory "
+ "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+ initrd_end,memory_end);
+ initrd_start = 0;
+ }
}
#endif
}
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index ea00551a9..b744823b1 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -2,8 +2,8 @@
* linux/arch/mips/kernel/signal.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
+ * Copyright (C) 1994, 1995, 1996 Ralf Baechle
*/
-
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/kernel.h>
@@ -13,158 +13,305 @@
#include <linux/ptrace.h>
#include <linux/unistd.h>
-#include <asm/segment.h>
-#include <asm/cachectl.h>
+#include <asm/asm.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/cache.h>
+#include <asm/mipsconfig.h>
+#include <asm/sgidefs.h>
+
+/*
+ * Linux/MIPS misstreats the SA_NOMASK flag for signal handlers.
+ * Actually this is a bug in libc that was made visible by the POSIX.1
+ * changes in Linux/MIPS 2.0.1. To keep old binaries alive enable
+ * this define but note that this is just a hack with sideeffects, not a
+ * perfect compatibility mode. This will go away, so rebuild your
+ * executables with libc 960709 or newer.
+ */
+#define CONF_NOMASK_BUG_COMPAT
#define _S(nr) (1<<((nr)-1))
#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
+asmlinkage int do_signal(unsigned long oldmask, struct pt_regs *regs);
+
+asmlinkage void (*save_fp_context)(struct sigcontext *sc);
+extern asmlinkage void (*restore_fp_context)(struct sigcontext *sc);
+
+asmlinkage int sys_sigprocmask(int how, sigset_t *set, sigset_t *oset)
+{
+ k_sigset_t new_set, old_set = current->blocked;
+
+ if (set) {
+ if (!access_ok(VERIFY_READ, set, sizeof(sigset_t)))
+ return -EFAULT;
+
+ __get_user(new_set, to_k_sigset_t(set));
+ new_set &= _BLOCKABLE;
+
+ switch (how) {
+ case SIG_BLOCK:
+ current->blocked |= new_set;
+ break;
+ case SIG_UNBLOCK:
+ current->blocked &= ~new_set;
+ break;
+ case SIG_SETMASK:
+ current->blocked = new_set;
+ break;
+ /*
+ * SGI goodie: Just set the low 32 bits of 'blocked' even
+ * for 128 bit sigset_t.
+ */
+ case SIG_SETMASK32:
+ current->blocked = new_set;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ if (oset) {
+ if(!access_ok(VERIFY_WRITE, oset, sizeof(sigset_t)))
+ return -EFAULT;
+ __put_user(old_set, &oset->__sigbits[0]);
+ __put_user(0, &oset->__sigbits[1]);
+ __put_user(0, &oset->__sigbits[2]);
+ __put_user(0, &oset->__sigbits[3]);
+ }
+
+ return 0;
+}
/*
- * atomically swap in the new signal mask, and wait for a signal.
+ * Atomically swap in the new signal mask, and wait for a signal.
*/
-asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, unsigned long set)
+asmlinkage int sys_sigsuspend(struct pt_regs *regs)
{
- unsigned long mask;
- struct pt_regs * regs = (struct pt_regs *) &restart;
+ unsigned int mask;
+ sigset_t *uset;
+ k_sigset_t kset;
mask = current->blocked;
- current->blocked = set & _BLOCKABLE;
- regs->reg2 = -EINTR;
+ uset = (sigset_t *)(long) regs->regs[4];
+ if (!access_ok(VERIFY_READ, uset, sizeof(sigset_t)))
+ return -EFAULT;
+
+ __get_user(kset, to_k_sigset_t(uset));
+
+ current->blocked = kset & _BLOCKABLE;
+ regs->regs[2] = -EINTR;
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
- if (do_signal(mask,regs))
+ if (do_signal(mask, regs))
return -EINTR;
}
+
+ return -EINTR;
}
-/*
- * This sets regs->reg29 even though we don't actually use sigstacks yet..
- */
-asmlinkage int sys_sigreturn(unsigned long __unused)
+asmlinkage int sys_sigreturn(struct pt_regs *regs)
{
- struct sigcontext_struct context;
- struct pt_regs * regs;
+ struct sigcontext *context;
+ int i;
- regs = (struct pt_regs *) &__unused;
- if (verify_area(VERIFY_READ, (void *) regs->reg29, sizeof(context)))
+ /*
+ * We don't support fixing ADEL/ADES exceptions for signal stack frames.
+ * No big loss - who doesn't care about the alignment of this stack
+ * really deserves to loose.
+ */
+ context = (struct sigcontext *)(long) regs->regs[29];
+ if (!access_ok(VERIFY_READ, context, sizeof(struct sigcontext)) ||
+ (regs->regs[29] & (SZREG - 1)))
goto badframe;
- memcpy_fromfs(&context,(void *) regs->reg29, sizeof(context));
- current->blocked = context.oldmask & _BLOCKABLE;
- regs->reg1 = context.sc_at;
- regs->reg2 = context.sc_v0;
- regs->reg3 = context.sc_v1;
- regs->reg4 = context.sc_a0;
- regs->reg5 = context.sc_a1;
- regs->reg6 = context.sc_a2;
- regs->reg7 = context.sc_a3;
- regs->reg8 = context.sc_t0;
- regs->reg9 = context.sc_t1;
- regs->reg10 = context.sc_t2;
- regs->reg11 = context.sc_t3;
- regs->reg12 = context.sc_t4;
- regs->reg13 = context.sc_t5;
- regs->reg14 = context.sc_t6;
- regs->reg15 = context.sc_t7;
- regs->reg16 = context.sc_s0;
- regs->reg17 = context.sc_s1;
- regs->reg18 = context.sc_s2;
- regs->reg19 = context.sc_s3;
- regs->reg20 = context.sc_s4;
- regs->reg21 = context.sc_s5;
- regs->reg22 = context.sc_s6;
- regs->reg23 = context.sc_s7;
- regs->reg24 = context.sc_t8;
- regs->reg25 = context.sc_t9;
+
+ current->blocked = context->sc_sigset.__sigbits[0] & _BLOCKABLE;
+ regs->cp0_epc = context->sc_pc;
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+ for(i = 31;i >= 0;i--)
+ __get_user(regs->regs[i], &context->sc_regs[i]);
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
/*
- * Skip k0/k1
+ * We only allow user processes in 64bit mode (n32, 64 bit ABI) to
+ * restore the upper half of registers.
*/
- regs->reg28 = context.sc_gp;
- regs->reg29 = context.sc_sp;
- regs->reg30 = context.sc_fp;
- regs->reg31 = context.sc_ra;
- regs->cp0_epc = context.sc_epc;
- regs->cp0_cause = context.sc_cause;
+ if (read_32bit_cp0_register(CP0_STATUS) & ST0_UX)
+ for(i = 31;i >= 0;i--)
+ __get_user(regs->regs[i], &context->sc_regs[i]);
+ else
+ for(i = 31;i >= 0;i--) {
+ __get_user(regs->regs[i], &context->sc_regs[i]);
+ regs->regs[i] = (int) regs->regs[i];
+ }
+#endif
+ __get_user(regs->hi, &context->sc_mdhi);
+ __get_user(regs->lo, &context->sc_mdlo);
+ restore_fp_context(context);
/*
- * disable syscall checks
+ * Disable syscall checks
*/
regs->orig_reg2 = -1;
- return regs->orig_reg2;
+
+ /*
+ * Don't let your children do this ...
+ */
+ asm( "move\t$29,%0\n\t"
+ "j\tret_from_sys_call"
+ :/* no outputs */
+ :"r" (regs));
+ /* Unreached */
+
badframe:
do_exit(SIGSEGV);
}
/*
* Set up a signal frame...
+ *
+ * This routine is somewhat complicated by the fact that if the kernel may be
+ * entered by an exception other than a system call; e.g. a bus error or other
+ * "bad" exception. If this is the case, then *all* the context on the kernel
+ * stack frame must be saved.
+ *
+ * For a large number of exceptions, the stack frame format is the same
+ * as that which will be created when the process traps back to the kernel
+ * when finished executing the signal handler. In this case, nothing
+ * must be done. This information is saved on the user stack and restored
+ * when the signal handler is returned.
+ *
+ * The signal handler will be called with ra pointing to code1 (see below) and
+ * signal number and pointer to the saved sigcontext as the two parameters.
+ *
+ * usp -> [unused] ; first free word on stack
+ * arg save space ; 16/32 bytes arg. save space
+ * code1 (addiu sp,#1-offset) ; pop stackframe
+ * code2 (li v0,__NR_sigreturn) ; syscall number
+ * code3 (syscall) ; do sigreturn(2)
+ * #1| $0, at, v0, v1, a0, a1, a2, a3 ; All integer registers
+ * | t0, t1, t2, t3, t4, t5, t6, t7 ; $0, k0 and k1 are placeholders
+ * | s0, s1, s2, s3, s4, s5, s6, s7
+ * | k0, k1, t8, t9, gp, sp, fp, ra;
+ * | epc ; old program counter
+ * | cause ; CP0 cause register
+ * | oldmask
*/
-static void setup_frame(struct sigaction * sa, unsigned long ** fp,
- unsigned long pc, struct pt_regs *regs,
+
+struct sc {
+ unsigned long ass[4];
+ unsigned int code[4];
+ struct sigcontext scc;
+};
+#define scc_offset ((size_t)&((struct sc *)0)->scc)
+
+static void setup_frame(struct sigaction * sa, struct pt_regs *regs,
int signr, unsigned long oldmask)
{
- unsigned long * frame;
+ struct sc *frame;
+ struct sigcontext *sc;
+ int i;
+
+ frame = (struct sc *) (long) regs->regs[29];
+ frame--;
- frame = *fp;
- frame -= 32;
- if (verify_area(VERIFY_WRITE,frame,21*4))
- do_exit(SIGSEGV);
- /*
- * set up the "normal" stack seen by the signal handler
- */
- put_fs_long(regs->reg1 , frame );
- put_fs_long(regs->reg2 , frame+ 1);
- put_fs_long(regs->reg3 , frame+ 2);
- put_fs_long(regs->reg4 , frame+ 3);
- put_fs_long(regs->reg5 , frame+ 4);
- put_fs_long(regs->reg6 , frame+ 5);
- put_fs_long(regs->reg7 , frame+ 6);
- put_fs_long(regs->reg8 , frame+ 7);
- put_fs_long(regs->reg9 , frame+ 8);
- put_fs_long(regs->reg10, frame+ 9);
- put_fs_long(regs->reg11, frame+10);
- put_fs_long(regs->reg12, frame+11);
- put_fs_long(regs->reg13, frame+12);
- put_fs_long(regs->reg14, frame+13);
- put_fs_long(regs->reg15, frame+14);
- put_fs_long(regs->reg16, frame+15);
- put_fs_long(regs->reg17, frame+16);
- put_fs_long(regs->reg18, frame+17);
- put_fs_long(regs->reg19, frame+18);
- put_fs_long(regs->reg20, frame+19);
- put_fs_long(regs->reg21, frame+20);
- put_fs_long(regs->reg22, frame+21);
- put_fs_long(regs->reg23, frame+22);
- put_fs_long(regs->reg24, frame+23);
- put_fs_long(regs->reg25, frame+24);
/*
- * Don't copy k0/k1
+ * We realign the stack to an adequate boundary for the architecture.
+ * The assignment to sc had to be moved over the if to prevent
+ * GCC from throwing warnings.
*/
- put_fs_long(regs->reg28, frame+25);
- put_fs_long(regs->reg29, frame+26);
- put_fs_long(regs->reg30, frame+27);
- put_fs_long(regs->reg31, frame+28);
- put_fs_long(pc , frame+29);
- put_fs_long(oldmask , frame+30);
+ frame = (struct sc *)((unsigned long)frame & ALMASK);
+ sc = &frame->scc;
+ if (!access_ok(VERIFY_WRITE, frame, sizeof (struct sc))) {
+ do_exit(SIGSEGV);
+ return;
+ }
+
/*
- * set up the return code...
+ * Set up the return code ...
*
* .set noreorder
- * .set noat
- * syscall
+ * addiu sp,24
* li v0,__NR_sigreturn
- * .set at
+ * syscall
* .set reorder
*/
- put_fs_long(0x24020077, frame+31); /* li $2,119 */
- put_fs_long(0x000000c0, frame+32); /* syscall */
- *fp = frame;
+ __put_user(0x27bd0000 + scc_offset, &frame->code[0]);
+ __put_user(0x24020000 + __NR_sigreturn, &frame->code[1]);
+ __put_user(0x0000000c, &frame->code[2]);
+
+ /*
+ * Flush caches so that the instructions will be correctly executed.
+ */
+ cacheflush((unsigned long)frame->code, sizeof (frame->code),
+ CF_BCACHE|CF_ALL);
+
/*
- * Flush caches so the instructions will be correctly executed.
+ * Set up the "normal" sigcontext
*/
- sys_cacheflush(frame, 32*4, BCACHE);
+ sc->sc_pc = regs->cp0_epc; /* Program counter */
+ sc->sc_status = regs->cp0_status; /* Status register */
+ for(i = 31;i >= 0;i--)
+ __put_user(regs->regs[i], &sc->sc_regs[i]);
+ save_fp_context(sc);
+ __put_user(regs->hi, &sc->sc_mdhi);
+ __put_user(regs->lo, &sc->sc_mdlo);
+ __put_user(regs->cp0_cause, &sc->sc_cause);
+ __put_user((regs->cp0_status & ST0_CU0) != 0, &sc->sc_ownedfp);
+ __put_user(oldmask, &sc->sc_sigset.__sigbits[0]);
+ __put_user(0, &sc->sc_sigset.__sigbits[1]);
+ __put_user(0, &sc->sc_sigset.__sigbits[2]);
+ __put_user(0, &sc->sc_sigset.__sigbits[3]);
+
+ regs->regs[4] = signr; /* Args for handler */
+ regs->regs[5] = (long) frame; /* Ptr to sigcontext */
+ regs->regs[29] = (unsigned long) frame; /* Stack pointer */
+ regs->regs[31] = (unsigned long) frame->code; /* Return address */
+ regs->cp0_epc = regs->regs[25] /* "return" to the first handler */
+ = (unsigned long) sa->sa_handler;
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+static inline void
+handle_signal(unsigned long signr, struct sigaction *sa,
+ unsigned long oldmask, struct pt_regs * regs)
+{
+ /* are we from a failed system call? */
+ if (regs->orig_reg2 >= 0 && regs->regs[7]) {
+ /* If so, check system call restarting.. */
+ switch (regs->regs[2]) {
+ case ERESTARTNOHAND:
+ regs->regs[2] = EINTR;
+ break;
+
+ case ERESTARTSYS:
+ if (!(sa->sa_flags & SA_RESTART)) {
+ regs->regs[2] = EINTR;
+ break;
+ }
+ /* fallthrough */
+ case ERESTARTNOINTR:
+ regs->regs[7] = regs->orig_reg7;
+ regs->cp0_epc -= 8;
+ }
+ }
+
+ /* set up the stack frame */
+ setup_frame(sa, regs, signr, oldmask);
+
+ if (sa->sa_flags & SA_ONESHOT)
+ sa->sa_handler = NULL;
+#ifdef CONF_NOMASK_BUG_COMPAT
+ current->blocked |= *to_k_sigset_t(&sa->sa_mask);
+#else
+ if (!(sa->sa_flags & SA_NOMASK))
+ current->blocked |= (*to_k_sigset_t(&sa->sa_mask) |
+ _S(signr)) & _BLOCKABLE;
+#endif
}
/*
@@ -179,16 +326,13 @@ static void setup_frame(struct sigaction * sa, unsigned long ** fp,
asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
{
unsigned long mask = ~current->blocked;
- unsigned long handler_signal = 0;
- unsigned long *frame = NULL;
- unsigned long pc = 0;
unsigned long signr;
struct sigaction * sa;
while ((signr = current->signal & mask)) {
signr = ffz(~signr);
clear_bit(signr, &current->signal);
- sa = current->sigaction + signr;
+ sa = current->sig->action + signr;
signr++;
if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
current->exit_code = signr;
@@ -204,7 +348,7 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
current->signal |= _S(signr);
continue;
}
- sa = current->sigaction + signr - 1;
+ sa = current->sig->action + signr - 1;
}
if (sa->sa_handler == SIG_IGN) {
if (signr != SIGCHLD)
@@ -221,19 +365,23 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
case SIGCONT: case SIGCHLD: case SIGWINCH:
continue;
- case SIGSTOP: case SIGTSTP: case SIGTTIN: case SIGTTOU:
+ case SIGTSTP: case SIGTTIN: case SIGTTOU:
+ if (is_orphaned_pgrp(current->pgrp))
+ continue;
+ case SIGSTOP:
if (current->flags & PF_PTRACED)
continue;
current->state = TASK_STOPPED;
current->exit_code = signr;
- if (!(current->p_pptr->sigaction[SIGCHLD-1].sa_flags &
+ if (!(current->p_pptr->sig->action[SIGCHLD-1].sa_flags &
SA_NOCLDSTOP))
notify_parent(current);
schedule();
continue;
case SIGQUIT: case SIGILL: case SIGTRAP:
- case SIGIOT: case SIGFPE: case SIGSEGV: case SIGBUS:
+ case SIGABRT: case SIGFPE: case SIGSEGV:
+ case SIGBUS:
if (current->binfmt && current->binfmt->core_dump) {
if (current->binfmt->core_dump(signr, regs))
signr |= 0x80;
@@ -241,55 +389,33 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
/* fall through */
default:
current->signal |= _S(signr & 0x7f);
+ current->flags |= PF_SIGNALED;
do_exit(signr);
}
}
- /*
- * OK, we're invoking a handler
- */
- if (regs->orig_reg2 >= 0) {
- if (regs->reg2 == -ERESTARTNOHAND ||
- (regs->reg2 == -ERESTARTSYS &&
- !(sa->sa_flags & SA_RESTART)))
- regs->reg2 = -EINTR;
- }
- handler_signal |= 1 << (signr-1);
- mask &= ~sa->sa_mask;
+ handle_signal(signr, sa, oldmask, regs);
+ return 1;
}
- if (regs->orig_reg2 >= 0 &&
- (regs->reg2 == -ERESTARTNOHAND ||
- regs->reg2 == -ERESTARTSYS ||
- regs->reg2 == -ERESTARTNOINTR)) {
- regs->reg2 = regs->orig_reg2;
- regs->cp0_epc -= 4;
- }
- if (!handler_signal) /* no handler will be called - return 0 */
- return 0;
- pc = regs->cp0_epc;
- frame = (unsigned long *) regs->reg29;
- signr = 1;
- sa = current->sigaction;
- for (mask = 1 ; mask ; sa++,signr++,mask += mask) {
- if (mask > handler_signal)
- break;
- if (!(mask & handler_signal))
- continue;
- setup_frame(sa,&frame,pc,regs,signr,oldmask);
- pc = (unsigned long) sa->sa_handler;
- if (sa->sa_flags & SA_ONESHOT)
- sa->sa_handler = NULL;
- /*
- * force a kernel-mode page-in of the signal
- * handler to reduce races
- */
- __asm__("lw\t$0,(%0)"
- : /* no output */
- :"r" ((char *) pc));
- current->blocked |= sa->sa_mask;
- oldmask |= sa->sa_mask;
+
+ /* Did we come from a system call? */
+ if (regs->orig_reg2 >= 0) {
+ /* Restart the system call - no handlers present */
+ if (regs->regs[2] == -ERESTARTNOHAND ||
+ regs->regs[2] == -ERESTARTSYS ||
+ regs->regs[2] == -ERESTARTNOINTR) {
+ regs->regs[2] = regs->orig_reg2;
+ regs->cp0_epc -= 8;
+ }
}
- regs->reg29 = (unsigned long) frame;
- regs->cp0_epc = pc; /* "return" to the first handler */
+ return 0;
+}
- return 1;
+/*
+ * The signal(2) syscall is no longer available in the kernel
+ * because GNU libc doesn't use it. Maybe I'll add it back to the
+ * kernel for the binary compatibility stuff.
+ */
+asmlinkage unsigned long sys_signal(int signum, __sighandler_t handler)
+{
+ return -ENOSYS;
}
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
new file mode 100644
index 000000000..144a3c905
--- /dev/null
+++ b/arch/mips/kernel/syscall.c
@@ -0,0 +1,280 @@
+/*
+ * MIPS specific syscall handling functions and syscalls
+ *
+ * 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.
+ *
+ * Copyright (C) 1995, 1996 by Ralf Baechle
+ *
+ * TODO: Implement the compatibility syscalls.
+ * Don't waste that much memory for empty entries in the syscall
+ * table.
+ */
+#undef CONF_PRINT_SYSCALLS
+
+#include <linux/linkage.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/sched.h>
+#include <linux/unistd.h>
+#include <asm/branch.h>
+#include <asm/ptrace.h>
+#include <asm/uaccess.h>
+#include <asm/signal.h>
+
+extern asmlinkage void syscall_trace(void);
+typedef asmlinkage int (*syscall_t)(void *a0,...);
+extern asmlinkage int do_syscalls(struct pt_regs *regs, syscall_t fun,
+ int narg);
+extern syscall_t sys_call_table[];
+extern unsigned char sys_narg_table[];
+
+/*
+ * The pipe syscall has a unusual calling convention. We return the two
+ * filedescriptors in the result registers v0/v1. The syscall wrapper
+ * from libc places these results in the array to which the argument of
+ * pipe points to. This is like other MIPS operating systems and unlike
+ * Linux/i386 where the kernel itself places the results in the file
+ * descriptor array itself. This calling convention also has the advantage
+ * of lower overhead because we don't need to call verify_area.
+ */
+asmlinkage int sys_pipe(struct pt_regs *regs)
+{
+ int fd[2];
+ int error;
+
+ error = do_pipe(fd);
+ if (error)
+ return error;
+ regs->regs[3] = fd[1];
+ return fd[0];
+}
+
+asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, int prot,
+ int flags, int fd, off_t offset)
+{
+ struct file * file = NULL;
+
+ if (!(flags & MAP_ANONYMOUS)) {
+ if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+ return -EBADF;
+ }
+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+ return do_mmap(file, addr, len, prot, flags, offset);
+}
+
+asmlinkage int sys_idle(void)
+{
+ if (current->pid != 0)
+ return -EPERM;
+
+ /* endless idle loop with no priority at all */
+ current->counter = -100;
+ for (;;) {
+ /*
+ * Not all MIPS R-series CPUs have the wait instruction.
+ * FIXME: We should save power by reducing the clock where
+ * possible.
+ */
+ if (wait_available && !need_resched)
+ __asm__(".set\tmips3\n\t"
+ "wait\n\t"
+ ".set\tmips0\n\t");
+ schedule();
+ }
+}
+
+#if 0
+/*
+ * RISC/os compatible SysV flavoured fork(2) syscall.
+ *
+ * This call has a different calling sequence:
+ * child return value: pid of parent, secondary result = 1.
+ * parent return value: pid of child, secondary result value = 0.
+ * error: errno, secondary result = 0.
+ */
+asmlinkage int sys_sysv_fork(struct pt_regs *regs)
+{
+ int pid;
+
+ pid = do_fork(SIGCHLD, regs->regs[29], regs);
+ if (pid == 0) { /* child */
+ regs->regs[3] = 1;
+ return current->p_pptr->pid;
+ } /* parent or error */
+
+ regs->regs[3] = 0;
+ return pid;
+}
+#endif
+
+/*
+ * Normal Linux fork(2) syscall
+ */
+asmlinkage int sys_fork(struct pt_regs *regs)
+{
+ return do_fork(SIGCHLD, regs->regs[29], regs);
+}
+
+asmlinkage int sys_clone(struct pt_regs *regs)
+{
+ unsigned long clone_flags;
+ unsigned long newsp;
+
+ clone_flags = regs->regs[4];
+ newsp = regs->regs[5];
+ if (!newsp)
+ newsp = regs->regs[29];
+ return do_fork(clone_flags, newsp, regs);
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage int sys_execve(struct pt_regs *regs)
+{
+ int error;
+ char * filename;
+
+ error = getname((char *) (long)regs->regs[4], &filename);
+ if (error)
+ return error;
+ error = do_execve(filename, (char **) (long)regs->regs[5],
+ (char **) (long)regs->regs[6], regs);
+ putname(filename);
+
+ return error;
+}
+
+/*
+ * Do the indirect syscall syscall.
+ */
+asmlinkage int sys_syscall(unsigned long a0, unsigned long a1, unsigned long a2,
+ unsigned long a3, unsigned long a4, unsigned long a5,
+ unsigned long a6)
+{
+ syscall_t syscall;
+
+ if (a0 > __NR_Linux + __NR_Linux_syscalls)
+ return -ENOSYS;
+
+ syscall = sys_call_table[a0];
+ /*
+ * Prevent stack overflow by recursive
+ * syscall(__NR_syscall, __NR_syscall,...);
+ */
+ if (syscall == (syscall_t) sys_syscall)
+ return -EINVAL;
+
+ if (syscall == NULL)
+ return -ENOSYS;
+
+ return syscall((void *)a0, a1, a2, a3, a4, a5, a6);
+}
+
+/*
+ * If we ever come here the user sp is bad. Zap the process right away.
+ * Due to the bad stack signaling wouldn't work.
+ */
+asmlinkage void bad_stack(void)
+{
+ do_exit(SIGSEGV);
+}
+
+#ifdef CONF_PRINT_SYSCALLS
+#define SYS(fun, narg) #fun,
+static char *sfnames[] = {
+#include "syscalls.h"
+};
+#endif
+
+asmlinkage void do_sys(struct pt_regs *regs)
+{
+ unsigned long syscallnr, usp;
+ syscall_t syscall;
+ int errno, narg;
+
+ /* Skip syscall instruction */
+ if (delay_slot(regs)) {
+ /*
+ * By convention "li v0,<syscallno>" is always preceeding
+ * the syscall instruction. So if we're in a delay slot
+ * userland is screwed up.
+ */
+ force_sig(SIGILL, current);
+ return;
+ }
+ regs->cp0_epc += 4;
+
+ syscallnr = regs->regs[2];
+ if (syscallnr > (__NR_Linux + __NR_Linux_syscalls))
+ goto illegal_syscall;
+ syscall = sys_call_table[syscallnr];
+
+#ifdef CONF_PRINT_SYSCALLS
+ printk("do_sys(): %s()", sfnames[syscallnr - __NR_Linux]);
+#endif
+ narg = sys_narg_table[syscallnr];
+ if (narg > 4) {
+ /*
+ * Verify that we can safely get the additional parameters
+ * from the user stack.
+ */
+ usp = regs->regs[29];
+ if (usp & 3) {
+ printk("unaligned usp\n");
+ do_exit(SIGBUS);
+ return;
+ }
+
+ if (!access_ok(VERIFY_READ, (void *) (usp + 16),
+ (narg - 4) * sizeof(unsigned long))) {
+ errno = -EFAULT;
+ goto syscall_error;
+ }
+ }
+
+ if ((current->flags & PF_TRACESYS) == 0) {
+ errno = do_syscalls(regs, syscall, narg);
+ if (errno < 0)
+ goto syscall_error;
+
+ regs->regs[2] = errno;
+ regs->regs[7] = 0;
+ } else {
+ syscall_trace();
+
+ errno = do_syscalls(regs, syscall, narg);
+ if (errno < 0) {
+ regs->regs[2] = -errno;
+ regs->regs[7] = 1;
+ } else {
+ regs->regs[2] = errno;
+ regs->regs[7] = 0;
+ }
+
+ syscall_trace();
+ }
+#ifdef CONF_PRINT_SYSCALLS
+ printk(" returning: normal\n");
+#endif
+ return;
+
+syscall_error:
+ regs->regs[2] = -errno;
+ regs->regs[7] = 1;
+#ifdef CONF_PRINT_SYSCALLS
+ printk(" returning: syscall_error, errno=%d\n", -errno);
+#endif
+ return;
+
+illegal_syscall:
+ regs->regs[2] = ENOSYS;
+ regs->regs[7] = 1;
+#ifdef CONF_PRINT_SYSCALLS
+ printk(" returning: illegal_syscall\n");
+#endif
+ return;
+}
diff --git a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h
new file mode 100644
index 000000000..6a398c92d
--- /dev/null
+++ b/arch/mips/kernel/syscalls.h
@@ -0,0 +1,205 @@
+/*
+ * List of Linux/MIPS syscalls.
+ *
+ * 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.
+ *
+ * Copyright (C) 1995, 1996 by Ralf Baechle
+ */
+
+/*
+ * This file is being included twice - once to build a list of all
+ * syscalls and once to build a table of how many arguments each syscall
+ * accepts. Syscalls that receive a pointer to the saved registers are
+ * marked as having zero arguments.
+ *
+ * The binary compatibility calls are still missing in this list.
+ */
+SYS(sys_syscall, 7) /* 4000 */
+SYS(sys_exit, 1)
+SYS(sys_fork, 0)
+SYS(sys_read, 3)
+SYS(sys_write, 3)
+SYS(sys_open, 3) /* 4005 */
+SYS(sys_close, 3)
+SYS(sys_waitpid, 3)
+SYS(sys_creat, 2)
+SYS(sys_link, 2)
+SYS(sys_unlink, 1) /* 4010 */
+SYS(sys_execve, 0)
+SYS(sys_chdir, 1)
+SYS(sys_time, 1)
+SYS(sys_mknod, 3)
+SYS(sys_chmod, 2) /* 4015 */
+SYS(sys_chown, 3)
+SYS(sys_break, 0)
+SYS(sys_stat, 2)
+SYS(sys_lseek, 3)
+SYS(sys_getpid, 0) /* 4020 */
+SYS(sys_mount, 5)
+SYS(sys_umount, 1)
+SYS(sys_setuid, 1)
+SYS(sys_getuid, 0)
+SYS(sys_stime, 1) /* 4025 */
+SYS(sys_ptrace, 4)
+SYS(sys_alarm, 1)
+SYS(sys_fstat, 2)
+SYS(sys_pause, 0)
+SYS(sys_utime, 2) /* 4030 */
+SYS(sys_stty, 0)
+SYS(sys_gtty, 0)
+SYS(sys_access, 2)
+SYS(sys_nice, 1)
+SYS(sys_ftime, 0) /* 4035 */
+SYS(sys_sync, 0)
+SYS(sys_kill, 2)
+SYS(sys_rename, 2)
+SYS(sys_mkdir, 2)
+SYS(sys_rmdir, 1) /* 4040 */
+SYS(sys_dup, 1)
+SYS(sys_pipe, 0)
+SYS(sys_times, 1)
+SYS(sys_prof, 0)
+SYS(sys_brk, 1) /* 4045 */
+SYS(sys_setgid, 1)
+SYS(sys_getgid, 0)
+SYS(sys_signal, 2)
+SYS(sys_geteuid, 0)
+SYS(sys_getegid, 0) /* 4050 */
+SYS(sys_acct, 0)
+SYS(sys_phys, 0)
+SYS(sys_lock, 0)
+SYS(sys_ioctl, 3)
+SYS(sys_fcntl, 3) /* 4055 */
+SYS(sys_mpx, 2)
+SYS(sys_setpgid, 2)
+SYS(sys_ulimit, 0)
+SYS(sys_olduname, 1)
+SYS(sys_umask, 1) /* 4060 */
+SYS(sys_chroot, 1)
+SYS(sys_ustat, 2)
+SYS(sys_dup2, 2)
+SYS(sys_getppid, 0)
+SYS(sys_getpgrp, 0) /* 4065 */
+SYS(sys_setsid, 0)
+SYS(sys_sigaction, 3)
+SYS(sys_sgetmask, 0)
+SYS(sys_ssetmask, 1)
+SYS(sys_setreuid, 2) /* 4070 */
+SYS(sys_setregid, 2)
+SYS(sys_sigsuspend, 0)
+SYS(sys_sigpending, 1)
+SYS(sys_sethostname, 2)
+SYS(sys_setrlimit, 2) /* 4075 */
+SYS(sys_getrlimit, 2)
+SYS(sys_getrusage, 2)
+SYS(sys_gettimeofday, 2)
+SYS(sys_settimeofday, 2)
+SYS(sys_getgroups, 2) /* 4080 */
+SYS(sys_setgroups, 2)
+SYS(sys_ni_syscall, 0) /* old_select */
+SYS(sys_symlink, 2)
+SYS(sys_lstat, 2)
+SYS(sys_readlink, 3) /* 4085 */
+SYS(sys_uselib, 1)
+SYS(sys_swapon, 2)
+SYS(sys_reboot, 3)
+SYS(old_readdir, 3)
+SYS(sys_mmap, 6) /* 4090 */
+SYS(sys_munmap, 2)
+SYS(sys_truncate, 2)
+SYS(sys_ftruncate, 2)
+SYS(sys_fchmod, 2)
+SYS(sys_fchown, 3) /* 4095 */
+SYS(sys_getpriority, 2)
+SYS(sys_setpriority, 3)
+SYS(sys_profil, 0)
+SYS(sys_statfs, 2)
+SYS(sys_fstatfs, 2) /* 4100 */
+SYS(sys_ioperm, 3)
+SYS(sys_socketcall, 2)
+SYS(sys_syslog, 3)
+SYS(sys_setitimer, 3)
+SYS(sys_getitimer, 2) /* 4105 */
+SYS(sys_newstat, 2)
+SYS(sys_newlstat, 2)
+SYS(sys_newfstat, 2)
+SYS(sys_uname, 1)
+SYS(sys_iopl, 0) /* Well, actually 17 args ... */ /* 4110 */
+SYS(sys_vhangup, 0)
+SYS(sys_idle, 0)
+SYS(sys_vm86, 1)
+SYS(sys_wait4, 4)
+SYS(sys_swapoff, 1) /* 4115 */
+SYS(sys_sysinfo, 1)
+SYS(sys_ipc, 6)
+SYS(sys_fsync, 1)
+SYS(sys_sigreturn, 0)
+SYS(sys_clone, 0) /* 4120 */
+SYS(sys_setdomainname, 2)
+SYS(sys_newuname, 1)
+SYS(sys_ni_syscall, 0) /* sys_modify_ldt */
+SYS(sys_adjtimex, 1)
+SYS(sys_mprotect, 3) /* 4125 */
+SYS(sys_sigprocmask, 3)
+SYS(sys_create_module, 2)
+SYS(sys_init_module, 5)
+SYS(sys_delete_module, 1)
+SYS(sys_get_kernel_syms, 1) /* 4130 */
+SYS(sys_quotactl, 0)
+SYS(sys_getpgid, 1)
+SYS(sys_fchdir, 1)
+SYS(sys_bdflush, 2)
+SYS(sys_sysfs, 3) /* 4135 */
+SYS(sys_personality, 1)
+SYS(sys_ni_syscall, 0) /* for afs_syscall */
+SYS(sys_setfsuid, 1)
+SYS(sys_setfsgid, 1)
+SYS(sys_llseek, 5) /* 4140 */
+SYS(sys_getdents, 3)
+SYS(sys_select, 5)
+SYS(sys_flock, 2)
+SYS(sys_msync, 3)
+SYS(sys_readv, 3) /* 4145 */
+SYS(sys_writev, 3)
+SYS(sys_cacheflush, 3)
+SYS(sys_cachectl, 3)
+SYS(sys_sysmips, 4)
+SYS(sys_setup, 0) /* 4150 */
+SYS(sys_getsid, 1)
+SYS(sys_fdatasync, 0)
+SYS(sys_sysctl, 1)
+SYS(sys_mlock, 2)
+SYS(sys_munlock, 2) /* 4155 */
+SYS(sys_mlockall, 1)
+SYS(sys_munlockall, 0)
+SYS(sys_sched_setparam,2)
+SYS(sys_sched_getparam,2)
+SYS(sys_sched_setscheduler,3) /* 4160 */
+SYS(sys_sched_getscheduler,1)
+SYS(sys_sched_yield,0)
+SYS(sys_sched_get_priority_max,1)
+SYS(sys_sched_get_priority_min,1)
+SYS(sys_sched_rr_get_interval,2) /* 4165 */
+SYS(sys_nanosleep,2)
+SYS(sys_mremap,4)
+SYS(sys_accept, 3)
+SYS(sys_bind, 3)
+SYS(sys_connect, 3) /* 4170 */
+SYS(sys_getpeername, 3)
+SYS(sys_getsockname, 3)
+SYS(sys_getsockopt, 5)
+SYS(sys_listen, 2)
+SYS(sys_recv, 4) /* 4175 */
+SYS(sys_recvfrom, 6)
+SYS(sys_recvmsg, 3)
+SYS(sys_send, 4)
+SYS(sys_sendmsg, 3)
+SYS(sys_sendto, 6) /* 4180 */
+SYS(sys_setsockopt, 5)
+SYS(sys_shutdown, 2)
+SYS(sys_socket, 3)
+SYS(sys_socketpair, 4)
+SYS(sys_setresuid, 3) /* 4185 */
+SYS(sys_getresuid, 3)
diff --git a/arch/mips/kernel/sysmips.c b/arch/mips/kernel/sysmips.c
new file mode 100644
index 000000000..d15aaa4dd
--- /dev/null
+++ b/arch/mips/kernel/sysmips.c
@@ -0,0 +1,113 @@
+/*
+ * MIPS specific syscalls
+ *
+ * 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.
+ *
+ * Copyright (C) 1995 by Ralf Baechle
+ */
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/utsname.h>
+
+#include <asm/cachectl.h>
+#include <asm/cache.h>
+#include <asm/ipc.h>
+#include <asm/uaccess.h>
+#include <asm/sysmips.h>
+
+static inline size_t
+strnlen_user(const char *s, size_t count)
+{
+ return strnlen(s, count);
+}
+
+asmlinkage int
+sys_sysmips(int cmd, int arg1, int arg2, int arg3)
+{
+ int *p;
+ char *name;
+ int flags, tmp, len, retval;
+
+ switch(cmd)
+ {
+ case SETNAME:
+ if (!suser())
+ return -EPERM;
+ name = (char *) arg1;
+ len = strnlen_user(name, retval);
+ if (len < 0)
+ retval = len;
+ break;
+ if (len == 0 || len > __NEW_UTS_LEN)
+ retval = -EINVAL;
+ break;
+ copy_from_user(system_utsname.nodename, name, len);
+ system_utsname.nodename[len] = '\0';
+ return 0;
+
+ case MIPS_ATOMIC_SET:
+ /* This is broken in case of page faults and SMP ...
+ Risc/OS fauls after maximum 20 tries with EAGAIN. */
+ p = (int *) arg1;
+ retval = verify_area(VERIFY_WRITE, p, sizeof(*p));
+ if (retval)
+ return retval;
+ save_flags(flags);
+ cli();
+ retval = *p;
+ *p = arg2;
+ restore_flags(flags);
+ break;
+
+ case MIPS_FIXADE:
+ tmp = current->tss.mflags & ~3;
+ current->tss.mflags = tmp | (arg1 & 3);
+ retval = 0;
+ break;
+
+ case FLUSH_CACHE:
+ cacheflush(0, ~0, CF_BCACHE|CF_ALL);
+ break;
+
+ case MIPS_RDNVRAM:
+ retval = -EIO;
+ break;
+
+ default:
+ retval = -EINVAL;
+ break;
+ }
+
+ return retval;
+}
+
+asmlinkage int
+sys_cacheflush(void *addr, int nbytes, int cache)
+{
+ unsigned int rw;
+ int ok;
+
+ if ((cache & ~(DCACHE | ICACHE)) != 0)
+ return -EINVAL;
+ rw = (cache & DCACHE) ? VERIFY_WRITE : VERIFY_READ;
+ if (!access_ok(rw, addr, nbytes))
+ return -EFAULT;
+
+ cacheflush((unsigned long)addr, (unsigned long)nbytes, cache|CF_ALL);
+
+ return 0;
+}
+
+/*
+ * No implemented yet ...
+ */
+asmlinkage int
+sys_cachectl(char *addr, int nbytes, int op)
+{
+ return -ENOSYS;
+}
diff --git a/arch/mips/kernel/tags.c b/arch/mips/kernel/tags.c
new file mode 100644
index 000000000..4bf480c54
--- /dev/null
+++ b/arch/mips/kernel/tags.c
@@ -0,0 +1,70 @@
+/*
+ * linux/arch/mips/kernel/tags.c
+ *
+ * Copyright (C) 1996 Stoned Elipot
+ */
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <asm/bootinfo.h>
+
+/*
+ * Parse the tags present in upper memory to find out
+ * a pecular one.
+ *
+ * Parameter: type - tag type to find
+ *
+ * returns : NULL - failure
+ * !NULL - pointer on the tag structure found
+ */
+tag *
+bi_TagFind(enum bi_tag type)
+{
+ tag* t = (tag*)(mips_memory_upper - sizeof(tag));
+
+ while((t->tag != tag_dummy) && (t->tag != type))
+ t = (tag*)(NEXTTAGPTR(t));
+
+ if (t->tag == tag_dummy) /* tag not found */
+ return (tag*)NULL;
+
+ return t;
+}
+
+/*
+ * Snarf from the tag list in memory end some tags needed
+ * before the kernel reachs setup_arch()
+ *
+ * add yours here if you want to, but *beware*: the kernel var
+ * that will hold the values you want to snarf have to be
+ * in .data section of the kernel, so initialized in to whatever
+ * value in the kernel's sources.
+ */
+void bi_EarlySnarf(void)
+{
+ tag* atag;
+
+ /* for wire_mappings() */
+ atag = bi_TagFind(tag_machgroup);
+ if (atag)
+ memcpy(&mips_machgroup, TAGVALPTR(atag), atag->size);
+ else
+ /* useless for boxes without text video mode but....*/
+ panic("machine group not specified by bootloader");
+
+ atag = bi_TagFind(tag_machtype);
+ if (atag)
+ memcpy(&mips_machtype, TAGVALPTR(atag), atag->size);
+ else
+ /* useless for boxes without text video mode but....*/
+ panic("machine type not specified by bootloader");
+
+ /* for tlbflush() */
+ atag = bi_TagFind(tag_tlb_entries);
+ if (atag)
+ memcpy(&mips_tlb_entries, TAGVALPTR(atag), atag->size);
+ else
+ /* useless for boxes without text video mode but....*/
+ panic("number of TLB entries not specified by bootloader");
+ return;
+}
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
new file mode 100644
index 000000000..2dd1d54ee
--- /dev/null
+++ b/arch/mips/kernel/time.c
@@ -0,0 +1,292 @@
+/*
+ * linux/arch/mips/kernel/time.c
+ *
+ * Copyright (C) 1991, 1992, 1995 Linus Torvalds
+ *
+ * This file contains the time handling details for PC-style clocks as
+ * found in some MIPS systems.
+ */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+
+#include <asm/bootinfo.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <linux/mc146818rtc.h>
+#include <linux/timex.h>
+
+/* This function must be called with interrupts disabled
+ * It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs
+ *
+ * However, the pc-audio speaker driver changes the divisor so that
+ * it gets interrupted rather more often - it loads 64 into the
+ * counter rather than 11932! This has an adverse impact on
+ * do_gettimeoffset() -- it stops working! What is also not
+ * good is that the interval that our timer function gets called
+ * is no longer 10.0002 ms, but 9.9767 ms. To get around this
+ * would require using a different timing source. Maybe someone
+ * could use the RTC - I know that this can interrupt at frequencies
+ * ranging from 8192Hz to 2Hz. If I had the energy, I'd somehow fix
+ * it so that at startup, the timer code in sched.c would select
+ * using either the RTC or the 8253 timer. The decision would be
+ * based on whether there was any other device around that needed
+ * to trample on the 8253. I'd set up the RTC to interrupt at 1024 Hz,
+ * and then do some jiggery to have a version of do_timer that
+ * advanced the clock by 1/1024 s. Every time that reached over 1/100
+ * of a second, then do all the old code. If the time was kept correct
+ * then do_gettimeoffset could just return 0 - there is no low order
+ * divider that can be accessed.
+ *
+ * Ideally, you would be able to use the RTC for the speaker driver,
+ * but it appears that the speaker driver really needs interrupt more
+ * often than every 120 us or so.
+ *
+ * Anyway, this needs more thought.... pjsg (1993-08-28)
+ *
+ * If you are really that interested, you should be reading
+ * comp.protocols.time.ntp!
+ */
+
+#define TICK_SIZE tick
+
+static unsigned long do_slow_gettimeoffset(void)
+{
+ int count;
+ unsigned long offset = 0;
+
+ /* timer count may underflow right here */
+ outb_p(0x00, 0x43); /* latch the count ASAP */
+ count = inb_p(0x40); /* read the latched count */
+ count |= inb(0x40) << 8;
+ /* we know probability of underflow is always MUCH less than 1% */
+ if (count > (LATCH - LATCH/100)) {
+ /* check for pending timer interrupt */
+ outb_p(0x0a, 0x20);
+ if (inb(0x20) & 1)
+ offset = TICK_SIZE;
+ }
+ count = ((LATCH-1) - count) * TICK_SIZE;
+ count = (count + LATCH/2) / LATCH;
+ return offset + count;
+}
+
+static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+ unsigned long flags;
+
+ save_flags(flags);
+ cli();
+ *tv = xtime;
+ tv->tv_usec += do_gettimeoffset();
+ if (tv->tv_usec >= 1000000) {
+ tv->tv_usec -= 1000000;
+ tv->tv_sec++;
+ }
+ restore_flags(flags);
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+ cli();
+ /* This is revolting. We need to set the xtime.tv_usec
+ * correctly. However, the value in this location is
+ * is value at the last tick.
+ * Discover what correction gettimeofday
+ * would have done, and then undo it!
+ */
+ tv->tv_usec -= do_gettimeoffset();
+
+ if (tv->tv_usec < 0) {
+ tv->tv_usec += 1000000;
+ tv->tv_sec--;
+ }
+
+ xtime = *tv;
+ time_state = TIME_BAD;
+ time_maxerror = MAXPHASE;
+ time_esterror = MAXPHASE;
+ sti();
+}
+
+/*
+ * In order to set the CMOS clock precisely, set_rtc_mmss has to be
+ * called 500 ms after the second nowtime has started, because when
+ * nowtime is written into the registers of the CMOS clock, it will
+ * jump to the next second precisely 500 ms later. Check the Motorola
+ * MC146818A or Dallas DS12887 data sheet for details.
+ */
+static int set_rtc_mmss(unsigned long nowtime)
+{
+ int retval = 0;
+ int real_seconds, real_minutes, cmos_minutes;
+ unsigned char save_control, save_freq_select;
+
+ save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
+ CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
+
+ save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
+ CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+
+ cmos_minutes = CMOS_READ(RTC_MINUTES);
+ if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
+ BCD_TO_BIN(cmos_minutes);
+
+ /*
+ * since we're only adjusting minutes and seconds,
+ * don't interfere with hour overflow. This avoids
+ * messing with unknown time zones but requires your
+ * RTC not to be off by more than 15 minutes
+ */
+ real_seconds = nowtime % 60;
+ real_minutes = nowtime / 60;
+ if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
+ real_minutes += 30; /* correct for half hour time zone */
+ real_minutes %= 60;
+
+ if (abs(real_minutes - cmos_minutes) < 30) {
+ if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+ BIN_TO_BCD(real_seconds);
+ BIN_TO_BCD(real_minutes);
+ }
+ CMOS_WRITE(real_seconds,RTC_SECONDS);
+ CMOS_WRITE(real_minutes,RTC_MINUTES);
+ } else
+ retval = -1;
+
+ /* The following flags have to be released exactly in this order,
+ * otherwise the DS12887 (popular MC146818A clone with integrated
+ * battery and crystal) will not reset the oscillator and will not
+ * update precisely 500 ms later. You won't find this mentioned in
+ * the Dallas Semiconductor data sheets, but who believes data
+ * sheets anyway ... -- Markus Kuhn
+ */
+ CMOS_WRITE(save_control, RTC_CONTROL);
+ CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+
+ return retval;
+}
+
+/* last time the cmos clock got updated */
+static long last_rtc_update = 0;
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+static void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+ do_timer(regs);
+
+ /*
+ * If we have an externally synchronized Linux clock, then update
+ * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+ * called as close as possible to 500 ms before the new second starts.
+ */
+ if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
+ xtime.tv_usec > 500000 - (tick >> 1) &&
+ xtime.tv_usec < 500000 + (tick >> 1))
+ if (set_rtc_mmss(xtime.tv_sec) == 0)
+ last_rtc_update = xtime.tv_sec;
+ else
+ last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+ /* As we return to user mode fire off the other CPU schedulers.. this is
+ basically because we don't yet share IRQ's around. This message is
+ rigged to be safe on the 386 - basically it's a hack, so don't look
+ closely for now.. */
+ smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0);
+}
+
+/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+ * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
+ * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
+ *
+ * [For the Julian calendar (which was used in Russia before 1917,
+ * Britain & colonies before 1752, anywhere else before 1582,
+ * and is still in use by some communities) leave out the
+ * -year/100+year/400 terms, and add 10.]
+ *
+ * This algorithm was first published by Gauss (I think).
+ *
+ * WARNING: this function will overflow on 2106-02-07 06:28:16 on
+ * machines were long is 32-bit! (However, as time_t is signed, we
+ * will already get problems at other places on 2038-01-19 03:14:08)
+ */
+static inline unsigned long mktime(unsigned int year, unsigned int mon,
+ unsigned int day, unsigned int hour,
+ unsigned int min, unsigned int sec)
+{
+ if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
+ mon += 12; /* Puts Feb last since it has leap day */
+ year -= 1;
+ }
+ return (((
+ (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
+ year*365 - 719499
+ )*24 + hour /* now have hours */
+ )*60 + min /* now have minutes */
+ )*60 + sec; /* finally seconds */
+}
+
+static struct irqaction irq0 = { timer_interrupt, 0, 0, "timer", NULL, NULL};
+
+void (*board_time_init)(struct irqaction *irq);
+
+void time_init(void)
+{
+ unsigned int year, mon, day, hour, min, sec;
+ int i;
+
+ /* The Linux interpretation of the CMOS clock register contents:
+ * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
+ * RTC registers show the second which has precisely just started.
+ * Let's hope other operating systems interpret the RTC the same way.
+ */
+ /* read RTC exactly on falling edge of update flag */
+ for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
+ if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
+ break;
+ for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
+ if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
+ break;
+ do { /* Isn't this overkill ? UIP above should guarantee consistency */
+ sec = CMOS_READ(RTC_SECONDS);
+ min = CMOS_READ(RTC_MINUTES);
+ hour = CMOS_READ(RTC_HOURS);
+ day = CMOS_READ(RTC_DAY_OF_MONTH);
+ mon = CMOS_READ(RTC_MONTH);
+ year = CMOS_READ(RTC_YEAR);
+ } while (sec != CMOS_READ(RTC_SECONDS));
+ if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
+ {
+ BCD_TO_BIN(sec);
+ BCD_TO_BIN(min);
+ BCD_TO_BIN(hour);
+ BCD_TO_BIN(day);
+ BCD_TO_BIN(mon);
+ BCD_TO_BIN(year);
+ }
+#if 0 /* the IBM way */
+ if ((year += 1900) < 1970)
+ year += 100;
+#else
+ /* true for all MIPS machines? */
+ year += 1980;
+#endif
+ xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+ xtime.tv_usec = 0;
+
+ /* FIXME: If we have the CPU hardware time counters, use them */
+ board_time_init(&irq0);
+}
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 36e8a31e8..0fb16f1a5 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1,39 +1,27 @@
/*
- * arch/mips/kernel/traps.c
+ * arch/mips/kernel/traps.c
*
* 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.
- */
-
-/*
- * 'traps.c' handles hardware traps and faults after we have saved some
- * state in 'asm.s'. Currently mostly a debugging-aid, will be extended
- * to mainly kill the offending process (probably by giving it a signal,
- * but possibly by killing it outright if necessary).
*
- * FIXME: This is the place for a fpu emulator.
+ * Copyright (C) 1994, 1995, 1996 by Ralf Baechle
+ * Copyright (C) 1994, 1995, 1996 by Paul M. Antoine
*/
-#include <linux/head.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/ptrace.h>
-#include <linux/config.h>
-#include <linux/timer.h>
#include <linux/mm.h>
+#include <asm/branch.h>
+#include <asm/cache.h>
+#include <asm/jazz.h>
#include <asm/vector.h>
-#include <asm/page.h>
#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/segment.h>
#include <asm/io.h>
-#include <asm/mipsregs.h>
#include <asm/bootinfo.h>
+#include <asm/sgidefs.h>
+#include <asm/uaccess.h>
+#include <asm/watch.h>
+
+#undef CONF_DEBUG_EXCEPTIONS
static inline void console_verbose(void)
{
@@ -63,20 +51,15 @@ extern asmlinkage void handle_ri(void);
extern asmlinkage void handle_cpu(void);
extern asmlinkage void handle_ov(void);
extern asmlinkage void handle_tr(void);
-extern asmlinkage void handle_vcei(void);
extern asmlinkage void handle_fpe(void);
-extern asmlinkage void handle_vced(void);
extern asmlinkage void handle_watch(void);
-extern asmlinkage void handle_reserved(void);
-static char *cpu_names[] = CPU_NAMES;
+char *cpu_names[] = CPU_NAMES;
-/*
- * Fix address errors. This is slow, so try not to use it. This is
- * disabled by default, anyway.
- */
-int fix_ade_enabled = 0;
-unsigned long page_colour_mask;
+unsigned int watch_available = 0;
+
+void (*ibe_board_handler)(struct pt_regs *regs);
+void (*dbe_board_handler)(struct pt_regs *regs);
int kstack_depth_to_print = 24;
@@ -86,6 +69,10 @@ int kstack_depth_to_print = 24;
*/
#define MODULE_RANGE (8*1024*1024)
+/*
+ * This routine abuses get_user()/put_user() to reference pointers
+ * with at least a bit of error checking ...
+ */
void die_if_kernel(char * str, struct pt_regs * regs, long err)
{
int i;
@@ -93,11 +80,23 @@ void die_if_kernel(char * str, struct pt_regs * regs, long err)
u32 *sp, *pc, addr, module_start, module_end;
extern char start_kernel, _etext;
- if ((regs->cp0_status & (ST0_ERL|ST0_EXL)) == 0)
+ /*
+ * Just return if in user mode.
+ */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+ if (!((regs)->cp0_status & 0x4))
return;
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
+ if (!(regs->cp0_status & 0x18))
+ return;
+#endif
- sp = (u32 *)regs->reg29;
- pc = (u32 *)regs->cp0_epc;
+ /*
+ * Yes, these double casts are required ...
+ */
+ sp = (u32 *)(unsigned long)regs->regs[29];
+ pc = (u32 *)(unsigned long)regs->cp0_epc;
console_verbose();
printk("%s: %08lx\n", str, err );
@@ -105,11 +104,6 @@ void die_if_kernel(char * str, struct pt_regs * regs, long err)
show_regs(regs);
/*
- * Some goodies...
- */
- printk("Int : %ld\n", regs->interrupt);
-
- /*
* Dump the stack
*/
if (STACK_MAGIC != *(u32 *)current->kernel_stack_page)
@@ -119,20 +113,30 @@ void die_if_kernel(char * str, struct pt_regs * regs, long err)
for(i=0;i<5;i++)
printk("%08x ", *sp++);
stack = (int *) sp;
+
for(i=0; i < kstack_depth_to_print; i++) {
+ unsigned int stackdata;
+
if (((u32) stack & (PAGE_SIZE -1)) == 0)
break;
if (i && ((i % 8) == 0))
printk("\n ");
- printk("%08lx ", get_user_long(stack++));
+ if (get_user(stackdata, stack++) < 0) {
+ printk("(Bad stack address)");
+ break;
+ }
+ printk("%08x ", stackdata);
}
printk("\nCall Trace: ");
stack = (int *)sp;
i = 1;
module_start = VMALLOC_START;
module_end = module_start + MODULE_RANGE;
- while (((u32)stack & (PAGE_SIZE -1)) != 0) {
- addr = get_user_long(stack++);
+ while (((unsigned long)stack & (PAGE_SIZE -1)) != 0) {
+ if (get_user(addr, stack++) < 0) {
+ printk("(Bad address)\n");
+ break;
+ }
/*
* If the address is either in the text segment of the
* kernel, or in the region which contains vmalloc'ed
@@ -152,123 +156,128 @@ void die_if_kernel(char * str, struct pt_regs * regs, long err)
}
printk("\nCode : ");
- for(i=0;i<5;i++)
- printk("%08x ", *pc++);
- printk("\n");
+ if ((KSEGX(pc) == KSEG0 || KSEGX(pc) == KSEG1) &&
+ (((unsigned long) pc & 3) == 0))
+ {
+ for(i=0;i<5;i++)
+ printk("%08x ", *pc++);
+ printk("\n");
+ }
+ else
+ printk("(Bad address in epc)\n");
do_exit(SIGSEGV);
}
-static void
-fix_ade(struct pt_regs *regs, int write)
+static void default_be_board_handler(struct pt_regs *regs)
{
- printk("Received address error (ade%c)\n", write ? 's' : 'l');
- panic("Fixing address errors not implemented yet");
+ /*
+ * Assume it would be too dangerous to continue ...
+ */
+ force_sig(SIGBUS, current);
}
-void do_adel(struct pt_regs *regs)
+void do_ibe(struct pt_regs *regs)
{
- unsigned long pc = regs->cp0_epc;
- int i;
-
- if(fix_ade_enabled)
- {
- fix_ade(regs, 0);
- return;
- }
-#if 0
- for(i=0; i<NR_TASKS;i++)
- if(task[i] && task[i]->pid >= 2)
- {
- printk("Process %d\n", task[i]->pid);
- dump_list_process(task[i], pc);
- }
-#endif
- show_regs(regs);
-while(1);
- dump_tlb_nonwired();
- send_sig(SIGSEGV, current, 1);
+ ibe_board_handler(regs);
}
-void do_ades(struct pt_regs *regs)
+void do_dbe(struct pt_regs *regs)
{
- unsigned long pc = regs->cp0_epc;
- int i;
-
- if(fix_ade_enabled)
- {
- fix_ade(regs, 1);
- return;
- }
-while(1);
- for(i=0; i<NR_TASKS;i++)
- if(task[i] && task[i]->pid >= 2)
- {
- printk("Process %d\n", task[i]->pid);
- dump_list_process(task[i], pc);
- }
- show_regs(regs);
- dump_tlb_nonwired();
- send_sig(SIGSEGV, current, 1);
+ dbe_board_handler(regs);
}
-/*
- * The ibe/dbe exceptions are signaled by onboard hardware and should get
- * a board specific handlers to get maximum available information. Bus
- * errors are always symptom of hardware malfunction or a kernel error.
- *
- * FIXME: Linux/68k sends a SIGSEGV for a buserror which seems to be wrong.
- * This is certainly wrong. Actually, all hardware errors (ades,adel,ibe,dbe)
- * are bus errors and therefor should send a SIGBUS! (Andy)
- */
-void do_ibe(struct pt_regs *regs)
+void do_ov(struct pt_regs *regs)
{
-while(1);
- send_sig(SIGBUS, current, 1);
+#ifdef CONF_DEBUG_EXCEPTIONS
+ show_regs(regs);
+#endif
+ if (compute_return_epc(regs))
+ return;
+ force_sig(SIGFPE, current);
}
-void do_dbe(struct pt_regs *regs)
+void do_fpe(struct pt_regs *regs, unsigned int fcr31)
{
-while(1);
- send_sig(SIGBUS, current, 1);
+#ifdef CONF_DEBUG_EXCEPTIONS
+ show_regs(regs);
+#endif
+ if (compute_return_epc(regs))
+ return;
+ force_sig(SIGFPE, current);
}
-void do_ov(struct pt_regs *regs)
+static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode)
{
-while(1);
- send_sig(SIGFPE, current, 1);
+ unsigned int *addr;
+
+ addr = (unsigned int *) (unsigned long) regs->cp0_epc;
+ if (regs->cp0_cause & CAUSEF_BD)
+ addr += 4;
+
+ if (get_user(*opcode, addr)) {
+ force_sig(SIGSEGV, current);
+ return -EFAULT;
+ }
+
+ return 0;
}
-void do_fpe(struct pt_regs *regs)
+static __inline__ void
+do_bp_and_tr(struct pt_regs *regs, char *exc, unsigned int trapcode)
{
-while(1);
- send_sig(SIGFPE, current, 1);
+ /*
+ * (A quick test says that IRIX 5.3 sends SIGTRAP for all break
+ * insns, even for break codes that indicate arithmetic failures.
+ * Wiered ...)
+ */
+ force_sig(SIGTRAP, current);
+#ifdef CONF_DEBUG_EXCEPTIONS
+ show_regs(regs);
+#endif
+ if (compute_return_epc(regs))
+ return;
}
void do_bp(struct pt_regs *regs)
{
-while(1);
- send_sig(SIGILL, current, 1);
+ unsigned int opcode, bcode;
+
+ /*
+ * There is the ancient bug in the MIPS assemblers that the break
+ * code starts left to bit 16 instead to bit 6 in the opcode.
+ * Gas is bug-compatible ...
+ */
+ if (get_insn_opcode(regs, &opcode))
+ return;
+ bcode = ((opcode >> 16) & ((1 << 20) - 1));
+
+ do_bp_and_tr(regs, "bp", bcode);
}
void do_tr(struct pt_regs *regs)
{
-while(1);
- send_sig(SIGILL, current, 1);
+ unsigned int opcode, bcode;
+
+ if (get_insn_opcode(regs, &opcode))
+ return;
+ bcode = ((opcode >> 6) & ((1 << 20) - 1));
+
+ do_bp_and_tr(regs, "tr", bcode);
}
+/*
+ * TODO: add emulation of higher ISAs' instruction. In particular
+ * interest in MUL, MAD MADU has been expressed such that R4640/R4650
+ * code can be run on other MIPS CPUs.
+ */
void do_ri(struct pt_regs *regs)
{
- int i;
-
- for(i=0; i<NR_TASKS;i++)
- if(task[i] && task[i]->pid >= 2)
- {
- printk("Process %d\n", task[i]->pid);
- dump_list_process(task[i], 0x7ffff000);
- }
+#ifdef CONF_DEBUG_EXCEPTIONS
show_regs(regs);
-while(1);
- send_sig(SIGILL, current, 1);
+#endif
+ if (compute_return_epc(regs))
+ return;
+ force_sig(SIGILL, current);
}
void do_cpu(struct pt_regs *regs)
@@ -276,53 +285,40 @@ void do_cpu(struct pt_regs *regs)
unsigned int cpid;
cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
- switch(cpid)
- {
- case 1:
+ if (cpid == 1) {
regs->cp0_status |= ST0_CU1;
- break;
- case 3:
- /*
- * This is a guess how to handle MIPS IV -
- * I don't have a manual.
- */
- if((boot_info.cputype == CPU_R8000) ||
- (boot_info.cputype == CPU_R10000))
- {
- regs->cp0_status |= ST0_CU3;
- break;
- }
- case 0:
- /*
- * CPU for cp0 can only happen in user mode
- */
- case 2:
- send_sig(SIGILL, current, 1);
- break;
+ return;
}
+
+ force_sig(SIGILL, current);
}
void do_vcei(struct pt_regs *regs)
{
/*
- * Only possible on R4[04]00[SM]C. No handler because
- * I don't have such a cpu.
+ * Only possible on R4[04]00[SM]C. No handler because I don't have
+ * such a cpu. Theory says this exception doesn't happen.
*/
- panic("Caught VCEI exception - can't handle yet\n");
+ panic("Caught VCEI exception - should not happen");
}
void do_vced(struct pt_regs *regs)
{
/*
- * Only possible on R4[04]00[SM]C. No handler because
- * I don't have such a cpu.
+ * Only possible on R4[04]00[SM]C. No handler because I don't have
+ * such a cpu. Theory says this exception doesn't happen.
*/
- panic("Caught VCED exception - can't handle yet\n");
+ panic("Caught VCE exception - should not happen");
}
void do_watch(struct pt_regs *regs)
{
- panic("Caught WATCH exception - can't handle yet\n");
+ /*
+ * We use the watch exception where available to detect stack
+ * overflows.
+ */
+ show_regs(regs);
+ panic("Caught WATCH exception - probably caused by stack overflow.");
}
void do_reserved(struct pt_regs *regs)
@@ -332,46 +328,56 @@ void do_reserved(struct pt_regs *regs)
* Most probably caused by a new unknown cpu type or
* after another deadly hard/software error.
*/
- panic("Caught reserved exception - can't handle.\n");
+ panic("Caught reserved exception - should not happen.");
}
-void trap_init(void)
+static void watch_init(unsigned long cputype)
{
- unsigned long i;
-
- if(boot_info.machtype == MACH_MIPS_MAGNUM_4000)
- EISA_bus = 1;
+ switch(cputype) {
+ case CPU_R10000:
+ case CPU_R4000MC:
+ case CPU_R4400MC:
+ case CPU_R4000SC:
+ case CPU_R4400SC:
+ case CPU_R4000PC:
+ case CPU_R4400PC:
+ case CPU_R4200:
+ /* case CPU_R4300: */
+ set_except_vector(23, handle_watch);
+ watch_available = 1;
+ break;
+ }
+}
+void trap_init(void)
+{
/*
- * Setup default vectors
+ * Only some CPUs have the watch exception.
*/
- for (i=0;i<=31;i++)
- set_except_vector(i, handle_reserved);
+ watch_init(mips_cputype);
/*
* Handling the following exceptions depends mostly of the cpu type
*/
- switch(boot_info.cputype) {
- case CPU_R4000MC:
- case CPU_R4400MC:
- case CPU_R4000SC:
- case CPU_R4400SC:
+ switch(mips_cputype) {
+ case CPU_R10000:
/*
- * Handlers not implemented yet. If should every be used
- * it's a bug in the Linux/MIPS kernel, anyway.
+ * The R10000 is in most aspects similar to the R4400. It
+ * should get some special optimizations.
*/
- set_except_vector(14, handle_vcei);
- set_except_vector(31, handle_vced);
- case CPU_R4000PC:
- case CPU_R4400PC:
- case CPU_R4200:
- /* case CPU_R4300: */
+ write_32bit_cp0_register(CP0_FRAMEMASK, 0);
+ set_cp0_status(ST0_XX, ST0_XX);
/*
- * Use watch exception to trap on access to address zero
+ * The R10k might even work for Linux/MIPS - but we're paranoid
+ * and refuse to run until this is tested on real silicon
*/
- set_except_vector(23, handle_watch);
- watch_set(KSEG0, 3);
- case CPU_R4600:
+ panic("CPU too expensive - making holiday in the ANDES!");
+ break;
+
+ case CPU_R4000MC: case CPU_R4400MC: case CPU_R4000SC:
+ case CPU_R4400SC: case CPU_R4000PC: case CPU_R4400PC:
+ case CPU_R4200: /*case CPU_R4300: case CPU_R4640: */
+ case CPU_R4600: case CPU_R4700:
set_except_vector(1, handle_mod);
set_except_vector(2, handle_tlbl);
set_except_vector(3, handle_tlbs);
@@ -392,47 +398,64 @@ void trap_init(void)
set_except_vector(12, handle_ov);
set_except_vector(13, handle_tr);
set_except_vector(15, handle_fpe);
+ break;
+ case CPU_R6000: case CPU_R6000A:
+#if 0
+ /* The R6000 is the only R-series CPU that features a machine
+ * check exception (similar to the R4000 cache error) and
+ * unaligned ldc1/sdc1 exception. The handlers have not been
+ * written yet. Well, anyway there is no R6000 machine on the
+ * current list of targets for Linux/MIPS.
+ */
+ set_except_vector(14, handle_mc);
+ set_except_vector(15, handle_ndc);
+#endif
+ case CPU_R2000: case CPU_R3000: case CPU_R3000A: case CPU_R3041:
+ case CPU_R3051: case CPU_R3052: case CPU_R3081: case CPU_R3081E:
+ /*
+ * Clear BEV, we are ready to handle exceptions using
+ * the in-RAM dispatchers. This will not be useful on all
+ * machines, but it can't hurt (the worst that can happen is
+ * that BEV is already 0).
+ */
+ set_cp0_status(ST0_BEV,0);
+
+ /*
+ * Actually don't know about these, but let's guess - PMA
+ */
+ set_except_vector(1, handle_mod);
+ set_except_vector(2, handle_tlbl);
+ set_except_vector(3, handle_tlbs);
+ set_except_vector(4, handle_adel);
+ set_except_vector(5, handle_ades);
/*
- * Compute mask for page_colour(). This is based on the
- * size of the data cache. Does the size of the icache
- * need to be accounted for?
+ * The Data Bus Error/ Instruction Bus Errors are signaled
+ * by external hardware. Therefore these two expection have
+ * board specific handlers.
*/
- i = read_32bit_cp0_register(CP0_CONFIG);
- i = (i >> 26) & 7;
- page_colour_mask = 1 << (12 + i);
+ set_except_vector(6, handle_ibe);
+ set_except_vector(7, handle_dbe);
+ ibe_board_handler = default_be_board_handler;
+ dbe_board_handler = default_be_board_handler;
+
+ set_except_vector(8, handle_sys);
+ set_except_vector(9, handle_bp);
+ set_except_vector(10, handle_ri);
+ set_except_vector(11, handle_cpu);
+ set_except_vector(12, handle_ov);
+ set_except_vector(13, handle_tr);
+ set_except_vector(15, handle_fpe);
break;
- 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:
+
+ case CPU_R8000: case CPU_R5000:
printk("Detected unsupported CPU type %s.\n",
- cpu_names[boot_info.cputype]);
- panic("Can't handle CPU\n");
+ cpu_names[mips_cputype]);
+ panic("Can't handle CPU");
break;
- /*
- * The R10000 is in most aspects similar to the R4400. It however
- * should get some special optimizations.
- */
- case CPU_R10000:
- write_32bit_cp0_register(CP0_FRAMEMASK, 0);
- panic("CPU too expensive - making holiday in the ANDES!");
- break;
case CPU_UNKNOWN:
default:
- panic("Unknown CPU type");
+ panic("Unsupported CPU type");
}
-
- /*
- * The interrupt handler depends most of the board type.
- */
- set_except_vector(0, feature->handle_int);
}
diff --git a/arch/mips/kernel/tynedma.c b/arch/mips/kernel/tynedma.c
deleted file mode 100644
index 04846cddd..000000000
--- a/arch/mips/kernel/tynedma.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Tiny Tyne DMA buffer allocator
- *
- * Copyright (C) 1995 Ralf Baechle
- */
-#include <linux/autoconf.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <asm/bootinfo.h>
-
-#ifdef CONFIG_DESKSTATION_TYNE
-
-static unsigned long allocated;
-
-/*
- * Not very sophisticated, but should suffice for now...
- */
-unsigned long deskstation_tyne_dma_alloc(size_t size)
-{
- unsigned long ret = allocated;
- allocated += size;
- if (allocated > boot_info.dma_cache_size)
- ret = -1;
- return ret;
-}
-
-void deskstation_tyne_dma_init(void)
-{
- if (boot_info.machtype != MACH_DESKSTATION_TYNE)
- return;
- allocated = 0;
- printk ("Deskstation Tyne DMA (%luk) buffer initialized.\n",
- boot_info.dma_cache_size >> 10);
-}
-
-#endif /* CONFIG_DESKSTATION_TYNE */
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
new file mode 100644
index 000000000..8bf2ad9b7
--- /dev/null
+++ b/arch/mips/kernel/unaligned.c
@@ -0,0 +1,457 @@
+/*
+ * Handle unaligned accesses by emulation.
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ *
+ * This file contains exception handler for address error exception with the
+ * special capability to execute faulting instructions in software. The
+ * handler does not try to handle the case when the program counter points
+ * to an address not aligned to a word boundary.
+ *
+ * Putting data to unaligned addresses is a bad practice even on Intel where
+ * only the performance is affected. Much worse is that such code is non-
+ * portable. Due to several programs that die on MIPS due to alignment
+ * problems I decieded to implement this handler anyway though I originally
+ * didn't intend to do this at all for user code.
+ *
+ * For now I enable fixing of address errors by default to make life easier.
+ * I however intend to disable this somewhen in the future when the alignment
+ * problems with user programs have been fixed. For programmers this is the
+ * right way to go.
+ *
+ * Fixing address errors is a per process option. The option is inherited
+ * across fork(2) and execve(2) calls. If you really want to use the
+ * option in your user programs - I discourage the use of the software
+ * emulation strongly - use the following code in your userland stuff:
+ *
+ * #include <sys/sysmips.h>
+ *
+ * ...
+ * sysmips(MIPS_FIXADE, x);
+ * ...
+ *
+ * The parameter x is 0 for disabeling software emulation. Set bit 0 for
+ * enabeling software emulation and bit 1 for enabeling printing debug
+ * messages into syslog to aid finding address errors in programs.
+ *
+ * The logging feature is an addition over RISC/os and IRIX where only the
+ * values 0 and 1 are acceptable values for x. I'll probably remove this
+ * hack later on.
+ *
+ * Below a little program to play around with this feature.
+ *
+ * #include <stdio.h>
+ * #include <asm/sysmips.h>
+ *
+ * struct foo {
+ * unsigned char bar[8];
+ * };
+ *
+ * main(int argc, char *argv[])
+ * {
+ * struct foo x = {0, 1, 2, 3, 4, 5, 6, 7};
+ * unsigned int *p = (unsigned int *) (x.bar + 3);
+ * int i;
+ *
+ * if (argc > 1)
+ * sysmips(MIPS_FIXADE, atoi(argv[1]));
+ *
+ * printf("*p = %08lx\n", *p);
+ *
+ * *p = 0xdeadface;
+ *
+ * for(i = 0; i <= 7; i++)
+ * printf("%02x ", x.bar[i]);
+ * printf("\n");
+ * }
+ *
+ * Until I've written the code to handle branch delay slots it may happen
+ * that the kernel receives an ades/adel instruction from an insn in a
+ * branch delay slot but is unable to handle this case. The kernel knows
+ * this fact and therefore will kill the process. For most code you can
+ * fix this temporarily by compiling with flags -fno-delayed-branch -Wa,-O0.
+ *
+ * Coprozessor loads are not supported; I think this case is unimportant
+ * in the practice.
+ *
+ * TODO: Handle ndc (attempted store to doubleword in uncached memory)
+ * exception for the R6000.
+ * A store crossing a page boundary might be executed only partially.
+ * Undo the partial store in this case.
+ */
+#include <linux/mm.h>
+#include <linux/signal.h>
+#include <asm/branch.h>
+#include <asm/byteorder.h>
+#include <asm/inst.h>
+#include <asm/uaccess.h>
+
+#undef CONF_NO_UNALIGNED_KERNEL_ACCESS
+#undef CONF_LOG_UNALIGNED_ACCESSES
+
+#define STR(x) __STR(x)
+#define __STR(x) #x
+
+/*
+ * User code may only access USEG; kernel code may access the
+ * entire address space.
+ */
+#define check_axs(p,a,s) \
+ if ((long)(~(pc) & ((a) | ((a)+(s)))) < 0) \
+ goto sigbus;
+
+static __inline__ void
+emulate_load_store_insn(struct pt_regs *regs, unsigned long addr, unsigned long pc)
+{
+ union mips_instruction insn;
+ __register_t value;
+
+ regs->regs[0] = 0;
+ /*
+ * This load never faults.
+ */
+ __get_user(insn.word, (unsigned int *)pc);
+
+ switch (insn.i_format.opcode) {
+ /*
+ * These are instructions that a compiler doesn't generate. We
+ * can assume therefore that the code is MIPS-aware and
+ * really buggy. Emulating these instructions would break the
+ * semantics anyway.
+ */
+ case ll_op:
+ case lld_op:
+ case sc_op:
+ case scd_op:
+
+ /*
+ * For these instructions the only way to create an address
+ * error is an attempted access to kernel/supervisor address
+ * space.
+ */
+ case ldl_op:
+ case ldr_op:
+ case lwl_op:
+ case lwr_op:
+ case sdl_op:
+ case sdr_op:
+ case swl_op:
+ case swr_op:
+ case lb_op:
+ case lbu_op:
+ case sb_op:
+ goto sigbus;
+
+ /*
+ * The remaining opcodes are the ones that are really of interrest.
+ */
+ case lh_op:
+ check_axs(pc, addr, 2);
+ __asm__(
+ ".set\tnoat\n"
+#ifdef __BIG_ENDIAN
+ "1:\tlb\t%0,0(%1)\n"
+ "2:\tlbu\t$1,1(%1)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ "1:\tlb\t%0,1(%1)\n"
+ "2:\tlbu\t$1,0(%1)\n\t"
+#endif
+ "sll\t%0,0x8\n\t"
+ "or\t%0,$1\n\t"
+ ".set\tat\n\t"
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b,%2\n\t"
+ STR(PTR)"\t2b,%2\n\t"
+ ".text"
+ :"=&r" (value)
+ :"r" (addr), "i" (&&fault)
+ :"$1");
+ regs->regs[insn.i_format.rt] = value;
+ return;
+
+ case lw_op:
+ check_axs(pc, addr, 4);
+ __asm__(
+#ifdef __BIG_ENDIAN
+ "1:\tlwl\t%0,(%1)\n"
+ "2:\tlwr\t%0,3(%1)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ "1:\tlwl\t%0,3(%1)\n"
+ "2:\tlwr\t%0,(%1)\n\t"
+#endif
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b,%2\n\t"
+ STR(PTR)"\t2b,%2\n\t"
+ ".text"
+ :"=&r" (value)
+ :"r" (addr), "i" (&&fault));
+ regs->regs[insn.i_format.rt] = value;
+ return;
+
+ case lhu_op:
+ check_axs(pc, addr, 2);
+ __asm__(
+ ".set\tnoat\n"
+#ifdef __BIG_ENDIAN
+ "1:\tlbu\t%0,0(%1)\n"
+ "2:\tlbu\t$1,1(%1)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ "1:\tlbu\t%0,1(%1)\n"
+ "2:\tlbu\t$1,0(%1)\n\t"
+#endif
+ "sll\t%0,0x8\n\t"
+ "or\t%0,$1\n\t"
+ ".set\tat\n\t"
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b,%2\n\t"
+ STR(PTR)"\t2b,%2\n\t"
+ ".text"
+ :"=&r" (value)
+ :"r" (addr), "i" (&&fault)
+ :"$1");
+ regs->regs[insn.i_format.rt] = value;
+ return;
+
+ case lwu_op:
+ check_axs(pc, addr, 4);
+ __asm__(
+#ifdef __BIG_ENDIAN
+ "1:\tlwl\t%0,(%1)\n"
+ "2:\tlwr\t%0,3(%1)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ "1:\tlwl\t%0,3(%1)\n"
+ "2:\tlwr\t%0,(%1)\n\t"
+#endif
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b,%2\n\t"
+ STR(PTR)"\t2b,%2\n\t"
+ ".text"
+ :"=&r" (value)
+ :"r" (addr), "i" (&&fault));
+ value &= 0xffffffff;
+ regs->regs[insn.i_format.rt] = value;
+ return;
+
+ case ld_op:
+ check_axs(pc, addr, 8);
+ __asm__(
+ ".set\tmips3\n"
+#ifdef __BIG_ENDIAN
+ "1:\tldl\t%0,(%1)\n"
+ "2:\tldr\t%0,7(%1)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ "1:\tldl\t%0,7(%1)\n"
+ "2:\tldr\t%0,(%1)\n\t"
+#endif
+ ".set\tmips0\n\t"
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b,%2\n\t"
+ STR(PTR)"\t2b,%2\n\t"
+ ".text"
+ :"=&r" (value)
+ :"r" (addr), "i" (&&fault));
+ regs->regs[insn.i_format.rt] = value;
+ return;
+
+ case sh_op:
+ check_axs(pc, addr, 2);
+ value = regs->regs[insn.i_format.rt];
+ __asm__(
+#ifdef __BIG_ENDIAN
+ ".set\tnoat\n"
+ "1:\tsb\t%0,1(%1)\n\t"
+ "srl\t$1,%0,0x8\n"
+ "2:\tsb\t$1,0(%1)\n\t"
+ ".set\tat\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ ".set\tnoat\n"
+ "1:\tsb\t%0,0(%1)\n\t"
+ "srl\t$1,%0,0x8\n"
+ "2:\tsb\t$1,1(%1)\n\t"
+ ".set\tat\n\t"
+#endif
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b,%2\n\t"
+ STR(PTR)"\t2b,%2\n\t"
+ ".text"
+ : /* no outputs */
+ :"r" (value), "r" (addr), "i" (&&fault)
+ :"$1");
+ return;
+
+ case sw_op:
+ check_axs(pc, addr, 4);
+ value = regs->regs[insn.i_format.rt];
+ __asm__(
+#ifdef __BIG_ENDIAN
+ "1:\tswl\t%0,(%1)\n"
+ "2:\tswr\t%0,3(%1)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ "1:\tswl\t%0,3(%1)\n"
+ "2:\tswr\t%0,(%1)\n\t"
+#endif
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b,%2\n\t"
+ STR(PTR)"\t2b,%2\n\t"
+ ".text"
+ : /* no outputs */
+ :"r" (value), "r" (addr), "i" (&&fault));
+ return;
+
+ case sd_op:
+ check_axs(pc, addr, 8);
+ value = regs->regs[insn.i_format.rt];
+ __asm__(
+ ".set\tmips3\n"
+#ifdef __BIG_ENDIAN
+ "1:\tsdl\t%0,(%1)\n"
+ "2:\tsdr\t%0,7(%1)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ "1:\tsdl\t%0,7(%1)\n"
+ "2:\tsdr\t%0,(%1)\n\t"
+#endif
+ ".set\tmips0\n\t"
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b,%2\n\t"
+ STR(PTR)"\t2b,%2\n\t"
+ ".text"
+ : /* no outputs */
+ :"r" (value), "r" (addr), "i" (&&fault));
+ return;
+
+ case lwc1_op:
+ case ldc1_op:
+ case swc1_op:
+ case sdc1_op:
+ /*
+ * I herewith declare: this does not happen. So send SIGBUS.
+ */
+ goto sigbus;
+
+ case lwc2_op:
+ case ldc2_op:
+ case swc2_op:
+ case sdc2_op:
+ /*
+ * These are the coprozessor 2 load/stores. The current
+ * implementations don't use cp2 and cp2 should always be
+ * disabled in c0_status. So send SIGILL.
+ * (No longer true: The Sony Praystation uses cp2 for
+ * 3D matrix operations. Dunno if that thingy has a MMU ...)
+ */
+ default:
+ /*
+ * Pheeee... We encountered an yet unknown instruction ...
+ */
+ force_sig(SIGILL, current);
+ }
+ return;
+
+fault:
+ send_sig(SIGSEGV, current, 1);
+ return;
+sigbus:
+ send_sig(SIGBUS, current, 1);
+ return;
+}
+
+unsigned long unaligned_instructions;
+
+static __inline__ void
+fix_ade(struct pt_regs *regs, unsigned long pc)
+{
+ /*
+ * Did we catch a fault trying to load an instruction?
+ */
+ if (regs->cp0_badvaddr == pc) {
+ /*
+ * Phee... Either the code is severly messed up or the
+ * process tried to activate some MIPS16 code.
+ */
+ force_sig(SIGBUS, current);
+ }
+
+ /*
+ * Ok, this wasn't a failed instruction load. The CPU was capable of
+ * reading the instruction and faulted after this. So we don't need
+ * to verify_area the address of the instrucion. We still don't
+ * know whether the address used was legal and therefore need to do
+ * verify_area(). The CPU already did the checking for legal
+ * instructions for us, so we don't need to do this.
+ */
+ emulate_load_store_insn(regs, regs->cp0_badvaddr, pc);
+ unaligned_instructions++;
+}
+
+#define kernel_address(x) ((long)(x) < 0)
+
+asmlinkage void
+do_ade(struct pt_regs *regs)
+{
+ __register_t pc = regs->cp0_epc;
+ __register_t badvaddr __attribute__ ((unused)) = regs->cp0_badvaddr;
+ char *adels;
+
+ adels = (((regs->cp0_cause & CAUSEF_EXCCODE) >>
+ CAUSEB_EXCCODE) == 4) ? "adel" : "ades";
+
+#ifdef CONF_NO_UNALIGNED_KERNEL_ACCESS
+ /*
+ * In an ideal world there are no unaligned accesses by the kernel.
+ * So be a bit noisy ...
+ */
+ if (kernel_address(badvaddr) && !user_mode(regs)) {
+ show_regs(regs);
+#ifdef __mips64
+ panic("Caught %s exception in kernel mode accessing %016Lx.",
+ adels, badvaddr);
+#else
+ panic("Caught %s exception in kernel mode accessing %08lx.",
+ adels, badvaddr);
+#endif
+ }
+#endif /* CONF_NO_UNALIGNED_KERNEL_ACCESS */
+
+#ifdef CONF_LOG_UNALIGNED_ACCESSES
+ if (current->tss.mflags & MF_LOGADE) {
+ __register_t logpc = pc;
+ if (regs->cp0_cause & CAUSEF_BD)
+ logpc += 4;
+#ifdef __mips64
+ printk(KERN_DEBUG
+ "Caught %s in '%s' at 0x%016Lx accessing 0x%016Lx.\n",
+ adels, current->comm, logpc, regs->cp0_badvaddr);
+#else
+ printk(KERN_DEBUG
+ "Caught %s in '%s' at 0x%08lx accessing 0x%08lx.\n",
+ adels, current->comm, logpc, regs->cp0_badvaddr);
+#endif
+ }
+#endif /* CONF_LOG_UNALIGNED_ACCESSES */
+
+ if (compute_return_epc(regs))
+ return;
+ if(current->tss.mflags & MF_FIXADE) {
+ pc += ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0);
+ fix_ade(regs, pc);
+ return;
+ }
+
+#ifdef CONF_DEBUG_EXCEPTIONS
+ show_regs(regs);
+#endif
+
+ force_sig(SIGBUS, current);
+}
diff --git a/arch/mips/kernel/vm86.c b/arch/mips/kernel/vm86.c
index 454b35fe0..53627201a 100644
--- a/arch/mips/kernel/vm86.c
+++ b/arch/mips/kernel/vm86.c
@@ -1,12 +1,13 @@
/*
- * arch/mips/vm86.c
+ * arch/mips/kernel/vm86.c
*
- * Copyright (C) 1994 Waldorf GMBH,
+ * Copyright (C) 1994, 1996 Waldorf GMBH,
* written by Ralf Baechle
*/
#include <linux/linkage.h>
#include <linux/errno.h>
-#include <linux/vm86.h>
+
+struct vm86_struct;
asmlinkage int sys_vm86(struct vm86_struct * v86)
{
diff --git a/arch/mips/ld.script b/arch/mips/ld.script
new file mode 100644
index 000000000..debe96282
--- /dev/null
+++ b/arch/mips/ld.script
@@ -0,0 +1,107 @@
+OUTPUT_FORMAT("elf32-littlemips")
+/* OUTPUT_FORMAT("a.out-mips-little-linux") */
+OUTPUT_ARCH(mips)
+ENTRY(kernel_entry)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0x80000000;
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.init : { *(.rel.init) }
+ .rela.init : { *(.rela.init) }
+ .rel.fini : { *(.rel.fini) }
+ .rela.fini : { *(.rela.fini) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) } =0
+ .text :
+ {
+ _ftext = . ;
+ *(.text)
+ *(.rodata)
+ *(.rodata1)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ } =0
+ _etext = .;
+ PROVIDE (etext = .);
+ .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 = .;
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ *(.sbss)
+ *(.scommon)
+ }
+ _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/lib/Makefile b/arch/mips/lib/Makefile
index 56279fb3e..ac3cf45ad 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -1,33 +1,25 @@
#
# Makefile for MIPS-specific library files..
#
+# Some of these routines are just left over debugging trash of ancient
+# times when I just could make my Tyne beep and so ...
+#
+# ...and for when I need to get the DECStation to use the boot prom to
+# do things... Paul M. Antoine.
+#
-.c.s:
- $(CC) $(CFLAGS) -S $<
-.s.o:
- $(AS) $(ASFLAGS) -o $*.o $<
-.c.o:
- $(CC) $(CFLAGS) -c $<
.S.s:
$(CPP) $(CFLAGS) $< -o $*.s
.S.o:
$(CC) $(CFLAGS) -c $< -o $*.o
-OBJS = dump_tlb.o tinycon.o watch.o
-
-include ../../../.config
-
-lib.a: $(OBJS)
- $(AR) rcs lib.a $(OBJS)
- sync
-
-dep:
- $(CPP) -M *.[cS] > .depend
-
-#
-# include a dependency file if one exists
-#
-ifeq (.depend,$(wildcard .depend))
-include .depend
+L_TARGET = lib.a
+L_OBJS = beep.o bitags.o checksum.o csum.o dump_tlb.o io.o memmove.o \
+ strncpy_user.o strlen_user.o watch.o
+ifdef CONFIG_MIPS_DECSTATION
+L_OBJS += pmaxcon.o pmaxio.o
+else
+L_OBJS += tinycon.o
endif
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips/lib/bcopy.c b/arch/mips/lib/bcopy.c
new file mode 100644
index 000000000..4afd557bf
--- /dev/null
+++ b/arch/mips/lib/bcopy.c
@@ -0,0 +1,20 @@
+/*
+ * arch/mips/lib/bcopy.c
+ *
+ * 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.
+ *
+ * Copyright (c) 1994, 1995, 1996 by Ralf Baechle
+ *
+ * bcopy() only exists here such that it doesn't get compiled into
+ * lib/strings.o. Though it's more efficient ...
+ */
+#include <linux/string.h>
+
+char * bcopy(const char *src, char *dest, size_t count)
+{
+ __memcpy(dest, src, count);
+
+ return dest;
+}
diff --git a/arch/mips/lib/beep.S b/arch/mips/lib/beep.S
new file mode 100644
index 000000000..e74a63c0e
--- /dev/null
+++ b/arch/mips/lib/beep.S
@@ -0,0 +1,21 @@
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+/*
+ * Just for debugging...
+ */
+ LEAF(beep)
+ lw t0,beepflag
+ bnez t0,1f
+ lbu t0,0xb4000061
+ xori t0,3
+ sb t0,0xb4000061
+ li t0,1
+ sw t0,beepflag
+1: jr ra
+ END(beep)
+
+ .bss
+beepflag: .word 0
+ .text
+
diff --git a/arch/mips/lib/bitags.c b/arch/mips/lib/bitags.c
new file mode 100644
index 000000000..4427c4195
--- /dev/null
+++ b/arch/mips/lib/bitags.c
@@ -0,0 +1,161 @@
+/*
+ * milo/bitags.c -- handles the tags passed to the kernel
+ *
+ * Copyright (C) 1995 by Stoned Elipot <Stoned.Elipot@fnet.fr>
+ * written by Stoned Elipot from an original idea of
+ * Ralf Baechle <ralf@waldorf-gmbh.de>
+ *
+ * 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
+ */
+#include <stdio.h>
+#include <asm/bootinfo.h>
+
+static unsigned int debuglevel = 0;
+
+extern unsigned long mach_mem_upper; /* from milo.c */
+extern unsigned long mach_mem_lower; /* from milo.c */
+
+static unsigned long next_tag = (unsigned long)NULL;
+
+/*
+ * Create a tag
+ *
+ * Parameters: tag - tag type to create
+ * size - tag's data size
+ * tagdata - pointer on tag's data
+ *
+ * returns : 0 - success
+ * 1 - failure
+ */
+int
+bi_TagAdd(enum bi_tag type, unsigned long size, void *data)
+{
+ tag t;
+ unsigned long addr;
+
+ t.tag = type;
+ t.size = size;
+ if (next_tag == (unsigned long)NULL) /* HuHo... first tag to create */
+ {
+ if (mach_mem_upper != (unsigned long)NULL) /* RAM detection code had run */
+ {
+ next_tag = mach_mem_upper;
+ }
+ else
+ /* RAM dectection code had not run, let's hope the
+ * tag we are creating is a memupper one, else fail
+ * ...miserably, hopelessly, lonely
+ */
+ {
+ if (type != tag_memupper)
+ {
+ return 1;
+ }
+ else
+ {
+ /*
+ * saved, it's a memupper tag: put it's value in
+ * mach_mem_upper so launch() can pass it to the kernel
+ * in a0 and well we're going to create a tag anyway...
+ */
+ next_tag = *(unsigned long*)data;
+ memcpy((void*)&mach_mem_upper, data, size);
+ }
+ }
+ }
+ addr = next_tag - (sizeof(tag));
+ if (debuglevel >=2)
+ {
+ printk("bi_TagAdd: adding tag struct at %08x, tag: %d, size: %08x\r\n", addr, t.tag, t.size);
+ }
+ memcpy((void*)addr, (void*)&t, (size_t)(sizeof(tag)));
+ if (size != 0)
+ {
+ addr = addr - size;
+ if (debuglevel >=2)
+ {
+ printk("bi_TagAdd: adding tag value at %08x\r\n", addr);
+ }
+ memcpy((void*)addr, data, (size_t)(t.size));
+ }
+ next_tag = addr;
+ return 0;
+}
+
+/*
+ * Create tags from a "null-terminated" array of tag
+ * (tag type of the tag_def struct in array must be 'dummy')
+ *
+ * Parameter: taglist - tag array pointer
+ *
+ * returns : 0 - success
+ * 1 - failure
+ */
+int
+bi_TagAddList(tag_def* taglist)
+{
+ int ret_val = 0;
+ for(; (taglist->t.tag != tag_dummy) && (!ret_val); taglist++)
+ {
+ /*
+ * we assume this tag is present in the default taglist
+ * for the machine we're running on
+ */
+ if (taglist->t.tag == tag_memlower)
+ {
+ mach_mem_lower = (unsigned long)(*((unsigned long*)taglist->d));
+/* ajouter detection de memupper pour simplifier le code de bi_TagAdd: soit mach_mem_upper
+ a ete initialise par <machine_ident>() soit est initialise par le pre;ier tag de la list
+ par default pour la machine */
+ }
+ ret_val = bi_TagAdd(taglist->t.tag, taglist->t.size, taglist->d);
+ }
+ return ret_val;
+}
+
+/*
+ * Parse the tags present in upper memory to find out
+ * a pecular one.
+ *
+ * Parameter: type - tag type to find
+ *
+ * returns : NULL - failure
+ * !NULL - pointer on the tag structure found
+ *
+ * Note: Just a 'prototype', the kernel's one is in
+ * arch/mips/kernel/setup.c
+ */
+/* tag* */
+/* bi_TagFind(enum bi_tag type) */
+/* { */
+/* tag* t; */
+/* t = (tag*)(mach_mem_upper - sizeof(tag)); */
+/* while((t->tag != tag_dummy) && (t->tag != type)) */
+/* t = (tag*)(NEXTTAGPTR(t)); */
+/* if (t->tag == tag_dummy) */
+/* { */
+/* return (tag*)NULL; */
+/* } */
+/* return t; */
+/* } */
+
+
+/*
+ * Make a listing of tags available in memory: debug helper.
+ */
+/* void */
+/* bi_TagWalk(void) */
+/* { */
+/* tag* t; */
+/* int i=0; */
+/* t = (tag*)(mach_mem_upper - sizeof(tag)); */
+/* while(t->tag != tag_dummy) */
+/* { */
+/* printk("tag #02%dm addr: %08x, type %d, size %u\n\r", i, (void*)t, t->tag, t->size); */
+/* t = (tag*)(NEXTTAGPTR(t)); */
+/* i++; */
+/* } */
+/* return; */
+/* } */
+
diff --git a/arch/mips/lib/checksum.c b/arch/mips/lib/checksum.c
new file mode 100644
index 000000000..0e04ac5e8
--- /dev/null
+++ b/arch/mips/lib/checksum.c
@@ -0,0 +1,158 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * MIPS specific IP/TCP/UDP checksumming routines
+ *
+ * Authors: Ralf Baechle, <ralf@waldorf-gmbh.de>
+ * Lots of code moved from tcp.c and ip.c; see those files
+ * for more names.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <net/checksum.h>
+#include <asm/string.h>
+
+/*
+ * computes a partial checksum, e.g. for TCP/UDP fragments
+ */
+unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum)
+{
+ unsigned long scratch1;
+ unsigned long scratch2;
+
+ /*
+ * This is for 32-bit MIPS processors.
+ */
+ __asm__("
+ .set noreorder
+ .set noat
+ andi $1,%4,2 # Check alignment
+ beqz $1,2f # Branch if ok
+ nop # delay slot
+ subu $1,%3,2 # Alignment uses up two bytes
+ bgez $1,1f # Jump if we had at least two bytes
+ move %3,$1 # delay slot
+ j 4f
+ addiu %3,2 # delay slot; len was < 2. Deal with it
+
+1: lhu %2,(%4)
+ addiu %4,2
+ addu %0,%2
+ sltu $1,%0,%2
+ addu %0,$1
+
+2: srl %1,%3,5
+ beqz %1,2f
+ sll %1,%1,5 # delay slot
+
+ addu %1,%4
+1: lw %2,0(%4)
+ addu %4,32
+ addu %0,%2
+ sltu $1,%0,%2
+
+ lw %2,-28(%4)
+ addu %0,$1
+ addu %0,%2
+ sltu $1,%0,%2
+
+ lw %2,-24(%4)
+ addu %0,$1
+ addu %0,%2
+ sltu $1,%0,%2
+
+ lw %2,-20(%4)
+ addu %0,$1
+ addu %0,%2
+ sltu $1,%0,%2
+
+ lw %2,-16(%4)
+ addu %0,$1
+ addu %0,%2
+ sltu $1,%0,%2
+
+ lw %2,-12(%4)
+ addu %0,$1
+ addu %0,%2
+ sltu $1,%0,%2
+
+ lw %2,-8(%4)
+ addu %0,$1
+ addu %0,%2
+ sltu $1,%0,%2
+
+ lw %2,-4(%4)
+ addu %0,$1
+ addu %0,%2
+ sltu $1,%0,%2
+
+ bne %4,%1,1b
+ addu %0,$1 # delay slot
+
+2: andi %1,%3,0x1c
+ beqz %1,4f
+ addu %1,%4 # delay slot
+3: lw %2,0(%4)
+ addu %4,4
+ addu %0,%2
+ sltu $1,%0,%2
+ bne %4,%1,3b
+ addu %0,$1 # delay slot
+
+4: andi $1,%3,3
+ beqz $1,7f
+ andi $1,%3,2 # delay slot
+ beqz $1,5f
+ move %2,$0 # delay slot
+ lhu %2,(%4)
+ addiu %4,2 # delay slot
+
+5: andi $1,%3,1
+ beqz $1,6f
+ nop # delay slot
+ lbu %1,(%4)
+ sll %2,16\n\t"
+#ifdef __MIPSEB__
+ "sll %1,8\n\t"
+#endif
+ "or %2,%1
+6: addu %0,%2
+ sltu $1,%0,%2
+ addu %0,$1
+7: .set at
+ .set reorder"
+ : "=r"(sum),
+ "=&r" (scratch1),
+ "=&r" (scratch2),
+ "=r" (len),
+ "=r" (buff)
+ : "0"(sum), "3"(len), "4"(buff)
+ : "$1");
+
+ return sum;
+}
+
+/*
+ * copy while checksumming, otherwise like csum_partial
+ */
+unsigned int csum_partial_copy(const char *src, char *dst,
+ int len, unsigned int sum)
+{
+ /*
+ * It's 2:30 am and I don't feel like doing it right ...
+ * This is lots slower than the real thing (tm)
+ *
+ * XXX This may nuke the kernel for unaligned src addresses!!!
+ * (Due to software address error fixing no longer true, but
+ * seems to happen very rarely only anyway.)
+ */
+ sum = csum_partial(src, len, sum);
+ memcpy(dst, src, len);
+
+ return sum;
+}
diff --git a/arch/mips/lib/csum.S b/arch/mips/lib/csum.S
new file mode 100644
index 000000000..08224e86b
--- /dev/null
+++ b/arch/mips/lib/csum.S
@@ -0,0 +1,25 @@
+#include <asm/addrspace.h>
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+/*
+ * Compute kernel code checksum to check kernel code against corruption
+ * (Ancient debugging trash ...)
+ */
+ LEAF(csum)
+ LONG_L t0,cacheflush
+ move t8,ra
+ jalr t0
+ li t0,KSEG1
+ la t1,final
+ li t2,KSEG1
+ or t0,t2
+ or t1,t2
+ move v0,zero
+1: lw t2,(t0)
+ addiu t0,4
+ bne t0,t1,1b
+ xor v0,t2
+ jr t8
+ nop
+ END(csum)
diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index f730b9fce..e7082e1ac 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -4,16 +4,20 @@
* Copyright (C) 1994, 1995 by Waldorf Electronics,
* written by Ralf Baechle.
*/
-
#include <linux/kernel.h>
+#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <asm/bootinfo.h>
-#include <asm/cachectl.h>
+#include <asm/cache.h>
+#include <asm/mipsconfig.h>
#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
-static void
+void
dump_tlb(int first, int last)
{
int i;
@@ -61,21 +65,20 @@ dump_tlb(int first, int last)
void
dump_tlb_all(void)
{
- dump_tlb(0, boot_info.tlb_entries - 1);
+ dump_tlb(0, mips_tlb_entries - 1);
}
void
-dump_tlb_nonwired(void)
+dump_tlb_wired(void)
{
- dump_tlb(read_32bit_cp0_register(CP0_WIRED), boot_info.tlb_entries - 1);
+ dump_tlb(0, read_32bit_cp0_register(CP0_WIRED));
}
-#include <linux/kernel.h>
-#include <linux/mm.h>
-
-#include <asm/mipsconfig.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
+void
+dump_tlb_nonwired(void)
+{
+ dump_tlb(read_32bit_cp0_register(CP0_WIRED), mips_tlb_entries - 1);
+}
void
dump_list_process(struct task_struct *t, void *address)
@@ -86,15 +89,15 @@ dump_list_process(struct task_struct *t, void *address)
unsigned int addr;
addr = (unsigned int) address;
- printk("Addr == %08x\n", addr);
- printk("tasks->tss.pg_dir == %08x\n",
- (unsigned int) t->tss.pg_dir);
+ printk("Addr == %08x\n", addr);
+ printk("tasks->tss.pg_dir == %08x\n", (unsigned int) t->tss.pg_dir);
+ printk("tasks->mm.pgd == %08x\n", (unsigned int) t->mm->pgd);
- page_dir = pgd_offset(t, 0);
+ page_dir = pgd_offset(t->mm, 0);
printk("page_dir == %08x\n", (unsigned int) page_dir);
- pgd = pgd_offset(t, addr);
+ pgd = pgd_offset(t->mm, addr);
printk("pgd == %08x, ", (unsigned int) pgd);
pmd = pmd_offset(pgd, addr);
@@ -105,7 +108,6 @@ dump_list_process(struct task_struct *t, void *address)
page = *pte;
printk("page == %08x\n", (unsigned int) pte_val(page));
-
}
void
@@ -125,8 +127,6 @@ dump_list_current(void *address)
printk("%08x\n", *pt);
}
-#include <asm/segment.h>
-
unsigned int
vtop(void *address)
{
@@ -135,8 +135,8 @@ vtop(void *address)
pte_t *pte;
unsigned int addr, paddr;
- addr = (unsigned int) address;
- pgd = pgd_offset(current, addr);
+ addr = (unsigned long) address;
+ pgd = pgd_offset(current->mm, addr);
pmd = pmd_offset(pgd, addr);
pte = pte_offset(pmd, addr);
paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
@@ -158,4 +158,3 @@ dump16(unsigned long *p)
(unsigned long)p, (unsigned long)*p++);
}
}
-
diff --git a/arch/mips/lib/io.c b/arch/mips/lib/io.c
new file mode 100644
index 000000000..c3c3f68d7
--- /dev/null
+++ b/arch/mips/lib/io.c
@@ -0,0 +1,24 @@
+/*
+ * include/asm-mips/string.h
+ *
+ * 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.
+ *
+ * Copyright (c) 1994, 1995, 1996 by Ralf Baechle
+ *
+ * For now io.c contains only the definition of isa_slot_offset. The
+ * real io.S doesn't assemble due to a GAS bug.
+ */
+
+/*
+ * port_base is the begin of the address space to which x86 style
+ * I/O ports are mapped.
+ */
+unsigned long port_base;
+
+/*
+ * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped
+ * for the processor.
+ */
+unsigned long isa_slot_offset;
diff --git a/arch/mips/lib/memmove.c b/arch/mips/lib/memmove.c
new file mode 100644
index 000000000..c3927ad49
--- /dev/null
+++ b/arch/mips/lib/memmove.c
@@ -0,0 +1,39 @@
+/*
+ * arch/mips/lib/memmove.c
+ *
+ * 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.
+ *
+ * Copyright (c) 1994, 1995, 1996 by Ralf Baechle
+ *
+ * Less stupid implementation of memmove.
+ */
+#include <linux/string.h>
+
+void __memmove(void *dest, const void *src, size_t n)
+{
+ if (!n)
+ return;
+
+ if (dest < src
+ || dest > src + n)
+ /* Copy forward */
+ __memcpy(dest, src, n);
+ else
+ /* Copy backwards */
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n"
+ "1:\tlbu\t$1,-1(%1)\n\t"
+ "subu\t%1,1\n\t"
+ "sb\t$1,-1(%0)\n\t"
+ "subu\t%2,1\n\t"
+ "bnez\t%2,1b\n\t"
+ "subu\t%0,1\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ : "=r" (dest), "=r" (src), "=r" (n)
+ : "0" (dest + n), "1" (src + n), "2" (n)
+ : "$1","memory" );
+}
diff --git a/arch/mips/lib/pmaxcon.c b/arch/mips/lib/pmaxcon.c
new file mode 100644
index 000000000..3b2cb1216
--- /dev/null
+++ b/arch/mips/lib/pmaxcon.c
@@ -0,0 +1,150 @@
+/* ----------------------------------------------------------------------
+ * console.c
+ *
+ * Copyright (C) 1994 by Waldorf Electronic,
+ * written by Ralf Baechle and Andreas Busse
+ * Copyright (C) 1995 Paul M. Antoine (PMAX)
+ *
+ * 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.
+ * ---------------------------------------------------------------------- */
+/*
+ * FIXME: This file is hacked to be hardwired for the Personal DECStation
+ * Only thought of as a debugging console output
+ */
+
+#include <linux/tty.h>
+#include <asm/bootinfo.h>
+
+static unsigned int size_x;
+static unsigned int size_y;
+static unsigned short cursor_x;
+static unsigned short cursor_y;
+static volatile unsigned short *vram_addr;
+static int console_needs_init = 1;
+
+extern struct bootinfo boot_info;
+extern struct screen_info screen_info;
+
+/*
+ * Here is the base address of the prom calls
+ */
+unsigned long pmax_rex_base = 0;
+
+/* ----------------------------------------------------------------------
+ * init_console()
+ * ---------------------------------------------------------------------- */
+
+void init_console(void)
+{
+ size_x = 80;
+ size_y = 50;
+ cursor_x = 0;
+ cursor_y = 0;
+
+ vram_addr = (unsigned short *)0xe10b8000;
+
+ console_needs_init = 0;
+}
+
+void
+set_size_x(unsigned int x)
+{
+ size_x = x;
+}
+
+void
+set_size_y(unsigned int y)
+{
+ size_y = y;
+}
+
+void
+set_vram(unsigned short *vram)
+{
+ vram_addr = vram;
+}
+
+/*
+ * FIXME: Temporary hack - changed its name to avoid conflict in
+ * drivers/char/vga.c that shouldn't be there <sigh> PMA
+ */
+void
+set_pmax_cursor(unsigned int x, unsigned int y)
+{
+ cursor_x = x;
+ cursor_y = y;
+}
+
+void
+print_char(unsigned int x, unsigned int y, unsigned char c)
+{
+ volatile unsigned short *caddr;
+
+/* caddr = vram_addr + (y * size_x) + x;
+ *caddr = (*caddr & 0xff00) | 0x0f00 | (unsigned short) c;
+*/
+ pmax_putch(c);
+}
+
+static void
+scroll(void)
+{
+ volatile unsigned short *caddr;
+ register int i;
+/*
+ caddr = vram_addr;
+ for(i=0; i<size_x * (size_y-1); i++)
+ *(caddr++) = *(caddr + size_x);
+
+ blank last line
+
+ caddr = vram_addr + (size_x * (size_y-1));
+ for(i=0; i<size_x; i++)
+ *(caddr++) = (*caddr & 0xff00) | (unsigned short) ' ';
+*/
+ pmax_putch('\n');
+}
+
+void print_string(const unsigned char *str)
+{
+ unsigned char c;
+
+ if (console_needs_init)
+ init_console();
+/*
+ while((c = *str++))
+ switch(c)
+ {
+ case '\n':
+ cursor_x = 0;
+ cursor_y++;
+ if(cursor_y == size_y)
+ {
+ scroll();
+ cursor_y = size_y - 1;
+ }
+ break;
+
+ default:
+ print_char(cursor_x, cursor_y, c);
+ cursor_x++;
+ if(cursor_x == size_x)
+ {
+ cursor_x = 0;
+ cursor_y++;
+ if(cursor_y == size_y)
+ {
+ scroll();
+ cursor_y = size_y - 1;
+ }
+ }
+ break;
+ }
+*/
+ pmax_printf(str);
+
+}
+
+/* end of file */
diff --git a/arch/mips/lib/pmaxio.S b/arch/mips/lib/pmaxio.S
new file mode 100644
index 000000000..97ee46a23
--- /dev/null
+++ b/arch/mips/lib/pmaxio.S
@@ -0,0 +1,78 @@
+#include <asm/regdef.h>
+#include <asm/dec/decstation.h>
+
+ .text
+ .set reorder
+/*
+ * pmax_printf - call the PROM printf() function
+ */
+ .globl pmax_printf
+pmax_printf:
+ lw v0,pmax_rex_base
+ lw v0,REX_PRINTF(v0)
+ j v0
+
+/*
+ * pmax_getchar - call the PROM getchar() function
+ */
+ .globl pmax_getch
+pmax_getch:
+ lw v0,pmax_rex_base
+ lw v0,REX_GETCHAR(v0)
+ j v0
+
+/*
+ * pmax_putchar - call the PROM putchar() function
+ */
+ .globl pmax_putch
+pmax_putch:
+ lw v0,pmax_rex_base
+ lw v0,REX_PUTCHAR(v0)
+ j v0
+
+/*
+ * pmax_callfn - call the PROM function
+ */
+ .globl pmax_callfn
+pmax_callfn:
+ lw v0,pmax_rex_base
+ addu v0,v0,a0
+ lw v0,(v0)
+ j v0
+
+/*
+ * pmax_getbitmap - call the PROM for memory bitmap function
+ */
+ .globl pmax_getbitmap
+pmax_getbitmap:
+ lw v0,pmax_rex_base
+ lw v0,REX_GETBITMAP(v0)
+ j v0
+
+/*
+ * pmax_getgetenv - call the PROM to get environment variable
+ */
+ .globl pmax_getenv
+pmax_getenv:
+ lw v0,pmax_rex_base
+ lw v0,REX_GETENV(v0)
+ j v0
+
+/*
+ * pmax_getsysid - call the PROM to get system id
+ */
+ .globl pmax_getsysid
+pmax_getsysid:
+ lw v0,pmax_rex_base
+ lw v0,REX_GETSYSID(v0)
+ j v0
+
+/*
+ * pmax_halt - call the PROM halt() function
+ */
+ .globl pmax_halt
+pmax_halt:
+ lw v0,pmax_rex_base
+ lw v0,REX_HALT(v0)
+ j v0
+
diff --git a/arch/mips/lib/strlen_user.S b/arch/mips/lib/strlen_user.S
new file mode 100644
index 000000000..3ef8ed18d
--- /dev/null
+++ b/arch/mips/lib/strlen_user.S
@@ -0,0 +1,33 @@
+/*
+ * arch/mips/lib/strlen_user.S
+ *
+ * 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.
+ *
+ * Copyright (c) 1996 by Ralf Baechle
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/sgidefs.h>
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 for error
+ */
+LEAF(__strlen_user)
+ move v0,zero
+1: lb t0,(a0)
+ LONG_ADDIU v0,1
+ LONG_ADDIU a0,1
+ bnez t0,1b
+ jr ra
+ END(strlen_user)
+
+ .section __ex_table,"a"
+ PTR 1b,fault
+ .text
+
+fault: move v0,zero
+ jr ra
diff --git a/arch/mips/lib/strncpy_user.S b/arch/mips/lib/strncpy_user.S
new file mode 100644
index 000000000..4230ffe6d
--- /dev/null
+++ b/arch/mips/lib/strncpy_user.S
@@ -0,0 +1,48 @@
+/*
+ * arch/mips/lib/strncpy_user.S
+ *
+ * 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.
+ *
+ * Copyright (c) 1996 by Ralf Baechle
+ */
+#include <linux/errno.h>
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+/*
+ * Returns: -EFAULT if exception before terminator, N if the entire
+ * buffer filled, else strlen.
+ */
+
+/*
+ * Ugly special case have to check: we might get passed a user space
+ * pointer which wraps into the kernel space ...
+ */
+
+LEAF(__strncpy_from_user)
+ move v0,zero
+ move v1,a1
+ .set noreorder
+1: lbu t0,(v1)
+ LONG_ADDIU v1,1
+ beqz t0,2f
+ sb t0,(a0) # delay slot
+ LONG_ADDIU v0,1
+ bne v0,a2,1b
+ LONG_ADDIU a0,1 # delay slot
+ .set reorder
+2: LONG_ADDU t0,a1,v0
+ xor t0,a1
+ bltz t0,fault
+ jr ra # return n
+ END(__strncpy_from_user)
+
+fault: li v0,-EFAULT
+ jr ra
+
+ .section __ex_table,"a"
+ PTR 1b,fault
+ .text
diff --git a/arch/mips/lib/tinycon.c b/arch/mips/lib/tinycon.c
index 4410986d8..4b75dec20 100644
--- a/arch/mips/lib/tinycon.c
+++ b/arch/mips/lib/tinycon.c
@@ -1,5 +1,5 @@
-/* ----------------------------------------------------------------------
- * console.c
+/*
+ * arch/mips/lib/console.c
*
* Copyright (C) 1994 by Waldorf Electronic,
* written by Ralf Baechle and Andreas Busse
@@ -7,10 +7,11 @@
* 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.
- * ---------------------------------------------------------------------- */
-/*
+ *
* FIXME: This file is hacked to be hardwired for the Deskstation
- * Only thought as a debugging console output
+ * Only thought as a debugging console output. It's as inefficient
+ * as a piece of code can be but probably a good piece of code to
+ * implement a preliminary console for a new target.
*/
#include <linux/tty.h>
@@ -23,7 +24,6 @@ static unsigned short cursor_y;
static volatile unsigned short *vram_addr;
static int console_needs_init = 1;
-extern struct bootinfo boot_info;
extern struct screen_info screen_info;
/* ----------------------------------------------------------------------
@@ -33,11 +33,13 @@ extern struct screen_info screen_info;
void init_console(void)
{
size_x = 80;
- size_y = 50;
+ // size_y = 50;
+ size_y = 25;
cursor_x = 0;
cursor_y = 0;
- vram_addr = (unsigned short *)0xe10b8000;
+ // vram_addr = (unsigned short *)0xe10b8000;
+ vram_addr = (unsigned short *)0xb00b8000;
console_needs_init = 0;
}
@@ -61,7 +63,7 @@ set_vram(unsigned short *vram)
}
void
-set_cursor(unsigned int x, unsigned int y)
+set_crsr(unsigned int x, unsigned int y)
{
cursor_x = x;
cursor_y = y;
@@ -129,5 +131,3 @@ void print_string(const unsigned char *str)
break;
}
}
-
-/* end of file */
diff --git a/arch/mips/lib/watch.S b/arch/mips/lib/watch.S
index 36b54d5c0..e460de6db 100644
--- a/arch/mips/lib/watch.S
+++ b/arch/mips/lib/watch.S
@@ -1,15 +1,16 @@
/*
* Kernel debug stuff to use the Watch registers.
- * Usefull to find stack overflows etc.
+ * Usefull to find stack overflows, dangeling pointers etc.
*
* 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.
*
- * Copyright (C) 1995 Ralf Baechle
+ * Copyright (C) 1995, 1996 by Ralf Baechle
*/
#include <asm/asm.h>
#include <asm/mipsregs.h>
+#include <asm/regdef.h>
.set noreorder
/*
@@ -19,30 +20,48 @@
* bit #0 to trap on store references
* Results : none
*/
- LEAF(watch_set)
+ LEAF(__watch_set)
li t0,0x80000000
subu a0,t0
ori a0,7
xori a0,7
or a0,a1
mtc0 a0,CP0_WATCHLO
+ sw a0,watch_savelo
jr ra
mtc0 zero,CP0_WATCHHI
- END(watch_set)
+ END(__watch_set)
/*
- * The stuff below are just some kernel debugging gadgets. It will
- * go away.
+ * Parameter: none
+ * Results : none
*/
+ LEAF(__watch_clear)
+ jr ra
+ mtc0 zero,CP0_WATCHLO
+ END(__watch_clear)
/*
* Parameter: none
* Results : none
*/
- LEAF(watch_clear)
+ LEAF(__watch_reenable)
+ lw t0,watch_savelo
jr ra
- mtc0 zero,CP0_WATCHLO
- END(watch_clear)
+ mtc0 t0,CP0_WATCHLO
+ END(__watch_reenable)
+
+/*
+ * Saved value of the c0_watchlo register for watch_reenable()
+ */
+ .data
+watch_savelo: .word 0
+ .text
+
+/*
+ * The stuff below are just some kernel debugging gadgets. It is only here
+ * because it had to be somewhere and will go away.
+ */
/*
* Parameter: none
@@ -75,28 +94,28 @@
* Parameter: none
* Results : none
*/
- NESTED(print_sp, 24, sp)
- .mask 0x80000000,16
- subu sp,24
- sw ra,16(sp)
- move a1,sp
+ NESTED(print_sp, ((5*SZREG)+ALSZ)&ALMASK, sp)
+ .mask 0x80000000,4*SZREG
+ PTR_SUBU sp,((5*SZREG)+ALSZ)&ALMASK
+ REG_S ra,4*SZREG(sp)
+ move a1,sp
PRINT("$sp == %08lx\n")
- lw ra,16(sp)
- jr ra
- addiu sp,24
+ REG_L ra,4*SZREG(sp)
+ jr ra
+ PTR_ADDU sp,((5*SZREG)+ALSZ)&ALMASK
END(print_sp)
/*
* Parameter: none
* Results : none
*/
- NESTED(print_st, 24, sp)
- .mask 0x80000000,16
- subu sp,24
- sw ra,16(sp)
- mfc0 a1,CP0_STATUS
+ NESTED(print_st, ((5*SZREG)+ALSZ)&ALMASK, sp)
+ .mask 0x80000000,4*SZREG
+ PTR_SUBU sp,((5*SZREG)+ALSZ)&ALMASK
+ REG_S ra,4*SZREG(sp)
+ mfc0 a1,CP0_STATUS
PRINT("cp0_status == %08lx\n")
- lw ra,16(sp)
- jr ra
- addiu sp,24
+ REG_L ra,4*SZREG(sp)
+ jr ra
+ PTR_ADDU sp,((5*SZREG)+ALSZ)&ALMASK
END(print_st)
diff --git a/arch/mips/man/de/man2/cacheflush.2 b/arch/mips/man/de/man2/cacheflush.2
new file mode 100644
index 000000000..1085f6ecb
--- /dev/null
+++ b/arch/mips/man/de/man2/cacheflush.2
@@ -0,0 +1,77 @@
+.\" Geschrieben von Ralf Baechle (ralf@waldorf-gmbh.de),
+.\" Copyright (c) 1994, 1995 Waldorf GMBH
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that 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 manual; if not, write to the Free
+.\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+.\" USA.
+.\"
+.TH CACHEFLUSH 2 "30 Juni 95" "Linux" "Systemaufrufe"
+.SH NAME
+cacheflush \- Befehls- und Datencaches l\(:oschen und zur\(:uckschreiben
+.SH \(:UBERSICHT
+.nf
+.B #include <sys/cachectl.h>
+.sp
+.BI "int cacheflush(char *" addr ", int "nbytes ", int "cache ");"
+.fi
+.SH BESCHREIBUNG
+.I Cacheflush
+schreibt den als Argument angegebenen Benutzeradressbereich addr bis
+(addr+nbytes-1) aus den Caches in den Speicher zur\(:uck und invalidiert
+die betroffenen Cachelines anschlie\(ssend. Cache ist eine der
+folgenden Konstanten:
+.TP
+.B ICACHE
+Befehlscache invalidieren.
+.TP
+.B DCACHE
+Den Datencache zur\(:uck in den Speicher schreiben und die betroffenen
+Cachelines invalidieren.
+.TP
+.B BCACHE
+Identisch mit
+(\fIICACHE\fP|\fIDCACHE\fP).
+.PP
+.SH "R\(:UCKGABEWERT"
+.B cacheflush
+gibt 0 bei Erfolg oder -1 im Fehlerfall zur\(:uck. Beim Auftreten
+von Fehlern, enth\(:alt
+.I errno
+die Fehlernummer.
+.SH FEHLER
+.TP
+.B EINVAL
+Der cache Parameter ist nicht
+.IR ICACHE ,
+.IR DCACHE ,
+oder
+.IR BCACHE .
+.TP
+.B EFAULT
+Der Adressbereich addr bis (addr+nbytes-1) ist ganz oder teilweise nicht
+adressierbar.
+.PP
+.SH FEHLER
+Die aktuelle Implementation ignoriert die addr und nbytes Parameter. Statt
+dessen wird immer der gesamte Cache geflusht.
+.SH BEMERKUNGEN
+Dieser Systemaufruf ist nur auf MIPS-basierten Systemen verf\(:ugbar.
+
+.SH "SIEHE"
+\fBcachectl\fP(2).
diff --git a/arch/mips/man/de/man2/syscall.2 b/arch/mips/man/de/man2/syscall.2
new file mode 100644
index 000000000..2d2345f9c
--- /dev/null
+++ b/arch/mips/man/de/man2/syscall.2
@@ -0,0 +1,60 @@
+.\" Copyright (c) 1995 by Ralf Baechle (ralf@waldorf-gmbh.de)
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that 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 manual; if not, write to the Free
+.\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+.\" USA.
+.\"
+.TH SYSCALL 2 "28 November 95" "Linux" "Systemaufrufe"
+.SH NAME
+syscall \- Indirekter Systemaufruf
+.SH SYNOPSIS
+.nf
+.B #include <sys/syscall.h>
+.sp
+.BI "int syscall(unsigned int " syscallnr ", ...);"
+.fi
+.SH DESCRIPTION
+.B syscall
+ruft den durch
+.B syscallnr
+bezeichneten Systemaufruf indirekt auf. Die weiteren optionalen
+Parameter werden an den indirekt aufgerufenen Systemaufruf uebergeben.
+.B syscallnr
+darf nicht SYS_syscall sein.
+.PP
+.SH "R\(:UCKGABEWERT"
+.B syscall
+gibt den R\(:uckgabewert des indirekt aufgerufenen Systemaufrufs zurueck, als
+ob dieser direkt aufgerufen worden w\(:are. Beim Auftreten von Fehlern,
+werden diese durch errno angezeigt.
+.SH FEHLER
+.TP
+.B ENOSYS
+syscallnr ist au\(sserhalb des erlaubten Wertebereiches oder der durch
+syscallnr bezeichnete Systemaufruf wird durch das System nicht unterst\(:utzt.
+.PP
+Wegen weiterer m\(:oglicher Werte von errno siehe auch die Dokumentation des
+Systemaufrufs syscallnr.
+.SH BUGS
+Syscall(2) ist ungetestet.
+.SH NOTE
+Dieser Systemaufruf ist nur auf MIPS basierten Systemen verf\(:ugbar. Die
+anderen Linuxsysteme implementieren syscall(2) als Funktion in libc.
+.SH "SIEHE AUCH"
+Dokumentation des Systemaufrufs syscallnr.
diff --git a/arch/mips/man/man2/cacheflush.2 b/arch/mips/man/man2/cacheflush.2
new file mode 100644
index 000000000..3d6778d92
--- /dev/null
+++ b/arch/mips/man/man2/cacheflush.2
@@ -0,0 +1,67 @@
+.\" Written by Ralf Baechle (ralf@waldorf-gmbh.de),
+.\" Copyright (c) 1994, 1995 Waldorf GMBH
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that 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 manual; if not, write to the Free
+.\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+.\" USA.
+.\"
+.TH CACHEFLUSH 2 "27 June 95" "Linux" "System calls"
+.SH NAME
+cacheflush \- flush contents of instruction and/or data cache
+.SH SYNOPSIS
+.nf
+.B #include <sys/cachectl.h>
+.sp
+.BI "int cacheflush(char *" addr ", int "nbytes ", int "cache ");"
+.fi
+.SH DESCRIPTION
+.B cacheflush
+flushes contents of indicated cache(s) for user addresses in the range
+addr to (addr+nbytes-1). Cache may be one of:
+.TP
+.B ICACHE
+Flush the instruction cache.
+.TP
+.B DCACHE
+Write back to memory and invalidate the affected valid cachelines.
+.TP
+.B BCACHE
+Same as
+.B (ICACHE|DCACHE).
+.PP
+.SH "RETURN VALUE"
+.B cacheflush
+returns 0 on success or -1 on error. If errors are detected,
+errno will indicate the error.
+.SH ERRORS
+.TP
+.B EINVAL
+cache parameter is not one of ICACHE, DCACHE, or BCACHE.
+.TP
+.B EFAULT
+Some or all of the address range addr to (addr+nbytes-1) is not accessible.
+.PP
+.SH BUGS
+The current implementation ignores the addr and nbytes parameters. Therefore
+always the whole cache is flushed.
+.SH NOTE
+This system call is only available on MIPS based systems.
+
+.SH "SEE ALSO"
+.BR cachectl "(2)"
diff --git a/arch/mips/man/man2/syscall.2 b/arch/mips/man/man2/syscall.2
new file mode 100644
index 000000000..86d7837db
--- /dev/null
+++ b/arch/mips/man/man2/syscall.2
@@ -0,0 +1,61 @@
+.\" Copyright (c) 1995 by Ralf Baechle (ralf@waldorf-gmbh.de)
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that 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 manual; if not, write to the Free
+.\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+.\" USA.
+.\"
+.TH SYSCALL 2 "28 November 95" "Linux" "System calls"
+.SH NAME
+syscall \- indirect syscall
+.SH SYNOPSIS
+.nf
+.B #include <sys/syscall.h>
+.sp
+.BI "int syscall(unsigned int " syscallnr ", ...);"
+.fi
+.SH DESCRIPTION
+.B syscall
+does an indirect syscall. The parameter
+.B syscallnr
+is the number of the syscall. The other optional parameters are the
+ones of the attempted syscall.
+.B syscallnr
+may no be SYS_syscall.
+.PP
+.SH "RETURN VALUE"
+.B syscall
+returns a return value as if the syscall indicated by
+.B syscall
+would have been called directly. If errors are detected, errno will indicate
+the error.
+.SH ERRORS
+.TP
+.B ENOSYS
+syscallnr has no legal value or the syscall indicated by syscallnr is not
+supported by the system.
+.PP
+For other values of errno see the documentation of the syscall indicated by
+syscallnr.
+.SH BUGS
+Syscall(2) hasn't yet been tested.
+.SH NOTE
+This system call is only available on MIPS based systems. The other Linux
+systems implement syscall(2) as library function in libc.
+.SH "SEE ALSO"
+Manpage of the syscall indicated by syscallnr.
diff --git a/arch/mips/man/man8/hardware.8 b/arch/mips/man/man8/hardware.8
new file mode 100644
index 000000000..b19e2d4e0
--- /dev/null
+++ b/arch/mips/man/man8/hardware.8
@@ -0,0 +1,97 @@
+.\" Copyright 1996 by Ralf Baechle (ralf@uni-koblenz.de)
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that 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 manual; if not, write to the Free
+.\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+.\" USA.
+.\"
+.TH HARDWARE 8 "29 May 96" "Linux" "Supported hardware"
+
+.SH ABSTRACT
+This file contains information about the status of hardware support
+of the various ports of Linux/MIPS.
+
+.TP
+.B "Acer PICA 61"
+ Supported; the onboard S3 graphics is fully supported in the
+ text mode as well as the parallel port and the floppy (buggy). There
+ are no drivers available yet for the onboard Ethernet interface and
+ SCSI controller. However 35c03 Ethernet cards are working in PIO mode
+ after disabeling the shared memory detection code, IDE harddisk and
+ CD ROM have been successfully tested as well as NE2000 Ethernet cards
+ and the DPT PM2041W ISA SCSI hostadapter (drivers EATA-DMA and
+ EATA-PIO). In general all drivers that do PIO via ports are supposed
+ to work.
+.TP
+.B "Mips Magnum 4000"
+ Same status as Acer PICA 61; additionally the serial interface is
+ supported. The current console driver for the standard G364 video
+ is however just a quick hack of \"better than nothing\" quality,
+ very unreliable and causes many crashes. It's as well very slow.
+ A replacement driver is in development.
+.TP
+.B "Olivetti M700"
+ Same status like Mips Magnum but the serial interface isn't
+ supported yet due to a smell, not yet know hardware difference
+ (different crystal clock for the serial interface) to the Magnum.
+.TP
+.B "Mips Magnum 3000"
+ This port hasn't been started yet but demand is relativly high.
+ So chances for this are still good.
+
+.TP
+.B "SNI RM 200"
+ Current status is that the ARC bootloader Milo is now also working
+ on the unusually bahaving SNI ARC BIOS 4.05 (which is supposed to
+ be the current version as of this writing); the kernel itself
+ supports the builtin VGA card and floppy controller. It boots via
+ an ISA NE2000 card from NFS; ISA DPT hostadapters have also
+ successfully been tested. Other SNI hardware isn't supported yet.
+
+.TP
+.B "Deskstation Tyne"
+ This R4600 based machine was the original targets for
+.IR "Linux/MIPS" ;
+ the port has stalled due to a defective motherboard. The code
+ hasn't been tested for over a year; if it's working at all only
+ console and PIO via ports based drivers are working.
+
+.TP
+.B "Deskstation rPC44"
+ (Warner could you please write something apropriate here?)
+
+.TP
+.B "SGI"
+ There is currently no port to SGI hardware; a port is about to
+ start. Due to the resources SGI is willing to invest in this
+ project this port will probably advance rather fast and help to
+ improve Linux/MIPS in general so stay tuned. According to SGI
+ also support of SMP machines is planned.
+
+.TP
+.B "DECstation"
+ This port is currently experimental; it involves not only the
+ port to a new, not PC-like hardware but also to the R3000
+ CPU.
+ Current status is that the kernel initializes and reaches the
+ BogoMIPS (TM) performance test where it locks up.
+.SH NOTES
+ I urge all the developers to send me updates to this file as soon
+ new configurations have been tested.
+.SH BUGS
+ Like every documentation this file is determined to be outdated.
diff --git a/arch/mips/mips1/Makefile b/arch/mips/mips1/Makefile
new file mode 100644
index 000000000..3e9f13037
--- /dev/null
+++ b/arch/mips/mips1/Makefile
@@ -0,0 +1,28 @@
+#
+# Makefile for the MIPS I specific parts of the Linux/MIPS kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+all: mips.o
+EXTRA_ASFLAGS = -mips1 -mcpu=r3000
+O_TARGET := mips.o
+O_OBJS := cache.o cpu.o memcpy.o memset.o r3000.o pagetables.o showregs.o
+ fp-context.o
+
+r3000.o: r3000.S
+
+fp-context.o: fp-context.S
+
+cache.o: cache.S
+
+clean:
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips/mips1/cache.S b/arch/mips/mips1/cache.S
new file mode 100644
index 000000000..788a567e8
--- /dev/null
+++ b/arch/mips/mips1/cache.S
@@ -0,0 +1,162 @@
+# R3000 cache routines lifted from IDT documentation
+# by Ruud Riem-Viis. Adapted for linux by Didier Frick
+# (dfrick@dial.eunet.ch)
+
+#include <asm/addrspace.h>
+#include <asm/asm.h>
+#include <asm/processor.h>
+#include <asm/regdef.h>
+#include <asm/cache.h>
+#include <asm/mipsregs.h>
+#include <asm/mipsconfig.h>
+#include <asm/stackframe.h>
+#include <asm/bootinfo.h>
+
+#define MINCACHE 0x00200 /* minimum cache size 512 */
+#define MAXCACHE 0x04000 /* maximum cache size 16K */
+
+/*
+ * Figure out the size of the I- and D-caches, using the diagnostic isolate
+ * swap features. The cache size is left in an environment variable because
+ * the system will want to know it later.
+ * Flush the cache so that it is in a known state.
+ */
+NESTED(cache_init,8,ra)
+ subu sp, sp, 24 # keep sp aligned on 8 words
+ sw ra, 20(sp) # push return address on stack
+ sw s0, 16(sp) # save s0 on stack
+ mfc0 s0, CP0_STATUS # save sr
+ mtc0 zero, CP0_STATUS
+ nop
+ .set reorder
+ jal cache_size
+ sw v0, mips_dcache_size
+ li v0, ST0_CE # swap caches
+ .set noreorder
+ mtc0 v0, CP0_STATUS
+ nop
+ jal cache_size
+ nop
+ sw v0, mips_icache_size
+ mtc0 zero, CP0_STATUS # swap back caches
+ nop
+ mtc0 s0, CP0_STATUS # restore sr
+ nop
+ .set reorder
+ jal cache_flush
+ lw s0, 16(sp) # restore s0
+ lw ra, 20(sp)
+ addu sp, sp, 24
+ j ra
+ nop
+END(cache_init)
+
+LEAF(cache_size)
+ .set noreorder
+ mfc0 t0, CP0_STATUS # save current SR
+ nop
+ and t0, ~ST0_SR # do not clear parity error bit
+ or v0, t0, ST0_DE # isolate cache
+ mtc0 v0, CP0_STATUS
+ nop
+
+ move v0, zero
+ li v1, 0xa5a5a5a5
+ nop
+ sw v1, KSEG0 # try to write in cache
+ lw t1, KSEG0 # try to read from cache
+ nop
+ mfc0 t2, CP0_STATUS
+ nop
+ .set reorder
+ and t2, (1<<19)
+ bne t2, zero, 3f # cache miss, must be no cache
+ bne v1, t1, 3f # data not equal -> no cache
+
+/*
+ * Clear cache boundries to known state.
+ */
+ li v0, MINCACHE
+1:
+ sw zero, KSEG0(v0)
+ sll v0, 1
+ ble v0, MAXCACHE, 1b
+
+ li v0, -1
+ sw v0, KSEG0(zero) # store marker in cache
+ li v0, MINCACHE # MIN cache size
+2:
+ lw v1, KSEG0(v0) # look for marker
+ bne v1, zero, 3f # found marker
+ sll v0, 1 # cache size * 2
+ ble v0, MAXCACHE, 2b # keep looking
+ move v0, zero # must be no cache
+ .set noreorder
+3:
+ mtc0 t0, CP0_STATUS # restore sr
+ nop
+ j ra
+ nop
+ .set reorder
+END(cache_size)
+
+LEAF(cache_flush)
+ lw t1, mips_icache_size
+ lw t2, mips_dcache_size
+ .set noreorder
+ mfc0 t3, CP0_STATUS # save sr
+ nop
+ and t3, ~ST0_SR # do not clear PE
+ beq t1, zero, check_dcache # if no icache, check dcache
+ nop
+ li v0, ST0_DE | ST0_CE # isolate and swap
+ nop
+ mtc0 v0, CP0_STATUS
+ nop
+ li t0, KSEG0
+ .set reorder
+ or t1, t0, t1
+1:
+ sb zero, 0(t0)
+ sb zero, 4(t0)
+ sb zero, 8(t0)
+ sb zero, 12(t0)
+ sb zero, 16(t0)
+ sb zero, 20(t0)
+ sb zero, 24(t0)
+ addu t0, 32
+ sb zero, -4(t0)
+ bne t0, t1, 1b # continue until done
+
+check_dcache:
+ li v0, ST0_DE
+ nop
+ .set noreorder
+ mtc0 v0, CP0_STATUS
+ nop
+ beq t2, zero, flush_done # if no dcache, done
+ .set reorder
+ li t0, KSEG0
+ or t1, t0, t2
+1:
+ sb zero, 0(t0)
+ sb zero, 4(t0)
+ sb zero, 8(t0)
+ sb zero, 12(t0)
+ sb zero, 16(t0)
+ sb zero, 20(t0)
+ sb zero, 24(t0)
+ addu t0, 32
+ sb zero, -4(t0)
+ bne t0, t1, 1b # continue until done
+
+ .set noreorder
+flush_done:
+ mtc0 t3, CP0_STATUS # restore old sr
+ nop
+ j ra
+ nop
+ .set reorder
+END(cache_flush)
+
+
diff --git a/arch/mips/mips1/cpu.c b/arch/mips/mips1/cpu.c
new file mode 100644
index 000000000..fd41ce15b
--- /dev/null
+++ b/arch/mips/mips1/cpu.c
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 1996 Ralf Baechle
+ */
+#include <linux/sched.h>
+
+#include <asm/cache.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+
+extern asmlinkage void mips1_cacheflush(void *addr, int nbytes, unsigned int flags);
+
+void (*mips_cache_init)(void);
+
+static void
+mips1_cache_init(void)
+{
+ cacheflush = mips1_cacheflush;
+}
+
+void (*switch_to_user_mode)(struct pt_regs *regs);
+
+static void
+mips1_switch_to_user_mode(struct pt_regs *regs)
+{
+ regs->cp0_status = regs->cp0_status | ST0_KUC;
+}
+
+unsigned long (*thread_saved_pc)(struct thread_struct *t);
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+static unsigned long mips1_thread_saved_pc(struct thread_struct *t)
+{
+ return ((unsigned long *)(unsigned long)t->reg29)[13];
+}
+
+unsigned long (*get_wchan)(struct task_struct *p);
+
+static unsigned long mips1_get_wchan(struct task_struct *p)
+{
+ /*
+ * This one depends on the frame size of schedule(). Do a
+ * "disass schedule" in gdb to find the frame size. Also, the
+ * code assumes that sleep_on() follows immediately after
+ * interruptible_sleep_on() and that add_timer() follows
+ * immediately after interruptible_sleep(). Ugly, isn't it?
+ * Maybe adding a wchan field to task_struct would be better,
+ * after all...
+ */
+ unsigned long schedule_frame;
+ unsigned long pc;
+
+ pc = thread_saved_pc(&p->tss);
+ if (pc >= (unsigned long) interruptible_sleep_on && pc < (unsigned long) add_timer) {
+ schedule_frame = ((unsigned long *)(long)p->tss.reg30)[13];
+ return ((unsigned long *)schedule_frame)[11];
+ }
+ return pc;
+}
+
+void (*pgd_init)(unsigned long page);
+void (*copy_page)(unsigned long to, unsigned long from);
+asmlinkage void (*restore_fp_context)(struct sigcontext *sc);
+asmlinkage void (*save_fp_context)(struct sigcontext *sc);
+
+void
+mips1_cpu_init(void)
+{
+ extern void mips1_cache_init(void);
+ extern void mips1_pgd_init(unsigned long page);
+ extern void mips1_clear_page(unsigned long page);
+ extern void mips1_copy_page(unsigned long to, unsigned long from);
+ extern asmlinkage void mips1_restore_fp_context(struct sigcontext *sc);
+ extern asmlinkage void mips1_save_fp_context(struct sigcontext *sc);
+
+ mips_cache_init = mips1_cache_init;
+ pgd_init = mips1_pgd_init;
+ switch_to_user_mode = mips1_switch_to_user_mode;
+ thread_saved_pc = mips1_thread_saved_pc;
+ get_wchan = mips1_get_wchan;
+ clear_page = mips1_clear_page;
+ copy_page = mips1_copy_page;
+ restore_fp_context = mips1_restore_fp_context;
+ save_fp_context = mips1_save_fp_context;
+}
diff --git a/arch/mips/mips1/fp-context.S b/arch/mips/mips1/fp-context.S
new file mode 100644
index 000000000..6ff3c6be3
--- /dev/null
+++ b/arch/mips/mips1/fp-context.S
@@ -0,0 +1,159 @@
+/*
+ * Save/restore floating point context for signal handlers.
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ */
+#include <asm/asm.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/sigcontext.h>
+
+#define SWC1(r,m) \
+7: swc1 r,m; \
+ .section __ex_table,"a"; \
+ PTR 7b,bad_stack; \
+ .text
+
+#define SW(r,m) \
+7: sw r,m; \
+ .section __ex_table,"a"; \
+ PTR 7b,bad_stack; \
+ .text
+
+#define LWC1(r,m) \
+7: lwc1 r,m; \
+ .section __ex_table,"a"; \
+ PTR 7b,bad_stack; \
+ .text
+
+#define LW(r,m) \
+7: lw r,m; \
+ .section __ex_table,"a"; \
+ PTR 7b,bad_stack; \
+ .text
+
+ .set noreorder
+/*
+ * Save floating point context
+ */
+LEAF(mips1_save_fp_context)
+ mfc0 t0,CP0_STATUS
+ sll t0,t0,2
+ bgez t0,1f
+ nop # delay slot
+ cfc1 t0,fcr31
+ /*
+ * Store the 16 odd double precision registers
+ */
+ SWC1 ($f0,(SC_FPREGS+0)(a0))
+ SWC1 ($f1,(SC_FPREGS+8)(a0))
+ SWC1 ($f2,(SC_FPREGS+16)(a0))
+ SWC1 ($f3,(SC_FPREGS+24)(a0))
+ SWC1 ($f4,(SC_FPREGS+32)(a0))
+ SWC1 ($f5,(SC_FPREGS+40)(a0))
+ SWC1 ($f6,(SC_FPREGS+48)(a0))
+ SWC1 ($f7,(SC_FPREGS+56)(a0))
+ SWC1 ($f8,(SC_FPREGS+64)(a0))
+ SWC1 ($f9,(SC_FPREGS+72)(a0))
+ SWC1 ($f10,(SC_FPREGS+80)(a0))
+ SWC1 ($f11,(SC_FPREGS+88)(a0))
+ SWC1 ($f12,(SC_FPREGS+96)(a0))
+ SWC1 ($f13,(SC_FPREGS+104)(a0))
+ SWC1 ($f14,(SC_FPREGS+112)(a0))
+ SWC1 ($f15,(SC_FPREGS+120)(a0))
+ SWC1 ($f16,(SC_FPREGS+128)(a0))
+ SWC1 ($f17,(SC_FPREGS+136)(a0))
+ SWC1 ($f18,(SC_FPREGS+144)(a0))
+ SWC1 ($f19,(SC_FPREGS+152)(a0))
+ SWC1 ($f20,(SC_FPREGS+160)(a0))
+ SWC1 ($f21,(SC_FPREGS+168)(a0))
+ SWC1 ($f22,(SC_FPREGS+176)(a0))
+ SWC1 ($f23,(SC_FPREGS+184)(a0))
+ SWC1 ($f24,(SC_FPREGS+192)(a0))
+ SWC1 ($f25,(SC_FPREGS+200)(a0))
+ SWC1 ($f26,(SC_FPREGS+208)(a0))
+ SWC1 ($f27,(SC_FPREGS+216)(a0))
+ SWC1 ($f28,(SC_FPREGS+224)(a0))
+ SWC1 ($f29,(SC_FPREGS+232)(a0))
+ SWC1 ($f30,(SC_FPREGS+240)(a0))
+ SWC1 ($f31,(SC_FPREGS+248)(a0))
+ SW (t0,SC_FPC_CSR(a0))
+ cfc1 t0,$0 # implementation/version
+ jr ra
+ .set nomacro
+ SW t0,SC_FPC_EIR(a0) # delay slot
+ .set macro
+
+1: jr ra
+ .set nomacro
+ nop # delay slot
+ .set macro
+ END(mips1_save_fp_context)
+
+/*
+ * Restore fpu state:
+ * - fp gp registers
+ * - cp1 status/control register
+ *
+ * We base the decission which registers to restore from the signal stack
+ * frame on the current content of c0_status, not on the content of the
+ * stack frame which might have been changed by the user.
+ */
+LEAF(mips1_restore_fp_context)
+ mfc0 t0,CP0_STATUS
+ sll t0,t0,2
+ bgez t0,1f
+ nop # delay slot
+ bgez t0,1f
+ LW (t0,SC_FPC_CSR(a0)) # delay slot
+ /*
+ * Restore the 16 odd double precision registers only
+ * when enabled in the cp0 status register.
+ */
+ LWC1 ($f0,(SC_FPREGS+0)(a0))
+ LWC1 ($f1,(SC_FPREGS+8)(a0))
+ LWC1 ($f2,(SC_FPREGS+16)(a0))
+ LWC1 ($f3,(SC_FPREGS+24)(a0))
+ LWC1 ($f4,(SC_FPREGS+32)(a0))
+ LWC1 ($f5,(SC_FPREGS+40)(a0))
+ LWC1 ($f6,(SC_FPREGS+48)(a0))
+ LWC1 ($f7,(SC_FPREGS+56)(a0))
+ LWC1 ($f8,(SC_FPREGS+64)(a0))
+ LWC1 ($f9,(SC_FPREGS+72)(a0))
+ LWC1 ($f10,(SC_FPREGS+80)(a0))
+ LWC1 ($f11,(SC_FPREGS+88)(a0))
+ LWC1 ($f12,(SC_FPREGS+96)(a0))
+ LWC1 ($f13,(SC_FPREGS+104)(a0))
+ LWC1 ($f14,(SC_FPREGS+112)(a0))
+ LWC1 ($f15,(SC_FPREGS+120)(a0))
+ LWC1 ($f16,(SC_FPREGS+128)(a0))
+ LWC1 ($f17,(SC_FPREGS+136)(a0))
+ LWC1 ($f18,(SC_FPREGS+144)(a0))
+ LWC1 ($f19,(SC_FPREGS+152)(a0))
+ LWC1 ($f20,(SC_FPREGS+160)(a0))
+ LWC1 ($f21,(SC_FPREGS+168)(a0))
+ LWC1 ($f22,(SC_FPREGS+176)(a0))
+ LWC1 ($f23,(SC_FPREGS+184)(a0))
+ LWC1 ($f24,(SC_FPREGS+192)(a0))
+ LWC1 ($f25,(SC_FPREGS+200)(a0))
+ LWC1 ($f26,(SC_FPREGS+208)(a0))
+ LWC1 ($f27,(SC_FPREGS+216)(a0))
+ LWC1 ($f28,(SC_FPREGS+224)(a0))
+ LWC1 ($f29,(SC_FPREGS+232)(a0))
+ LWC1 ($f30,(SC_FPREGS+240)(a0))
+ LWC1 ($f31,(SC_FPREGS+248)(a0))
+ jr ra
+ .set nomacro
+ ctc1 t0,fcr31 # delay slot
+ .set macro
+
+1: jr ra
+ .set nomacro
+ nop # delay slot
+ .set macro
+ END(mips1_restore_fp_context)
diff --git a/arch/mips/mips1/memcpy.S b/arch/mips/mips1/memcpy.S
new file mode 100644
index 000000000..9685fa8df
--- /dev/null
+++ b/arch/mips/mips1/memcpy.S
@@ -0,0 +1,206 @@
+/*
+ * arch/mips/mips1/memcpy.S
+ *
+ * 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.
+ *
+ * Copyright (c) 1996 by Ralf Baechle
+ *
+ * Less stupid memcpy/user_copy implementation for 32 bit MIPS CPUs.
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+
+#define BLOCK_SIZE 16
+
+#define EX(addr,handler) \
+ .section __ex_table,"a"; \
+ PTR addr, handler; \
+ .text
+#define UEX(addr,handler) \
+ EX(addr,handler); \
+ EX(addr+4,handler)
+
+ .set noreorder
+ .set noat
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * Bad. We can't fix the alignment for both address parts.
+ * Align the source address and copy slowly ...
+ */
+not_even_the_same_alignment:
+ LONG_SUBU v1,zero,a1
+ andi v1,a1,3
+ sltu t0,v0,v1
+ MOVN(v1,v0,t0)
+ beqz v1,align4 # -> finished
+ LONG_ADDU v1,a0 # delay slot
+1: lb $1,(a1)
+ EX(1b, fault)
+ LONG_ADDIU a1,1
+2: sb $1,(a0)
+ EX(2b, fault)
+ LONG_ADDIU a0,1
+ bne a0,v1,1b
+ LONG_SUBU v0,1 # delay slot
+
+/*
+ * Ok. We've fixed the alignment of the copy src for this case.
+ * Now let's copy in the usual BLOCK_SIZE byte blocks using unaligned
+ * stores.
+ * XXX Align the destination address. This is better if the __copy_user
+ * encounters an access fault because we never have to deal with an
+ * only partially modified destination word.
+ */
+ ori v1,v0,BLOCK_SIZE-1
+ xori v1,BLOCK_SIZE-1
+ beqz v1,copy_left_over
+ nop # delay slot
+ LONG_SUBU v0,v1
+ LONG_ADDU v1,a0
+
+1: lw t0,(a1) # Can cause tlb fault
+ EX(1b, fault)
+2: lw t1,4(a1) # Can cause tlb fault
+ EX(2b, fault)
+2: lw t2,8(a1) # Can cause tlb fault
+ EX(2b, fault)
+2: lw t3,12(a1) # Can cause tlb fault
+ EX(2b, fault)
+2: usw t0,(a0) # Can cause tlb faults
+ UEX(2b, fault)
+2: usw t1,4(a0) # Can cause tlb faults
+ UEX(2b, fault_plus_4)
+2: usw t2,8(a0) # Can cause tlb faults
+ UEX(2b, fault_plus_8)
+2: usw t3,12(a0) # Can cause tlb faults
+ UEX(2b, fault_plus_12)
+ LONG_ADDIU a0,BLOCK_SIZE
+ bne a0,v1,1b
+ LONG_ADDIU a1,BLOCK_SIZE # delay slot
+9:
+ b copy_left_over # < BLOCK_SIZE bytes left
+ nop # delay slot
+
+/* ---------------------------------------------------------------------- */
+
+not_w_aligned:
+/*
+ * Ok, src or destination are not 8-byte aligned.
+ * Try to fix that. Do at least both addresses have the same alignment?
+ */
+ xor t0,a0,a1
+ andi t0,3
+ bnez t0,not_even_the_same_alignment
+ nop # delay slot
+
+/*
+ * Ok, we can fix the alignment for both operands and go back to the
+ * fast path. We have to copy at least one byte, on average 3 bytes
+ * bytewise.
+ */
+ LONG_SUBU v1,zero,a0
+ andi v1,3
+ sltu t0,v0,v1
+ MOVN(v1,v0,t0)
+ beqz v1,align4 # -> finished
+ LONG_ADDU v1,a0 # delay slot
+1: lb $1,(a1)
+ EX(1b, fault)
+ LONG_ADDIU a1,1
+2: sb $1,(a0)
+ EX(2b, fault)
+ LONG_ADDIU a0,1
+ bne a0,v1,1b
+ LONG_SUBU v0,1 # delay slot
+ b align4
+ nop # delay slot
+
+/* ---------------------------------------------------------------------- */
+
+LEAF(__copy_user)
+ or t1,a0,a1
+ andi t1,3
+ bnez t1,not_w_aligned
+ move v0,a2 # delay slot
+
+align4:
+ ori v1,v0,BLOCK_SIZE-1
+ xori v1,BLOCK_SIZE-1
+ beqz v1,copy_left_over
+ nop # delay slot
+ LONG_SUBU v0,v1
+ LONG_ADDU v1,a0
+
+1: lw t0,(a1) # Can cause tlb fault
+ EX(1b, fault)
+2: lw t1,4(a1) # Can cause tlb fault
+ EX(2b, fault)
+2: lw t2,8(a1) # Can cause tlb fault
+ EX(2b, fault)
+2: lw t3,12(a1) # Can cause tlb fault
+ EX(2b, fault)
+2: sw t0,(a0) # Can cause tlb fault
+ EX(2b, fault)
+2: sw t1,4(a0) # Can cause tlb fault
+ EX(2b, fault_plus_4)
+2: sw t2,8(a0) # Can cause tlb fault
+ EX(2b, fault_plus_8)
+2: sw t3,12(a0) # Can cause tlb fault
+ EX(2b, fault_plus_12)
+ LONG_ADDIU a0,BLOCK_SIZE
+ bne a0,v1,1b
+ LONG_ADDIU a1,BLOCK_SIZE # delay slot
+9:
+
+/*
+ * XXX Tune me ...
+ */
+copy_left_over:
+ beqz v0,3f
+ nop # delay slot
+1: lb $1,(a1)
+ EX(1b, fault)
+ LONG_ADDIU a1,1
+2: sb $1,(a0)
+ EX(2b, fault)
+ LONG_SUBU v0,1
+ bnez v0,1b
+ LONG_ADDIU a0,1
+3: jr ra
+ nop # delay slot
+
+ END(__copy_user)
+ .set at
+ .set reorder
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * Access fault. The number of not copied bytes is in v0. We have to
+ * correct the number of the not copied bytes in v0 in case of a access
+ * fault in an unrolled loop, then return.
+ */
+
+fault: jr ra
+fault_plus_4: LONG_ADDIU v0,4
+ jr ra
+fault_plus_8: LONG_ADDIU v0,8
+ jr ra
+fault_plus_12: LONG_ADDIU v0,12
+ jr ra
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * For now we use __copy_user for __memcpy, too. This is effizient (one
+ * instruction penatly) and smaller but adds unwanted error checking we don't
+ * need. This hopefully doesn't cover any bugs. The memcpy() wrapper in
+ * <asm/string.h> takes care of the return value in a way GCC can optimize.
+ */
+ .globl __memcpy
+__memcpy = __copy_user
diff --git a/arch/mips/mips1/memset.S b/arch/mips/mips1/memset.S
new file mode 100644
index 000000000..5cfb5d9a7
--- /dev/null
+++ b/arch/mips/mips1/memset.S
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ *
+ * Generic memset for all MIPS CPUs.
+ * This is time critical. Hear it crying "optimize me" ...
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+LEAF(__generic_memset_b)
+__generic_memset_dw = __generic_memset_b
+ .set noreorder
+ beqz a2,2f
+ LONG_ADDU a3,a0,a2
+ .set reorder
+ LONG_SUBU a3,1
+1: sb a1,(a0)
+ .set noreorder
+ bne a0,a3,1b
+ LONG_ADDIU a0,1
+ .set reorder
+2: jr ra
+ END(__generic_memset_b)
diff --git a/arch/mips/mips1/pagetables.c b/arch/mips/mips1/pagetables.c
new file mode 100644
index 000000000..22419d1c9
--- /dev/null
+++ b/arch/mips/mips1/pagetables.c
@@ -0,0 +1,86 @@
+/*
+ * 32 bit MIPS specific page handling.
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 Ralf Baechle
+ */
+#include <linux/mm.h>
+#include <asm/cache.h>
+#include <asm/mipsconfig.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+void (*pgd_init)(unsigned long page);
+
+/*
+ * Initialize new page directory with pointers to invalid ptes
+ */
+void mips1_pgd_init(unsigned long page)
+{
+ unsigned long dummy1, dummy2;
+
+ /*
+ * The plain and boring version for the R3000. No cache flushing
+ * stuff is needed since the R3000 has physical caches.
+ */
+ __asm__ __volatile__(
+ ".set\tnoreorder\n"
+ "1:\tsw\t%2,(%0)\n\t"
+ "sw\t%2,4(%0)\n\t"
+ "sw\t%2,8(%0)\n\t"
+ "sw\t%2,12(%0)\n\t"
+ "sw\t%2,16(%0)\n\t"
+ "sw\t%2,20(%0)\n\t"
+ "sw\t%2,24(%0)\n\t"
+ "sw\t%2,28(%0)\n\t"
+ "subu\t%1,1\n\t"
+ "bnez\t%1,1b\n\t"
+ "addiu\t%0,32\n\t"
+ ".set\treorder"
+ :"=r" (dummy1),
+ "=r" (dummy2)
+ :"r" (((unsigned long) invalid_pte_table /* - PAGE_OFFSET */ ) |
+ _PAGE_TABLE),
+ "0" (page),
+ "1" (PAGE_SIZE/(sizeof(pmd_t)*8)));
+}
+
+void (*clear_page)(unsigned long page)
+
+/*
+ * To do: cache magic ...
+ */
+void mips1_clear_page(unsigned long page)
+{
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ "addiu\t$1,%0,%2\n"
+ "1:\tsw\t$0,(%0)\n\t"
+ "sw\t$0,4(%0)\n\t"
+ "sw\t$0,8(%0)\n\t"
+ "sw\t$0,12(%0)\n\t"
+ "addiu\t%0,32\n\t"
+ "sw\t$0,-16(%0)\n\t"
+ "sw\t$0,-12(%0)\n\t"
+ "sw\t$0,-8(%0)\n\t"
+ "bne\t$1,%0,1b\n\t"
+ "sw\t$0,-4(%0)\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :"=r" (page)
+ :"0" (page),
+ "I" (PAGE_SIZE)
+ :"$1","memory");
+}
+
+void (*copy_page)(unsigned long to, unsigned long from);
+
+void mips1_copy_page(unsigned long to, unsigned long from)
+{
+ memcpy((void *) to,
+ (void *) (from + (PT_OFFSET - PAGE_OFFSET)), PAGE_SIZE);
+}
diff --git a/arch/mips/mips1/r3000.S b/arch/mips/mips1/r3000.S
new file mode 100644
index 000000000..25529d9a0
--- /dev/null
+++ b/arch/mips/mips1/r3000.S
@@ -0,0 +1,1125 @@
+/*
+ * arch/mips/kernel/r3000.S
+ *
+ * Copyright (C) 1994, 1995 Waldorf Electronics, 1996 Paul M. Antoine
+ * Written by Ralf Baechle and Andreas Busse
+ * Modified for R3000 by Paul M. Antoine
+ *
+ * Additional R3000 support by Didier Frick <dfrick@dial.eunet.ch>
+ * for ACN S.A, Copyright (C) 1996 by ACN S.A
+ *
+ * This file contains most of the R3000/R3000A specific routines, which would
+ * probably work on the R2000 (if anyone's interested!).
+ *
+ * This code is evil magic. Read appendix f (coprocessor 0 hazards) of
+ * all R3000/MIPS manuals and think about that MIPS means "Microprocessor without
+ * Interlocked Pipeline Stages" before you even think about changing this code!
+ *
+ * Then remember that some bugs here are due to my not having completely
+ * converted the R4xx0 code to R3000 and that the R4xx0 CPU's are more
+ * forgiving than the R3000/A!! All that, and the fact that I'm not up to
+ * 'guru' level on R3000 - PMA.
+ * (Paul, I replaced all occurances of TLBMAPHI with %HI(TLBMAP) -- Ralf)
+ */
+#include <linux/config.h>
+
+#include <asm/asm.h>
+#include <asm/bootinfo.h>
+#include <asm/cache.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsconfig.h>
+#include <asm/mipsregs.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+#ifdef __SMP__
+#error "Fix this for SMP!"
+#else
+#define current current_set
+#endif
+
+/*
+
+FIXME:
+ - First of all, this really screams for a light version of SAVE_ALL
+ and RESTORE_ALL, saving and restoring only the context actually
+ needed in this case. I'm afraid it's necessary to save some context
+ on the stack because on the R3000 tlb exceptions can nest in some
+ cases where they wouldn't on the R4000.
+
+ - The TLB handling code should be completely rewritten for the R3000
+ because too many things are different from the R4000.
+ For instance, the CP0_CONTEXT register has a different format
+ and cannot be reused with the current setup.
+ I really had to do a fast hack to get it to work, but no time to do
+ it cleanly for now, sorry.
+ We also introduced a tlb_softindex variable to point to the next
+ TLB entry to write. This variable is incremented everytime we add a
+ new entry to the TLB. We did this because we felt that using the
+ CP0_RANDOM register could be unsafe in some cases (like trashing
+ the TLB entry for the handler's return address in user space).
+ It's very possible that we are wrong on this one, but we had so
+ much trouble with this TLB thing that we chose the safe side.
+*/
+
+#define CONF_DEBUG_TLB
+#undef CONFIG_TLB_SHUTDOWN
+#undef TLB_LOG
+
+MODE_ALIAS = 0x00e0 # cachable
+
+ .text
+ .set mips1
+ .set noreorder
+
+ .align 5
+ NESTED(handle_tlbl, FR_SIZE, sp)
+ .set noat
+ /*
+ * Check whether this is a refill or an invalid exception
+ */
+ mfc0 k0,CP0_BADVADDR
+ nop
+ mfc0 k1,CP0_ENTRYHI
+ ori k0,0xfff # clear ASID...
+ xori k0,0xfff # in BadVAddr
+ andi k1,0xfc0 # get current ASID
+ or k0,k1 # make new entryhi
+ mfc0 k1,CP0_ENTRYHI
+ nop
+ mtc0 k0,CP0_ENTRYHI
+ nop # for pipeline
+ tlbp
+ nop # for pipeline
+ mfc0 k0,CP0_INDEX
+ nop
+ mtc0 k1,CP0_ENTRYHI # delay slot
+ bgez k0,invalid_tlbl # bad addr in c0_badvaddr
+ nop
+
+
+ mfc0 k0,CP0_BADVADDR
+ lui k1,0xe000
+ subu k0,k0,k1
+ bgez k0,1f
+ nop
+ j real_utlb
+ nop
+
+1:
+
+
+#ifdef CONF_DEBUG_TLB
+ /*
+ * OK, this is a double fault. Let's see whether this is
+ * due to an invalid entry in the page_table.
+ */
+
+ lw k0, tlbl_lock
+ nop
+ bnez k0,1f
+ li k1,1
+ la k0, tlbl_lock
+ sw k1,(k0)
+
+
+ mfc0 k0,CP0_BADVADDR
+ lui k1,58368
+ srl k0,12 # get PFN?
+ sll k0,2
+ addu k0,k1
+ lw k1,(k0)
+ nop
+ andi k1,(_PAGE_PRESENT|_PAGE_ACCESSED)
+ bnez k1,reload_pgd_entries
+ nop # delay slot
+
+1:
+ SAVE_ALL
+ REG_S sp,FR_ORIG_REG2(sp)
+
+ PRINT("Double fault caused by invalid entries in pgd:\n")
+ mfc0 a1,CP0_BADVADDR
+ nop
+ PRINT("Double fault address : %08lx\n")
+ mfc0 a1,CP0_EPC
+ nop
+ PRINT("c0_epc : %08lx\n")
+ jal show_regs
+ move a0,sp
+ jal dump_tlb_nonwired
+ nop
+ mfc0 a0,CP0_BADVADDR
+ jal dump_list_current
+ nop
+ .set noat
+ STI
+ .set at
+ PANIC("Corrupted pagedir")
+ .set noat
+
+reload_pgd_entries:
+#endif /* CONF_DEBUG_TLB */
+
+ /*
+ * Load missing pair of entries from the pgd and return.
+ */
+
+ mfc0 k0,CP0_BADVADDR
+ nop
+ lui k1,58368
+
+ srl k0,12
+ sll k0,2
+ addu k0,k1
+ lw k0,(k0)
+ nop
+ mtc0 k0,CP0_ENTRYLO0
+
+ la k0, tlb_softIndex
+ lw k1,(k0)
+ nop
+ mtc0 k1,CP0_INDEX
+ nop
+ addu k1,(1<<8)
+ andi k0,k1,(63<<8)
+ bnez k0, 1f
+ nop
+ li k1,(8<<8)
+1:
+ la k0, tlb_softIndex
+ sw k1,(k0)
+
+
+ nop
+ nop
+ nop # for pipeline
+ tlbwi
+ nop # for pipeline
+ nop
+ nop
+
+
+#ifdef CONF_DEBUG_TLB
+ la k0, tlbl_lock
+ sw zero,(k0)
+#endif
+ mfc0 k0,CP0_EPC
+ nop
+ jr k0
+ rfe
+ nop
+
+
+ /*
+ * Handle invalid exception
+ *
+ * There are two possible causes for an invalid (tlbl)
+ * exception:
+ * 1) pages with present bit set but the valid bit clear
+ * 2) nonexistant pages
+ * Case one needs fast handling, therefore don't save
+ * registers yet.
+ *
+ * k0 contains c0_index.
+ */
+invalid_tlbl:
+ SAVE_ALL
+ REG_S sp,FR_ORIG_REG2(sp)
+
+#ifdef TLB_LOG
+ PRINT ("tlbl: invalid\n");
+ nop
+#endif
+ /*
+ * Test present bit in entry
+ */
+ lw s0,FR_BADVADDR(sp)
+ nop
+ srl s0,12
+ sll s0,2
+ lui k1,58368
+ addu s0,k1
+
+ lw k1,(s0)
+ nop
+ andi k1,(_PAGE_PRESENT|_PAGE_READ)
+ xori k1,(_PAGE_PRESENT|_PAGE_READ)
+ bnez k1,nopage_tlbl
+ nop
+ /*
+ * Present and read bits are set -> set valid and accessed bits
+ */
+ lw k1,(s0) # delay slot
+ nop
+ ori k1,(_PAGE_VALID|_PAGE_ACCESSED)
+ sw k1,(s0)
+
+ mtc0 k1,CP0_ENTRYLO0
+ nop
+ tlbwi
+ nop
+ nop
+
+ j return
+ nop
+
+ /*
+ * Page doesn't exist. Lots of work which is less important
+ * for speed needs to be done, so hand it all over to the
+ * kernel memory management routines.
+ */
+nopage_tlbl:
+/* SAVE_ALL */
+ REG_S sp,FR_ORIG_REG2(sp) */
+#ifdef TLB_LOG
+ PRINT ("nopage_tlbl\n");
+ nop
+#endif
+#ifdef CONFIG_TLB_SHUTDOWN
+ mfc0 t0,CP0_INDEX
+ sll t0,4
+ la t1,KSEG1
+ or t0,t1
+ mtc0 t0,CP0_ENTRYHI
+ mtc0 zero,CP0_ENTRYLO0
+ nop
+ nop
+ tlbwi
+ nop
+ nop
+#endif
+
+ lw a2,FR_BADVADDR(sp)
+ li t1,-1 # not a sys call
+ sw t1,FR_ORIG_REG2(sp)
+ nop
+ STI
+ .set at
+ /*
+ * a0 (struct pt_regs *) regs
+ * a1 (unsigned long) 0 for read access
+ * a2 (unsigned long) faulting virtual address
+ */
+ move a0,sp
+ jal do_page_fault
+ li a1,0 # delay slot
+ j ret_from_sys_call
+ nop # delay slot
+ END(handle_tlbl)
+
+ .text
+ .align 5
+ NESTED(handle_tlbs, FR_SIZE, sp)
+ .set noat
+ /*
+ * It is impossible that is a nested reload exception.
+ * Therefore this must be a invalid exception.
+ * Two possible cases:
+ * 1) Page exists but not dirty.
+ * 2) Page doesn't exist yet. Hand over to the kernel.
+ *
+ * Test whether present bit in entry is set
+ */
+ /* used to be dmfc0 */
+
+#ifdef CONF_DEBUG_TLB
+
+ la k0,tlbs_lock
+ lw k1,(k0)
+ nop
+ beqz k1,3f
+ nop
+ .set noat
+ SAVE_ALL
+ REG_S sp,FR_ORIG_REG2(sp)
+ .set at
+ PRINT("Nested tlbs exception:\n")
+ mfc0 a1,CP0_BADVADDR
+ nop
+ PRINT("Virtual address : %08lx\n")
+ mfc0 a1,CP0_EPC
+ nop
+ PRINT("c0_epc : %08lx\n")
+ jal show_regs
+ move a0,sp
+ jal dump_tlb_nonwired
+ nop
+ mfc0 a0,CP0_BADVADDR
+ jal dump_list_current
+ nop
+ .set noat
+ STI
+ .set at
+ PANIC("Nested tlbs exception")
+
+3:
+ li k1,1
+ sw k1,(k0)
+
+#endif
+ .set noat
+ SAVE_ALL
+ REG_S sp,FR_ORIG_REG2(sp)
+ .set at
+
+ mfc0 s0,CP0_BADVADDR
+
+ lui k1,58368
+ srl s0,12
+ sll s0,2
+ addu s0,k1
+ nop
+ lw k1,(s0) # may cause nested xcpt.
+ nop
+ move k0,s0
+
+ lw k1,FR_ENTRYHI(sp)
+ nop
+ mtc0 k1,CP0_ENTRYHI
+ nop
+ nop
+ tlbp # find faulting entry
+ nop
+ lw k1,(k0)
+ nop
+ andi k1,(_PAGE_PRESENT|_PAGE_WRITE)
+ xori k1,(_PAGE_PRESENT|_PAGE_WRITE)
+ bnez k1,nopage_tlbs
+ nop
+ /*
+ * Present and writable bits set: set accessed and dirty bits.
+ */
+ lw k1,(k0) # delay slot
+ nop
+ ori k1,k1,(_PAGE_ACCESSED|_PAGE_MODIFIED| \
+ _PAGE_VALID|_PAGE_DIRTY)
+ sw k1,(k0)
+ /*
+ * Now reload the entry into the TLB
+ */
+ mtc0 k1,CP0_ENTRYLO0
+ nop
+ nop
+ nop # for pipeline
+ tlbwi
+ nop # for pipeline
+#ifdef CONF_DEBUG_TLB
+ la k0,tlbs_lock
+ li k1,0
+ sw k1,(k0)
+#endif
+ j return
+ nop
+
+ /*
+ * Page doesn't exist. Lots of work which is less important
+ * for speed needs to be done, so hand it all over to the
+ * kernel memory management routines.
+ */
+nowrite_mod:
+nopage_tlbs:
+
+#ifdef CONFIG_TLB_SHUTDOWN
+ /*
+ * Remove entry so we don't need to care later
+ */
+ mfc0 k0,CP0_INDEX
+ nop
+#ifdef CONF_DEBUG_TLB
+ bgez k0,2f
+ nop
+ /*
+ * We got a tlbs exception but found no matching entry in
+ * the tlb. This should never happen. Paranoia makes us
+ * check it, though.
+ */
+ .set noat
+/* SAVE_ALL
+ REG_S sp,FR_ORIG_REG2(sp) */
+ jal show_regs
+ move a0,sp
+ .set at
+ la a1,FR_BADVADDR(sp)
+ lw a1,(a1)
+ nop
+ PRINT("c0_badvaddr == %08lx\n")
+ nop
+ mfc0 a1,CP0_INDEX
+ nop
+ PRINT("c0_index == %08x\n")
+ nop
+ la a1,FR_ENTRYHI(sp)
+ lw a1,(a1)
+ nop
+ PRINT("c0_entryhi == %08x\n")
+ nop
+ jal dump_tlb_nonwired
+ nop
+ la a0,FR_BADVADDR(sp)
+ lw a0,(a0)
+ jal dump_list_current
+ nop
+
+ .set noat
+ STI
+ .set at
+ PANIC("Tlbs or tlbm exception with no matching entry in tlb")
+1: j 1b
+ nop
+2:
+#endif /* CONF_DEBUG_TLB */
+ lui k1,0xa000
+ sll k0,4
+ or k0,k1
+ xor k0,k1
+ or k0,k1 # make it a KSEG1 address
+ mtc0 k0,CP0_ENTRYHI
+ nop
+ mtc0 zero,CP0_ENTRYLO0
+ nop
+ nop
+ nop
+ tlbwi
+ nop
+#endif /* CONFIG_TLB_SHUTDOWN */
+
+#ifdef CONF_DEBUG_TLB
+ la k0,tlbs_lock
+ li k1,0
+ sw k1,(k0)
+#endif
+ .set noat
+/* SAVE_ALL
+ REG_S sp,FR_ORIG_REG2(sp) */
+ lw a2,FR_BADVADDR(sp)
+ li t1,-1
+ sw t1,FR_ORIG_REG2(sp) # not a sys call
+ nop
+ STI
+ .set at
+ /*
+ * a0 (struct pt_regs *) regs
+ * a1 (unsigned long) 1 for write access
+ * a2 (unsigned long) faulting virtual address
+ */
+ move a0,sp
+ jal do_page_fault
+ li a1,1 # delay slot
+ j ret_from_sys_call
+ nop # delay slot
+ END(handle_tlbs)
+
+ .align 5
+ NESTED(handle_mod, FR_SIZE, sp)
+ .set noat
+ /*
+ * Two possible cases:
+ * 1) Page is writable but not dirty -> set dirty and return
+ * 2) Page is not writable -> call C handler
+ */
+ /* used to be dmfc0 */
+
+ SAVE_ALL
+ REG_S sp,FR_ORIG_REG2(sp)
+
+ mfc0 s0,CP0_BADVADDR
+ nop
+
+ srl s0,12
+ sll s0,2
+ lui k1,58368
+ addu s0,k1
+ lw k1,(s0)
+ nop
+ move k0,s0
+ nop
+
+ lw k1,FR_ENTRYHI(sp)
+ nop
+ mtc0 k1,CP0_ENTRYHI
+ nop
+ tlbp
+ nop
+ lw k1,(k0)
+ nop
+ andi k1,_PAGE_WRITE
+ beqz k1,nowrite_mod
+ nop
+ /*
+ * Present and writable bits set: set accessed and dirty bits.
+ */
+ lw k1,(k0) # delay slot
+ nop
+ ori k1,(_PAGE_ACCESSED|_PAGE_DIRTY)
+ sw k1,(k0)
+ /*
+ * Now reload the entry into the tlb
+ */
+ lw k0,(k0)
+ nop
+ mtc0 k0,CP0_ENTRYLO0
+ nop
+ nop # for pipeline
+ nop
+ tlbwi
+ nop # for pipeline
+ j return
+ nop
+ END(handle_mod)
+ .set at
+
+ .set reorder
+ LEAF(tlbflush)
+
+ .set noreorder
+
+ mfc0 t3,CP0_STATUS # disable interrupts...
+ nop
+ ori t4,t3,1
+ xori t4,1
+ mtc0 t4,CP0_STATUS
+ lw t1,mips_tlb_entries /* mips_tlb_enbtries is set */
+ /* by bi_EarlySnarf() */
+ mfc0 t0,CP0_ENTRYHI
+ nop
+ mtc0 zero,CP0_ENTRYLO0
+ sll t1,t1,8
+ li t2,KSEG1
+ li t5,(7<<8) /* R3000 has 8 wired entries */
+1:
+ subu t1,(1<<8)
+ beq t1,t5,2f /* preserve wired entries */
+
+ sll t6,t1,4
+ addu t6,t2
+ mtc0 t6,CP0_ENTRYHI
+ nop
+ mtc0 t1,CP0_INDEX
+ nop
+ nop
+ nop
+ tlbwi
+ nop
+ b 1b
+ nop
+2:
+
+ mtc0 t0,CP0_ENTRYHI
+ nop
+ mtc0 t3,CP0_STATUS
+ nop
+ jr ra
+ nop
+ END(tlbflush)
+
+/*
+ * Flush a single entry from the TLB
+ *
+ * Parameters: a0 - unsigned long address
+ */
+ .set noreorder
+ LEAF(tlbflush_page)
+ /*
+ * Step 1: Wipe out old TLB information. Not shure if
+ * we really need that step; call it paranoia ...
+ * In order to do that we need to disable interrupts.
+ */
+ mfc0 t0,CP0_STATUS # interrupts off
+ nop
+ ori t1,t0,1
+ xori t1,1
+ mtc0 t1,CP0_STATUS
+ li t3,TLBMAP # then wait 3 cycles
+ ori t1,a0,0xfff # mask off low 12 bits
+ xori t1,0xfff
+ mfc0 t2,CP0_ENTRYHI # copy ASID into address
+ nop
+ andi t2,0xfc0 # ASID in bits 11-6
+ or t2,t1
+ mtc0 t2,CP0_ENTRYHI
+/* FIXME:
+ shouldn't we save ENTRYHI before trashing it ?
+*/
+
+ srl t4,a0,12 # wait again three cycles
+ sll t4,t4,PTRLOG
+ mtc0 zero,CP0_ENTRYLO0
+ nop
+ tlbp # now query the TLB
+ addu t3,t4 # wait another three cycles
+ ori t3,0xffff
+ xori t3,0xffff
+ mfc0 t1,CP0_INDEX
+ nop
+ blez t1,1f # No old entry?
+ nop # delay slot
+ li t5, KSEG1
+ sll t1,4
+ addu t5,t1
+ mtc0 t5,CP0_ENTRYHI
+ nop
+ nop
+ tlbwi
+ /*
+ * But there still might be a entry for the pgd ...
+ */
+1: mtc0 t3,CP0_ENTRYHI
+ nop # wait 3 cycles
+ nop
+ nop
+ tlbp # TLB lookup
+ nop
+ nop
+ mfc0 t1,CP0_INDEX # wait 3 cycles
+ nop
+ blez t1,1f # No old entry?
+ nop
+ li t5, KSEG1
+ sll t1,4
+ addu t5,t1
+ mtc0 t5,CP0_ENTRYHI
+ nop
+ nop
+ tlbwi # gotcha ...
+ nop
+ nop
+ nop
+
+1:
+ mtc0 t0,CP0_STATUS
+ nop
+ jr ra
+ nop
+
+ END(tlbflush_page)
+
+ .set noreorder
+ LEAF(tlbload)
+ /*
+ address in a0
+ pte in a1
+ */
+
+ mfc0 t1,CP0_STATUS
+ nop
+ ori t0,t1,1
+ xori t0,1
+ mtc0 t0,CP0_STATUS
+ nop
+ mfc0 t0,CP0_ENTRYHI
+ nop
+ ori a0,0xfff
+ xori a0,0xfff
+ andi t2,t0,0xfc0
+ or a0,t2
+ mtc0 a0,CP0_ENTRYHI
+ nop
+ nop
+ mtc0 a1,CP0_ENTRYLO0
+
+ la t2, tlb_softIndex
+ lw t3,(t2)
+ nop
+ mtc0 t3, CP0_INDEX
+ nop
+ addu t3,(1<<8)
+ andi t2,t3,(63<<8)
+ bnez t2, 1f
+ nop
+ li t3,(8<<8)
+1:
+ la t2, tlb_softIndex
+ sw t3,(t2)
+
+
+ nop
+ nop
+ nop
+ tlbwi
+ nop
+ nop
+ mtc0 t0,CP0_ENTRYHI
+ nop
+ mtc0 t1,CP0_STATUS
+
+ jr ra
+ nop
+
+ END(tlbload)
+
+
+
+/*
+ * Code necessary to switch tasks on an Linux/MIPS machine.
+ * FIXME: We don't need to disable interrupts anymore.
+ */
+ .align 5
+ LEAF(resume)
+ /*
+ * Current task's task_struct
+ */
+ lui t5,%hi(current)
+ lw t0,%lo(current)(t5)
+
+ /*
+ * Save status register
+ */
+ mfc0 t1,CP0_STATUS
+ addu t0,a1 # Add tss offset
+ sw t1,TOFF_CP0_STATUS(t0)
+
+/*
+ li t2,ST0_CU0
+ and t2,t1
+ beqz t2,1f
+ nop
+ sw sp,TOFF_KSP(t0)
+1:
+*/
+ /*
+ * Disable interrupts
+ */
+#ifndef __R3000__
+ ori t2,t1,0x1f
+ xori t2,0x1e
+#else
+ ori t2,t1,1
+ xori t2,1
+#endif
+ mtc0 t2,CP0_STATUS
+
+ /*
+ * Save non-scratch registers
+ * All other registers have been saved on the kernel stack
+ */
+ sw s0,TOFF_REG16(t0)
+ sw s1,TOFF_REG17(t0)
+ sw s2,TOFF_REG18(t0)
+ sw s3,TOFF_REG19(t0)
+ sw s4,TOFF_REG20(t0)
+ sw s5,TOFF_REG21(t0)
+ sw s6,TOFF_REG22(t0)
+ sw s7,TOFF_REG23(t0)
+ sw gp,TOFF_REG28(t0)
+ sw sp,TOFF_REG29(t0)
+ sw fp,TOFF_REG30(t0)
+
+ /*
+ * Save floating point state
+ */
+ sll t2,t1,2
+ bgez t2,2f
+ sw ra,TOFF_REG31(t0) # delay slot
+ sll t2,t1,5
+ bgez t2,1f
+ swc1 $f0,(TOFF_FPU+0)(t0) # delay slot
+ /*
+ * Store the 16 odd double precision registers
+ */
+ swc1 $f1,(TOFF_FPU+8)(t0)
+ swc1 $f3,(TOFF_FPU+24)(t0)
+ swc1 $f5,(TOFF_FPU+40)(t0)
+ swc1 $f7,(TOFF_FPU+56)(t0)
+ swc1 $f9,(TOFF_FPU+72)(t0)
+ swc1 $f11,(TOFF_FPU+88)(t0)
+ swc1 $f13,(TOFF_FPU+104)(t0)
+ swc1 $f15,(TOFF_FPU+120)(t0)
+ swc1 $f17,(TOFF_FPU+136)(t0)
+ swc1 $f19,(TOFF_FPU+152)(t0)
+ swc1 $f21,(TOFF_FPU+168)(t0)
+ swc1 $f23,(TOFF_FPU+184)(t0)
+ swc1 $f25,(TOFF_FPU+200)(t0)
+ swc1 $f27,(TOFF_FPU+216)(t0)
+ swc1 $f29,(TOFF_FPU+232)(t0)
+ swc1 $f31,(TOFF_FPU+248)(t0)
+
+ /*
+ * Store the 16 even double precision registers
+ */
+1: cfc1 t1,fcr31
+ swc1 $f2,(TOFF_FPU+16)(t0)
+ swc1 $f4,(TOFF_FPU+32)(t0)
+ swc1 $f6,(TOFF_FPU+48)(t0)
+ swc1 $f8,(TOFF_FPU+64)(t0)
+ swc1 $f10,(TOFF_FPU+80)(t0)
+ swc1 $f12,(TOFF_FPU+96)(t0)
+ swc1 $f14,(TOFF_FPU+112)(t0)
+ swc1 $f16,(TOFF_FPU+128)(t0)
+ swc1 $f18,(TOFF_FPU+144)(t0)
+ swc1 $f20,(TOFF_FPU+160)(t0)
+ swc1 $f22,(TOFF_FPU+176)(t0)
+ swc1 $f24,(TOFF_FPU+192)(t0)
+ swc1 $f26,(TOFF_FPU+208)(t0)
+ swc1 $f28,(TOFF_FPU+224)(t0)
+ swc1 $f30,(TOFF_FPU+240)(t0)
+ sw t1,(TOFF_FPU+256)(t0)
+
+ /*
+ * Switch current task
+ */
+2: sw a0,%lo(current)(t5)
+ addu a0,a1 # Add tss offset
+
+ /*
+ * Switch address space
+ */
+
+ /*
+ * (Choose new ASID for process)
+ * This isn't really required, but would speed up
+ * context switching.
+ */
+
+ /*
+ * Switch the root pointer
+ */
+ lw t0,TOFF_PG_DIR(a0) # get PFN
+ li t1,TLB_ROOT
+ mtc0 t1,CP0_ENTRYHI
+ nop
+ mtc0 zero,CP0_INDEX
+ ori t0,MODE_ALIAS # want cachable, dirty, valid
+ mtc0 t0,CP0_ENTRYLO0
+ nop
+ nop
+ nop
+ tlbwi # delay slot
+ nop
+
+ /*
+ * Flush tlb
+ * (probably not needed, doesn't clobber a0-a3)
+ */
+ jal tlbflush
+ nop
+
+ lw a2,TOFF_CP0_STATUS(a0)
+ nop
+
+ /*
+ * Restore fpu state:
+ * - cp0 status register bits
+ * - fp gp registers
+ * - cp1 status/control register
+ */
+ ori t1,a2,1 # pipeline magic
+ xori t1,1
+ mtc0 t1,CP0_STATUS
+ sll t0,a2,2
+ bgez t0,2f
+ sll t0,a2,5 # delay slot
+ bgez t0,1f
+ nop
+ lwc1 $f0,(TOFF_FPU+0)(a0) # delay slot
+ /*
+ * Restore the 16 odd double precision registers only
+ * when enabled in the cp0 status register.
+ */
+ lwc1 $f1,(TOFF_FPU+8)(a0)
+ lwc1 $f3,(TOFF_FPU+24)(a0)
+ lwc1 $f5,(TOFF_FPU+40)(a0)
+ lwc1 $f7,(TOFF_FPU+56)(a0)
+ lwc1 $f9,(TOFF_FPU+72)(a0)
+ lwc1 $f11,(TOFF_FPU+88)(a0)
+ lwc1 $f13,(TOFF_FPU+104)(a0)
+ lwc1 $f15,(TOFF_FPU+120)(a0)
+ lwc1 $f17,(TOFF_FPU+136)(a0)
+ lwc1 $f19,(TOFF_FPU+152)(a0)
+ lwc1 $f21,(TOFF_FPU+168)(a0)
+ lwc1 $f23,(TOFF_FPU+184)(a0)
+ lwc1 $f25,(TOFF_FPU+200)(a0)
+ lwc1 $f27,(TOFF_FPU+216)(a0)
+ lwc1 $f29,(TOFF_FPU+232)(a0)
+ lwc1 $f31,(TOFF_FPU+248)(a0)
+
+ /*
+ * Restore the 16 even double precision registers
+ * when cp1 was enabled in the cp0 status register.
+ */
+1: lw t0,(TOFF_FPU+256)(a0)
+ lwc1 $f2,(TOFF_FPU+16)(a0)
+ lwc1 $f4,(TOFF_FPU+32)(a0)
+ lwc1 $f6,(TOFF_FPU+48)(a0)
+ lwc1 $f8,(TOFF_FPU+64)(a0)
+ lwc1 $f10,(TOFF_FPU+80)(a0)
+ lwc1 $f12,(TOFF_FPU+96)(a0)
+ lwc1 $f14,(TOFF_FPU+112)(a0)
+ lwc1 $f16,(TOFF_FPU+128)(a0)
+ lwc1 $f18,(TOFF_FPU+144)(a0)
+ lwc1 $f20,(TOFF_FPU+160)(a0)
+ lwc1 $f22,(TOFF_FPU+176)(a0)
+ lwc1 $f24,(TOFF_FPU+192)(a0)
+ lwc1 $f26,(TOFF_FPU+208)(a0)
+ lwc1 $f28,(TOFF_FPU+224)(a0)
+ lwc1 $f30,(TOFF_FPU+240)(a0)
+ ctc1 t0,fcr31
+
+ /*
+ * Restore non-scratch registers
+ */
+2: lw s0,TOFF_REG16(a0)
+ lw s1,TOFF_REG17(a0)
+ lw s2,TOFF_REG18(a0)
+ lw s3,TOFF_REG19(a0)
+ lw s4,TOFF_REG20(a0)
+ lw s5,TOFF_REG21(a0)
+ lw s6,TOFF_REG22(a0)
+ lw s7,TOFF_REG23(a0)
+ lw gp,TOFF_REG28(a0)
+ lw sp,TOFF_REG29(a0)
+ lw fp,TOFF_REG30(a0)
+ lw ra,TOFF_REG31(a0)
+
+ /*
+ * Restore status register
+ */
+ lw t0,TOFF_KSP(a0)
+ nop
+ sw t0,kernelsp
+
+ mtc0 a2,CP0_STATUS # delay slot
+ jr ra
+ nop
+ END(resume)
+
+ /*
+ * Load a new root pointer into the tlb
+ */
+ .set noreorder
+ LEAF(load_pgd)
+ /*
+ * Switch the root pointer
+ */
+ mfc0 t0,CP0_STATUS
+ nop
+ ori t1,t0,1
+ xori t1,1
+ mtc0 t1,CP0_STATUS
+
+ ori a0,MODE_ALIAS
+ li t1,TLB_ROOT
+ mtc0 t1,CP0_ENTRYHI
+ nop
+ mtc0 zero,CP0_INDEX
+ nop
+ mtc0 a0,CP0_ENTRYLO0
+ nop
+ nop
+ nop
+ tlbwi
+ nop
+ nop
+ mtc0 t0,CP0_STATUS
+ nop
+ jr ra
+ nop
+ END(load_pgd)
+
+/*
+ * Some bits in the config register
+ */
+#define CONFIG_DB (1<<4)
+#define CONFIG_IB (1<<5)
+
+/*
+ * Flush instruction/data caches - FIXME: Don't know how to do this on R[236]000!
+ * (Actually most of this flushing stuff isn't needed for the R2000/R3000/R6000
+ * since these CPUs have physical indexed caches unlike R4000 and better
+ * which have virtual indexed caches.)
+ *
+ * Parameters: a0 - starting address to flush
+ * a1 - size of area to be flushed
+ * a2 - which caches to be flushed
+ *
+ * FIXME: - ignores parameters in a0/a1
+ * - doesn't know about second level caches
+
+ */
+ .set noreorder
+ LEAF(mips1_cacheflush)
+
+done: j cache_flush
+ nop
+ END(mips1_cacheflush)
+
+/*
+ * Invalidate virtual addresses. - FIXME: Don't know how on R[236]000 yet!
+ * (Flushing is relativly expensive; it isn't required at all if a
+ * particular machines' chipset keeps the external cache in a state that is
+ * consistent with memory -- Ralf)
+ *
+ * Parameters: a0 - starting address to flush
+ * a1 - size of area to be flushed
+ *
+ * FIXME: - ignores parameters in a0/a1
+ * - doesn't know about second level caches
+ */
+ .set noreorder
+ LEAF(fd_cacheflush)
+ jr ra
+ nop
+ END(fd_cacheflush)
+
+/*
+ * do_syscall calls the function in a1 with upto 7 arguments. If over
+ * four arguments are being requested, the additional arguments will
+ * be copied from the user stack pointed to by a0->reg29.
+ *
+ * a0 (struct pt_regs *) pointer to user registers
+ * a1 (syscall_t) pointer to syscall to do
+ * a2 (int) number of arguments to syscall
+ */
+ .set reorder
+ .text
+NESTED(do_syscalls, 32, sp)
+ subu sp,32
+ sw ra,28(sp)
+ sll a2,a2,PTRLOG
+ lw t1,dst(a2)
+ move t2,a1
+ lw t0,FR_REG29(a0) # get old user stack pointer
+ jalr t1
+
+7: lw t1,24(t0) # parameter #7 from usp
+ sw t1,24(sp)
+6: lw t1,20(t0) # parameter #6 from usp
+ sw t1,20(sp)
+5: lw t1,16(t0) # parameter #5 from usp
+ sw t1,16(sp)
+4: lw a3,FR_REG7(a0) # 4 args
+3: lw a2,FR_REG6(a0) # 3 args
+2: lw a1,FR_REG5(a0) # 2 args
+1: lw a0,FR_REG4(a0) # delay slot
+ jalr t2 # 1 args
+ lw ra,28(sp)
+ addiu sp,32
+ jr ra
+0: jalr t2 # 0 args, just pass a0
+ lw ra,28(sp)
+ addiu sp,32
+ jr ra
+ END(do_syscalls)
+
+ .rdata
+ .align PTRLOG
+dst: PTR 0b, 1b, 2b, 3b, 4b, 5b, 6b, 7b
+
+ .section __ex_table,"a"
+ PTR 7b,bad_stack
+ PTR 6b,bad_stack
+ PTR 5b,bad_stack
+
+ .data
+
+ EXPORT(tlbl_lock)
+ .word 0
+
+tlbs_lock:
+ .word 0
+
+ EXPORT(tlb_softIndex)
+ .word 0
diff --git a/arch/mips/mips1/showregs.c b/arch/mips/mips1/showregs.c
new file mode 100644
index 000000000..0be6db80e
--- /dev/null
+++ b/arch/mips/mips1/showregs.c
@@ -0,0 +1,32 @@
+/*
+ * linux/arch/mips/mips1/showregs.c
+ *
+ * Copyright (C) 1995, 1996 Ralf Baechle, Paul M. Antoine.
+ */
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+
+void show_regs(struct pt_regs * regs)
+{
+ /*
+ * Saved main processor registers
+ */
+ printk("$0 : %08x %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ 0, regs->regs[1], regs->regs[2], regs->regs[3],
+ regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
+ printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11],
+ regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
+ printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19],
+ regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
+ printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ regs->regs[24], regs->regs[25], regs->regs[28], regs->regs[29],
+ regs->regs[30], regs->regs[31]);
+
+ /*
+ * Saved cp0 registers
+ */
+ printk("epc : %08lx\nStatus: %08x\nCause : %08x\nBadVAdddr : %08x\n",
+ regs->cp0_epc, regs->cp0_status, regs->cp0_cause,regs->cp0_badvaddr);
+}
diff --git a/arch/mips/mips2/Makefile b/arch/mips/mips2/Makefile
new file mode 100644
index 000000000..1d53d027c
--- /dev/null
+++ b/arch/mips/mips2/Makefile
@@ -0,0 +1,21 @@
+#
+# Makefile for the MIPS II specific parts of the Linux/MIPS kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+all: mips.o
+EXTRA_ASFLAGS = -mips2 -mcpu=r6000
+O_TARGET := mips.o
+O_OBJS := cpu.o pagetables.o showregs.o
+
+clean:
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips/mips2/README b/arch/mips/mips2/README
new file mode 100644
index 000000000..c64808874
--- /dev/null
+++ b/arch/mips/mips2/README
@@ -0,0 +1,3 @@
+This directory contains the R6000 specific part. I (Ralf) tried to support
+this CPU as good as possible without a machine and without detailed
+documentation. So don't look to close on this part ...
diff --git a/arch/mips/mips2/cpu.c b/arch/mips/mips2/cpu.c
new file mode 100644
index 000000000..bcc021ee7
--- /dev/null
+++ b/arch/mips/mips2/cpu.c
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 1996 Ralf Baechle
+ */
+#include <linux/sched.h>
+
+#include <asm/cache.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+
+extern asmlinkage void mips2_cacheflush(void *addr, int nbytes, unsigned int flags);
+
+void (*mips_cache_init)(void);
+
+static void
+mips2_cache_init(void)
+{
+ cacheflush = mips2_cacheflush;
+}
+
+void (*switch_to_user_mode)(struct pt_regs *regs);
+
+static void
+mips2_switch_to_user_mode(struct pt_regs *regs)
+{
+ regs->cp0_status = regs->cp0_status | ST0_KUC;
+}
+
+unsigned long (*thread_saved_pc)(struct thread_struct *t);
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+static unsigned long mips2_thread_saved_pc(struct thread_struct *t)
+{
+ return ((unsigned long *)(unsigned long)t->reg29)[13];
+}
+
+unsigned long (*get_wchan)(struct task_struct *p);
+
+static unsigned long mips2_get_wchan(struct task_struct *p)
+{
+ /*
+ * This one depends on the frame size of schedule(). Do a
+ * "disass schedule" in gdb to find the frame size. Also, the
+ * code assumes that sleep_on() follows immediately after
+ * interruptible_sleep_on() and that add_timer() follows
+ * immediately after interruptible_sleep(). Ugly, isn't it?
+ * Maybe adding a wchan field to task_struct would be better,
+ * after all...
+ */
+ unsigned long schedule_frame;
+ unsigned long pc;
+
+ pc = thread_saved_pc(&p->tss);
+ if (pc >= (unsigned long) interruptible_sleep_on && pc < (unsigned long) add_timer) {
+ schedule_frame = ((unsigned long *)(long)p->tss.reg30)[13];
+ return ((unsigned long *)schedule_frame)[11];
+ }
+ return pc;
+}
+
+void (*pgd_init)(unsigned long page);
+void (*copy_page)(unsigned long to, unsigned long from);
+asmlinkage void (*restore_fp_context)(struct sigcontext *sc);
+asmlinkage void (*save_fp_context)(struct sigcontext *sc);
+
+void
+mips2_cpu_init(void)
+{
+ extern void mips2_cache_init(void);
+ extern void mips2_pgd_init(unsigned long page);
+ extern void mips2_clear_page(unsigned long page);
+ extern void mips2_copy_page(unsigned long to, unsigned long from);
+ extern asmlinkage void mips2_restore_fp_context(struct sigcontext *sc);
+ extern asmlinkage void mips2_save_fp_context(struct sigcontext *sc);
+
+ mips_cache_init = mips2_cache_init;
+ pgd_init = mips2_pgd_init;
+ switch_to_user_mode = mips2_switch_to_user_mode;
+ thread_saved_pc = mips2_thread_saved_pc;
+ get_wchan = mips2_get_wchan;
+ clear_page = mips2_clear_page;
+ copy_page = mips2_copy_page;
+ restore_fp_context = mips2_restore_fp_context;
+ save_fp_context = mips2_save_fp_context;
+}
diff --git a/arch/mips/mips2/fp-context.S b/arch/mips/mips2/fp-context.S
new file mode 100644
index 000000000..fc11a7fed
--- /dev/null
+++ b/arch/mips/mips2/fp-context.S
@@ -0,0 +1,124 @@
+/*
+ * Save/restore floating point context for signal handlers.
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ */
+#include <asm/asm.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/sigcontext.h>
+
+#define SDC1(r,m) \
+7: sdc1 r,m; \
+ .section __ex_table,"a"; \
+ PTR 7b,bad_stack; \
+ .text
+
+#define SW(r,m) \
+7: sw r,m; \
+ .section __ex_table,"a"; \
+ PTR 7b,bad_stack; \
+ .text
+
+#define LDC1(r,m) \
+7: ldc1 r,m; \
+ .section __ex_table,"a"; \
+ PTR 7b,bad_stack; \
+ .text
+
+#define LW(r,m) \
+7: lw r,m; \
+ .section __ex_table,"a"; \
+ PTR 7b,bad_stack; \
+ .text
+
+ .set noreorder
+/*
+ * Save floating point context
+ */
+LEAF(mips2_save_fp_context)
+ mfc0 t0,CP0_STATUS
+ sll t0,t0,2
+ bgez t0,1f
+ nop # delay slot
+ cfc1 t1,fcr31
+ /*
+ * Store the 16 double precision registers
+ */
+ SDC1 ($f0,(SC_FPREGS+0)(a0))
+ SDC1 ($f2,(SC_FPREGS+16)(a0))
+ SDC1 ($f4,(SC_FPREGS+32)(a0))
+ SDC1 ($f6,(SC_FPREGS+48)(a0))
+ SDC1 ($f8,(SC_FPREGS+64)(a0))
+ SDC1 ($f10,(SC_FPREGS+80)(a0))
+ SDC1 ($f12,(SC_FPREGS+96)(a0))
+ SDC1 ($f14,(SC_FPREGS+112)(a0))
+ SDC1 ($f16,(SC_FPREGS+128)(a0))
+ SDC1 ($f18,(SC_FPREGS+144)(a0))
+ SDC1 ($f20,(SC_FPREGS+160)(a0))
+ SDC1 ($f22,(SC_FPREGS+176)(a0))
+ SDC1 ($f24,(SC_FPREGS+192)(a0))
+ SDC1 ($f26,(SC_FPREGS+208)(a0))
+ SDC1 ($f28,(SC_FPREGS+224)(a0))
+ SDC1 ($f30,(SC_FPREGS+240)(a0))
+ SW (t0,SC_FPC_CSR(a0))
+ cfc1 t0,$0 # implementation/version
+ jr ra
+ .set nomacro
+ SW (t0,SC_FPC_EIR(a0)) # delay slot
+ .set macro
+
+1: jr ra
+ .set nomacro
+ nop # delay slot
+ .set macro
+ END(mips2_save_fp_context)
+
+/*
+ * Restore fpu state:
+ * - fp gp registers
+ * - cp1 status/control register
+ *
+ * We base the decission which registers to restore from the signal stack
+ * frame on the current content of c0_status, not on the content of the
+ * stack frame which might have been changed by the user.
+ */
+LEAF(mips2_restore_fp_context)
+ mfc0 t0,CP0_STATUS
+ sll t0,t0,2
+ bgez t0,1f
+ LW t0,SC_FPC_CSR(a0) # delay slot
+ /*
+ * Restore the 16 double precision registers
+ */
+ LDC1 ($f0,(SC_FPREGS+0)(a0))
+ LDC1 ($f2,(SC_FPREGS+16)(a0))
+ LDC1 ($f4,(SC_FPREGS+32)(a0))
+ LDC1 ($f6,(SC_FPREGS+48)(a0))
+ LDC1 ($f8,(SC_FPREGS+64)(a0))
+ LDC1 ($f10,(SC_FPREGS+80)(a0))
+ LDC1 ($f12,(SC_FPREGS+96)(a0))
+ LDC1 ($f14,(SC_FPREGS+112)(a0))
+ LDC1 ($f16,(SC_FPREGS+128)(a0))
+ LDC1 ($f18,(SC_FPREGS+144)(a0))
+ LDC1 ($f20,(SC_FPREGS+160)(a0))
+ LDC1 ($f22,(SC_FPREGS+176)(a0))
+ LDC1 ($f24,(SC_FPREGS+192)(a0))
+ LDC1 ($f26,(SC_FPREGS+208)(a0))
+ LDC1 ($f28,(SC_FPREGS+224)(a0))
+ LDC1 ($f30,(SC_FPREGS+240)(a0))
+ jr ra
+ .set nomacro
+ ctc1 t0,fcr31 # delay slot
+ .set macro
+
+1: jr ra
+ .set nomacro
+ nop # delay slot
+ .set macro
+ END(mips2_restore_fp_context)
diff --git a/arch/mips/mips2/pagetables.c b/arch/mips/mips2/pagetables.c
new file mode 100644
index 000000000..2c0061d39
--- /dev/null
+++ b/arch/mips/mips2/pagetables.c
@@ -0,0 +1,99 @@
+/*
+ * 32 bit MIPS specific page handling.
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 Ralf Baechle
+ */
+#include <linux/mm.h>
+#include <asm/cache.h>
+#include <asm/mipsconfig.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+void (*pgd_init)(unsigned long page);
+
+/*
+ * Initialize new page directory with pointers to invalid ptes
+ */
+void mips2_pgd_init(unsigned long page)
+{
+ unsigned long dummy1, dummy2;
+
+ /*
+ * This version is optimized for the R6000. We generate dirty lines
+ * in the datacache, overwrite these lines with zeros and then flush
+ * the cache. Sounds horribly complicated but is just a trick to
+ * avoid unnecessary loads of from memory and uncached stores which
+ * are very expensive. Not tested yet as the R6000 is a rare CPU only
+ * available in SGI machines and I don't have one.
+ */
+ __asm__ __volatile__(
+ ".set\tnoreorder\n"
+ "1:\t"
+ "cache\t%5,(%0)\n\t"
+ "sw\t%2,(%0)\n\t"
+ "sw\t%2,4(%0)\n\t"
+ "sw\t%2,8(%0)\n\t"
+ "sw\t%2,12(%0)\n\t"
+ "cache\t%5,16(%0)\n\t"
+ "sw\t%2,16(%0)\n\t"
+ "sw\t%2,20(%0)\n\t"
+ "sw\t%2,24(%0)\n\t"
+ "sw\t%2,28(%0)\n\t"
+ "subu\t%1,1\n\t"
+ "bnez\t%1,1b\n\t"
+ "addiu\t%0,32\n\t"
+ ".set\treorder"
+ :"=r" (dummy1),
+ "=r" (dummy2)
+ :"r" (((unsigned long) invalid_pte_table - PAGE_OFFSET) |
+ _PAGE_TABLE),
+ "0" (page),
+ "1" (PAGE_SIZE/(sizeof(pmd_t)*8)),
+ "i" (Create_Dirty_Excl_D));
+#endif
+ /*
+ * Now force writeback to ashure values are in the RAM.
+ */
+ cacheflush(page, PAGE_SIZE, CF_DCACHE|CF_PHYSICAL);
+}
+
+void (*clear_page)(unsigned long page);
+
+/*
+ * To do: cache magic, maybe FPU for 64 accesses when clearing cache pages.
+ */
+void mips2_clear_page(unsigned long page)
+{
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ "addiu\t$1,%0,%2\n"
+ "1:\tsw\t$0,(%0)\n\t"
+ "sw\t$0,4(%0)\n\t"
+ "sw\t$0,8(%0)\n\t"
+ "sw\t$0,12(%0)\n\t"
+ "addiu\t%0,32\n\t"
+ "sw\t$0,-16(%0)\n\t"
+ "sw\t$0,-12(%0)\n\t"
+ "sw\t$0,-8(%0)\n\t"
+ "bne\t$1,%0,1b\n\t"
+ "sw\t$0,-4(%0)\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :"=r" (page)
+ :"0" (page),
+ "I" (PAGE_SIZE)
+ :"$1","memory");
+}
+
+void (*copy_page)(unsigned long to, unsigned long from);
+
+void mips2_copy_page(unsigned long to, unsigned long from)
+{
+ memcpy((void *) to,
+ (void *) (from + (PT_OFFSET - PAGE_OFFSET)), PAGE_SIZE);
+}
diff --git a/arch/mips/mips2/showregs.c b/arch/mips/mips2/showregs.c
new file mode 100644
index 000000000..d207d231b
--- /dev/null
+++ b/arch/mips/mips2/showregs.c
@@ -0,0 +1,32 @@
+/*
+ * linux/arch/mips/mips1/showregs.c
+ *
+ * Copyright (C) 1995, 1996 Ralf Baechle, Paul M. Antoine.
+ */
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+
+void show_regs(struct pt_regs * regs)
+{
+ /*
+ * Saved main processor registers
+ */
+ printk("$0 : %08x %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ 0, regs->regs[1], regs->regs[2], regs->regs[3],
+ regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
+ printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11],
+ regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
+ printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19],
+ regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
+ printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ regs->regs[24], regs->regs[25], regs->regs[28], regs->regs[29],
+ regs->regs[30], regs->regs[31]);
+
+ /*
+ * Saved cp0 registers
+ */
+ printk("epc : %08lx\nStatus: %08x\nCause : %08x\n",
+ regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
+}
diff --git a/arch/mips/mips3/Makefile b/arch/mips/mips3/Makefile
new file mode 100644
index 000000000..e0f6bcf29
--- /dev/null
+++ b/arch/mips/mips3/Makefile
@@ -0,0 +1,25 @@
+#
+# Makefile for the MIPS III specific parts of the Linux/MIPS kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+all: mips.o
+EXTRA_ASFLAGS = -mips3 -mcpu=r4400
+O_TARGET := mips.o
+O_OBJS := cache.o cpu.o fp-context.o memcpy.o memset.o r4xx0.o pagetables.o \
+ showregs.o
+
+copy_user.o: copy_user.S
+r4xx0.o: r4xx0.S
+
+clean:
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips/mips3/cache.c b/arch/mips/mips3/cache.c
new file mode 100644
index 000000000..3fac95b75
--- /dev/null
+++ b/arch/mips/mips3/cache.c
@@ -0,0 +1,309 @@
+/*
+ * Cache maintenance for R4000/R4400/R4600 CPUs.
+ *
+ * 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.
+ *
+ * (C) Copyright 1996 by Ralf Baechle
+ * FIXME: Support for SC/MC version is missing.
+ */
+#include <linux/kernel.h>
+#include <asm/addrspace.h>
+#include <asm/asm.h>
+#include <asm/bootinfo.h>
+#include <asm/cache.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/system.h>
+
+#define STR(x) __STR(x)
+#define __STR(x) #x
+
+unsigned long page_colour_mask;
+
+/*
+ * Size of the caches
+ * Line size of the caches
+ */
+unsigned int dcache_size, icache_size;
+unsigned int dcache_line_size, icache_line_size;
+unsigned long dcache_line_mask, icache_line_mask;
+
+/*
+ * Profiling counter
+ */
+extern unsigned int dflushes;
+extern unsigned int iflushes;
+
+/*
+ * Pointers to code for particular CPU sub family.
+ */
+static void (*wb_inv_d_cache)(void);
+static void (*inv_i_cache)(void);
+
+#define CACHELINES 512 /* number of cachelines (kludgy) */
+
+extern inline void cache(unsigned int cacheop, unsigned long addr,
+ unsigned long offset, void *fault)
+{
+ __asm__ __volatile__ (
+ "1:\tcache\t%0,%2+%1\n\t"
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b,%3\n\t"
+ ".text"
+ : /* no outputs */
+ :"ri" (cacheop),
+ "o" (*(unsigned char *)addr),
+ "ri" (offset),
+ "ri" (fault));
+}
+
+/*
+ * Code for R4000 style primary caches.
+ *
+ * R4000 style caches are direct-mapped, virtual indexed and physical tagged.
+ * The size of cache line is either 16 or 32 bytes.
+ * SC/MC versions of the CPUs add support for an second level cache with
+ * upto 4mb configured as either joint or split I/D. These level two
+ * caches with direct support from CPU aren't yet supported.
+ */
+
+static void r4000_wb_inv_d_cache(void)
+{
+ unsigned long addr = KSEG0;
+ int i;
+
+ for (i=CACHELINES;i;i--) {
+ cache(Index_Writeback_Inv_D, addr, 0, &&fault);
+ addr += 32;
+ }
+ if (read_32bit_cp0_register(CP0_CONFIG) & CONFIG_DB)
+ return;
+ for (i=CACHELINES;i;i--) {
+ cache(Index_Writeback_Inv_D, addr, 16, &&fault);
+ addr += 32;
+ }
+fault:
+}
+
+static void r4000_inv_i_cache(void)
+{
+ unsigned long addr = KSEG0;
+ int i;
+
+ for (i=CACHELINES;i;i--) {
+ cache(Index_Invalidate_I, addr, 0, &&fault);
+ addr += 32;
+ }
+ if (read_32bit_cp0_register(CP0_CONFIG) & CONFIG_IB)
+ return;
+ for (i=CACHELINES;i;i--) {
+ cache(Index_Invalidate_I, addr, 16, &&fault);
+ addr += 32;
+ }
+fault:
+}
+
+/*
+ * Code for R4600 style primary caches.
+ *
+ * R4600 has two way primary caches with 32 bytes line size. The way to
+ * flush is selected by bith 12 of the physical address given as argument
+ * to an Index_* cache operation. CPU supported second level caches are
+ * not available.
+ *
+ * R4600 v1.0 bug: Flush way 2, then way 1 of the instruction cache when
+ * using Index_Invalidate_I. IDT says this should work but is untested.
+ * If this should not work, we have to disable interrupts for the broken
+ * chips. The CPU might otherwise execute code from the wrong cache way
+ * during an interrupt.
+ */
+static void r4600_wb_inv_d_cache(void)
+{
+ unsigned long addr = KSEG0;
+ int i;
+
+ for (i=CACHELINES;i;i-=2) {
+ cache(Index_Writeback_Inv_D, addr, 8192, &&fault);
+ cache(Index_Writeback_Inv_D, addr, 0, &&fault);
+ addr += 32;
+ }
+fault:
+}
+
+static void r4600_inv_i_cache(void)
+{
+ unsigned long addr = KSEG0;
+ int i;
+
+ for (i=CACHELINES;i;i-=2) {
+ cache(Index_Invalidate_I, addr, 8192, &&fault);
+ cache(Index_Invalidate_I, addr, 0, &&fault);
+ addr += 32;
+ }
+fault:
+}
+
+/*
+ * Flush the cache of R4x00.
+ *
+ * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Invalidate_D,
+ * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only
+ * operate correctly if the internal data cache refill buffer is empty. These
+ * CACHE instructions should be separated from any potential data cache miss
+ * by a load instruction to an uncached address to empty the response buffer."
+ * (Revision 2.0 device errata from IDT available on http://www.idt.com/
+ * in .pdf format.)
+ *
+ * To do: Use Hit_Invalidate where possible to be more economic.
+ * Handle SC & MC versions.
+ * The decission to nuke the entire cache might be based on a better
+ * decission algorithem based on the real costs.
+ * Handle different cache sizes.
+ * Combine the R4000 and R4600 cases.
+ */
+extern inline void
+flush_d_cache(unsigned long addr, unsigned long size)
+{
+ unsigned long end;
+ unsigned long a;
+
+ dflushes++;
+ if (1 || size >= dcache_size) {
+ wb_inv_d_cache();
+ return;
+ }
+
+ /*
+ * Workaround for R4600 bug. Explanation see above.
+ */
+ *(volatile unsigned long *)KSEG1;
+
+ /*
+ * Ok, we only have to invalidate parts of the cache.
+ */
+ a = addr & dcache_line_mask;
+ end = (addr + size) & dcache_line_mask;
+ while (1) {
+ cache(Hit_Writeback_Inv_D, a, 0, &&fault);
+ if (a == end) break;
+ a += dcache_line_size;
+ }
+fault:
+ return;
+}
+
+extern inline void
+flush_i_cache(unsigned long addr, unsigned long size)
+{
+ unsigned long end;
+ unsigned long a;
+
+ iflushes++;
+ if (1 || size >= icache_size) {
+ inv_i_cache();
+ return;
+ }
+
+ /*
+ * Ok, we only have to invalidate parts of the cache.
+ */
+ a = addr & icache_line_mask;
+ end = (addr + size) & dcache_line_mask;
+ while (1) {
+ cache(Hit_Invalidate_I, a, 0, &&fault);
+ if (a == end) break;
+ a += icache_line_size;
+ }
+fault:
+ return;
+}
+
+asmlinkage void
+mips3_cacheflush(unsigned long addr, unsigned long size, unsigned int flags)
+{
+ if (!(flags & CF_ALL))
+ printk("mips3_cacheflush called without cachetype parameter\n");
+ if (!(flags & CF_VIRTUAL))
+ return; /* Nothing to do */
+ if (flags & CF_DCACHE)
+ flush_d_cache(addr, size);
+ if (flags & CF_ICACHE)
+ flush_i_cache(addr, size);
+}
+
+/* Going away. */
+asmlinkage void fd_cacheflush(unsigned long addr, unsigned long size)
+{
+ cacheflush(addr, size, CF_DCACHE|CF_VIRTUAL);
+}
+
+void mips3_cache_init(void)
+{
+ extern asmlinkage void handle_vcei(void);
+ extern asmlinkage void handle_vced(void);
+ unsigned int c0_config = read_32bit_cp0_register(CP0_CONFIG);
+
+ switch (mips_cputype) {
+ case CPU_R4000MC: case CPU_R4400MC:
+ case CPU_R4000SC: case CPU_R4400SC:
+ /*
+ * Handlers not implemented yet.
+ */
+ set_except_vector(14, handle_vcei);
+ set_except_vector(31, handle_vced);
+ break;
+ default:
+ }
+
+ /*
+ * Which CPU are we running on? There are different styles
+ * of primary caches in the MIPS R4xx0 CPUs.
+ */
+ switch (mips_cputype) {
+ case CPU_R4000MC: case CPU_R4400MC:
+ case CPU_R4000SC: case CPU_R4400SC:
+ case CPU_R4000PC: case CPU_R4400PC:
+ inv_i_cache = r4000_inv_i_cache;
+ wb_inv_d_cache = r4000_wb_inv_d_cache;
+ break;
+ case CPU_R4600: case CPU_R4700:
+ inv_i_cache = r4600_inv_i_cache;
+ wb_inv_d_cache = r4600_wb_inv_d_cache;
+ break;
+ default:
+ panic("Don't know about cache type ...");
+ }
+ cacheflush = mips3_cacheflush;
+
+ /*
+ * Find the size of primary instruction and data caches.
+ * For most CPUs these sizes are the same.
+ */
+ dcache_size = 1 << (12 + ((c0_config >> 6) & 7));
+ icache_size = 1 << (12 + ((c0_config >> 9) & 7));
+ page_colour_mask = (dcache_size - 1) & ~(PAGE_SIZE - 1);
+
+ /*
+ * Cache line sizes
+ */
+ dcache_line_size = (c0_config & CONFIG_DB) ? 32 : 16;
+ dcache_line_mask = ~(dcache_line_size - 1);
+ icache_line_size = (c0_config & CONFIG_IB) ? 32 : 16;
+ icache_line_mask = ~(icache_line_size - 1);
+
+ printk("Primary D-cache size %dkb bytes, %d byte lines.\n",
+ dcache_size >> 10, dcache_line_size);
+ printk("Primary I-cache size %dkb bytes, %d byte lines.\n",
+ icache_size >> 10, icache_line_size);
+
+ /*
+ * Second level cache.
+ * FIXME ...
+ */
+ if (!(c0_config & CONFIG_SC)) {
+ printk("S-cache detected. This type of of cache is not "
+ "supported yet.\n");
+ }
+}
diff --git a/arch/mips/mips3/cpu.c b/arch/mips/mips3/cpu.c
new file mode 100644
index 000000000..cd8a293e5
--- /dev/null
+++ b/arch/mips/mips3/cpu.c
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 1996 Ralf Baechle
+ */
+#include <linux/sched.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cache.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+
+extern asmlinkage void mips3_cacheflush(unsigned long addr, unsigned long nbytes, unsigned int flags);
+
+void (*mips_cache_init)(void);
+void (*switch_to_user_mode)(struct pt_regs *regs);
+
+static void
+mips3_switch_to_user_mode(struct pt_regs *regs)
+{
+ regs->cp0_status = (regs->cp0_status & ~(ST0_CU0|ST0_KSU)) | KSU_USER;
+}
+
+unsigned long (*thread_saved_pc)(struct thread_struct *t);
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+static unsigned long mips3_thread_saved_pc(struct thread_struct *t)
+{
+ return ((unsigned long long *)(unsigned long)t->reg29)[11];
+}
+
+unsigned long (*get_wchan)(struct task_struct *p);
+
+static unsigned long mips3_get_wchan(struct task_struct *p)
+{
+ /*
+ * This one depends on the frame size of schedule(). Do a
+ * "disass schedule" in gdb to find the frame size. Also, the
+ * code assumes that sleep_on() follows immediately after
+ * interruptible_sleep_on() and that add_timer() follows
+ * immediately after interruptible_sleep(). Ugly, isn't it?
+ * Maybe adding a wchan field to task_struct would be better,
+ * after all...
+ */
+ unsigned long schedule_frame;
+ unsigned long pc;
+
+ pc = thread_saved_pc(&p->tss);
+ if (pc >= (unsigned long) interruptible_sleep_on && pc < (unsigned long) add_timer) {
+ schedule_frame = ((unsigned long long *)(long)p->tss.reg30)[10];
+ return (unsigned long)((unsigned long long *)schedule_frame)[9];
+ }
+ return pc;
+}
+
+void (*pgd_init)(unsigned long page);
+void (*copy_page)(unsigned long to, unsigned long from);
+asmlinkage void (*restore_fp_context)(struct sigcontext *sc);
+asmlinkage void (*save_fp_context)(struct sigcontext *sc);
+
+void
+mips3_cpu_init(void)
+{
+ extern void mips3_cache_init(void);
+ extern void mips3_pgd_init_32byte_lines(unsigned long page);
+ extern void mips3_pgd_init_16byte_lines(unsigned long page);
+ extern void mips3_clear_page_32byte_lines(unsigned long page);
+ extern void mips3_clear_page_16byte_lines(unsigned long page);
+ extern void mips3_copy_page_32byte_lines(unsigned long to, unsigned long from);
+ extern void mips3_copy_page_16byte_lines(unsigned long to, unsigned long from);
+ extern void mips3_copy_page(unsigned long to, unsigned long from);
+ extern asmlinkage void mips3_restore_fp_context(struct sigcontext *sc);
+ extern asmlinkage void mips3_save_fp_context(struct sigcontext *sc);
+
+ mips_cache_init = mips3_cache_init;
+ if (read_32bit_cp0_register(CP0_CONFIG) & CONFIG_DB) {
+ pgd_init = mips3_pgd_init_32byte_lines;
+ clear_page = mips3_clear_page_32byte_lines;
+ copy_page = mips3_copy_page_32byte_lines;
+ } else {
+ pgd_init = mips3_pgd_init_16byte_lines;
+ clear_page = mips3_clear_page_16byte_lines;
+ copy_page = mips3_copy_page_16byte_lines;
+ }
+ switch_to_user_mode = mips3_switch_to_user_mode;
+ thread_saved_pc = mips3_thread_saved_pc;
+ get_wchan = mips3_get_wchan;
+ restore_fp_context = mips3_restore_fp_context;
+ save_fp_context = mips3_save_fp_context;
+}
diff --git a/arch/mips/mips3/fp-context.S b/arch/mips/mips3/fp-context.S
new file mode 100644
index 000000000..5e04aa61f
--- /dev/null
+++ b/arch/mips/mips3/fp-context.S
@@ -0,0 +1,170 @@
+/*
+ * Save/restore floating point context for signal handlers.
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ */
+#include <asm/asm.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/sigcontext.h>
+
+#define SDC1(r,m) \
+7: sdc1 r,m; \
+ .section __ex_table,"a"; \
+ PTR 7b,bad_stack; \
+ .text
+
+#define SW(r,m) \
+7: sw r,m; \
+ .section __ex_table,"a"; \
+ PTR 7b,bad_stack; \
+ .text
+
+#define LDC1(r,m) \
+7: ldc1 r,m; \
+ .section __ex_table,"a"; \
+ PTR 7b,bad_stack; \
+ .text
+
+#define LW(r,m) \
+7: lw r,m; \
+ .section __ex_table,"a"; \
+ PTR 7b,bad_stack; \
+ .text
+
+ .set noreorder
+/*
+ * Save floating point context
+ */
+LEAF(mips3_save_fp_context)
+ mfc0 t1,CP0_STATUS
+ sll t2,t1,2
+ bgez t2,2f
+ sll t2,t1,5 # delay slot
+ bgez t2,1f
+ cfc1 t1,fcr31 # delay slot
+ /*
+ * Store the 16 odd double precision registers
+ */
+ SDC1 ($f1,(SC_FPREGS+8)(a0))
+ SDC1 ($f3,(SC_FPREGS+24)(a0))
+ SDC1 ($f5,(SC_FPREGS+40)(a0))
+ SDC1 ($f7,(SC_FPREGS+56)(a0))
+ SDC1 ($f9,(SC_FPREGS+72)(a0))
+ SDC1 ($f11,(SC_FPREGS+88)(a0))
+ SDC1 ($f13,(SC_FPREGS+104)(a0))
+ SDC1 ($f15,(SC_FPREGS+120)(a0))
+ SDC1 ($f17,(SC_FPREGS+136)(a0))
+ SDC1 ($f19,(SC_FPREGS+152)(a0))
+ SDC1 ($f21,(SC_FPREGS+168)(a0))
+ SDC1 ($f23,(SC_FPREGS+184)(a0))
+ SDC1 ($f25,(SC_FPREGS+200)(a0))
+ SDC1 ($f27,(SC_FPREGS+216)(a0))
+ SDC1 ($f29,(SC_FPREGS+232)(a0))
+ SDC1 ($f31,(SC_FPREGS+248)(a0))
+
+ /*
+ * Store the 16 even double precision registers
+ */
+1: SDC1 ($f0,(SC_FPREGS+0)(a0))
+ SDC1 ($f2,(SC_FPREGS+16)(a0))
+ SDC1 ($f4,(SC_FPREGS+32)(a0))
+ SDC1 ($f6,(SC_FPREGS+48)(a0))
+ SDC1 ($f8,(SC_FPREGS+64)(a0))
+ SDC1 ($f10,(SC_FPREGS+80)(a0))
+ SDC1 ($f12,(SC_FPREGS+96)(a0))
+ SDC1 ($f14,(SC_FPREGS+112)(a0))
+ SDC1 ($f16,(SC_FPREGS+128)(a0))
+ SDC1 ($f18,(SC_FPREGS+144)(a0))
+ SDC1 ($f20,(SC_FPREGS+160)(a0))
+ SDC1 ($f22,(SC_FPREGS+176)(a0))
+ SDC1 ($f24,(SC_FPREGS+192)(a0))
+ SDC1 ($f26,(SC_FPREGS+208)(a0))
+ SDC1 ($f28,(SC_FPREGS+224)(a0))
+ SDC1 ($f30,(SC_FPREGS+240)(a0))
+ SW t1,SC_FPC_CSR(a0)
+ cfc1 t0,$0 # implementation/version
+ jr ra
+ .set nomacro
+ SW t1,SC_FPC_EIR(a0) # delay slot
+ .set macro
+
+2: jr ra
+ .set nomacro
+ nop # delay slot
+ .set macro
+ END(mips3_save_fp_context)
+
+/*
+ * Restore fpu state:
+ * - fp gp registers
+ * - cp1 status/control register
+ *
+ * We base the decission which registers to restore from the signal stack
+ * frame on the current content of c0_status, not on the content of the
+ * stack frame which might have been changed by the user.
+ */
+LEAF(mips3_restore_fp_context)
+ mfc0 t1,CP0_STATUS
+ sll t0,t1,2
+ bgez t0,2f
+ sll t0,t1,5 # delay slot
+ bgez t0,1f
+ LW t0,SC_FPC_CSR(a0) # delay slot
+ /*
+ * Restore the 16 odd double precision registers only
+ * when enabled in the cp0 status register.
+ */
+ LDC1 ($f1,(SC_FPREGS+8)(a0))
+ LDC1 ($f3,(SC_FPREGS+24)(a0))
+ LDC1 ($f5,(SC_FPREGS+40)(a0))
+ LDC1 ($f7,(SC_FPREGS+56)(a0))
+ LDC1 ($f9,(SC_FPREGS+72)(a0))
+ LDC1 ($f11,(SC_FPREGS+88)(a0))
+ LDC1 ($f13,(SC_FPREGS+104)(a0))
+ LDC1 ($f15,(SC_FPREGS+120)(a0))
+ LDC1 ($f17,(SC_FPREGS+136)(a0))
+ LDC1 ($f19,(SC_FPREGS+152)(a0))
+ LDC1 ($f21,(SC_FPREGS+168)(a0))
+ LDC1 ($f23,(SC_FPREGS+184)(a0))
+ LDC1 ($f25,(SC_FPREGS+200)(a0))
+ LDC1 ($f27,(SC_FPREGS+216)(a0))
+ LDC1 ($f29,(SC_FPREGS+232)(a0))
+ LDC1 ($f31,(SC_FPREGS+248)(a0))
+
+ /*
+ * Restore the 16 even double precision registers
+ * when cp1 was enabled in the cp0 status register.
+ */
+1: LDC1 ($f0,(SC_FPREGS+0)(a0))
+ LDC1 ($f2,(SC_FPREGS+16)(a0))
+ LDC1 ($f4,(SC_FPREGS+32)(a0))
+ LDC1 ($f6,(SC_FPREGS+48)(a0))
+ LDC1 ($f8,(SC_FPREGS+64)(a0))
+ LDC1 ($f10,(SC_FPREGS+80)(a0))
+ LDC1 ($f12,(SC_FPREGS+96)(a0))
+ LDC1 ($f14,(SC_FPREGS+112)(a0))
+ LDC1 ($f16,(SC_FPREGS+128)(a0))
+ LDC1 ($f18,(SC_FPREGS+144)(a0))
+ LDC1 ($f20,(SC_FPREGS+160)(a0))
+ LDC1 ($f22,(SC_FPREGS+176)(a0))
+ LDC1 ($f24,(SC_FPREGS+192)(a0))
+ LDC1 ($f26,(SC_FPREGS+208)(a0))
+ LDC1 ($f28,(SC_FPREGS+224)(a0))
+ LDC1 ($f30,(SC_FPREGS+240)(a0))
+ jr ra
+ .set nomacro
+ ctc1 t0,fcr31 # delay slot
+ .set macro
+
+2: jr ra
+ .set nomacro
+ nop # delay slot
+ .set macro
+ END(mips3_restore_fp_context)
+ .set reorder
diff --git a/arch/mips/mips3/memcpy.S b/arch/mips/mips3/memcpy.S
new file mode 100644
index 000000000..6f03032a6
--- /dev/null
+++ b/arch/mips/mips3/memcpy.S
@@ -0,0 +1,185 @@
+/*
+ * arch/mips/mips3/memcpy.S
+ *
+ * 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.
+ *
+ * Copyright (c) 1996 by Ralf Baechle
+ *
+ * Less stupid memcpy/user_copy implementation for 64 bit MIPS CPUs.
+ * Much faster than the old memcpy but definately work in progress.
+ * The list of tricks for a good memcpy is long ...
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+
+#define BLOCK_SIZE (SZREG*4)
+
+#define SWAP(x,y) \
+ subu x,x,y; \
+ addu y,x,y; \
+ subu x,y,x
+
+#define EX(addr,handler) \
+ .section __ex_table,"a"; \
+ PTR addr, handler; \
+ .text
+#define UEX(addr,handler) \
+ EX(addr,handler); \
+ EX(addr+4,handler)
+
+ .set noreorder
+ .set noat
+
+/* ---------------------------------------------------------------------- */
+
+not_dw_aligned:
+/*
+ * At least one address is missaligned.
+ * Let's see if we can fix the alignment.
+ */
+ LONG_SUBU v1,zero,a0
+ andi v1,SZREG-1
+ sltu t0,v0,v1
+ MOVN(v1,v0,t0)
+ beqz v1,still_not_aligned
+ LONG_ADDU v1,a0 # delay slot
+1: lb $1,(a1)
+ EX(1b, fault)
+ LONG_ADDIU a1,1
+2: sb $1,(a0)
+ EX(2b, fault)
+ LONG_ADDIU a0,1
+ bne a0,v1,1b
+ LONG_SUBU v0,1 # delay slot
+
+/*
+ * Ok, now the destination address is 8-byte aligned.
+ * Is the source also aligned?
+ */
+ andi t0,a1,SZREG-1
+ beqz t0,align8 # fine ...
+
+/*
+ * Bad. We could only fix the alignment of the destination address.
+ * Now let's copy in the usual BLOCK_SIZE byte blocks using unaligned
+ * load and aligned stores.
+ */
+still_not_aligned:
+ ori v1,v0,BLOCK_SIZE-1 # delay slot
+ xori v1,BLOCK_SIZE-1
+ beqz v1,copy_left_over
+ nop # delay slot
+ LONG_SUBU v0,v1
+ LONG_ADDU v1,a0
+
+1: uld t0,(a1)
+ UEX(1b, fault)
+2: uld t1,8(a1)
+ UEX(2b, fault)
+2: uld t2,16(a1)
+ UEX(2b, fault)
+2: uld t3,24(a1)
+ UEX(2b, fault)
+2: sd t0,(a0)
+ EX(2b, fault)
+2: sd t1,8(a0)
+ EX(2b, fault_plus_one_reg)
+2: sd t2,16(a0)
+ EX(2b, fault_plus_two_reg)
+2: sd t3,24(a0)
+ EX(2b, fault_plus_three_reg)
+ LONG_ADDIU a0,BLOCK_SIZE
+ bne a0,v1,1b
+ LONG_ADDIU a1,BLOCK_SIZE # delay slot
+9:
+ b copy_left_over # < BLOCK_SIZE bytes left
+ nop # delay slot
+
+/* ---------------------------------------------------------------------- */
+
+LEAF(__copy_user)
+
+ or t1,a0,a1
+ andi t1,SZREG-1
+ bnez t1,not_dw_aligned
+ move v0,a2 # delay slot
+
+align8:
+ ori v1,v0,BLOCK_SIZE-1
+ xori v1,BLOCK_SIZE-1
+ beqz v1,copy_left_over
+ nop # delay slot
+ LONG_SUBU v0,v1
+ LONG_ADDU v1,a0
+
+1: ld t0,(a1)
+ EX(1b, fault)
+2: ld t1,8(a1)
+ EX(2b, fault)
+2: ld t2,16(a1)
+ EX(2b, fault)
+2: ld t3,24(a1)
+ EX(2b, fault)
+2: sd t0,(a0)
+ EX(2b, fault)
+2: sd t1,8(a0)
+ EX(2b, fault_plus_one_reg)
+2: sd t2,16(a0)
+ EX(2b, fault_plus_two_reg)
+2: sd t3,24(a0)
+ EX(2b, fault_plus_three_reg)
+ LONG_ADDIU a0,BLOCK_SIZE
+ bne a0,v1,1b
+ LONG_ADDIU a1,BLOCK_SIZE # delay slot
+9:
+
+/*
+ * We've got upto 31 bytes left to copy ...
+ */
+copy_left_over:
+ beqz v0,3f
+ nop # delay slot
+1: lb $1,(a1)
+ EX(1b, fault)
+ LONG_ADDIU a1,1
+2: sb $1,(a0)
+ EX(2b, fault)
+ LONG_SUBU v0,1
+ bnez v0,1b
+ LONG_ADDIU a0,1
+3: jr ra
+ nop # delay slot
+
+ END(__copy_user)
+ .set at
+ .set reorder
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * Access fault. The number of not copied bytes is in v0. We have to
+ * correct the number of the not copied bytes in v0 in case of a access
+ * fault in an unrolled loop, then return.
+ */
+
+fault: jr ra
+fault_plus_one_reg: LONG_ADDIU v0,SZREG
+ jr ra
+fault_plus_two_reg: LONG_ADDIU v0,SZREG*2
+ jr ra
+fault_plus_three_reg: LONG_ADDIU v0,SZREG*3
+ jr ra
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * For now we use __copy_user for __memcpy, too. This is efficient (one
+ * instruction penatly) and smaller but adds unwanted error checking we don't
+ * need. This hopefully doesn't cover any bugs. The memcpy() wrapper in
+ * <asm/string.h> takes care of the return value in a way GCC can optimize.
+ */
+ .globl __memcpy
+__memcpy = __copy_user
diff --git a/arch/mips/mips3/memset.c b/arch/mips/mips3/memset.c
new file mode 100644
index 000000000..e92a0907f
--- /dev/null
+++ b/arch/mips/mips3/memset.c
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ *
+ * Less stupid memset for 64 bit MIPS CPUs.
+ */
+#include <linux/linkage.h>
+#include <linux/string.h>
+
+static void __inline__ b_memset(void *s, unsigned long long c, size_t count)
+{
+ unsigned char *p = s;
+
+ while(count--)
+ *(p++) = c;
+}
+
+static void __inline__ dw_memset(void *s, unsigned long long c, size_t count)
+{
+ unsigned long long *p = s;
+
+ count >>= 3;
+ while(count--)
+ *(p++) = c;
+}
+
+asm( ".globl\t__generic_memset_b\n\t"
+ ".align\t2\n\t"
+ ".type\t__generic_memset_b,@function\n\t"
+ ".ent\t__generic_memset_b,0\n\t"
+ ".frame\t$29,0,$31\n"
+ "__generic_memset_b:\n\t"
+ "andi\t$5,0xff\n\t"
+ "dsll\t$2,$5,8\n\t"
+ "or\t$5,$2\n\t"
+ "dsll\t$2,$5,16\n\t"
+ "or\t$5,$2\n\t"
+ "dsll32\t$2,$5,0\n\t"
+ "or\t$5,$2\n\t"
+ ".end\t__generic_memset_b\n\t"
+ ".size\t__generic_memset_b,.-t__generic_memset_b");
+
+/*
+ * Fill small area bytewise. For big areas fill the source bytewise
+ * until the pointer is doubleword aligned, then fill in doublewords.
+ * Fill the rest again in single bytes.
+ */
+void __generic_memset_dw(void *s, unsigned long long c, size_t count)
+{
+ unsigned long i;
+
+ /*
+ * Fill small areas bytewise.
+ */
+ if (count <= 16) {
+ b_memset(s, c, count);
+ return;
+ }
+
+ /*
+ * Pad for 8 byte boundary
+ */
+ i = 8 - ((unsigned long)s & 7);
+ b_memset(s, c, i);
+ s += i;
+ count -= i;
+
+ /*
+ * Now start filling with aligned doublewords
+ */
+ dw_memset(s, c, count);
+ s += (count | 7) ^ 7;
+ count &= 7;
+
+ /*
+ * And do what ever is left over again with single bytes.
+ */
+ b_memset(s, c, count);
+}
diff --git a/arch/mips/mips3/pagetables.c b/arch/mips/mips3/pagetables.c
new file mode 100644
index 000000000..e8cb83d03
--- /dev/null
+++ b/arch/mips/mips3/pagetables.c
@@ -0,0 +1,297 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 1996 Ralf Baechle
+ *
+ * Functions that manipulate entire pages.
+ *
+ * Not nice to have all these functions in two versions for cpus with
+ * different cache line size but it seems to be by far the fastest thing
+ * to schedule the cache instructions immediately before the store
+ * instructions. For example using the clear_page() version for 16 byte
+ * lines on machine with 32 byte lines gives a measured penalty of
+ * ~1280 cycles per page.
+ */
+#include <linux/mm.h>
+#include <asm/cache.h>
+#include <asm/mipsconfig.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+extern unsigned int dflushes;
+
+/*
+ * Initialize new page directory with pointers to invalid ptes.
+ */
+void mips3_pgd_init_32byte_lines(unsigned long page)
+{
+ unsigned long dummy1, dummy2;
+
+ /*
+ * We generate dirty lines in the datacache, overwrite them
+ * then writeback the cache.
+ */
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ ".set\tmips3\n\t"
+ "dsll32\t$1,%2,0\n\t"
+ "dsrl32\t%2,$1,0\n\t"
+ "or\t%2,$1\n"
+ "1:\tcache\t%5,(%0)\n\t"
+ "sd\t%2,(%0)\n\t"
+ "sd\t%2,8(%0)\n\t"
+ "sd\t%2,16(%0)\n\t"
+ "sd\t%2,24(%0)\n\t"
+ "daddiu\t%0,64\n\t"
+ "cache\t%5,-32(%0)\n\t"
+ "sd\t%2,-32(%0)\n\t"
+ "sd\t%2,-24(%0)\n\t"
+ "sd\t%2,-16(%0)\n\t"
+ "bne\t%0,%1,1b\n\t"
+ "sd\t%2,-8(%0)\n\t"
+ ".set\tmips0\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :"=&r" (dummy1),
+ "=&r" (dummy2)
+ :"r" (((unsigned long) invalid_pte_table - PAGE_OFFSET) |
+ _PAGE_TABLE),
+ "0" (page),
+ "1" (page + PAGE_SIZE - 64),
+ "i" (Create_Dirty_Excl_D)
+ :"$1");
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ ".set\tmips3\n\t"
+ "1:\tcache\t%3,(%0)\n\t"
+ "bne\t%0,%1,1b\n\t"
+ "daddiu\t%0,32\n\t"
+ ".set\tmips0\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :"=r" (dummy1)
+ :"0" (page),
+ "r" (page + PAGE_SIZE - 32),
+ "i" (Hit_Writeback_D));
+ dflushes++;
+
+#if 0
+ cacheflush(page, PAGE_SIZE, CF_DCACHE|CF_VIRTUAL);
+#endif
+}
+
+/*
+ * Initialize new page directory with pointers to invalid ptes
+ */
+void mips3_pgd_init_16byte_lines(unsigned long page)
+{
+ unsigned long dummy1, dummy2;
+
+ /*
+ * We generate dirty lines in the datacache, overwrite them
+ * then writeback the cache.
+ */
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ ".set\tmips3\n\t"
+ "dsll32\t$1,%2,0\n\t"
+ "dsrl32\t%2,$1,0\n\t"
+ "or\t%2,$1\n"
+ "1:\tcache\t%5,(%0)\n\t"
+ "sd\t%2,(%0)\n\t"
+ "sd\t%2,8(%0)\n\t"
+ "cache\t%5,16(%0)\n\t"
+ "sd\t%2,16(%0)\n\t"
+ "sd\t%2,24(%0)\n\t"
+ "daddiu\t%0,64\n\t"
+ "cache\t%5,-32(%0)\n\t"
+ "sd\t%2,-32(%0)\n\t"
+ "sd\t%2,-24(%0)\n\t"
+ "cache\t%5,-16(%0)\n\t"
+ "sd\t%2,-16(%0)\n\t"
+ "bne\t%0,%1,1b\n\t"
+ "sd\t%2,-8(%0)\n\t"
+ ".set\tmips0\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :"=&r" (dummy1),
+ "=&r" (dummy2)
+ :"r" (((unsigned long) invalid_pte_table - PAGE_OFFSET) |
+ _PAGE_TABLE),
+ "0" (page),
+ "1" (page + PAGE_SIZE - 64),
+ "i" (Create_Dirty_Excl_D)
+ :"$1");
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ ".set\tmips3\n\t"
+ "1:\tcache\t%3,(%0)\n\t"
+ "bne\t%0,%1,1b\n\t"
+ "daddiu\t%0,16\n\t"
+ ".set\tmips0\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :"=r" (dummy1)
+ :"0" (page),
+ "r" (page + PAGE_SIZE - 16),
+ "i" (Hit_Writeback_D));
+ dflushes++;
+
+#if 0
+ cacheflush(page, PAGE_SIZE, CF_DCACHE|CF_VIRTUAL);
+#endif
+}
+
+/*
+ * Zero an entire page.
+ */
+
+void (*clear_page)(unsigned long page);
+
+void mips3_clear_page_32byte_lines(unsigned long page)
+{
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ "daddiu\t$1,%0,%2\n"
+ "1:\tcache\t%3,(%0)\n\t"
+ "sd\t$0,(%0)\n\t"
+ "sd\t$0,8(%0)\n\t"
+ "sd\t$0,16(%0)\n\t"
+ "sd\t$0,24(%0)\n\t"
+ "daddiu\t%0,64\n\t"
+ "cache\t%3,-32(%0)\n\t"
+ "sd\t$0,-32(%0)\n\t"
+ "sd\t$0,-24(%0)\n\t"
+ "sd\t$0,-16(%0)\n\t"
+ "bne\t$1,%0,1b\n\t"
+ "sd\t$0,-8(%0)\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :"=r" (page)
+ :"0" (page),
+ "I" (PAGE_SIZE),
+ "i" (Create_Dirty_Excl_D)
+ :"$1","memory");
+}
+
+void mips3_clear_page_16byte_lines(unsigned long page)
+{
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ "daddiu\t$1,%0,%2\n"
+ "1:\tcache\t%3,(%0)\n\t"
+ "sd\t$0,(%0)\n\t"
+ "sd\t$0,8(%0)\n\t"
+ "cache\t%3,16(%0)\n\t"
+ "sd\t$0,16(%0)\n\t"
+ "sd\t$0,24(%0)\n\t"
+ "daddiu\t%0,64\n\t"
+ "cache\t%3,-32(%0)\n\t"
+ "sd\t$0,-32(%0)\n\t"
+ "sd\t$0,-24(%0)\n\t"
+ "cache\t%3,-16(%0)\n\t"
+ "sd\t$0,-16(%0)\n\t"
+ "bne\t$1,%0,1b\n\t"
+ "sd\t$0,-8(%0)\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :"=r" (page)
+ :"0" (page),
+ "I" (PAGE_SIZE),
+ "i" (Create_Dirty_Excl_D)
+ :"$1","memory");
+}
+
+/*
+ * This is still inefficient. We only can do better if we know the
+ * virtual address where the copy will be accessed.
+ */
+void (*copy_page)(unsigned long to, unsigned long from);
+
+void mips3_copy_page_32byte_lines(unsigned long to, unsigned long from)
+{
+ unsigned long dummy1, dummy2;
+ unsigned long reg1, reg2, reg3, reg4;
+
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ "daddiu\t$1,%0,%8\n"
+ "1:\tcache\t%9,(%0)\n\t"
+ "ld\t%2,(%1)\n\t"
+ "ld\t%3,8(%1)\n\t"
+ "ld\t%4,16(%1)\n\t"
+ "ld\t%5,24(%1)\n\t"
+ "sd\t%2,(%0)\n\t"
+ "sd\t%3,8(%0)\n\t"
+ "sd\t%4,16(%0)\n\t"
+ "sd\t%5,24(%0)\n\t"
+ "cache\t%9,32(%0)\n\t"
+ "daddiu\t%0,64\n\t"
+ "daddiu\t%1,64\n\t"
+ "ld\t%2,-32(%1)\n\t"
+ "ld\t%3,-24(%1)\n\t"
+ "ld\t%4,-16(%1)\n\t"
+ "ld\t%5,-8(%1)\n\t"
+ "sd\t%2,-32(%0)\n\t"
+ "sd\t%3,-24(%0)\n\t"
+ "sd\t%4,-16(%0)\n\t"
+ "bne\t$1,%0,1b\n\t"
+ "sd\t%5,-8(%0)\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :"=r" (dummy1), "=r" (dummy2),
+ "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
+ :"0" (to), "1" (from),
+ "I" (PAGE_SIZE),
+ "i" (Create_Dirty_Excl_D));
+}
+
+void mips3_copy_page_16byte_lines(unsigned long to, unsigned long from)
+{
+ unsigned dummy1, dummy2;
+ unsigned long reg1, reg2;
+
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ "daddiu\t$1,%0,%6\n"
+ "1:\tcache\t%7,(%0)\n\t"
+ "ld\t%2,(%1)\n\t"
+ "ld\t%3,8(%1)\n\t"
+ "sd\t%2,(%0)\n\t"
+ "sd\t%3,8(%0)\n\t"
+ "cache\t%7,16(%0)\n\t"
+ "ld\t%2,16(%1)\n\t"
+ "ld\t%3,24(%1)\n\t"
+ "sd\t%2,16(%0)\n\t"
+ "sd\t%3,24(%0)\n\t"
+ "cache\t%7,32(%0)\n\t"
+ "daddiu\t%0,64\n\t"
+ "daddiu\t%1,64\n\t"
+ "ld\t%2,-32(%1)\n\t"
+ "ld\t%3,-24(%1)\n\t"
+ "sd\t%2,-32(%0)\n\t"
+ "sd\t%3,-24(%0)\n\t"
+ "cache\t%7,-16(%0)\n\t"
+ "ld\t%2,-16(%1)\n\t"
+ "ld\t%3,-8(%1)\n\t"
+ "sd\t%2,-16(%0)\n\t"
+ "bne\t$1,%0,1b\n\t"
+ "sd\t%3,-8(%0)\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :"=r" (dummy1), "=r" (dummy2),
+ "=&r" (reg1), "=&r" (reg2)
+ :"0" (to), "1" (from),
+ "I" (PAGE_SIZE),
+ "i" (Create_Dirty_Excl_D));
+}
diff --git a/arch/mips/kernel/r4xx0.S b/arch/mips/mips3/r4xx0.S
index a68b32243..a282998ac 100644
--- a/arch/mips/kernel/r4xx0.S
+++ b/arch/mips/mips3/r4xx0.S
@@ -1,33 +1,61 @@
/*
- * arch/mips/kernel/r4xx0.S
+ * arch/mips/mips3/r4xx0.S
*
- * Copyright (C) 1994, 1995 Waldorf Electronics
- * Written by Ralf Baechle and Andreas Busse
+ * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
*
- * This file contains most of the R4xx0 specific routines.
+ * This file contains most of the R4xx0 specific routines. Due to the
+ * similarities this should hopefully also be fine for the R10000. For
+ * now we especially support the R10000 by not invalidating entries out of
+ * the TLB before calling the C handlers.
*
- * This code is evil magic. Read appendix f (coprozessor 0 hazards) of
+ * This code is evil magic. Read appendix F (coprocessor 0 hazards) of
* all R4xx0 manuals and think about that MIPS means "Microprocessor without
* Interlocked Pipeline Stages" before you even think about changing this code!
+ *
+ * CAVEATS: The R4000/R4400/R4600 manual say that the operation of a memory
+ * reference associated with a instruction immediately after a tlpb
+ * instruction is undefined. It seems that the R4600 v2.0 also
+ * failes to handle the case where a tlbp instruction follows a
+ * (mapped???) memory reference. In this case c0_index gets
+ * overwritten by some value which I suppose to be the entry
+ * mapping the associated instruction's memory reference.
+ *
+ * This needs a complete overhaul; it was written for a Linux kernel that
+ * handled it's page tables the old i386 way ...
*/
-#include <linux/autoconf.h>
+#include <linux/config.h>
#include <asm/asm.h>
#include <asm/bootinfo.h>
-#include <asm/cachectl.h>
+#include <asm/cache.h>
+#include <asm/fpregdef.h>
#include <asm/mipsconfig.h>
#include <asm/mipsregs.h>
-#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
-#include <asm/mipsregs.h>
-#include <asm/segment.h>
+#include <asm/regdef.h>
#include <asm/stackframe.h>
+/*
+ * Use this to activate extra TLB error checking
+ */
+#define CONF_DEBUG_TLB
+
+/*
+ * Use this to activate extra TLB profiling code
+ * (not implemented yet)
+ */
+#undef CONF_PROFILE_TLB
+
+#ifdef __SMP__
+#error "Fix this for SMP"
+#else
+#define current current_set
+#endif
+
MODE_ALIAS = 0x0016 # uncachable
.text
- .set mips3
.set noreorder
.align 5
@@ -52,7 +80,9 @@ MODE_ALIAS = 0x0016 # uncachable
nop # for R4[04]00 pipeline
nop
nop
+ nop
tlbp
+ nop
nop # for R4[04]00 pipeline
nop
mfc0 k0,CP0_INDEX
@@ -65,7 +95,7 @@ MODE_ALIAS = 0x0016 # uncachable
*/
nop
-#ifdef CONFIG_DEBUG_TLB
+#ifdef CONF_DEBUG_TLB
/*
* OK, this is a double fault. Let's see whether this is
* due to an invalid entry in the page_table.
@@ -85,11 +115,16 @@ MODE_ALIAS = 0x0016 # uncachable
.set at
PRINT("Double fault caused by invalid entries in pgd:\n")
dmfc0 a1,CP0_BADVADDR
- PRINT("Double fault address : %08lx\n")
+ PRINT("Double fault address : %016Lx\n")
dmfc0 a1,CP0_EPC
- PRINT("c0_epc : %08lx\n")
+ PRINT("c0_epc : %016Lx\n")
jal show_regs
move a0,sp
+ jal dump_tlb_nonwired
+ nop
+ dmfc0 a0,CP0_BADVADDR
+ jal dump_list_current
+ nop
.set noat
STI
.set at
@@ -97,12 +132,13 @@ MODE_ALIAS = 0x0016 # uncachable
.set noat
reload_pgd_entries:
-#endif /* CONFIG_DEBUG_TLB */
+#endif /* CONF_DEBUG_TLB */
/*
* Load missing pair of entries from the pgd and return.
*/
dmfc0 k1,CP0_CONTEXT
+// mfc0 k1,CP0_CONTEXT
dsra k1,1
lwu k0,(k1) # Never causes nested exception
lwu k1,4(k1)
@@ -133,7 +169,9 @@ reload_pgd_entries:
*
* k0 contains c0_index.
*/
-invalid_tlbl: /*
+invalid_tlbl:
+#ifdef CONFIG_TLB_SHUTDOWN
+ /*
* Remove entry so we don't need to care later
* For sake of the R4000 V2.2 pipeline the tlbwi insn
* has been moved down. Moving it around is juggling with
@@ -145,13 +183,16 @@ invalid_tlbl: /*
dmtc0 k0,CP0_ENTRYHI
dmtc0 zero,CP0_ENTRYLO0
dmtc0 zero,CP0_ENTRYLO1
+#endif
/*
* Test present bit in entry
*/
dmfc0 k0,CP0_BADVADDR
srl k0,12
sll k0,2
+#ifdef CONFIG_TLB_SHUTDOWN
tlbwi # do not move!
+#endif
lui k1,%HI(TLBMAP)
addu k0,k1
lw k1,(k0)
@@ -172,11 +213,14 @@ invalid_tlbl: /*
* kernel memory management routines.
*/
nopage_tlbl: SAVE_ALL
+ dmfc0 a2,CP0_BADVADDR
STI
+ REG_S sp,FR_ORIG_REG2(sp)
.set at
/*
* a0 (struct pt_regs *) regs
* a1 (unsigned long) 0 for read access
+ * a2 (unsigned long) faulting virtual address
*/
move a0,sp
jal do_page_fault
@@ -204,7 +248,10 @@ nopage_tlbl: SAVE_ALL
lui k1,%HI(TLBMAP)
addu k0,k1
lw k1,(k0)
+ nop
+ nop
tlbp # find faulting entry
+ nop
andi k1,(_PAGE_PRESENT|_PAGE_WRITE)
xori k1,(_PAGE_PRESENT|_PAGE_WRITE)
bnez k1,nopage_tlbs
@@ -239,35 +286,13 @@ nopage_tlbl: SAVE_ALL
* kernel memory management routines.
*/
nopage_tlbs:
-#if 0
- .set mips3
- SAVE_ALL
- .set mips0
- PRINT("nopage_tlbs\n")
- .set mips3
- RESTORE_ALL
- .set mips3
- j 1f
- nop
-#endif
nowrite_mod:
-#if 0
- .set mips3
- SAVE_ALL
- .set mips0
- PRINT("nopage_mod\n")
- .set mips3
- RESTORE_ALL
- .set mips3
- j 1f
- nop
-1:
-#endif
+#ifdef CONFIG_TLB_SHUTDOWN
/*
* Remove entry so we don't need to care later
*/
mfc0 k0,CP0_INDEX
-#ifdef CONFIG_DEBUG_TLB
+#ifdef CONF_DEBUG_TLB
bgez k0,2f
nop
/*
@@ -279,14 +304,12 @@ nowrite_mod:
jal show_regs
move a0,sp
.set at
- mfc0 a1,CP0_BADVADDR
- PRINT("c0_badvaddr == %08lx\n")
+ dmfc0 a1,CP0_BADVADDR
+ PRINT("c0_badvaddr == %016Lx\n")
mfc0 a1,CP0_INDEX
PRINT("c0_index == %08x\n")
- mfc0 a1,CP0_ENTRYHI
- PRINT("c0_entryhi == %08x\n")
- jal dump_tlb_nonwired
- nop
+ dmfc0 a1,CP0_ENTRYHI
+ PRINT("c0_entryhi == %016Lx\n")
.set noat
STI
.set at
@@ -294,7 +317,7 @@ nowrite_mod:
1: j 1b
nop
2:
-#endif /* CONFIG_DEBUG_TLB */
+#endif /* CONF_DEBUG_TLB */
lui k1,0x0008
or k0,k1
dsll k0,13
@@ -306,13 +329,17 @@ nowrite_mod:
nop
nop
tlbwi
+#endif /* CONFIG_TLB_SHUTDOWN */
.set noat
SAVE_ALL
+ dmfc0 a2,CP0_BADVADDR
STI
+ REG_S sp,FR_ORIG_REG2(sp)
.set at
/*
* a0 (struct pt_regs *) regs
* a1 (unsigned long) 1 for write access
+ * a2 (unsigned long) faulting virtual address
*/
move a0,sp
jal do_page_fault
@@ -335,7 +362,10 @@ nowrite_mod:
lui k1,%HI(TLBMAP)
addu k0,k1
lw k1,(k0)
+ nop
+ nop
tlbp # find faulting entry
+ nop
andi k1,_PAGE_WRITE
beqz k1,nowrite_mod
/*
@@ -366,12 +396,15 @@ nowrite_mod:
END(handle_mod)
.set at
+/*
+ * Flush the complete TLB
+ */
.set noreorder
LEAF(tlbflush)
li t0,PM_4K
mtc0 t0,CP0_PAGEMASK
- la t0,boot_info
- lw t0,OFFSET_BOOTINFO_TLB_ENTRIES(t0)
+ lw t0,mips_tlb_entries /* mips_tlb_enbtries is set */
+ /* by bi_EarlySnarf() */
dmtc0 zero,CP0_ENTRYLO0
dmtc0 zero,CP0_ENTRYLO1
mfc0 t2,CP0_WIRED
@@ -384,12 +417,67 @@ nowrite_mod:
bne t2,t0,1b
tlbwi # delay slot
jr ra
- nop
+ nop # delay slot
END(tlbflush)
+/*
+ * Flush a single entry from the TLB
+ *
+ * Parameters: a0 - unsigned long address
+ */
+ .set noreorder
+ LEAF(tlbflush_page)
+ /*
+ * Step 1: Wipe out old TLB information. Not shure if
+ * we really need that step; call it paranoia ...
+ * In order to do that we need to disable interrupts.
+ */
+ li t3,TLBMAP # then wait 3 cycles
+ ori t1,a0,0xfff # mask off low 12 bits
+ xori t1,0xfff
+ mfc0 t2,CP0_ENTRYHI # copy ASID into address
+ andi t2,0xff
+ or t2,t1
+ mtc0 t2,CP0_ENTRYHI
+ srl t4,a0,12 # wait again three cycles
+ sll t4,t4,PTRLOG
+ dmtc0 zero,CP0_ENTRYLO0
+ nop
+ tlbp # now query the TLB
+ nop
+ addu t3,t4 # wait another three cycles
+ ori t3,0xffff
+ xori t3,0xffff
+ mfc0 t1,CP0_INDEX
+ bltz t1,1f # No old entry?
+ dmtc0 zero,CP0_ENTRYLO1
+ or t3,t1 # wait one cycle
+ tlbwi
/*
- * Code necessary to switch tasks on an Linux/MIPS machine.
+ * But there still might be an entry for the pgd ...
*/
+1: mtc0 t3,CP0_ENTRYHI
+ nop # wait 3 cycles
+ nop
+ nop
+ nop
+ tlbp # TLB lookup
+ nop
+ nop
+ nop
+ mfc0 t1,CP0_INDEX # wait 3 cycles
+ bltz t1,1f # No old entry?
+ nop
+ tlbwi # gotcha ...
+1: jr ra
+ nop # delay slot
+ END(tlbflush_page)
+
+/*
+ * Code necessary to switch tasks on an Linux/MIPS machine.
+ * FIXME: We don't need to disable interrupts anymore.
+ * FIXME: Do some cache magic for faster loading/saving.
+ */
.align 5
LEAF(resume)
/*
@@ -416,24 +504,24 @@ nowrite_mod:
* Save non-scratch registers
* All other registers have been saved on the kernel stack
*/
- sw s0,TOFF_REG16(t0)
- sw s1,TOFF_REG17(t0)
- sw s2,TOFF_REG18(t0)
- sw s3,TOFF_REG19(t0)
- sw s4,TOFF_REG20(t0)
- sw s5,TOFF_REG21(t0)
- sw s6,TOFF_REG22(t0)
- sw s7,TOFF_REG23(t0)
- sw gp,TOFF_REG28(t0)
- sw sp,TOFF_REG29(t0)
- sw fp,TOFF_REG30(t0)
+ sd s0,TOFF_REG16(t0)
+ sd s1,TOFF_REG17(t0)
+ sd s2,TOFF_REG18(t0)
+ sd s3,TOFF_REG19(t0)
+ sd s4,TOFF_REG20(t0)
+ sd s5,TOFF_REG21(t0)
+ sd s6,TOFF_REG22(t0)
+ sd s7,TOFF_REG23(t0)
+ sd gp,TOFF_REG28(t0)
+ sd sp,TOFF_REG29(t0)
+ sd fp,TOFF_REG30(t0)
/*
* Save floating point state
*/
sll t2,t1,2
bgez t2,2f
- sw ra,TOFF_REG31(t0) # delay slot
+ sd ra,TOFF_REG31(t0) # delay slot
sll t2,t1,5
bgez t2,1f
sdc1 $f0,(TOFF_FPU+0)(t0) # delay slot
@@ -460,7 +548,7 @@ nowrite_mod:
/*
* Store the 16 even double precision registers
*/
-1: cfc1 t1,$31
+1: cfc1 t1,fcr31
sdc1 $f2,(TOFF_FPU+16)(t0)
sdc1 $f4,(TOFF_FPU+32)(t0)
sdc1 $f6,(TOFF_FPU+48)(t0)
@@ -569,23 +657,23 @@ nowrite_mod:
ldc1 $f26,(TOFF_FPU+208)(a0)
ldc1 $f28,(TOFF_FPU+224)(a0)
ldc1 $f30,(TOFF_FPU+240)(a0)
- ctc1 t0,$31
+ ctc1 t0,fcr31
/*
* Restore non-scratch registers
*/
-2: lw s0,TOFF_REG16(a0)
- lw s1,TOFF_REG17(a0)
- lw s2,TOFF_REG18(a0)
- lw s3,TOFF_REG19(a0)
- lw s4,TOFF_REG20(a0)
- lw s5,TOFF_REG21(a0)
- lw s6,TOFF_REG22(a0)
- lw s7,TOFF_REG23(a0)
- lw gp,TOFF_REG28(a0)
- lw sp,TOFF_REG29(a0)
- lw fp,TOFF_REG30(a0)
- lw ra,TOFF_REG31(a0)
+2: ld s0,TOFF_REG16(a0)
+ ld s1,TOFF_REG17(a0)
+ ld s2,TOFF_REG18(a0)
+ ld s3,TOFF_REG19(a0)
+ ld s4,TOFF_REG20(a0)
+ ld s5,TOFF_REG21(a0)
+ ld s6,TOFF_REG22(a0)
+ ld s7,TOFF_REG23(a0)
+ ld gp,TOFF_REG28(a0)
+ ld sp,TOFF_REG29(a0)
+ ld fp,TOFF_REG30(a0)
+ ld ra,TOFF_REG31(a0)
/*
* Restore status register
@@ -598,135 +686,156 @@ nowrite_mod:
END(resume)
/*
- * Some bits in the config register
+ * Load a new root pointer into the tlb
*/
-#define CONFIG_DB (1<<4)
-#define CONFIG_IB (1<<5)
+ .set noreorder
+ LEAF(load_pgd)
+ /*
+ * Switch the root pointer
+ */
+ mfc0 t0,CP0_STATUS
+ ori t1,t0,1
+ xori t1,1
+ mtc0 t1,CP0_STATUS
+ srl a0,6
+ ori a0,MODE_ALIAS
+ li t1,TLB_ROOT
+ mtc0 t1,CP0_ENTRYHI
+ mtc0 zero,CP0_INDEX
+ mtc0 a0,CP0_ENTRYLO0
+ mtc0 zero,CP0_ENTRYLO1
+ mtc0 t0,CP0_STATUS
+ jr ra
+ tlbwi # delay slot
+ END(load_pgd)
/*
- * Flush instruction/data caches
+ * do_syscall calls the function in a1 with upto 7 arguments. If over
+ * four arguments are being requested, the additional arguments will
+ * be copied from the user stack pointed to by a0->reg29.
*
- * Parameters: a0 - starting address to flush
- * a1 - size of area to be flushed
- * a2 - which caches to be flushed
+ * FIXME: This function will fail for syscalls with more than four
+ * arguments from kernelspace.
*
- * FIXME: - ignores parameters in a0/a1
- * - doesn't know about second level caches
+ * a0 (struct pt_regs *) pointer to user registers
+ * a1 (syscall_t) pointer to syscall to do
+ * a2 (int) number of arguments to syscall
*/
- .set noreorder
- LEAF(sys_cacheflush)
- andi t1,a2,DCACHE
- beqz t1,do_icache
- li t0,KSEG0 # delay slot
-
- /*
- * Writeback data cache, even lines
- */
- li t1,CACHELINES-1
-1: cache Index_Writeback_Inv_D,0(t0)
- cache Index_Writeback_Inv_D,32(t0)
- cache Index_Writeback_Inv_D,64(t0)
- cache Index_Writeback_Inv_D,96(t0)
- cache Index_Writeback_Inv_D,128(t0)
- cache Index_Writeback_Inv_D,160(t0)
- cache Index_Writeback_Inv_D,192(t0)
- cache Index_Writeback_Inv_D,224(t0)
- cache Index_Writeback_Inv_D,256(t0)
- cache Index_Writeback_Inv_D,288(t0)
- cache Index_Writeback_Inv_D,320(t0)
- cache Index_Writeback_Inv_D,352(t0)
- cache Index_Writeback_Inv_D,384(t0)
- cache Index_Writeback_Inv_D,416(t0)
- cache Index_Writeback_Inv_D,448(t0)
- cache Index_Writeback_Inv_D,480(t0)
- addiu t0,512
- bnez t1,1b
- subu t1,1
-
- /*
- * Writeback data cache, odd lines
- * Only needed for 16 byte line size
- */
- mfc0 t1,CP0_CONFIG
- andi t1,CONFIG_DB
- bnez t1,do_icache
- li t1,CACHELINES-1
-1: cache Index_Writeback_Inv_D,16(t0)
- cache Index_Writeback_Inv_D,48(t0)
- cache Index_Writeback_Inv_D,80(t0)
- cache Index_Writeback_Inv_D,112(t0)
- cache Index_Writeback_Inv_D,144(t0)
- cache Index_Writeback_Inv_D,176(t0)
- cache Index_Writeback_Inv_D,208(t0)
- cache Index_Writeback_Inv_D,240(t0)
- cache Index_Writeback_Inv_D,272(t0)
- cache Index_Writeback_Inv_D,304(t0)
- cache Index_Writeback_Inv_D,336(t0)
- cache Index_Writeback_Inv_D,368(t0)
- cache Index_Writeback_Inv_D,400(t0)
- cache Index_Writeback_Inv_D,432(t0)
- cache Index_Writeback_Inv_D,464(t0)
- cache Index_Writeback_Inv_D,496(t0)
- addiu t0,512
- bnez t1,1b
- subu t1,1
-
-do_icache: andi t1,a2,ICACHE
- beqz t1,done
-
- /*
- * Flush instruction cache, even lines
- */
- lui t0,0x8000
- li t1,CACHELINES-1
-1: cache Index_Invalidate_I,0(t0)
- cache Index_Invalidate_I,32(t0)
- cache Index_Invalidate_I,64(t0)
- cache Index_Invalidate_I,96(t0)
- cache Index_Invalidate_I,128(t0)
- cache Index_Invalidate_I,160(t0)
- cache Index_Invalidate_I,192(t0)
- cache Index_Invalidate_I,224(t0)
- cache Index_Invalidate_I,256(t0)
- cache Index_Invalidate_I,288(t0)
- cache Index_Invalidate_I,320(t0)
- cache Index_Invalidate_I,352(t0)
- cache Index_Invalidate_I,384(t0)
- cache Index_Invalidate_I,416(t0)
- cache Index_Invalidate_I,448(t0)
- cache Index_Invalidate_I,480(t0)
- addiu t0,512
- bnez t1,1b
- subu t1,1
-
- /*
- * Flush instruction cache, even lines
- * Only needed for 16 byte line size
- */
- mfc0 t1,CP0_CONFIG
- andi t1,CONFIG_IB
- bnez t1,done
- li t1,CACHELINES-1
-1: cache Index_Invalidate_I,16(t0)
- cache Index_Invalidate_I,48(t0)
- cache Index_Invalidate_I,80(t0)
- cache Index_Invalidate_I,112(t0)
- cache Index_Invalidate_I,144(t0)
- cache Index_Invalidate_I,176(t0)
- cache Index_Invalidate_I,208(t0)
- cache Index_Invalidate_I,240(t0)
- cache Index_Invalidate_I,272(t0)
- cache Index_Invalidate_I,304(t0)
- cache Index_Invalidate_I,336(t0)
- cache Index_Invalidate_I,368(t0)
- cache Index_Invalidate_I,400(t0)
- cache Index_Invalidate_I,432(t0)
- cache Index_Invalidate_I,464(t0)
- cache Index_Invalidate_I,496(t0)
- addiu t0,512
- bnez t1,1b
- subu t1,1
-
-done: j ra
- nop
- END(sys_cacheflush)
+#if defined (__MIPSEB__) && defined (__mips64)
+#define bo 4
+#else
+#define bo 0
+#endif
+ .set reorder
+ .text
+NESTED(do_syscalls, 64, sp)
+ LONG_SUBU sp,64
+ REG_S ra,56(sp)
+ dsll a2,a2,PTRLOG
+ lw t1,dst(a2)
+ move t2,a1
+ REG_L t0,FR_REG29(a0) # get old user stack pointer
+ jalr t1
+
+7: lw t1,24+bo(t0) # parameter #7 from usp
+ REG_S t1,SZREG*6(sp)
+6: lw t1,20+bo(t0) # parameter #6 from usp
+ REG_S t1,SZREG*5(sp)
+5: lw t1,16+bo(t0) # parameter #5 from usp
+ REG_S t1,SZREG*4(sp)
+
+4: lw a3,FR_REG7+bo(a0) # 4 args
+3: lw a2,FR_REG6+bo(a0) # 3 args
+2: lw a1,FR_REG5+bo(a0) # 2 args
+1: lw a0,FR_REG4+bo(a0) # 1 args
+ jalr t2
+ ld ra,56(sp)
+ addiu sp,64
+ jr ra
+0: jalr t2 # 0 args, just pass a0
+ ld ra,56(sp)
+ LONG_ADDIU sp,64
+ jr ra
+ END(do_syscalls)
+
+ .rdata
+ .align PTRLOG
+dst: PTR 0b, 1b, 2b, 3b, 4b, 5b, 6b, 7b
+
+ .section __ex_table,"a"
+ PTR 7b,bad_stack
+ PTR 6b,bad_stack
+ PTR 5b,bad_stack
+ .text
+
+#ifdef CONFIG_REVERSE
+
+/*
+ * Same as above but for processes running with reverse byte order.
+ * When exec(2)ing a file the system detects normal/reverse byteorder in
+ * an executable and
+ * - sets the appropriate vector for syscalls and other low level
+ * routines that depend of userspace byteorder.
+ * - set the reverse byteorder flag in c0_status
+ * - marks the process as reverse in the process table.
+ */
+#define REG_SWAP(r,t) \
+ .set push; \
+ .set noat; \
+ sll $1,r,24; \
+ andi t,r,0xff00; \
+ sll t,$t,8; \
+ or $1,t; \
+ srl t,r,8; \
+ andi t,$t,0xff00; \
+ or $1,t; \
+ srl r,r,24; \
+ or $1,r; \
+ .set pop
+
+ .set reorder
+ .text
+NESTED(do_syscalls_rev, 64, sp)
+ LONG_SUBU sp,64
+ REG_S ra,56(sp)
+ dsll a2,a2,PTRLOG
+ lw t1,dst_rev(a2)
+ move t2,a1
+ REG_L t0,FR_REG29(a0) # get old user stack pointer
+ jalr t1
+
+7: lw t1,24+bo(t0) # parameter #7 from usp
+ REG_SWAP(t1,v0) # convert byteorder
+ REG_S t1,SZREG*6(sp)
+6: lw t1,20+bo(t0) # parameter #6 from usp
+ REG_SWAP(t1,v0) # convert byteorder
+ REG_S t1,SZREG*5(sp)
+5: lw t1,16+bo(t0) # parameter #5 from usp
+ REG_SWAP(t1,v0) # convert byteorder
+ REG_S t1,SZREG*4(sp)
+
+4: lw a3,FR_REG7+bo(a0) # 4 args
+3: lw a2,FR_REG6+bo(a0) # 3 args
+2: lw a1,FR_REG5+bo(a0) # 2 args
+1: lw a0,FR_REG4+bo(a0) # 1 args
+ jalr t2
+ ld ra,56(sp)
+ addiu sp,64
+ jr ra
+0: jalr t2 # 0 args, just pass a0
+ ld ra,56(sp)
+ LONG_ADDIU sp,64
+ jr ra
+ END(do_syscalls)
+
+ .rdata
+ .align PTRLOG
+dst_rev: PTR 0b, 1b, 2b, 3b, 4b, 5b, 6b, 7b
+
+ .section __ex_table,"a"
+ PTR 7b,bad_stack
+ PTR 6b,bad_stack
+ PTR 5b,bad_stack
+ .text
+
+#endif /* CONFIG_REVERSE */
diff --git a/arch/mips/mips3/showregs.c b/arch/mips/mips3/showregs.c
new file mode 100644
index 000000000..651cb6a24
--- /dev/null
+++ b/arch/mips/mips3/showregs.c
@@ -0,0 +1,36 @@
+/*
+ * linux/arch/mips/mips3/showregs.c
+ *
+ * Copyright (C) 1995, 1996 Ralf Baechle
+ */
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+
+void show_regs(struct pt_regs * regs)
+{
+ /*
+ * Saved main processor registers
+ */
+ printk("$0 : %016Lx %016Lx %016Lx %016Lx\n",
+ 0ULL, regs->regs[1], regs->regs[2], regs->regs[3]);
+ printk("$4 : %016Lx %016Lx %016Lx %016Lx\n",
+ regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
+ printk("$8 : %016Lx %016Lx %016Lx %016Lx\n",
+ regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
+ printk("$12: %016Lx %016Lx %016Lx %016Lx\n",
+ regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
+ printk("$16: %016Lx %016Lx %016Lx %016Lx\n",
+ regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
+ printk("$20: %016Lx %016Lx %016Lx %016Lx\n",
+ regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
+ printk("$24: %016Lx %016Lx\n",
+ regs->regs[24], regs->regs[25]);
+ printk("$28: %016Lx %016Lx %016Lx %016Lx\n",
+ regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
+
+ /*
+ * Saved cp0 registers
+ */
+ printk("epc : %016Lx\nStatus: %08x\nCause : %08x\n",
+ regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
+}
diff --git a/arch/mips/mips4/Makefile b/arch/mips/mips4/Makefile
new file mode 100644
index 000000000..d5827861b
--- /dev/null
+++ b/arch/mips/mips4/Makefile
@@ -0,0 +1,21 @@
+#
+# Makefile for the MIPS IV specific parts of the Linux/MIPS kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+all: mips.o
+EXTRA_ASFLAGS = -mips4 -mcpu=r8000
+O_TARGET := mips.o
+O_OBJS := cpu.o pagetables.o showregs.o
+
+clean:
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips/mips4/README b/arch/mips/mips4/README
new file mode 100644
index 000000000..22e90921b
--- /dev/null
+++ b/arch/mips/mips4/README
@@ -0,0 +1,3 @@
+This directory contains the start of the R8000/R10000 specific part. I
+tried to support this CPU as good as possible without a machine and
+without detailed documentation.
diff --git a/arch/mips/mips4/cpu.c b/arch/mips/mips4/cpu.c
new file mode 100644
index 000000000..ef5a3f8db
--- /dev/null
+++ b/arch/mips/mips4/cpu.c
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 1996 Ralf Baechle
+ */
+#include <linux/sched.h>
+
+#include <asm/cache.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+
+extern asmlinkage void mips4_cacheflush(void *addr, int nbytes, unsigned int flags);
+
+unsigned long page_colour_mask;
+
+void (*mips_cache_init)(void);
+
+static void
+mips4_cache_init(void)
+{
+ /*
+ * The R10000 is in most aspects similar to the R4400. It
+ * should get some special optimizations.
+ */
+ write_32bit_cp0_register(CP0_FRAMEMASK, 0);
+ set_cp0_status(ST0_XX, ST0_XX);
+ /*
+ * Actually this mask stands for only 16k cache. This is
+ * correct since the R10000 has multiple ways in it's cache.
+ */
+ page_colour_mask = 0x3000;
+ cacheflush = mips4_cacheflush;
+ /*
+ * The R10k might even work for Linux/MIPS - but we're paranoid
+ * and refuse to run until this is tested on real silicon
+ */
+ panic("CPU too expensive - making holiday in the ANDES!");
+}
+
+void (*switch_to_user_mode)(struct pt_regs *regs);
+
+static void
+mips4_switch_to_user_mode(struct pt_regs *regs)
+{
+ regs->cp0_status = (regs->cp0_status & ~(ST0_CU0|ST0_KSU)) | KSU_USER;
+}
+
+unsigned long (*thread_saved_pc)(struct thread_struct *t);
+
+/*
+ * Return saved PC of a blocked thread.
+ * XXX This works only for 64 bit kernels.
+ */
+static unsigned long mips4_thread_saved_pc(struct thread_struct *t)
+{
+ return ((unsigned long long *)(unsigned long)t->reg29)[11];
+}
+
+unsigned long (*get_wchan)(struct task_struct *p);
+
+static unsigned long mips4_get_wchan(struct task_struct *p)
+{
+ /*
+ * This one depends on the frame size of schedule(). Do a
+ * "disass schedule" in gdb to find the frame size. Also, the
+ * code assumes that sleep_on() follows immediately after
+ * interruptible_sleep_on() and that add_timer() follows
+ * immediately after interruptible_sleep(). Ugly, isn't it?
+ * Maybe adding a wchan field to task_struct would be better,
+ * after all...
+ */
+ unsigned long schedule_frame;
+ unsigned long pc;
+
+ pc = thread_saved_pc(&p->tss);
+ if (pc >= (unsigned long) interruptible_sleep_on && pc < (unsigned long) add_timer) {
+ schedule_frame = ((unsigned long long *)(long)p->tss.reg30)[10];
+ return (unsigned long)((unsigned long long *)schedule_frame)[9];
+ }
+ return pc;
+}
+
+extern void mips4_clear_page(unsigned long page);
+extern void mips4_copy_page(unsigned long to, unsigned long from);
+asmlinkage void (*restore_fp_context)(struct sigcontext *sc);
+asmlinkage void (*save_fp_context)(struct sigcontext *sc);
+
+void
+mips4_cpu_init(void)
+{
+ extern void mips4_pgd_init(unsigned long page);
+ extern asmlinkage void mips4_restore_fp_context(struct sigcontext *sc);
+ extern asmlinkage void mips4_save_fp_context(struct sigcontext *sc);
+
+ mips_cache_init = mips4_cache_init;
+ pgd_init = mips1_pgd_init;
+ switch_to_user_mode = mips4_switch_to_user_mode;
+ thread_saved_pc = mips4_thread_saved_pc;
+ get_wchan = mips4_get_wchan;
+ clear_page = mips4_clear_page;
+ restore_fp_context = mips4_restore_fp_context;
+ save_fp_context = mips4_save_fp_context;
+}
diff --git a/arch/mips/mips4/pagetables.c b/arch/mips/mips4/pagetables.c
new file mode 100644
index 000000000..b1b86290a
--- /dev/null
+++ b/arch/mips/mips4/pagetables.c
@@ -0,0 +1,122 @@
+/*
+ * 64 bit MIPS specific page handling.
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 Ralf Baechle
+ */
+#include <linux/mm.h>
+#include <asm/cache.h>
+#include <asm/mipsconfig.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+void (*pgd_init)(unsigned long page);
+
+/*
+ * Initialize new page directory with pointers to invalid ptes
+ */
+void mips4_pgd_init(unsigned long page)
+{
+ unsigned long dummy1, dummy2;
+
+ /*
+ * We generate dirty lines in the datacache, overwrite these lines
+ * with zeros and then flush the cache. Sounds horribly complicated
+ * but is just a trick to avoid unnecessary loads of from memory
+ * and uncached stores which are very expensive.
+ * FIXME: This is the same like the R4000 version. We could do some
+ * R10000 trickery using caching mode "uncached accelerated".
+ */
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ ".set\tmips3\n\t"
+ "dsll32\t$1,%2,0\n\t"
+ "dsrl32\t%2,$1,0\n\t"
+ "or\t%2,$1\n"
+ "1:\t"
+ "cache\t%5,(%0)\n\t"
+ "sd\t%2,(%0)\n\t"
+ "sd\t%2,8(%0)\n\t"
+ "cache\t%5,16(%0)\n\t"
+ "sd\t%2,16(%0)\n\t"
+ "sd\t%2,24(%0)\n\t"
+ "cache\t%5,32(%0)\n\t"
+ "sd\t%2,32(%0)\n\t"
+ "sd\t%2,40(%0)\n\t"
+ "cache\t%5,48(%0)\n\t"
+ "sd\t%2,48(%0)\n\t"
+ "sd\t%2,56(%0)\n\t"
+ "subu\t%1,1\n\t"
+ "bnez\t%1,1b\n\t"
+ "addiu\t%0,64\n\t"
+ ".set\tmips0\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :"=&r" (dummy1),
+ "=&r" (dummy2)
+ :"r" (((unsigned long) invalid_pte_table - PAGE_OFFSET) |
+ _PAGE_TABLE),
+ "0" (page),
+ "1" (PAGE_SIZE/(sizeof(pmd_t)*16)),
+ "i" (Create_Dirty_Excl_D)
+ :"$1");
+ /*
+ * Now force writeback to ashure values are in the RAM.
+ */
+ cacheflush(page, PAGE_SIZE, CF_DCACHE|CF_VIRTUAL);
+}
+
+void (*clear_page)(unsigned long page);
+
+/*
+ * To do: cache magic
+ */
+void mips4_clear_page(unsigned long page)
+{
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ "daddiu\t$1,%0,%2\n"
+ "1:\tsd\t$0,(%0)\n\t"
+ "sd\t$0,8(%0)\n\t"
+ "sd\t$0,16(%0)\n\t"
+ "sd\t$0,24(%0)\n\t"
+ "daddiu\t%0,64\n\t"
+ "sd\t$0,-32(%0)\n\t"
+ "sd\t$0,-24(%0)\n\t"
+ "sd\t$0,-16(%0)\n\t"
+ "bne\t$1,%0,1b\n\t"
+ "sd\t$0,-8(%0)\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :"=r" (page)
+ :"0" (page),
+ "I" (PAGE_SIZE)
+ :"$1","memory");
+}
+
+void (*copy_page)(unsigned long to, unsigned long from);
+
+/*
+ * This is horribly inefficient ...
+ */
+void mips4_copy_page(unsigned long to, unsigned long from)
+{
+ /*
+ * Force writeback of old page to memory. We don't know the
+ * virtual address, so we have to flush the entire cache ...
+ */
+ cacheflush(0, ~0, CF_DCACHE|CF_VIRTUAL);
+ sync_mem();
+ memcpy((void *) to,
+ (void *) (from + (PT_OFFSET - PAGE_OFFSET)), PAGE_SIZE);
+ /*
+ * Now writeback the page again if colour has changed.
+ */
+ if (page_colour(from) != page_colour(to))
+ cacheflush(0, ~0, CF_DCACHE|CF_VIRTUAL);
+}
diff --git a/arch/mips/mkdisk b/arch/mips/mkdisk
deleted file mode 100644
index 468d34727..000000000
--- a/arch/mips/mkdisk
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-cp vmlinux vmlinux.tmp
-mipsel-linux-strip -g -x vmlinux.tmp
-mwrite -n vmlinux.tmp a:vmlinux
-rm -f vmlinux.tmp
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index 6ff21fafd..6f69a0ee6 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -1,5 +1,5 @@
#
-# Makefile for the linux mips-specific parts of the memory manager.
+# Makefile for the Linux/MIPS-specific parts of the memory manager.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
@@ -7,26 +7,7 @@
#
# Note 2! The CFLAGS definition is now in the main makefile...
-.c.o:
- $(CC) $(CFLAGS) -c $<
-.s.o:
- $(AS) -o $*.o $<
-.c.s:
- $(CC) $(CFLAGS) -S $<
+O_TARGET := mm.o
+O_OBJS := extable.o init.o fault.o stack.o
-OBJS = fault.o init.o
-
-mm.o: $(OBJS)
- $(LD) -r -o mm.o $(OBJS)
-
-modules:
-
-dep:
- $(CPP) -M *.c > .depend
-
-#
-# include a dependency file if one exists
-#
-ifeq (.depend,$(wildcard .depend))
-include .depend
-endif
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips/mm/extable.c b/arch/mips/mm/extable.c
new file mode 100644
index 000000000..c46568ab1
--- /dev/null
+++ b/arch/mips/mm/extable.c
@@ -0,0 +1,57 @@
+/*
+ * linux/arch/mips/mm/extable.c
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+extern const struct exception_table_entry __start___ex_table[];
+extern const struct exception_table_entry __stop___ex_table[];
+
+static inline unsigned
+search_one_table(const struct exception_table_entry *first,
+ const struct exception_table_entry *last,
+ unsigned long value)
+{
+ while (first <= last) {
+ const struct exception_table_entry *mid;
+ long diff;
+
+ mid = (last - first) / 2 + first;
+ diff = mid->insn - value;
+ if (diff == 0)
+ return mid->nextinsn;
+ else if (diff < 0)
+ first = mid+1;
+ else
+ last = mid-1;
+ }
+ return 0;
+}
+
+unsigned long search_exception_table(unsigned long addr)
+{
+ unsigned ret;
+#ifdef CONFIG_MODULES
+ struct module *mp;
+#endif
+
+ /* Search the kernel's table first. */
+ ret = search_one_table(__start___ex_table,
+ __stop___ex_table-1, addr);
+ if (ret)
+ return ret;
+
+#ifdef CONFIG_MODULES
+ for (mp = module_list; mp != NULL; mp = mp->next) {
+ if (mp->exceptinfo.start != NULL) {
+ ret = search_one_table(mp->exceptinfo.start,
+ mp->exceptinfo.stop-1, addr);
+ if (ret)
+ return ret;
+ }
+ }
+#endif
+
+ return 0;
+}
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 9256025d9..f1462eff9 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -1,10 +1,8 @@
/*
* arch/mips/mm/fault.c
*
- * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
- * Ported to MIPS by Ralf Baechle
+ * Copyright (C) 1995, 1996 by Ralf Baechle
*/
-#include <linux/config.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/head.h>
@@ -16,45 +14,47 @@
#include <linux/mman.h>
#include <linux/mm.h>
+#include <asm/cache.h>
#include <asm/system.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <asm/pgtable.h>
extern void die_if_kernel(char *, struct pt_regs *, long);
/*
+ * Macro for exception fixup code to access integer registers.
+ */
+#define dpf_reg(r) (regs->regs[r])
+
+/*
* This routine handles page faults. It determines the address,
* and the problem, and then passes it off to one of the appropriate
* routines.
*/
asmlinkage void
-do_page_fault(struct pt_regs *regs, unsigned long writeaccess)
+do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
+ unsigned long address)
{
struct vm_area_struct * vma;
- unsigned long address;
-
- /* get the address */
- __asm__(".set\tmips3\n\t"
- "dmfc0\t%0,$8\n\t"
- ".set\tmips0"
- : "=r" (address));
+ struct task_struct *tsk = current;
+ struct mm_struct *mm = tsk->mm;
+ unsigned long fixup;
#if 0
- printk("do_page_fault() #1: %s %08lx (epc == %08lx)\n",
+ printk("do_page_fault() #1: %s %08lx (epc == %08lx, ra == %08lx)\n",
writeaccess ? "writeaccess to" : "readaccess from",
- address, regs->cp0_epc);
+ address, regs->cp0_epc, regs->regs[31]);
#endif
- vma = find_vma(current, address);
+ down(&mm->mmap_sem);
+ vma = find_vma(mm, address);
if (!vma)
goto bad_area;
if (vma->vm_start <= address)
goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
- if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur)
+ if (expand_stack(vma, address))
goto bad_area;
- vma->vm_offset -= vma->vm_start - (address & PAGE_MASK);
- vma->vm_start = (address & PAGE_MASK);
/*
* Ok, we have a good vm_area for this memory access, so
* we can handle it..
@@ -68,6 +68,8 @@ good_area:
goto bad_area;
}
handle_mm_fault(vma, address, writeaccess);
+ up(&mm->mmap_sem);
+
return;
/*
@@ -75,18 +77,43 @@ good_area:
* Fix it, but check if it's kernel or user first..
*/
bad_area:
+ up(&mm->mmap_sem);
+ /* Did we have an exception handler installed? */
+
+ fixup = search_exception_table(regs->cp0_epc);
+ if (fixup) {
+ long new_epc;
+ new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
+ printk("Taking exception at %lx (%lx)\n",
+ regs->cp0_epc, new_epc);
+ regs->cp0_epc = new_epc;
+ return;
+ }
if (user_mode(regs)) {
- current->tss.cp0_badvaddr = address;
- current->tss.error_code = writeaccess;
- send_sig(SIGSEGV, current, 1);
+ tsk->tss.cp0_badvaddr = address;
+ tsk->tss.error_code = writeaccess;
+#if 1
+ printk("do_page_fault() #2: sending SIGSEGV to %s for illegal %s\n"
+ "%08lx (epc == %08lx, ra == %08lx)\n",
+ tsk->comm,
+ writeaccess ? "writeaccess to" : "readaccess from",
+ address,
+ (unsigned long) regs->cp0_epc,
+ (unsigned long) regs->regs[31]);
+#endif
+ force_sig(SIGSEGV, tsk);
return;
}
/*
* Oops. The kernel tried to access some bad page. We'll have to
* terminate things with extreme prejudice.
*/
- printk(KERN_ALERT "Unable to handle kernel paging request at virtual address %08lx",
- address);
+ printk(KERN_ALERT "Unable to handle kernel paging request at virtual "
+#ifdef __mips64
+ "address %08lx, epc == %08Lx\n", address, regs->cp0_epc);
+#else
+ "address %08lx, epc == %016lx\n", address, regs->cp0_epc);
+#endif
die_if_kernel("Oops", regs, writeaccess);
do_exit(SIGKILL);
}
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 37912e2d0..149349102 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -15,26 +15,29 @@
#include <linux/ptrace.h>
#include <linux/mman.h>
#include <linux/mm.h>
+#include <linux/swap.h>
+#ifdef CONFIG_BLK_DEV_INITRD
+#include <linux/blk.h>
+#endif
-#include <asm/cachectl.h>
+#include <asm/bootinfo.h>
+#include <asm/cache.h>
+#include <asm/dma.h>
+#include <asm/jazzdma.h>
#include <asm/vector.h>
#include <asm/system.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <asm/pgtable.h>
+#include <asm/page.h>
extern void deskstation_tyne_dma_init(void);
-extern void scsi_mem_init(unsigned long);
-extern void sound_mem_init(void);
-extern void die_if_kernel(char *,struct pt_regs *,long);
extern void show_net_buffers(void);
-extern char empty_zero_page[PAGE_SIZE];
-
/*
* BAD_PAGE is the page that is used for page faults when linux
* is out-of-memory. Older versions of linux just did a
* do_exit(), but using this instead means there is less risk
- * for a process dying in kernel mode, possibly leaving a inode
+ * for a process dying in kernel mode, possibly leaving an inode
* unused etc..
*
* BAD_PAGETABLE is the accompanying page-table: it is initialized
@@ -48,9 +51,18 @@ pte_t * __bad_pagetable(void)
extern char empty_bad_page_table[PAGE_SIZE];
unsigned long page;
unsigned long dummy1, dummy2;
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
+ unsigned long dummy3;
+#endif
- page = ((unsigned long)empty_bad_page_table) + (PT_OFFSET - PAGE_OFFSET);
-#ifdef __R4000__
+ page = (unsigned long) empty_bad_page_table;
+ page = page_to_ptp(page);
+ /*
+ * As long as we only save the low 32 bit of the 64 bit wide
+ * R4000 registers on interrupt we cannot use 64 bit memory accesses
+ * to the main memory.
+ */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
/*
* Use 64bit code even for Linux/MIPS 32bit on R4000
*/
@@ -69,11 +81,12 @@ pte_t * __bad_pagetable(void)
".set\tat\n"
".set\treorder"
:"=r" (dummy1),
- "=r" (dummy2)
- :"r" (pte_val(BAD_PAGE)),
- "0" (page),
- "1" (PAGE_SIZE/8));
-#else
+ "=r" (dummy2),
+ "=r" (dummy3)
+ :"0" (page),
+ "1" (PAGE_SIZE/8),
+ "2" (pte_val(BAD_PAGE)));
+#else /* (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) */
__asm__ __volatile__(
".set\tnoreorder\n"
"1:\tsw\t%2,(%0)\n\t"
@@ -91,128 +104,37 @@ pte_t * __bad_pagetable(void)
return (pte_t *)page;
}
-static inline void
-__zeropage(unsigned long page)
-{
- unsigned long dummy1, dummy2;
-
-#ifdef __R4000__
- /*
- * Use 64bit code even for Linux/MIPS 32bit on R4000
- */
- __asm__ __volatile__(
- ".set\tnoreorder\n"
- ".set\tnoat\n\t"
- ".set\tmips3\n"
- "1:\tsd\t$0,(%0)\n\t"
- "subu\t%1,1\n\t"
- "bnez\t%1,1b\n\t"
- "addiu\t%0,8\n\t"
- ".set\tmips0\n\t"
- ".set\tat\n"
- ".set\treorder"
- :"=r" (dummy1),
- "=r" (dummy2)
- :"0" (page),
- "1" (PAGE_SIZE/8));
-#else
- __asm__ __volatile__(
- ".set\tnoreorder\n"
- "1:\tsw\t$0,(%0)\n\t"
- "subu\t%1,1\n\t"
- "bnez\t%1,1b\n\t"
- "addiu\t%0,4\n\t"
- ".set\treorder"
- :"=r" (dummy1),
- "=r" (dummy2)
- :"0" (page),
- "1" (PAGE_SIZE/4));
-#endif
-}
-
-static inline void
-zeropage(unsigned long page)
-{
- sys_cacheflush((void *)page, PAGE_SIZE, BCACHE);
- sync_mem();
- __zeropage(page + (PT_OFFSET - PAGE_OFFSET));
-}
-
pte_t __bad_page(void)
{
extern char empty_bad_page[PAGE_SIZE];
unsigned long page = (unsigned long)empty_bad_page;
- zeropage(page);
+ clear_page(page_to_ptp(page));
+ cacheflush(page, PAGE_SIZE, CF_DCACHE|CF_VIRTUAL);
return pte_mkdirty(mk_pte(page, PAGE_SHARED));
}
-unsigned long __zero_page(void)
-{
- unsigned long page = (unsigned long) empty_zero_page;
-
- zeropage(page);
- return page;
-}
-
-/*
- * This is horribly inefficient ...
- */
-void __copy_page(unsigned long from, unsigned long to)
-{
- /*
- * Now copy page from uncached KSEG1 to KSEG0. The copy destination
- * is in KSEG0 so that we keep stupid L2 caches happy.
- */
- if(from == (unsigned long) empty_zero_page)
- {
- /*
- * The page copied most is the COW empty_zero_page. Since we
- * know it's contents we can avoid the writeback reading of
- * the page. Speeds up the standard case alot.
- */
- __zeropage(to);
- }
- else
- {
- /*
- * Force writeback of old page to memory. We don't know the
- * virtual address, so we have to flush the entire cache ...
- */
- sys_cacheflush(0, ~0, DCACHE);
- sync_mem();
- memcpy((void *) to,
- (void *) (from + (PT_OFFSET - PAGE_OFFSET)), PAGE_SIZE);
- }
- /*
- * Now writeback the page again if colour has changed.
- * Actually this does a Hit_Writeback, but due to an artifact in
- * the R4xx0 implementation this should be slightly faster.
- * Then sweep chipset controlled secondary caches and the ICACHE.
- */
- if (page_colour(from) != page_colour(to))
- sys_cacheflush(0, ~0, DCACHE);
- sys_cacheflush(0, ~0, ICACHE);
-}
-
void show_mem(void)
{
- int i,free = 0,total = 0;
+ int i, free = 0, total = 0, reserved = 0;
int shared = 0;
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
- i = (high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
+ i = max_mapnr;
while (i-- > 0) {
total++;
- if (!mem_map[i])
+ if (PageReserved(mem_map+i))
+ reserved++;
+ else if (!mem_map[i].count)
free++;
else
- shared += mem_map[i]-1;
+ shared += mem_map[i].count-1;
}
printk("%d pages of RAM\n", total);
printk("%d free pages\n", free);
+ printk("%d reserved pages\n", reserved);
printk("%d pages shared\n", shared);
show_buffers();
#ifdef CONFIG_NET
@@ -224,6 +146,7 @@ extern unsigned long free_area_init(unsigned long, unsigned long);
unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
{
+ mips_cache_init();
pgd_init((unsigned long)swapper_pg_dir - (PT_OFFSET - PAGE_OFFSET));
return free_area_init(start_mem, end_mem);
}
@@ -235,41 +158,65 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
unsigned long tmp;
extern int _etext;
+#ifdef CONFIG_MIPS_JAZZ
+ if (mips_machgroup == MACH_GROUP_JAZZ)
+ start_mem = vdma_init(start_mem, end_mem);
+#endif
+
end_mem &= PAGE_MASK;
- high_memory = end_mem;
+ max_mapnr = MAP_NR(end_mem);
+ high_memory = (void *)end_mem;
+
+ /* clear the zero-page */
+ memset(empty_zero_page, 0, PAGE_SIZE);
/* mark usable pages in the mem_map[] */
start_mem = PAGE_ALIGN(start_mem);
- tmp = start_mem;
- while (tmp < high_memory) {
- mem_map[MAP_NR(tmp)] = 0;
- tmp += PAGE_SIZE;
- }
+ for(tmp = MAP_NR(start_mem);tmp < max_mapnr;tmp++)
+ clear_bit(PG_reserved, &mem_map[tmp].flags);
+
+ /*
+ * For rPC44 we've reserved some memory too much. Free the memory
+ * from PAGE_SIZE to PAGE_OFFSET + 0xa0000 again. We don't free the
+ * lowest page where the exception handlers will reside.
+ */
+ if (mips_machgroup == MACH_GROUP_ARC &&
+ mips_machtype == MACH_DESKSTATION_RPC44)
+ for(tmp = MAP_NR(PAGE_OFFSET + PAGE_SIZE);
+ tmp < MAP_NR(PAGE_OFFSET + 0xa000); tmp++)
+ clear_bit(PG_reserved, &mem_map[tmp].flags);
+
#ifdef CONFIG_DESKSTATION_TYNE
- deskstation_tyne_dma_init();
-#endif
-#ifdef CONFIG_SCSI
- scsi_mem_init(high_memory);
+ if (mips_machtype == MACH_DESKSTATION_TYNE)
+ deskstation_tyne_dma_init();
#endif
-#ifdef CONFIG_SOUND
- sound_mem_init();
-#endif
- for (tmp = PAGE_OFFSET ; tmp < high_memory ; tmp += PAGE_SIZE) {
- if (mem_map[MAP_NR(tmp)]) {
+ for (tmp = PAGE_OFFSET; tmp < end_mem; tmp += PAGE_SIZE) {
+ /*
+ * This is only for PC-style DMA. The onboard DMA
+ * of Jazz and Tyne machines is completly different and
+ * not handled via a flag in mem_map_t.
+ */
+ if (tmp >= MAX_DMA_ADDRESS)
+ clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
+ if (PageReserved(mem_map+MAP_NR(tmp))) {
if (tmp < (unsigned long) &_etext)
codepages++;
else if (tmp < start_mem)
datapages++;
continue;
}
- mem_map[MAP_NR(tmp)] = 1;
- free_page(tmp);
+ mem_map[MAP_NR(tmp)].count = 1;
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (!initrd_start || (tmp < initrd_start || tmp >=
+ initrd_end))
+#endif
+ free_page(tmp);
}
tmp = nr_free_pages << PAGE_SHIFT;
printk("Memory: %luk/%luk available (%dk kernel code, %dk data)\n",
tmp >> 10,
- (high_memory - PAGE_OFFSET) >> 10,
+ max_mapnr << (PAGE_SHIFT-10),
codepages << (PAGE_SHIFT-10),
datapages << (PAGE_SHIFT-10));
@@ -280,18 +227,18 @@ void si_meminfo(struct sysinfo *val)
{
int i;
- i = high_memory >> PAGE_SHIFT;
+ i = MAP_NR(high_memory);
val->totalram = 0;
val->sharedram = 0;
val->freeram = nr_free_pages << PAGE_SHIFT;
val->bufferram = buffermem;
while (i-- > 0) {
- if (mem_map[i] & MAP_PAGE_RESERVED)
+ if (PageReserved(mem_map+i))
continue;
val->totalram++;
- if (!mem_map[i])
+ if (!mem_map[i].count)
continue;
- val->sharedram += mem_map[i]-1;
+ val->sharedram += mem_map[i].count-1;
}
val->totalram <<= PAGE_SHIFT;
val->sharedram <<= PAGE_SHIFT;
diff --git a/arch/mips/mm/stack.c b/arch/mips/mm/stack.c
new file mode 100644
index 000000000..3a4dccd26
--- /dev/null
+++ b/arch/mips/mm/stack.c
@@ -0,0 +1,26 @@
+/*
+ * Kernel stack allocation/deallocation
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ *
+ * (This is _bad_ if the free page pool is fragmented ...)
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+extern unsigned long alloc_kernel_stack(void)
+{
+ unsigned long stack;
+ stack = __get_free_pages(GFP_KERNEL, 1, 0);
+
+ return stack;
+}
+
+extern void free_kernel_stack(unsigned long stack)
+{
+ free_pages(stack, 1);
+}
diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile
new file mode 100644
index 000000000..bfa8e2cad
--- /dev/null
+++ b/arch/mips/sni/Makefile
@@ -0,0 +1,28 @@
+#
+# Makefile for the SNI specific part of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+include ../../../.config
+
+all: sni.o
+O_TARGET := sni.o
+O_OBJS := hw-access.o int-handler.o reset.o setup.o
+
+ifdef CONFIG_PCI
+O_OBJS += bios32.o
+endif
+
+int-handler.o: int-handler.S
+
+clean:
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips/sni/bios32.c b/arch/mips/sni/bios32.c
new file mode 100644
index 000000000..366347902
--- /dev/null
+++ b/arch/mips/sni/bios32.c
@@ -0,0 +1,264 @@
+/*
+ * bios32.c - Fake PCI BIOS functions for RM200 C systems. Chainsawed
+ * from the Alpha version.
+ *
+ * Written by Ralf Baechle (ralf@gnu.ai.mit.edu)
+ *
+ * For more information, please consult
+ *
+ * PCI BIOS Specification Revision
+ * PCI Local Bus Specification
+ * PCI System Design Guide
+ *
+ * PCI Special Interest Group
+ * M/S HF3-15A
+ * 5200 N.E. Elam Young Parkway
+ * Hillsboro, Oregon 97124-6497
+ * +1 (503) 696-2000
+ * +1 (800) 433-5177
+ *
+ * Manuals are $25 each or $50 for all three, plus $7 shipping
+ * within the United States, $35 abroad.
+ */
+#include <linux/config.h>
+
+#include <linux/kernel.h>
+#include <linux/bios32.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/malloc.h>
+#include <linux/mm.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+/*
+ * This is a table of the onboard PCI devices of the RM200 C
+ * onboard devices.
+ */
+static struct board {
+ unsigned short vendor;
+ unsigned short device_id;
+ unsigned int memory;
+ unsigned int io;
+ unsigned char irq;
+ unsigned char revision;
+ } boards[] = {
+ {
+ PCI_VENDOR_ID_NCR,
+ PCI_DEVICE_ID_NCR_53C810,
+ 0x1b000000,
+ 0x00000000,
+ 5,
+ 0x11
+ },
+ {
+ PCI_VENDOR_ID_AMD,
+ PCI_DEVICE_ID_AMD_LANCE,
+ 0x1b000100,
+ 0x17beffe0,
+ 6,
+ 0x16
+ },
+ {
+ PCI_VENDOR_ID_CIRRUS,
+ PCI_DEVICE_ID_CIRRUS_5434_8,
+ 0x18000000,
+ 0x00000000,
+ 4,
+ 0x8e
+ },
+ { 0xffff, }
+};
+
+/*
+ * Given the vendor and device ids, find the n'th instance of that device
+ * in the system.
+ */
+int pcibios_find_device (unsigned short vendor, unsigned short device_id,
+ unsigned short index, unsigned char *bus,
+ unsigned char *devfn)
+{
+ unsigned int curr = 0;
+ struct board *p;
+
+ for (p = pci_devices; p->vendor != 0xffff; p++) {
+ if (p->vendor == vendor && p->device == device_id) {
+ if (curr == index) {
+ *devfn = p->devfn;
+ *bus = 0;
+ return PCIBIOS_SUCCESSFUL;
+ }
+ ++curr;
+ }
+ }
+
+ return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+/*
+ * Given the class, find the n'th instance of that device
+ * in the system.
+ */
+int pcibios_find_class (unsigned int class_code, unsigned short index,
+ unsigned char *bus, unsigned char *devfn)
+{
+ unsigned int curr = 0;
+ struct pci_dev *dev;
+
+ for (dev = pci_devices; dev; dev = dev->next) {
+ if (dev->class == class_code) {
+ if (curr == index) {
+ *devfn = dev->devfn;
+ *bus = dev->bus->number;
+ return PCIBIOS_SUCCESSFUL;
+ }
+ ++curr;
+ }
+ }
+ return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+int pcibios_present(void)
+{
+ return 1;
+}
+
+unsigned long pcibios_init(unsigned long mem_start,
+ unsigned long mem_end)
+{
+ printk("SNI RM200 C BIOS32 fake implementation\n");
+
+ return mem_start;
+}
+
+const char *pcibios_strerror (int error)
+{
+ static char buf[80];
+
+ switch (error) {
+ case PCIBIOS_SUCCESSFUL:
+ return "SUCCESSFUL";
+
+ case PCIBIOS_FUNC_NOT_SUPPORTED:
+ return "FUNC_NOT_SUPPORTED";
+
+ case PCIBIOS_BAD_VENDOR_ID:
+ return "SUCCESSFUL";
+
+ case PCIBIOS_DEVICE_NOT_FOUND:
+ return "DEVICE_NOT_FOUND";
+
+ case PCIBIOS_BAD_REGISTER_NUMBER:
+ return "BAD_REGISTER_NUMBER";
+
+ default:
+ sprintf (buf, "UNKNOWN RETURN 0x%x", error);
+ return buf;
+ }
+}
+
+/*
+ * BIOS32-style PCI interface:
+ */
+
+int pcibios_read_config_byte (unsigned char bus, unsigned char device_fn,
+ unsigned char where, unsigned char *value)
+{
+ unsigned long addr = LCA_CONF;
+ unsigned long pci_addr;
+
+ *value = 0xff;
+
+ if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) {
+ return PCIBIOS_SUCCESSFUL;
+ }
+ addr |= (pci_addr << 5) + 0x00;
+ *value = conf_read(addr) >> ((where & 3) * 8);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+int pcibios_read_config_word (unsigned char bus, unsigned char device_fn,
+ unsigned char where, unsigned short *value)
+{
+ unsigned long addr = LCA_CONF;
+ unsigned long pci_addr;
+
+ *value = 0xffff;
+
+ if (where & 0x1) {
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ }
+ if (mk_conf_addr(bus, device_fn, where, &pci_addr)) {
+ return PCIBIOS_SUCCESSFUL;
+ }
+ addr |= (pci_addr << 5) + 0x08;
+ *value = conf_read(addr) >> ((where & 3) * 8);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+int pcibios_read_config_dword (unsigned char bus, unsigned char device_fn,
+ unsigned char where, unsigned int *value)
+{
+ unsigned long addr = LCA_CONF;
+ unsigned long pci_addr;
+
+ *value = 0xffffffff;
+ if (where & 0x3) {
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ }
+ if (mk_conf_addr(bus, device_fn, where, &pci_addr)) {
+ return PCIBIOS_SUCCESSFUL;
+ }
+ addr |= (pci_addr << 5) + 0x18;
+ *value = conf_read(addr);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+int pcibios_write_config_byte (unsigned char bus, unsigned char device_fn,
+ unsigned char where, unsigned char value)
+{
+ unsigned long addr = LCA_CONF;
+ unsigned long pci_addr;
+
+ if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) {
+ return PCIBIOS_SUCCESSFUL;
+ }
+ addr |= (pci_addr << 5) + 0x00;
+ conf_write(addr, value << ((where & 3) * 8));
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+int pcibios_write_config_word (unsigned char bus, unsigned char device_fn,
+ unsigned char where, unsigned short value)
+{
+ unsigned long addr = LCA_CONF;
+ unsigned long pci_addr;
+
+ if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) {
+ return PCIBIOS_SUCCESSFUL;
+ }
+ addr |= (pci_addr << 5) + 0x08;
+ conf_write(addr, value << ((where & 3) * 8));
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+int pcibios_write_config_dword (unsigned char bus, unsigned char device_fn,
+ unsigned char where, unsigned int value)
+{
+ unsigned long addr = LCA_CONF;
+ unsigned long pci_addr;
+
+ if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) {
+ return PCIBIOS_SUCCESSFUL;
+ }
+ addr |= (pci_addr << 5) + 0x18;
+ conf_write(addr, value << ((where & 3) * 8));
+ return PCIBIOS_SUCCESSFUL;
+}
diff --git a/arch/mips/sni/hw-access.c b/arch/mips/sni/hw-access.c
new file mode 100644
index 000000000..42c69590a
--- /dev/null
+++ b/arch/mips/sni/hw-access.c
@@ -0,0 +1,157 @@
+/*
+ * Low-level hardware access stuff for SNI RM200 PCI
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ */
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <asm/bootinfo.h>
+#include <asm/cache.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mc146818rtc.h>
+#include <asm/vector.h>
+
+extern int FLOPPY_IRQ;
+extern int FLOPPY_DMA;
+
+/*
+ * How to access the FDC's registers.
+ */
+static unsigned char
+fd_inb(unsigned int port)
+{
+ return inb_p(port);
+}
+
+static void
+fd_outb(unsigned char value, unsigned int port)
+{
+ outb_p(value, port);
+}
+
+/*
+ * How to access the floppy DMA functions.
+ */
+static void
+fd_enable_dma(void)
+{
+ enable_dma(FLOPPY_DMA);
+}
+
+static void
+fd_disable_dma(void)
+{
+ disable_dma(FLOPPY_DMA);
+}
+
+static int
+fd_request_dma(void)
+{
+ return request_dma(FLOPPY_DMA, "floppy");
+}
+
+static void
+fd_free_dma(void)
+{
+ free_dma(FLOPPY_DMA);
+}
+
+static void
+fd_clear_dma_ff(void)
+{
+ clear_dma_ff(FLOPPY_DMA);
+}
+
+static void
+fd_set_dma_mode(char mode)
+{
+ set_dma_mode(FLOPPY_DMA, mode);
+}
+
+static void
+fd_set_dma_addr(unsigned int addr)
+{
+ set_dma_addr(FLOPPY_DMA, addr);
+}
+
+static void
+fd_set_dma_count(unsigned int count)
+{
+ set_dma_count(FLOPPY_DMA, count);
+}
+
+static int
+fd_get_dma_residue(void)
+{
+ return get_dma_residue(FLOPPY_DMA);
+}
+
+static void
+fd_enable_irq(void)
+{
+ enable_irq(FLOPPY_IRQ);
+}
+
+static void
+fd_disable_irq(void)
+{
+ disable_irq(FLOPPY_IRQ);
+}
+
+void
+sni_fd_cacheflush(const void *addr, size_t size)
+{
+ cacheflush((unsigned long)addr, (unsigned long)size, CF_DCACHE|CF_ALL);
+}
+
+/*
+ * RTC stuff (This is a guess on how the RM handles this ...)
+ */
+static unsigned char
+rtc_read_data(unsigned long addr)
+{
+ outb_p(addr, RTC_PORT(0));
+ return inb_p(RTC_PORT(1));
+}
+
+static void
+rtc_write_data(unsigned char data, unsigned long addr)
+{
+ outb_p(addr, RTC_PORT(0));
+ outb_p(data, RTC_PORT(1));
+}
+
+struct feature sni_rm200_pci_feature = {
+ /*
+ * How to access the floppy controller's ports
+ */
+ fd_inb,
+ fd_outb,
+ /*
+ * How to access the floppy DMA functions.
+ */
+ fd_enable_dma,
+ fd_disable_dma,
+ fd_request_dma,
+ fd_free_dma,
+ fd_clear_dma_ff,
+ fd_set_dma_mode,
+ fd_set_dma_addr,
+ fd_set_dma_count,
+ fd_get_dma_residue,
+ fd_enable_irq,
+ fd_disable_irq,
+ /*
+ * How to access the RTC functions.
+ */
+ rtc_read_data,
+ rtc_write_data
+};
diff --git a/arch/mips/sni/int-handler.S b/arch/mips/sni/int-handler.S
new file mode 100644
index 000000000..367c07d84
--- /dev/null
+++ b/arch/mips/sni/int-handler.S
@@ -0,0 +1,193 @@
+/*
+ * SNI RM200 PCI specific interrupt handler code.
+ *
+ * Copyright (C) 1994, 1995, 1996 by Ralf Baechle
+ *
+ * This is a verbose copy of the Tyne/rPC44 interrupt handler. We
+ * don't share the code because the SNI machine has some extra interrupt
+ * features that want to be supported.
+ */
+#include <asm/asm.h>
+#include <linux/config.h>
+#include <asm/mipsconfig.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+ .text
+ .set noreorder
+ .set noat
+ .align 5
+ NESTED(sni_rm200_pci_handle_int, FR_SIZE, sp)
+ SAVE_ALL
+ REG_S sp,FR_ORIG_REG2(sp)
+ CLI
+ .set at
+ lui s0,%hi(PORT_BASE_SNI)
+ li a0,0x0f
+ sb a0,%lo(PORT_BASE_SNI+0x20)(s0) # poll command
+ lb a0,%lo(PORT_BASE_SNI+0x20)(s0) # read result
+ bgtz a0,poll_second
+ andi a0,7
+ beq a0,2,poll_second # cascade?
+ li s1,1 # delay slot
+ /*
+ * Acknowledge first pic
+ */
+ lb t2,%lo(PORT_BASE_SNI+0x21)(s0)
+ lui s4,%hi(cache_21)
+ lb t0,%lo(cache_21)(s4)
+ sllv s1,s1,a0
+ or t0,s1
+ sb t0,%lo(cache_21)(s4)
+ sb t0,%lo(PORT_BASE_SNI+0x21)(s0)
+ lui s3,%hi(intr_count)
+ lw s7,%lo(intr_count)(s3)
+ li t2,0x20
+ sb t2,%lo(PORT_BASE_SNI+0x20)(s0)
+ /*
+ * Now call the real handler
+ */
+ la t3,IRQ_vectors
+ sll t2,a0,PTRLOG
+ addu t3,t2
+ LONG_L t3,(t3)
+ addiu t0,s7,1
+ jalr t3
+ sw t0,%lo(intr_count)(s3)
+ sw s7,%lo(intr_count)(s3)
+ /*
+ * Unblock first pic
+ */
+ lbu t1,%lo(PORT_BASE_SNI+0x21)(s0)
+ lb t1,%lo(cache_21)(s4)
+ nor s1,zero,s1
+ and t1,s1
+ sb t1,%lo(cache_21)(s4)
+ jr v0
+ sb t1,%lo(PORT_BASE_SNI+0x21)(s0) # delay slot
+
+ /*
+ * Cascade interrupt from second PIC
+ */
+ .align 5
+poll_second: li a0,0x0f
+ sb a0,%lo(PORT_BASE_SNI+0xa0)(s0) # poll command
+ lb a0,%lo(PORT_BASE_SNI+0xa0)(s0) # read result
+ bgtz a0,3f
+ andi a0,7
+ /*
+ * Acknowledge second pic
+ */
+ lbu t2,%lo(PORT_BASE_SNI+0xa1)(s0)
+ lui s4,%hi(cache_A1)
+ lb t3,%lo(cache_A1)(s4)
+ sllv s1,s1,a0
+ or t3,s1
+ sb t3,%lo(cache_A1)(s4)
+ sb t3,%lo(PORT_BASE_SNI+0xa1)(s0)
+ li t3,0x20
+ sb t3,%lo(PORT_BASE_SNI+0xa0)(s0)
+ lui s3,%hi(intr_count)
+ lw s7,%lo(intr_count)(s3)
+ sb t3,%lo(PORT_BASE_SNI+0x20)(s0)
+ /*
+ * Now call the real handler
+ */
+ la t3,IRQ_vectors
+ addiu a0,8
+ sll t2,a0,PTRLOG
+ addu t3,t2
+ LONG_L t3,(t3)
+ addiu t0,s7,1
+ jalr t3
+ sw t0,%lo(intr_count)(s3) # delay slot
+ sw s7,%lo(intr_count)(s3)
+ /*
+ * Unblock second pic
+ */
+ lb t1,%lo(PORT_BASE_SNI+0xa1)(s0)
+ lb t1,%lo(cache_A1)(s4)
+ subu t0,1
+ nor s1,zero,s1
+ and t1,t1,s1
+ sb t1,%lo(cache_A1)(s4)
+ jr v0
+ sb t1,%lo(PORT_BASE_SNI+0xa1)(s0) # delay slot
+
+/*
+ * FIXME: This is definatly wrong but I'll have to do it this way
+ * 'till I get more hardware info.
+ */
+#ifdef CONFIG_LANCE32
+
+/*
+ * FIXME: detect this address
+ */
+#define LANCE_BASE 0xbb000100
+
+/* Offsets from base I/O address. */
+#define LANCE_DATA 0x10
+#define LANCE_ADDR 0x12
+#define LANCE_RESET 0x14
+#define LANCE_BUS_IF 0x16
+#define LANCE_TOTAL_SIZE 0x18
+
+/*
+ * ... check if we were interrupted by the Lance ...
+ */
+3: lh s0,LANCE_BASE+LANCE_ADDR
+ sh zero,LANCE_BASE+LANCE_ADDR
+ lh t1,LANCE_BASE+LANCE_DATA
+ andi t2,t1,0x80
+ beqz t1,3f # no Lance interrupt?
+ mfc0 t0,CP0_STATUS # delay slot
+ ori t0,0x041f
+ xori t0,0x041e
+ mtc0 t0,CP0_STATUS
+ jal do_IRQ
+ li a0,10 # delay slot
+ sh s0,LANCE_BASE+LANCE_ADDR
+ mfc0 t0,CP0_STATUS
+ ori t0,0x0401
+ xori t0,0x0001
+ mtc0 t0,CP0_STATUS
+ j ret_from_sys_call
+ nop # delay slot
+
+#endif /* CONFIG_LANCE32 */
+
+/*
+ * FIXME: This is definatly wrong but I'll have to do it this way
+ * 'till I get more hardware info.
+ */
+#ifdef CONFIG_SCSI_NCR53C8XX
+
+/*
+ * FIXME: detect this address
+ */
+#define NCR_BASE 0xb8000000
+
+/* Offsets from base I/O address. */
+#define NCR_INTF 0x14
+
+/*
+ * ... check if we were interrupted by the NCR ...
+ */
+3: lb t0,NCR_BASE+NCR_INTF
+ andi t0,7
+ beqz t0,3f # no NCR interrupt?
+ nop # delay slot
+ jal do_fast_IRQ
+ li a0,5 # delay slot
+ j return
+ nop # delay slot
+
+#endif /* CONFIG_SCSI_NCR53C8XX */
+
+/*
+ * "Jump extender" to reach spurious_interrupt
+ */
+3: j spurious_interrupt
+ nop # delay slot
+ END(sni_rm200_pci_handle_int)
diff --git a/arch/mips/sni/reset.c b/arch/mips/sni/reset.c
new file mode 100644
index 000000000..9dd017a7c
--- /dev/null
+++ b/arch/mips/sni/reset.c
@@ -0,0 +1,38 @@
+/*
+ * linux/arch/mips/sni/process.c
+ *
+ * Reset a SNI machine.
+ */
+#include <asm/io.h>
+#include <asm/system.h>
+
+/*
+ * This routine reboots the machine by asking the keyboard
+ * controller to pulse the reset-line low. We try that for a while,
+ * and if it doesn't work, we do some other stupid things.
+ */
+static inline void
+kb_wait(void)
+{
+ int i;
+
+ for (i=0; i<0x10000; i++)
+ if ((inb_p(0x64) & 0x02) == 0)
+ break;
+}
+
+void
+sni_hard_reset_now(void)
+{
+ int i, j;
+
+ sti();
+ for (;;) {
+ for (i=0; i<100; i++) {
+ kb_wait();
+ for(j = 0; j < 100000 ; j++)
+ /* nothing */;
+ outb_p(0xfe,0x64); /* pulse reset low */
+ }
+ }
+}
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
new file mode 100644
index 000000000..a4cc4a57f
--- /dev/null
+++ b/arch/mips/sni/setup.c
@@ -0,0 +1,108 @@
+/*
+ * Setup pointers to hardware dependand routines.
+ *
+ * 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.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ */
+#include <asm/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/processor.h>
+#include <asm/vector.h>
+
+/*
+ * Initial irq handlers.
+ */
+static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+
+/*
+ * IRQ2 is cascade interrupt to second interrupt controller
+ */
+static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL};
+
+extern asmlinkage void sni_rm200_pci_handle_int(void);
+extern asmlinkage void sni_fd_cacheflush(const void *addr, size_t size);
+extern struct feature sni_rm200_pci_feature;
+extern void sni_hard_reset_now(void);
+
+static void
+sni_irq_setup(void)
+{
+ set_except_vector(0, sni_rm200_pci_handle_int);
+ request_region(0x20,0x20, "pic1");
+ request_region(0xa0,0x20, "pic2");
+ setup_x86_irq(2, &irq2);
+ /*
+ * IRQ0 seems to be the irq for PC style stuff.
+ * I don't know how to handle the debug button interrupt, so
+ * don't use this button yet or bad things happen ...
+ */
+ set_cp0_status(ST0_IM, IE_IRQ0);
+}
+
+void (*board_time_init)(struct irqaction *irq);
+
+static void sni_rm200_pci_time_init(struct irqaction *irq)
+{
+ /* set the clock to 100 Hz */
+ outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
+ outb_p(LATCH & 0xff , 0x40); /* LSB */
+ outb(LATCH >> 8 , 0x40); /* MSB */
+ setup_x86_irq(0, irq);
+}
+
+unsigned char aux_device_present;
+
+void
+sni_rm200_pci_setup(void)
+{
+ tag *atag;
+
+ /*
+ * We just check if a tag_screen_info can be gathered
+ * in setup_arch(), if yes we don't proceed futher...
+ */
+ atag = bi_TagFind(tag_screen_info);
+ if (!atag) {
+ /*
+ * If no, we try to find the tag_arc_displayinfo which is
+ * always created by Milo for an ARC box (for now Milo only
+ * works on ARC boxes :) -Stoned.
+ */
+ atag = bi_TagFind(tag_arcdisplayinfo);
+ if (atag) {
+ screen_info.orig_x =
+ ((mips_arc_DisplayInfo*)TAGVALPTR(atag))->cursor_x;
+ screen_info.orig_y =
+ ((mips_arc_DisplayInfo*)TAGVALPTR(atag))->cursor_y;
+ screen_info.orig_video_cols =
+ ((mips_arc_DisplayInfo*)TAGVALPTR(atag))->columns;
+ screen_info.orig_video_lines =
+ ((mips_arc_DisplayInfo*)TAGVALPTR(atag))->lines;
+ }
+ }
+
+ irq_setup = sni_irq_setup;
+ fd_cacheflush = sni_fd_cacheflush; // Will go away
+ feature = &sni_rm200_pci_feature;
+ port_base = PORT_BASE_SNI;
+ isa_slot_offset = 0xb0000000;
+ request_region(0x00,0x20,"dma1");
+ request_region(0x40,0x20,"timer");
+ request_region(0x70,0x10,"rtc");
+ board_time_init = sni_rm200_pci_time_init;
+
+ hard_reset_now = sni_hard_reset_now;
+
+ if (mips_machtype == MACH_SNI_RM200_PCI)
+ EISA_bus = 1;
+ aux_device_present = 0xaa;
+}